Amatino Swift 0.0.11 Released

Amatino Swift 0.0.11 has been released! This is a huge release with wide ranging changes and substantial new features. It is not backwards compatible with 0.0.10, but any code written for 0.0.10 will compile for 0.0.11 with minor adjustments.

  • Almost all asynchronous Amatino methods now accept a (Result<T, Error>) -> Void callback parameter, using the new Swift 5 Result type. The previous (Error?, T?) -> Void parameter remains available. You now have a choice to use either depending on your preferred style.
  • Add Denomination protocol, which codifies the characteristics of CustomUnit and GlobalUnit and allows method signatures accepting either of those classes to be streamlined.
  • Add Denominated protocol, which gives default behaviours to classes denominated in a Denomination, such as Transactions and Ledgers.
  • Renamed many method signatures parameters for more expressive syntax. For example, someMethod(then: (Error?, Object?) rather than someMethod(callback: (Error?, Object?)
  • Remove all use of Int64, replace with Int. Amatino Swift will not function on 32-bit platforms, so the occasional use of Int64 added needless confusion.
  • The AmatinoError case .inconsistentInternalState has been renamed .inconsistentState
  • Publicly exposed Account.create() taking Account.CreateArguments struct. Gives extra flexibility when designing GUI for account creation
  • GlobalUnitList now conforms to the Sequence protocol. I.e. you can loop over the list without needing to access the raw .units property.
  • TheGlobalUnitList units property is now sorted first by GlobalUnit.priority and then alphabetically by GlobalUnit.name
  • AccountType has a new static method, .typeWith(:name), which returns an AccountType with the given name
  • Tree now conforms to the Sequence protocol, iterating over Node conforming objects
  • Multiline strings throughout the library are no longer peppered with \n newlines. For example, AmatinoError messages.
  • Account.CreateArguments now enforces a minimum .name character length of 1.
  • Tree now features a .flatAccounts property, which returns recursive flattened list of all Accounts in the Tree as Node objects. This is effectively a list of all Accounts in an Entity.
  • Add new AccountRepresentative protocol, to which Account, TreeNode and PlaceholderNode conform. Provides base Account metadata – accountId, name, type, and is accepted in many places where Account was formerly required.
  • Fixed an internal typo in Account.DeletionArguments (no effect on public API)
  • Transaction, Balance, Account, Ledger, GlobalUnitList, Performance, Position and Entity methods may no longer throw. Errors are now exclusively handled by the error parameter in respective callbacks.
  • Ledger may now be retrieved with an object conforming to the AccountRepresentative protocol. This saves an intermediary Account retrieval when, for example, retrieving a Ledger based on a Tree node
  • Add User class including create(), retrieve(), delete() methods
  • Add User class lifecycle testing
  • Ledger.nextPage() renamed .retrieveNextPage()
  • RecursiveLedger.nextPage() renamed .retrieveNextPage()
  • Add Session.delete() method

Amatino Swift source code is available on GitHub, and you can add Amatino accounting functionality to your macOS or iOS project via Carthage or CocoaPods.

Amatino Python 0.0.13 Released

Rejoice, Pythonistas! A new version of the Amatino Python library is now available. 0.0.13 adds new capabilities. Amatino Python is now nearing initial feature completion, with almost all existing API classes covered. Watch out, 0.0.13 is catastrophically breaking, many method signatures have changed and code written for 0.0.12 will not work.

Why all the breaks? Many methods in 0.0.12 required the provision of a Session independent of an Entity, despite that Entity having ready access to the Session used when it was itself initialised. This redundancy was needlessly verbose.

  • Add new UserList class
  • Add User.delete(), .create(), and .create_many() method
  • Add TransactionVersionList class
  • Conform Ledger to collections.Sequence
  • Simplify Ledger, Balance, Account, and Transaction method signatures: No more Session requirement
  • Publicise User.decode_many() method
  • Conform Transaction to collections.Sequence
  • Add Transaction.magnitude property
  • Conform Balance and RecursiveBalance to Denominated protocol
  • Conform Ledger and RecursiveLedger to Denominated protocol

Ledger and Transaction may be now be directly iterated over, revealing constituent LedgerRows and Entries respectively. They may also be subscripted.

An example using Ledger:

ledger = Ledger.retrieve(
   entity=mega_corp,
   account=revenue
)

for row in ledger:
   print("[{date}] {balance}".format(
      date=row.transaction.time.strftime("%Y-%m-%d"),
      balance='{:,.2f}'.format(row.balance)
   ))

print("Last row balance: {balance}".format(
   balance='{:,.2f}'.format(ledger[-1].balance)
))

And Transaction:

sale = Transaction.retrieve(
   entity=mega_corp,
   id_=42,
   denomination=USD
)

print("Largest single entry: {amount}".format(
   amount='{:,2f}'.format(
      max([entry.amount for entry in sale])
   )
))

The new UserList allows you to retrieve all white-labels managed by your billing account. Draw on the State enum to refine the retrieval to all, deleted, or active users.

active_users = UserList(
   session=session,
   state=State.active
)

print("Currently paying for {num} users".format(
   num=str(len(active_users))
))

Review the history of modifications to a Transaction using the TransactionVersionList.

versions = TransactionVersionList.retrieve(
   entity=mega_corp,
   transaction=big_sale
)

for version in versions:
   print("{time}: {magnitude}".format(
      time=version.version_time.strftime("%Y-%m-%d"),
      magnitude='{:,2f}'.format(version.magnitude)
   )

For detailed documentation of the properties and methods of all Amatino classes, check out the Amatino Python Documentation.

You can install Amatino via PyPi:

$ pip install amatino

Or, if you already have Amatino Python installed, upgrade:

$ pip install --upgrade amatino

Your feedback is most welcome on the Amatino discussion forums, or on Twitter.

Amatino Python 0.12 Released

Hot on the heels of 0.0.11, Amatino Python 0.0.12 has been released. 0.0.12 enhances the capabilities of the Position and Performance classes added in 0.0.11, and introduces the new Tree class.

  • Add Tree class
  • Add total account balance properties to Performance
  • Add total account balance properties to Position
  • Add tests for all new features

The new properties in Position and Performance give you quick access to key financial data describing an entity.

print("{name} total assets: ${assets}".format(
   name=mega_corp.name,
   assets='{:,}'.format(position.total_assets)
)
# Example output:
# Mega Corp total assets: $1,543

Check out the Amatino Python documentation to see all the new properties.

The new Tree class is a beast, combining all accounts in an entity into a single recursive object, at a particular balance date. Like Position and Performance, Tree accounts are of type TreeNode, which means you have access to recursive and individual balances and other useful data.

from amatino import Tree
from datetime import datetime

tree = Tree.retrieve(
   entity=mega_corp,
   balance_time=datetime.utcnow()
)

print("{name} equity: ${equity}".format(
   name=mega_corp.name,
   equity='{:,}'.format(tree.total_equity)
)

For detailed documentation of the properties and methods of the Tree class, check out the Amatino Python Documentation.

You can install Amatino via PyPi:

$ pip install amatino

Or, if you already have Amatino Python installed, upgrade:

$ pip install --upgrade amatino

Be sure to leave your feedback on the Amatino discussion forums, or on Twitter, we’d love to hear what you think about Amatino Python.

Amatino API v0.0.8 now live

A new version of the Amatino API is live in all regions. API 0.0.8 may be substantially backward compatible with 0.0.7, however, is not tested as such and relying on backwards compatibility during these 0.0.X releases is not recommended.

  • Fixed a bug which could cause a stale, cached Performance or Position to be returned after a Transaction insertion
  • Fixed a bug causing Custom Unit update requests to fail, returning a 500 code.
  • Account objects now feature a ‘Children’ parameter, which contains integer IDs of all direct child Accounts.
  • Fixed a rare condition wherein internal telemetry recording could fail due to a unique key constraint violation, causing the API to spew 500 errors in response to any request
  • Substantial code-style enhancements in the core API to ease maintainability
  • Improved test coverage over rare edge cases in Account operations

Amatino JS 0.0.14 Released

A tiny update has been released for Amatino’s Node library.  0.0.14 fixes a silly bug in the inbuilt Node version enforcement script. The script is run after installation, and was supposed to stop Node versions lower than 10.4 from running Amatino JS. Instead it was stopping versions greater than 11.0 from running it!

Amatino JS 0.0.14 is available on NPM and on GitHub.

Amatino JS 0.0.13 Released

A new version of the Amatino Node.js library is now available. 0.0.13 addresses a big issue that has plagued previous Amatino JS versions, and fixes one other nasty bug:

  • Decode large integers as BigInt rather than hacking them into String
  • Encode Date month properly (previously the previous month was encoded)

When it comes to large integers, JavaScript is a bit of a minefield. Until BigInt came along, JS had no native way of dealing with integers larger than 53 bits.

Internally, the Amatino API only thinks in 64-bit integers and arbitrary-precision numbers. Floats & lower-width integers are absent.

These 64-bit integers flow out into the public domain as IDs of various objects. For example, Session IDs and User IDs are random 64-bit integers. If your Entity is extremely large, you might also encounter them as IDs for Transactions.

It is therefore critical that any Amatino client library be able to understand 64-bit integers. So what to do with JavaScript, whose native number type is 53 bits wide? At first, Amatino JS translated them to String, and sent them back to the API as JSON Strings. This was a huge, awful hack involving a flakey Regular Expression.

Surprise surprise, this caused problems for customers. We are very sorry for that. 0.0.13 solves the problem by taking advantage of the “new” native BigInt type. BigInts arrived in Google V8 version 6.7, have been available in Node since version 10.4.

Consequently, Node.js 10.4 is now the minimum required version for a project that includes Amatino JS.

Because JavaScript wants to be a constant barrel of laughs, the native JSON library cannot serialise or deserialise BigInt. We therefore owe big thanks to Andrey Sidorov, whose MIT licensed json-bigint project we adapted to handle the relevant JSON operations.

Installation & Usage

You can install Amatino JS via NPM. For more information about NPM, check out npmjs.com.

$ npm install amatino

Amatino classes may then be accessed by requiring Amatino:

const Amatino = require('Amatino'); Amatino.Transaction.create(...);

If you already have Amatino JS installed, you can update it by executing:

$ npm update Amatino

Take care – This operation may not update the Amatino version number in package.json. You may need to change that manually.

Amatino Python 0.0.7 Released

Amatino Python 0.0.7 has been released! This is a major new release, introducing a vast array of capabilities. It is not backwards compatible with 0.0.6. You can install Amatino via PyPi:

$ pip install amatino

Or, if you already have Amatino Python installed, upgrade:

$ pip install --upgrade amatino

Here’s the full list of changes:

  • Added Entity class including .create(), .retrieve()
  • Added Account class including .create(), .retrieve(), .update()
  • Added Transaction class including .create(), .retrieve(), .update(), .delete()
  • Added Entry class including various convenience initialisers
  • Added GlobalUnit class including .retrieve()
  • Added CustomUnit class including .create(), .retrieve()
  • Added User class including .retrieve()
  • Added Ledger & RecursiveLedger classes
  • Added internal Denomination abstract class
  • Added internal enumeration HTTPMethod
  • Added internal interface Encodable
  • Added some internal error types to provide more robust error explanations
  • Added tests for new classes
  • Removed AmatinoAlpha class & attendant tests

The high level

0.0.7 is the first Amatino Python release to include expressive, object-oriented syntax. Previous releases required manual composition of requests using the AmatinoAlpha object.

Documentation

So many new goodies. But how do we use them? Documentation to the rescue! All the new classes included in 0.0.7 are documented in Amatino Python’s GitHub Wiki. For example, you can check out the Transaction page to see all the Transaction class’s properties and methods.

The future

The most glaring omissions are 0.0.7 are probably Balance, Position, and Performance. Expect 0.0.8 to add those bad boys in the near future.

Enjoy!

– Hugh

Amatino JS 0.0.12 Released

Amatino’s Node.js library has receive a big ‘ol update. 0.0.12 lifts Amatino JS out of bare-bones alpha territory. New classes allow you to build accounting & finance functions into Node.js applications.

0.0.12 is by no means a ‘feature complete’ or beta release. Most Amatino services still lack dedicated classes. However, it is a major step towards such a release. To see plans for 0.0.13 and beyond, check out the newly populated GitHub issue tracker, and Projects page within which future work is organised into planned releases.

New capabilities

Amatino JS now offers the following classes:

Allowing you to easily access and manipulate the `Primary Objects’ discussed in Amatino’s HTTP documentation.

Amatino Javascript Documentation

This release includes the first version of Amatino’s Javascript documentation. The docs are hosted on the Amatino JS GitHub wiki. They provide comprehensive reference for all properties and methods, and example code.

Screenshot from the Amatino JS docs Account page

Installation & Usage

You can install Amatino JS via NPM. For more information about NPM, check out npmjs.com.

$ npm install amatino

Amatino classes may then be accessed by requiring Amatino:

const Amatino = require('Amatino');
Amatino.Transaction.create(...);

The Amatino JS Readme has been updated with a getting-started guide, including example code showing you how to start utilising Amatino services. Check it out on the Amatino JS GitHub page.

What’s next?

Check out the Amatino JS Projects page to see the roadmap for future releases. These plans are totally in flux: Feel free to contact me via Twitter (@hugh_jeremy), email (hugh@amatino.io), or on the Amatino discussion forums, and tell me what you would like to see next.

Special thanks must go to James Robb (jamesrobb.co.uk). Over the past few weeks, James has provided substantial and invaluable advice about how to move the Amatino JS project forward. Thank you James!

– Hugh

 

 

Amatino Swift 0.0.8 Released

A new version of Amatino Swift has been released. 0.0.8 makes Amatino Swift CocoaPods compatible. You can now install Amatino by adding it to your Podfile:

pod 'Amatino', '>= 0.0.8'

The underlying library is unchanged. Here’s the full changelog:

  • Added Amatino.podspec
  • Changed macOS target to 10.10 (arbitrary at this point)
  • Changed iOS target to 10.3 (arbitrary at this point)
  • Added MIT license
  • Updated readme.md to reflect latest development of the library

– Hugh

Amatino Swift v0.0.7 Released

Amatino Swift 0.0.7 is now available! You can install it via Carthage or get the source code from GitHub. 0.0.7 is a major new release that adds significant capability. The powerful Tree, Position, and Performance objects are now available. Here’s the full change-log:

    • Remove InternalLibraryError, which sneakily survived the error consolidation purge in 0.0.6
    • Add Account.update() method
    • Add Account.delete() method
    • Add Account.deleteRecursively() method
    • Add Tree class
    • Add Position class
    • Add Performance class
    • Add Node protocol
    • Add Node conforming TreeNode and PlaceholderNode classes (used by Tree, Position, and Performance)
  • Consolidate SessionCreateArguments & SessionAttributes into Session
  • Consolidate BalanceRetrieveArguments into Balance
  • Drastically simplified and empowered the internal EntityObject protocol, reducing code complexity and duplication (does not affect public API)
  • Added unit tests for new features

Plant some Trees

Trees present the entire chart of accounts of an Entity as a hierarchical object. Each node in the Tree summarises an Account, including an individual and recursive balances.

Each node is represented by an instance of a class conforming to the Node protocol. Two such classes existing: TreeNode and PlaceholderNode.

TreeNodes present summarised account data, including individual and recursive balances. PlaceholderNodes stand in for TreeNodes where the requesting User does not have read permissions for the Account in question. A PlaceholderNode still includes children, which may include TreeNodes if the User has permission to read from accounts further down the hierarchy.

Determine Position

Positions are generic representations of the accounting construct variously known as a balance sheet, statement of financial position, or something else depending on your jurisdiction. They include hierarchical representations of all asset, liability, and equity Accounts inside an Entity.

Like the Tree, each Account is represented by an instance of an object conforming to the Node protocol.

Measure Performance

Performances are generic representations of the accounting construct variously known as an income statement, statement of financial performance, or comprehensive income statement, depending on your jurisdiction. They include hierarchical representations of all income and expense accounts inside an Entity.

Like the Tree and Position objects, each Account is represented by an instance of an object conforming to the Node protocol.

Updating & Deleting Accounts

Account instances now feature .update() and delete() methods, which do what it says on the tin. Here’s an example of an update operation:

Delete operations require a bit of thought. Deleting an Account does not delete any Transactions with Entries party to that Account. As such, you must supply an Account you wish to transfer any Entries to upon deletion. Here’s an example:

What next…

0.0.8 will probably focus on units of account, i.e. GlobalUnits & CustomUnits. In particular, loading CustomUnits into an Entity so that you can denominate Transactions in whatever unit suits you.

– Hugh