A new version of the Amatino API has been deployed to all regions. 0.0.6 fixes a single bug, wherein the JSON result of a Transaction update was corrupted, and is otherwise backward compatible with 0.0.5.
Amatino is a double entry accounting API, and Amatino Swift allows macOS & iOS developers to utilise Amatino in a Swift application. v0.0.5 is a major new Alpha release introducing the
Ledger class, and some attendant smaller changes.
- Added new
- Added new
- Added new
LedgerPageclass, a low level class underpinning
- Added new
LedgerRowstruct, used by Ledgers
AccountTypeis now inferred by
- Added new
Account.create()async initialisers for various attribute mixes
Transactionwill now throw
ConstraintErrorif debits & credits do not balance on creation
- Fixed a bug whereby all times sent to the Amatino API were in local system timezone rather than UTC
- Added new Ledger-related unit tests
Retrieving a Ledger
Ledger.retrieve() overloads are available, allowing you to tailor the Ledger to your needs. For example, you might want to retrieve a specific timeframe or denominate the ledger in a particular unit (e.g. a non-native currency). You can also reverse-order the Ledger such that the first pages retrieves the most recent transactions.
Amatino Swift may be installed via Carthage. Add
github "amatino-code/amatino-swift"to your
Enjoy, and be sure to tell me what you think!
A new version of the Amatino API has been deployed to all regions. 0.0.5 contains breaking changes to the Ledger object, and is not backward compatible with 0.0.4.
- Ledgers may now only be retrieved one at a time
- Ledgers are now paginated in rows of 500
- Ledgers may now be returned in order of ascending or descending transaction time
- Ledgers now require a
- Returned Ledger root type is now a
JSON Objectrather than a
- Returned Ledger
end_timewill now be the start and end of the Ledger window, rather than the earliest and latest Transaction in the Ledger
end_timewill now default to now at UTC if supplied as
start_timewill now default to
end_time– 1 year if supplied as
- Fixed a bug that could cause Amatino to return a stale cached Ledger when
nullhad previously been provided as a Ledger start time
- Fixed a bug that caused Transactions to be stored with incorrect times (The
transaction_timefield was not being properly interpreted as UTC)
All the above changes also apply identically to the RecursiveLedger object.
The Amatino API obeys the Semantic Versioning convention: Any version before 1.0.0 should be considered unstable, and breaking changes may occur at any time. Even so, I don’t want to cause breaking changes unnecessarily, and don’t take this lightly.
These changes are aimed at making Ledger objects more useful in real world applications. They are the result of experimentation during development of the upcoming Amatino Swift v0.0.5.
A new version of the Amatino API, v0.0.4, is now live and running in all regions. 0.0.4 is backward-compatible with 0.0.3, and makes the following changes:
- Add new ‘Position‘ object
- Add new ‘Performance‘ object
- Fix bug causing Trees to display negative balances in <> instead of ()
- Fix bug causing Trees to sometimes miscalculate the balance of income or expenses accounts in non-native denominations
Position & Performance were not the features I expected to be working on this week. In fact, I had not ever thought of building them at all. Last weekend, I posted Amatino to HackerNews. Lots of great feedback flowed in.
A consistent theme was: “where are the reporting tools?” In my grand-vision, Amatino is a data layer sitting below reporting in an application stack. However, an email from a prospective customer gave me a jolt. They asked: ‘Can Amatino create a balance sheet?’
Well no, it can’t, I answered. I started to type a response about how a balance sheet is too domain-specific, not a generic enough construct, and that it could be constructed in application logic out of the base components Amatino provides. Then it hit me that I was very wrong.
Abstract it back far enough, and a balance sheet is a snapshot of the position of an entity in time. We call it various names and format it in various ways, but it is at its core a very simple way of observing asset, liability, and equity accounts.
The same appears to hold true for income statements. They are, in their most generalised form, a measurement of the performance of an entity over a period of time.
Thought of in this way, balance sheets and income statements become generic objects. They are fully compatible with Amatino’s mission as a provider of generic, jurisdiction-agnostic functions for manipulating financial data.
Armed with this new thinking, I set out to add in-built capability to produce Position and Performance objects, which may be extended by an application to produce balance sheets and income statements.
Creating these objects was, fortunately, quite painless. Most of the machinery used to build them is repurposed from the Tree production line. In particular, the ability to generate a Position or Performance in any denominating unit is lifted straight from the code that builds Trees.
Trees, Positions, and Performances are by far the most complex objects Amatino can synthesise. The algorithms that compute them make my head spin.
That’s a roundabout way of saying: There will be bugs. Positions and Performances have been integrated into the API unit-testing suite at a shallow level. It will take time to build more comprehensive testing. More testing is most especially required around the production of Positions and Performances in arbitrary denominations featuring heterogeneous underlying native units.
The most important takeaway from all this is: Thank you for your feedback. By telling me what you want, you can shape Amatino’s development.
Trees are, in my humble opinion, the most exciting object the Amatino API can build. They are hierarchical structures of every Account in an Entity, including balances, recursive balances. They are a great way to get a whole-Entity picture.
Somehow, I had ommitted them from the docs. That omission is now fixed! In future, I will need to do some work to flesh out the related Tree Node documentation. It is not yet clear how the Tree Node behaves when it omits data due to a lack of read permissions on a particular Account.
The Amatino API HTTP documentation has been updated. This update corrects errors in references to Global Units and Custom Units. Previously, the documentation stated that such units should be identified by their string codes. For example,
'usd' for U.S. Dollars.
Now, the documentation states that units should be identified by their integer identifiers. For example,
5 for U.S. Dollars.
This error was the result of some earlier experiments with removing integer unit identifiers in favour of string identifiers. The experiments did not go well, and lots of problems resulted. So, I reverted to integer identifiers, but forgot to update the documentation.
Amatino Swift allows MacOS and iOS developers to build double-entry accounting functionality into their apps. Until today’s v0.0.4 release, it was a bit tricky to install. To make installation easy, Amatino Swift is now compatible with Carthage. Carthage is a Swift dependency manager. In the project’s own words:
Carthage is intended to be the simplest way to add frameworks to your Cocoa application.
Carthage builds your dependencies and provides you with binary frameworks, but you retain full control over your project structure and setup. Carthage does not automatically modify your project files or your build settings.
You can install Carthage by downloading and running
Carthage.pkg from the Carthage project releases page.
Installing Amatino Swift with Carthage
Navigate to your project directory, and create a file named “
Cartfile“. Inside that file, add the line
github "amatino-code/amatino-swift". You can create the file, and insert the required line into the file, with the following command:
$ echo 'github "amatino-code/amatino-swift"' > Cartfile
Next, tell Carthage to download the Amatino Swift repository and compile MacOS and iOS frameworks, by running the following command inside your project directory:
$ carthage update
Once the process is complete, you should have
Amatino.framework binaries available in the
The following instructions are applicable to MacOS applications. Instructions for iOS are broadly similar, and all instructions are available in detailed form in the Carthage project documentation.
Embedding Amatino in a MacOS application
Drag the binaries for your target platforms to the Embedded Binaries section of your Xcode project.
Next, to enable debugging, create a Copy Files phase in your target’s Build Phases tab:
Inside the phase, select Products Directory from the Destination drop down menu.
Finally, drag the
Amatino.framework.dSYMfile into the Add files here section.
For more detailed instructions, check out the Carthage project documentation.
Where to next?
Now that Amatino Swift is easier to install, it’s time to smash together more functionality. In particular, I’d like to get Ledgers working as soon as possible.
Have a preferred method of installing Swift Frameworks? Please tell me about it on Twitter, on the forums, or via email. I would love to hear from you, and develop Amatino Swift in such a way as to make it easy for you to install.
A new version of Amatino Swift is 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
- Add new
- Add new
- Add new
- Add unit tests covering all of the above
- Remove some debugging cruft & 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.
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:
RecursiveBalance.retrieve() syntax is identical.
You can already create single Transactions using
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:
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:
There are 36 currencies available. You can look for a specific
GlobalUnit in the
GlobalUnitList with it’s
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
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.
A new version of the Amatino API has been deployed to all regions. v0.0.3 is not fully backwards compatible with v0.0.2. v0.0.3 makes the following changes:
- Fixed a bug which could cause Balance retrieval to yield
()to denote negative values
The second change is the big bad backwards compatibility breaker. Say you recorded a debit of $10 against an asset account. In 0.0.1, Amatino would have retrieved the balance as
<10.00>. Now, it will return
To be honest, I have no idea why I was using
<> to begin with. There might have been some logic to it, perhaps because it is the default for negative numbers in PostgreSQL. But it’s not appropriate for an accounting system, where convention heavily favours
This kind of breaking change is not something I take lightly. Amatino obeys the Semantic Versioning convention, wherein versions before 1.0.0 may make breaking changes at any time. Regardless, I want breaking changes to be few and far between, if they must occur at all.
In future, once Amatino hits 1.0.0 and is stabilised, a breaking change would be pushed to a new major version and would require opt-in. You will never have to worry about a breaking change after 1.0.0.
A new version of the Amatino API Swift library is available. Amatino Swift allows you to store double-entry accounting data in a Swift application, on iOS or MacOS.
Entrystruct, with comprehensive initialisers
Sessionclass for use outside
- Unit tests for all of the above
Taken together, these changes allow you to interact with the Amatino API much more easily than in 0.0.1. 0.0.1 was fully dependent on the
AmatinoAlpha class – A thin wrapper around HTTP requests that required you to deal with your own data encoding, and parse raw
Data responses from the Amatino API.
I’m still studying the best way to distribute iOS and MacOS libraries. Right now I am leaning towards CocoaPods, and would welcome any input you might have. In the mean time, compiled libraries are available on GitHub. You are also most welcome to clone the repo and compile Amatino Swift yourself.
Here are some examples the new capabilities available in Amatino Swift v0.0.2:
Create a Session
This is analogous to ‘logging in’. You’ll notice the session is passed as a parameter throughout following examples.
Create an Entity
Entities are beings you wish to describe with accounting information. For example, a person, company, country, or project.
- Retrieve an Entity
- Retrieve a GlobalUnit
- Create an Account
- Retrieve an Account
- Create a Transaction
- Retrieve a Transaction
Still to come
The majority of objects specified in the Amatino API HTTP documentation are still not available in Amatino Swift. One glaring example is the Global Unit List – How are you supposed to retrieve Global Units if you don’t know which ones are available!?
Look out for v0.0.3 and onwards to add the missing pieces of the puzzle. 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.