Skip to content

Objects

Jóhannes Erlingsson edited this page May 15, 2017 · 1 revision

Business objects

All business objects in the Meniga SDK implement both Parcelable and Serializable. Furthermore, any object that can be updated also extends StateObject which means that they can revert themselves to a previous revision of themselves, such as when a network call to persist the object fails. Furthermore, all updateable objects also implement the clone method.

All Meniga business objects implement equals.

All Meniga business objects provide a getter for a field but a setter is in most cases only provided for fields that can be updated on the server.

To make changes to an updateable object, use the setters to set new data and then call the instanced .update method. This will cause the object to persist the changes. If the network call fails you can call the .revert method to revert any changes made through the setters.

Some objects have setters for fields that are not updateable and they will be marked as such in the documentation. These setters are usually for user convenience or to make the objects easier to use than what is provided directly from the api.

Also available is the instanced .refresh method that reloads the object from the server and refreshes all fields that have been updated remotely.

Each business objects contains either static or instance API methods. For example, each object that can be created by a client has a static .create method which returns the newly created object. Similarly, most objects have a static .fetch method that takes the id of the object as a parameter and returns the specified, here's an example using the MenigaTransaction object:

MenigaTransaction.create(DateTime.now(), "Bakery Trip", new MenigaDecimal(-100), bakeriesCatId).getTask().continueWith(new Continuation<MenigaTransaction, Object>() {
	@Override
	public Object then(Task<MenigaTransaction> task) throws Exception {
		if(task.isFaulted()) {
			// Handle error
			return null;
		}
		MenigaTransaction newTransaction = task.getResult();
		return null;
	}
});

newTransaction.setAmount(new MenigaDecimal(-72));
newTransaction.update().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		if(task.isFaulted()) {
			// Failure, revert changes
			newTransaction.revert();
			// TODO notify UI
			return null;
		}
		// TODO refresh UI
		return null;
	}
});

MenigaTransaction

Transactions are the heart of the Meniga solution. Therefore we provide a robust and flexible API of querying transactions in different ways from the Meniga API. The MenigaSDK provides ability to get, create, update, delete and refresh transactions.

Fetch a single transaction

MenigaTransaction.fetch(736).getTask().continueWith(new Continuation<MenigaTransaction, Object>() {
	@Override
	public Object then(Task<MenigaTransaction> task) throws Exception {
		// MenigaTransaction with id 736 can be retrieved via task.getResult if there was no network error
		return null;
	}
});

Fetch a list of transactions

MenigaTransaction.fetch(new TransactionsFilter.Builder().merchantId(345).build()).getTask().continueWith(new Continuation<MenigaTransactionPage, Object>() {
	@Override
	public Object then(Task<MenigaTransactionPage> task) throws Exception {
		// All transactions with merchant id 345 are contained in the task
		return null;
	}
});

Create a transaction

MenigaTransaction.create(DateTime.now(), "Bakery Trip", new MenigaDecimal(-100), bakeriesCatId).getTask().continueWith(new Continuation<MenigaTransaction, Object>() {
	@Override
	public Object then(Task<MenigaTransaction> task) throws Exception {
		// The newly created transaction is contained in the task
		return null;
	}
});

Save a transaction

newTransaction.update().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		// Update was successful if task.isFaulted is false
		return null;
	}
});

Delete a transaction

newTransaction.delete().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		// Delete was successful if task.isFaulted is false
		return null;
	}
});

Refresh a transaction with new server data

transaction.refresh().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		if(task.isFaulted()) {
			// TODO
		}
		return null;
	}
});

TransactionsFilter

A transaction filter can be used when fetching transactions. To use a transaction filter create an TransactionsFilter using the Builder class inside it (new TransactionsFilter.Builder) and set the properties you want to filter by.

Creating a filter

//Filter by a category, within the dates from - to and order by amount
TransactionsFilter filter = new TransactionsFilter.Builder()
	.category(catId)
	.amounts(from, to)
	.orderBy(SeriesOrderBy.BY_AMOUNT)
	.build();

This is just an example of how a filter can be created and then used to fetch transactions.

MenigaTransactionPage

Sometimes when dealing with a large number of transactions it may be preferable to paginate them. This is available through MenigaTransactionPage. It contains an extra variable, numTotalTransactions, which you can use to configure through the .page() which page you are interested in. You can determine how many transactions per page you want and what page you want allowing you to skip transactions in the list using the .page() method. You can then fetch the next page which will fetch the next number of transactions.

Fetch a transaction list

TransactionsFilter filter = new TransactionsFilter.Builder()
		.category(catId)
		.amounts(from, to)
		.orderBy(SeriesOrderBy.BY_AMOUNT)
		.page(0, 20)
		.build();
MenigaTransaction.fetch(filter).getTask().continueWith(new Continuation<MenigaTransactionPage, Object>() {
	@Override
	public Object then(Task<MenigaTransactionPage> task) throws Exception {
		// Task object contains the transaction list. The transaction list object will tell you how many total transactions
		// this filter qualifies for and you can then use that to find out how many pages you have by dividing (in this case)
		//page.getTotalNumTransactions() / 20
		return null;
	}
});

MenigaTransactionSeries

An MenigaTransactionSeries can be used when you want to aggregate transaction data. To fetch a series a transactionSeriesFilter must be created.

Fetch transaction series

//.disableSkipTake turns off pagination so that we can be sure to get all the results in one
TransactionsFilter filter = new TransactionsFilter.Builder()
	.period(from, to)
	.category(this.selectedTransaction.getCategoryId())
	.disableSkipTake()
	.build();
Options options = new Options(
	TimeResolution.MONTH,
	true,
	false,
	false
);
List<SeriesSelector> selectors = new ArrayList<>();
selectors.add(new SeriesSelector(
				new TransactionsFilter.Builder()
						.merchantId(selectedTransaction.getMerchantId())
						.useParentMerchantIds(true)
						.disableSkipTake()
						.build()
		));
MenigaTransactionSeries.fetch(
		filter,
		options,
		selectors
).getTask().continueWith(new Continuation<List<MenigaTransactionSeries>, Object>() {
	@Override
	public Object then(Task<List<MenigaTransactionSeries>> task) throws Exception {
		// Use series
		return null;
	}
});

MenigaTransactionRule

A user can create rules that are triggered by certain conditions (a new transaction with a certain merchant). The rules perform actions on the transaction(s), such as marking all transactions from said merchant as read as soon as they enter the system or recategorize them. There are many options when creating rules.

MenigaAccount

Your accounts are represented by MenigaAccount and its additional objects. You can query your accounts the same way as transactions. They can be fetched, updated, deleted and refreshed.

Fetch an account

MenigaAccount.fetch(384).getTask().continueWith(new Continuation<MenigaAccount, Object>() {
	@Override
	public Object then(Task<MenigaAccount> task) throws Exception {
		// The account is in the task object
		return null;
	}
});

Fetch a list of accounts (all accounts)

MenigaAccount.fetch().getTask().continueWith(new Continuation<List<MenigaAccount>, Object>() {
	@Override
	public Object then(Task<List<MenigaAccount>> task) throws Exception {
		// All of the user's accounts are in the task object
		return null;
	}
});

Update an account

acc.setName("New Account Name");
acc.update().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		if(task.isFaulted()) {
			acc.revert();
		}
		else {
			// Do something with the updated account
		}
		return null;
	}
});

Delete an account

acc.delete().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		if(task.isFaulted()) {
			// Trying to delete from the server failed.
			// The account still exists in the server database and you can continue to work with it.
		}
		else {
			// The account has now been deleted from the server.
			// The account is now marked deleted and you should remove it. Any further api operations on this account are not allowed.
		}
		return null;
	}
})

Refresh an account

account.refresh().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		if(task.isFaulted()) {
			// TODO
		}
		return null;
	}
});

MenigaCategory

Categories are an integral part of the Meniga solution. Each transaction is categorized and marked with a categoryId. An MenigaCategory provides further information on each category. A user can also create her/his own categories. The distinction between user created categories and system created categories is made with the 'isSystemCategory' property. Categories also have a children categories property allowing you to have categories in a two tier category tree.

If a category is a user created category it will be of the type MenigaUserCategory and directly inherit from MenigaUserCategory. Only the MenigaUserCategory has setters and can be updated.

Fetch a category

MenigaCategory.fetch(8374).getTask().continueWith(new Continuation<MenigaCategory, Object>() {
	@Override
	public Object then(Task<MenigaCategory> task) throws Exception {
		// The task object contains the category we are after
		return null;
	}
});

Fetch all categories as a flattened list

// Fetches all categories as a flat list where parent categories and children are in one dimensional list
MenigaCategory.fetch().getTask().continueWith(new Continuation<List<MenigaCategory>, Object>() {
	@Override
	public Object then(Task<List<MenigaCategory>> task) throws Exception {
		// Task object contains all categories in a flattened list
		return null;
	}
});

Fetch a category tree

MenigaCategory.fetchTree().getTask().continueWith(new Continuation<List<MenigaCategory>, Object>() {
	@Override
	public Object then(Task<List<MenigaCategory>> task) throws Exception {
		// Task object contains list of all root categories. Each root category will contain it's children.
		return null;
	}
});

Create a user category that is a root category

MenigaUserCategory.create("My Custom Category", false, CategoryType.INCOME).getTask().continueWith(new Continuation<MenigaUserCategory, Object>() {
	@Override
	public Object then(Task<MenigaUserCategory> task) throws Exception {
		// Task will contain the newly created user category. This will be a root category, not under any other category
		return null;
	}
});

Create a user category that is a child category

MenigaUserCategory.create("My Custom Category", false, rootCategoryId).getTask().continueWith(new Continuation<MenigaUserCategory, Object>() {
	@Override
	public Object then(Task<MenigaUserCategory> task) throws Exception {
		// Task will contain the newly created user category. This will be a child category, under category with rootCategoryId
		return null;
	}
});

Update a category

userCat.setName("New Category Name");
userCat.setName("New Category Name");
		userCat.update().getTask().continueWith(new Continuation<Void, Object>() {
			@Override
			public Object then(Task<Void> task) throws Exception {
				// Task will indicate if the update was successful
				return null;
			}
		});

Delete a user category

userCat.delete().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		// Task will indicate if the delete was successful
		return null;
	}
});

Refresh a user category

userCat.refresh().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		if(task.isFaulted()) {
			// TODO
		}
		return null;
	}
});

MenigaMerchant

Sometimes we want more detailed information on a particular merchant. We can fetch an MenigaMerchant object to obtain this information. Merchants can only be fetched from the server and only one at a time.

Fetch a merchant

MenigaMerchant.fetch(3838).getTask().continueWith(new Continuation<MenigaMerchant, Object>() {
	@Override
	public Object then(Task<MenigaMerchant> task) throws Exception {
		// Task object will contain the merchant object
		return null;
	}
});

MenigaUser

Note that the user endpoint has not been fully implemented.

To get all the information on the user currently logged in we can us the MenigaUser object. The MenigaUser class exposes several api operations on a user. A user can be fetched, updated, deleted and refresh. In addition a user can be reset, he can opt in and out of the Meniga system and metadata can be set.

Fetch users

// Coming in a future release

Update a user

// Coming in a future release

Delete a user

// Coming in a future release

Refresh a user

user.refresh().getTask().continueWith(new Continuation<Void, Object>() {
	@Override
	public Object then(Task<Void> task) throws Exception {
		if(task.isFaulted()) {
			// TODO
		}
		return null;
	}
});

Change culture

// Coming in a future release

Opt in

// Coming in a future release

Opt out

// Coming in a future release

Reset

// Coming in a future release