{"id":20254791,"url":"https://github.com/chippyash/simple-accounts","last_synced_at":"2025-04-11T00:04:59.052Z","repository":{"id":32360892,"uuid":"35936868","full_name":"chippyash/Simple-Accounts","owner":"chippyash","description":"Simple double entry accounting library","archived":false,"fork":false,"pushed_at":"2018-01-15T19:37:00.000Z","size":728,"stargazers_count":42,"open_issues_count":1,"forks_count":19,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-04-11T00:04:38.528Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chippyash.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-20T08:51:55.000Z","updated_at":"2023-08-02T17:55:21.000Z","dependencies_parsed_at":"2022-09-12T03:30:40.494Z","dependency_job_id":null,"html_url":"https://github.com/chippyash/Simple-Accounts","commit_stats":null,"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FSimple-Accounts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FSimple-Accounts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FSimple-Accounts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2FSimple-Accounts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chippyash","download_url":"https://codeload.github.com/chippyash/Simple-Accounts/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248317708,"owners_count":21083528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T10:34:56.763Z","updated_at":"2025-04-11T00:04:59.032Z","avatar_url":"https://github.com/chippyash.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# chippyash/Simple-Accounts\n\n## Notice\n\nThis project has been stopped.  There is not enough traction on it to warrant \nits continuance.  If you want to take it over, please contact me. Or simply\nfork it and carry on.\n\n## Quality Assurance\n\n![PHP 5.5](https://img.shields.io/badge/PHP-5.5-blue.svg)\n![PHP 5.6](https://img.shields.io/badge/PHP-5.6-blue.svg)\n![PHP 7](https://img.shields.io/badge/PHP-7-blue.svg)\n[![Build Status](https://travis-ci.org/chippyash/Simple-Accounts.svg?branch=master)](https://travis-ci.org/chippyash/Simple-Accounts)\n[![Test Coverage](https://codeclimate.com/github/chippyash/Simple-Accounts/badges/coverage.svg)](https://codeclimate.com/github/chippyash/Simple-Accounts/coverage)\n[![Code Climate](https://codeclimate.com/github/chippyash/Simple-Accounts/badges/gpa.svg)](https://codeclimate.com/github/chippyash/Simple-Accounts)\n\nThe above badges and this documentation represent the current development branch.  \nAs a rule, I don't push to GitHub unless tests, coverage and usability are acceptable.  \nThis may not be true for short periods of time; on holiday, need code for some other \ndownstream project etc.  If you need stable code, use a tagged version.  For definitive\ndocumentation for a tgged version, read the README file in that version.\n \nSee the [Test Contract](https://github.com/chippyash/Simple-Accounts/blob/master/docs/Test-Contract.md)\n\n### End of life notice\n\nIn March 2018, developer support will be withdrawn from this library for PHP \u003c5.6. Older\nversions of PHP are now in such little use that the added effort of maintaining \ncompatibility is not effort effective.  See [PHP Version Stats](https://seld.be/notes/php-versions-stats-2017-1-edition)\n for the numbers.\n\n## What?\n\nProvides a simple double entry accounting system, that can be used as a component in\n a larger application.\n\n### Features\n\n*  Chart of Accounts \\(see [here ](http://www.itzbits.co.uk/business-articles/67/What-is-a-Chart-of-Accounts.html) \nfor a reasonable explanation\\)\n    * You can define your own chart structures\n*  Account types\n    * DR\n        * ASSET\n             * BANK\n            * CUSTOMER\n        * EXPENSE\n    * CR\n        * INCOME\n        * LIABILITY\n            * EQUITY\n            * SUPPLIER\n        \n*  Ability to save and retrieve a Chart through a simple interface\n*  Organisation concept that can have multiple Chart of Accounts\n*  Fantasy currencies are catered for\n*  Extensible Journal system, allowing recording of account transactions\n\n## Why?\n\nWhilst full blown accounting systems are available, requiring a massive integration \neffort, some applications simply need to be able keep some form of internal account. \nThis library is the direct descendant of something I wrote for a [client](http://www.amaranthgames.com/) \nmany years ago to keep account of game points earned on a web site.  Using the double \nentry accounting paradigm allowed the site owner to keep track of who had gathered \npoints, and in which ways, whilst at the same time seeing what this meant to their \nbusiness as game points translated into real world value for the customer by way of \ndiscounts and prizes.\n   \n## When\n\nThe current library support Organisations, Charts of Account, Journals and Control Accounts.  \n\n### Roadmap\n\n- Accounting\n    - closing accounts\n- Reporting\n    - balance sheet\n    - trial balance\n    - profit and loss\n    \nIf you want more, either suggest it, or better still, fork it and provide a pull request.\n\nCheck out [ZF4 Packages](http://zf4.biz/packages?utm_source=github\u0026utm_medium=web\u0026utm_campaign=blinks\u0026utm_content=accounts) for more packages\n\n## How\n\n### Coding Basics\n\n#### Creating a new chart of accounts\n\n##### Creating it manually\n\u003cpre\u003e\nuse SAccounts\\Chart;\nuse SAccounts\\Organisation;\nuse Chippyash\\Currency\\Factory as Currency;\nuse Chippyash\\Type\\Number\\IntType;\nuse Chippyash\\Type\\String\\StringType;\n\n$org = new Organisation(new IntType(1), new StringType('Foo'), Currency::create('gbp'));\n$chart = new Chart(new StringType('Foo Chart'), $org);\n\u003c/pre\u003e\n\n##### Using the Accountant\nThe Accountant is a useful 'person'\\! But as usual they come at a cost: they need a \nfileClerk to do some of the work for them, and you have to give them that as payment.  \nA fileClerk implements the AccountStorageInterface. A simple example that allows \nsaving of Charts as serialized PHP file is provided to get you started, but of course\nyou can create your own.\n\n\u003cpre\u003e\nuse SAccounts\\Accountant;\nuse SAccounts\\Storage\\Account\\Serialized;\n\n$fileClerk = new Serialized(new StringType('/path/To/My/Account/Store'));\n$accountant = new Accountant($fileClerk);\n\u003c/pre\u003e\n\nTo create a chart via the accountant you still need to tell it what organisation the \nnew chart is for, and also which COA template you want to use. A simple 'personal \naccounts' template is provided, which is an XML file. You can create and supply your own.\n\n\u003cpre\u003e\nuse SAccounts\\ChartDefinition;\nuse SAccounts\\Organisation;\nuse Chippyash\\Type\\String\\StringType;\nuse Chippyash\\Type\\Number\\IntType;\nuse Chippyash\\Currency\\Factory as Currency;\n\n$def = new ChartDefinition(new StringType('/path/to/definitions/personal.xml'));\n$org = new Organisation(new IntType(1), new StringType('Foo'), Currency::create('gbp'));\n$chart = $accountant-\u003ecreateChart(new StringType('Name of Chart'), $org, $def);\n\u003c/pre\u003e\n\n#### Adding accounts to the chart\nOnce you have a chart you may want  to add new accounts to it.  If you have created \none manually from scratch it will not have a root account, so you need to add that \nfirst.  All accounts are identified by a 'nominal code'.  This is of type \nNominal (based on chippyash\\Type\\String\\DigitType) and is a numeric string.  You can \nuse any nominal code structure you like, but make sure you give yourself enough room \nto add the accounts you want.  Take a look at the definitions/personal.xml for some insight.\n\nAccounts also need a type for the account.  These are defined in the AccountType \nenum class and are simply created by calling the class constant as a method. See the \nlink in the thanks section for more information about Enums.\n\n- add a root account\n\n\u003cpre\u003e\nuse SAccounts\\Nominal;\nuse SAccounts\\AccountType;\n\nac1 = new Account($chart, new Nominal('2000'), AccountType::ASSET(), new StringType('Asset'));\n$chart-\u003eaddAccount($ac)\n\u003c/pre\u003e\n\n- add a child account\n\n\u003cpre\u003e\nac2 = new Account($chart, new Nominal('2100'), AccountType::BANK(), new StringType('Bank'));\n$chart-\u003eaddAccount($ac, $ac1-\u003eid())\n\u003c/pre\u003e\n\n#### Saving the chart\n\u003cpre\u003e\n$accountant-\u003efileChart($chart));\n\u003c/pre\u003e\n\n#### Fetching the chart\nIn fetching a chart you need to know the id of the organisation that it belongs to\n\n\u003cpre\u003e\n$chart = $accountant-\u003efetchChart(new StringType('Name of Chart'), new IntType(1));\n\u003c/pre\u003e\n\nThis allows you to create multiple COAs for an organisation, potentially allowing\nyou to keep task specific COAs or COAs for different currencies.\n\n#### Making entries into accounts\n\nYou can make debit and credit entries to any account. Obviously, to maintain double \nentry accounting rules, you'll generally make one of each for any transaction.\n\nYou don't need to keep track of accounts, simply get them from the chart using their id.\n\nWhilst it is not enforced, you are advised to use the same currency that you used for \nyour organisation when creating amounts to debit and credit.\n\n\u003cpre\u003e\n//can be used in most situations\n$amount = Currency::create($chart-\u003egetOrg()-\u003egetCurrencyCode(), 12.26);\n\n//use this method if locale issues are important or you are using a fantasy currency\n$amount = clone $chart-\u003egetOrg()-\u003egetCurrency();\n$amount-\u003esetAsFloat(12.26);\n//or use set() if you know your currency precision\n$amount-\u003eset(1226);\n\n$chart-\u003egetAccount(new Nominal('1000'))-\u003edebit($amount);\n$chart-\u003egetAccount(new Nominal('2000'))-\u003ecredit($amount);\n\u003c/pre\u003e\n\n#### Getting account values\n\nAll account values are expressed as [chippyash\\Currency\\Currency](https://github.com/chippyash/currency) objects.\n\n- debit and credit amounts\n\n\u003cpre\u003e\n$debitAsInt = $chart-\u003egetAccount(new Nominal('1000'))-\u003egetDebit()-\u003eget();\n$debitAsFloat = $chart-\u003egetAccount(new Nominal('1000'))-\u003egetDebit()-\u003egetAsFloat()\necho $chart-\u003egetAccount(new Nominal('1000'))-\u003egetDebit()-\u003edisplay();\n$creditAsInt = $chart-\u003egetAccount(new Nominal('1000'))-\u003egetCredit()-\u003eget();\n$creditAsFloat = $chart-\u003egetAccount(new Nominal('1000'))-\u003egetCredit()-\u003egetAsFloat()\necho $chart-\u003egetAccount(new Nominal('1000'))-\u003egetCredit()-\u003edisplay();\n\u003c/pre\u003e\n\n- account balance\n\nFor all account types (excluding DUMMY and REAL) get the account balance:\n\n\u003cpre\u003e\n$balanceAsInt = $chart-\u003egetAccount(new Nominal('1000'))-\u003egetBalance()-\u003eget();\n$balanceAsFloat = $chart-\u003egetAccount(new Nominal('1000'))-\u003egetBalance()-\u003egetAsFloat();\necho $chart-\u003egetAccount(new Nominal('1000'))-\u003egetBalance()-\u003edisplay();\n\u003c/pre\u003e\n\nThe balance respects the conventions of DR and CR accounts.:\n\n- DR balance = dr-cr\n- CR balance = cr-dr\n\n#### Using Journals\n\nWhilst an Account records the value state at any given point in time, and a Chart holds \nthe state of a collection (tree) of accounts, a Journal is responsible for recording \nthe transaction history that led to the current state of the Account.\n \nYou may use the library without using Journalling at all, but most systems will want \na transaction history. The Accountant can make use of an optional 'Journalist' that \nimplements the JournalStorageInterface to create, save and amend both a Journal and \nthe transactions that it records.\n\nYou must first supply a Journalist in the form of a JournalStorageInterface.  An \nexample is provided, Accounts\\Storage\\Journal\\Xml which stores the Journal and its \ntransactions into an XML file.  You can provide your own to store against any other\nstorage mechanism that you want to use.\n \n\u003cpre\u003e\nuse SAccounts\\Storage\\Journal\\Xml as Journalist;\n\n$accountant-\u003esetJournalist(new Journalist(new StringType('/path/to/my/journal/store/folder')));\n\u003c/pre\u003e\n \n#### Creating a Journal\n\n\u003cpre\u003e\nuse Chippyash\\Currency\\Factory as Currency;\n\n$journal = $accountant-\u003ecreateJournal(new StringType('My Journal'), Currency::create('gbp'));\n\u003c/pre\u003e\n\nUnder most circumstances, you'll associate an Organisation, and a Chart with a Journal, \nso it makes sense to use the same Currency:\n\n\u003cpre\u003e\n$journal = $accountant-\u003ecreateJournal(new StringType('My Journal'), $chart-\u003egetOrg()-\u003egetCurrency());\n\u003c/pre\u003e\n\n#### Fetching a Journal that you already made\n\n\u003cpre\u003e\nuse SAccounts\\Storage\\Journal\\Xml as Journalist;\n\n$accountant-\u003esetJournalist(new Journalist(new StringType('/path/to/my/journal/store/folder')));\n$journal = $accountant-\u003efetchJournal();\n\u003c/pre\u003e\n\nYou can also store a journal via the accountant if you amend its definition\n\n#### Creating transactions in the journal\n\nYou can either manage the link between the Journal and the Chart yourself by calling \ntheir appropriate store mechanisms (see the code, tests and diagrams for that,) or \nmore simply, ask the accountant to do it for you.  In either case, you first of all\nneed a Transaction. Transactions are provided by way of the `SAccounts\\Transaction\\SplitTransaction`\nand `SAccounts\\Transaction\\SimpleTransaction`.  `SimpleTransaction` is provided as helper\nfor creating and writing out transactions that consist of a pair of balanced debit and credit\namounts.\n\n\u003cpre\u003e\nuse SAccounts\\Transaction\\SimpleTransaction;\nuse SAccounts\\Nominal;\n\n$drAc = new Nominal('0000');\n$crAc = new Nominal('1000');\n$amount = Currency::create($chart-\u003egetOrg()-\u003egetCurrencyCode(), 12.26);\n$txn = new  SimpleTransaction($drAc, $crAc, $amount);\n\u003c/pre\u003e\n\nYou can set an optional 4th parameter when creating a SimpleTransaction:\n \n\u003cpre\u003e\n$txn = new  SimpleTransaction($drAc, $crAc, $amount, new StringType('This is a note'));\n\u003c/pre\u003e\n\nBy default the date and time for the transaction is set to now().  You can set an \noptional 5th parameter when creating a SimpleTransaction and supply a DateTime object\nof your own choosing.\n\n\u003cpre\u003e\n$txn = new  SimpleTransaction($drAc, $crAc, $amount, new StringType(''), new \\DateTime('2015-12-03T12:14:30Z));\n\u003c/pre\u003e\n\nTo record a transaction and update the chart of accounts you can now use the Accountant again:\n\n\u003cpre\u003e\n$txn = $accountant-\u003ewriteTransaction($txn, $chart, $journal);\n//or\n$accountant-\u003ewriteTransaction($txn, $chart, $journal);\n\u003c/pre\u003e\n\nThe Transaction will now have its transaction id set, which you can recover via:\n\n\u003cpre\u003e\n$txnId = $txn-\u003egetId() //returns IntType\n\u003c/pre\u003e\n\nYou don't need to save the Journal, as it is inherently transactional, but don't forget \nto save your Chart once you have finished writing transactions. \n\nThe full power of the transaction is provided by the `SplitTransaction`. And remember,\n that when you read transactions back from the journal they will be in SplitTransaction\n format.  A split transaction allows you to have, say, one debit entry and three credit\n entries.  As long as the total debit entry amounts equal the total credit entry \n amounts, you have a balanced transaction, i.e. a valid double entry transaction.\n \nWith power comes a little more complexity, as you'd expect! \n\n\u003cpre\u003e\nuse SAccounts\\Transaction\\SimpleTransaction;\nuse SAccounts\\Transaction\\Entry;\nuse SAccounts\\Nominal;\nuse Chippyash\\Type\\String\\StringType;\nuse Chippyash\\Currency\\Factory as Currency;\n\n$txn = new SplitTransaction() // date == now(), note == ''\n$txn = new SplitTransaction(new DateTime());\n$txn = new SplitTransaction(null, new StringType('foo'));\n$txn = new SplitTransaction(new DateTime(), new StringType('foo'));\n\n//the following is analogous to a SimpleTransaction\n$note = new StringType('foo bar');\n$dt = new \\DateTime();\n$amount = Currency::create('gbp', 12.26);\n$txn = (new SplitTransaction($dt, $note))\n    -\u003eaddEntry(new Entry(new Nominal('0000'), $amount, AccountType::DR()))\n    -\u003eaddEntry(new Entry(new Nominal('1000'), $amount, AccountType::CR()));\n    \n\u003c/pre\u003e\n\nWhen creating an Entry, you need to tell it:\n- which account to use\n- how much \n- whether to debit or credit\n\nTo create true split transaction, lets use the following example:\n- bank account: 3001\n- vat account: 6007\n- items account: 9056\n- total transaction £120.00, £100 for the item, £20 as VAT\n\n\u003cpre\u003e\n$txn = (new SplitTransaction($dt, $note))\n    -\u003eaddEntry(new Entry(new Nominal('3001'), Currency::create('gbp', 120), AccountType::DR()))\n    -\u003eaddEntry(new Entry(new Nominal('6007'), Currency::create('gbp', 20), AccountType::CR()))\n    -\u003eaddEntry(new Entry(new Nominal('9056'), Currency::create('gbp', 100), AccountType::CR()));\n\u003c/pre\u003e\n\nOn the whole it is a really bad idea to create an unbalanced transaction and you can\ncheck this with `checkBalance()` which returns true if the transaction is balanced else false.\n\nYou can also do a simple check to see if the transaction conforms to being simple\nusing the `isSimple()` method:\n\n\u003cpre\u003e\n$drAc = $txn-\u003egetDrAc();\nif ($txn-\u003eisSimple()) {\n    $actualDrAc = $drAc[0];\n} else {\n    //you have an array of debit accounts, so process them\n}\n\u003c/pre\u003e\n\n`getCrAc()` gets the credit accounts on a transaction.\n\nThe `getEntries()` method of a SplitTransaction returns a SAccounts\\Transaction\\Entries\ncollection of entries.\n\n#### Control Accounts\n\nIn the sense of an [accounting definition](https://en.wikipedia.org/wiki/Controlling_account) of Control\nAccounts, the Simple Accounts `Control Account` can certainly be used to point to an adjustment account\nin your Chart. However, in practical use, Control Accounts have a more broadly defined \nuse; that of pointing to specific accounts within the Chart.  So in this sense, the\nSimple Accounts Control Account is simply a pointer to another account.\n\nIn programming terms, we set up a Collection (`Control\\Links`) of Control Accounts (`Control\\Link`). \nLet's use an example:\n\nYou have a system in which you want generic cash transactions to go to specific\naccounts:\n\n- cash to/from the 'bank' account\n- purchases to the 'sundries' account\n- sales to the 'cash sales' account\n\nThe problem is, that as your COA (or business) grows, the actual account in the COA\nthat you want to use may change.  By dereferencing the actual account with a Control\nAccount, your main code can remain the same, yet allowing you to reconfigure at will.\n\n\u003cpre\u003e\nuse SAccounts\\Control;\n\n$linkArray = [\n    new Control\\Link(new StringType('bank'), new Nominal('1000')),\n    new Control\\Link(new StringType('sundries'), new Nominal('2000')),\n    new Control\\Link(new StringType('cash sales'), new Nominal('3000')),\n];\n$ctrlAcs = (new Control\\Links($linkArray));\n\n$txn = (new SplitTransaction($dt, $note))\n    -\u003eaddEntry($ctrlAcs-\u003egetLinkId(new StringType('bank')), Currency::create('gbp', 120), AccountType::DR()))\n    -\u003eaddEntry($ctrlAcs-\u003egetLinkId(new StringType('cash sales')), Currency::create('gbp', 120), AccountType::CR()));\n\n$txn2 = (new SplitTransaction($dt, $note))\n    -\u003eaddEntry($ctrlAcs-\u003egetLinkId(new StringType('bank')), Currency::create('gbp', 90), AccountType::CR()))\n    -\u003eaddEntry($ctrlAcs-\u003egetLinkId(new StringType('sundries')), Currency::create('gbp', 90), AccountType::DR()));\n\n\u003c/pre\u003e\n\nIt is really as simple as that.  I've not included a storage mechanism for Control Accounts\non the basis, that it is likely that you'll dependency inject them into your application,\n however there is an XML XSD in the definitions folder, with an example XML file in the \n docs directory.  In practice you may find yourself using a number of Control Account\n Collections in an application.\n \n### Class diagrams\n\n![UML Diagram](https://github.com/chippyash/Simple-Accounts/blob/master/docs/ClassesForAccounts.png)\n![UML Diagram](https://github.com/chippyash/Simple-Accounts/blob/master/docs/ClassesForJournals.png)\n![UML Diagram](https://github.com/chippyash/Simple-Accounts/blob/master/docs/ClassesForControlAccounts.png)\n\n### Changing the library\n\n1.  fork it\n2.  write the test\n3.  amend it\n4.  do a pull request\n\nFound a bug you can't figure out?\n\n1.  fork it\n2.  write the test\n3.  do a pull request\n\nNB. Make sure you rebase to HEAD before your pull request\n\nOr - raise an issue ticket.\n\n## Where?\n\nThe library is hosted at [Github](https://github.com/chippyash/Simple-Accounts). It is\navailable at [Packagist.org](https://packagist.org/packages/chippyash/simple-accounts)\n\n### Installation\n\nInstall [Composer](https://getcomposer.org/)\n\n#### For production\n\n\u003cpre\u003e\n    \"chippyash/simple-accounts\": \"~2\"\n\u003c/pre\u003e\n\n#### For development\n\nClone this repo, and then run Composer in local repo root to pull in dependencies\n\n\u003cpre\u003e\n    git clone git@github.com:chippyash/Simple-Accounts.git Accounts\n    cd Accounts\n    composer update\n\u003c/pre\u003e\n\nTo run the tests:\n\n\u003cpre\u003e\n    cd Accounts\n    vendor/bin/phpunit -c test/phpunit.xml test/\n\u003c/pre\u003e\n\n## Thanks\n\nBack in the day, when the first Simple Accounts was written, I had to write a lot of \nsupport code myself.  In this version I have been able to take advantage of the work \nof others. As well as the normal suspects of [PHPUnit](https://github.com/sebastianbergmann/phpunit)\n and [vfsStream](https://github.com/mikey179/vfsStream) for writing the test code,\nI'd like to highlight some others:\n\n* [PHP Enum](https://github.com/myclabs/php-enum) : a neat implementation of enums for PHP\n* [Tree](https://github.com/nicmart/Tree) : A simple tree component that supports the \nvisitor pattern allowing for easy extension\n\n## License\n\nThis software library is released under the [GNU GPL V3 or later license](http://www.gnu.org/copyleft/gpl.html)\n\nThis software library is Copyright (c) 2015-2018, Ashley Kitson, UK\n\nA commercial license is available for this software library, please contact the author. \nIt is normally free to deserving causes, but gets you around the limitation of the GPL\nlicense, which does not allow unrestricted inclusion of this code in commercial works.\n\n## History\n\nV1.0.0 Original release\n\nV1.1.0 Journals added\n\nV1.2.0\n\n- replaced chippyash\\Accounts namespace with SAccounts\n- Transaction deprecated, use SimpleTransaction (Transaction proxies to SimpleTransaction and will be removed in the future)\n- SplitTransactions introduced, use these for preference\n- BC break with XML Journal file format to accommodate split transactions \n\nV1.3.0 Added Control Accounts\n\nV1.4.0 Update dependencies\n\nV1.4.1 Add link to packages\n\nV1.4.2 Verify PHP 7 compatibility\n\nV1.4.3 Code cleanup\n\nV1.4.4 Dependency update\n\nV1.4.5 PhpUnit test suite update\n\nV1.4.6 Update build script\n\nV2.0.0 BC break in some interface definitions to support implementation of DB based systems.\n\nV2.1.0 Add ability to set chart root node","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchippyash%2Fsimple-accounts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchippyash%2Fsimple-accounts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchippyash%2Fsimple-accounts/lists"}