Skip to content

Amatino 0.0.3 iOS & MacOS

Compare
Choose a tag to compare
@hwjeremy hwjeremy released this 19 Jul 04:46
· 139 commits to master since this release

Amatino Swift 0.0.3 is now available. Amatino Swift is library / framework that lets MacOS and iOS developers build double-entry accounting functionality into their applications. v0.0.3 is backwards compatible with v0.0.2, and makes the following changes:

  • Add new Balance class
  • Add new RecursiveBalance class
  • Add new GlobalUnitList class
  • Add new Transaction.createMany() method
  • Add unit tests covering all of the above
  • Remove some debugging craft and dead code

These features build on v0.0.2's progress toward making Amatino Swift easy to use. Where in the past you would need to manually encode and decode Data responses via the AmatinoAlpha class, you now have more expressive, clean, and simple syntax at your disposal.

##Balance & RecursiveBalance

Balance and RecursiveBalance allow you to retrieve the balance of a particular account. In practice, that means the total of all debits & credits party to that account. A 'recursive' balance totals debits and credits for the target account, and any child accounts.

Balances can be retrieved for any combination of date and denomination. For example, you might have an account denominated in U.S. Dollars, but be interested in retrieving its balance in Euros.

Here's an example of Balance.retrieve() in action:

try Balance.retrieve(
      session: session,
      entity: starkIndustries,
      account: cashAccount,
      callback: { (error: Error?, balance: Balance?) in
          guard error == nil else {
              // Handle error, e.g. 404 account not found, 403 you are not
              // authorised to view the account
          }
          guard let cashAccountBalance: Balance = balance else {
              // Should never happen, but we guard against nil like good
              // little programmers!
          }
          // Do cool stuff with the cashAccountBalance
          print("Cash account balance: \(cashAccountBalance.magnitude)")
  })

Transaction.createMany()

You can already create single Transactions using Transaction.create(). createMany() allows you to create up to ten Transactions in a single request. This dramatically reduces the round-trip latency suffered when you have more than one Transaction to insert.

createMany() is fed by lists of TransactionCreateArguments structs. Here’s an example:

let tx1Arguments = try TransactionCreateArguments(
    transactionTime: Date(),
    description: "Raise invoice for slick services",
    globalUnit: usd,
    entries: [
        Entry(side: .debit, account: receivables, amount: Decimal(20)),
        Entry(side: .credit, account: revenueAccount, amount: Decimal(20))
    ]
)
let tx2Arguments = try TransactionCreateArguments(
    transactionTime: Date(),
    description: "Borrow some Benjamins",
    globalUnit: usd,
    entries: [
        Entry(side: .credit, account: bankLoan, amount: Decimal(200)),
        Entry(side: .debit, account: cashAccount, amount: Decimal(200))
    ]
)
try Transaction.createMany(
    session: session,
    entity: starkIndustries,
    arguments: [tx1Arguments, tx2Arguments],
    callback: { (error: Error?, transactions: [Transaction]?) in
        guard error == nil else {
            // Handle errors
        }
        guard storedTransactions: [Transactions] = transactions else {
            // Should never happen, but guarding against nil is
            // spiritually wholesome
        }
        // Do cool stuff with newly stored Transactions
})

GlobalUnitList

v0.0.2 introduced the GlobalUnit class, without a way to list available Global Units! Enter GlobalUnitList, which will provide you with, you guessed it, a list of all available Global Units! Here’s how to use it:

try GlobalUnitList.retrieve(
    session: session,
    callback: { (error: Error?, units: GlobalUnitsList?) in
        guard error == nil else {
            // Handle errors
        }
        guard currencies: GlobalUnitList = units else {
            // Should never happen, but accidentally
            // unwrapping nil angers the startup gods
        }
        // Do cool stuff with our shiny currency list
        print("Retrieved \(currencies.count) currencies")
        return
})

There are 36 currencies available. You can look for a specific GlobalUnit in the GlobalUnitList with it’s unitWith(code:) method:

guard let USD: GlobalUnit = currencies.findWith(code: "USD") else {
    // .findWith() returns an optional. If we end up here, Amatino
    // doesn't support a currency with the supplied code.
}
// Do cool stuff with our new currency
print("Loaded a currency! Name: \(USD.name)")

Installation

I’m in the process of creating Carthage and Cocoapods distributions for Amatino Swift. In the mean time, compiled libraries are available on GitHub. You are also most welcome to clone the repo and compile Amatino Swift yourself.

Still to come

Many objects specified in the Amatino API HTTP documentation are not yet available in Amatino Swift. For example, account Ledgers. Further, available objects are missing some critical methods, like Transaction.delete().

Look out for v0.0.4 and onwards to add yet more capability to Amatino Swift. Let me know how you want Amatino Swift to develop on Twitter or on the forums. Sign up to the Development Newsletter to be notified when new versions of Amatino Swift are available.

– Hugh