{"id":14971477,"url":"https://github.com/chippyash/simple-accounts-3","last_synced_at":"2025-10-26T15:30:32.352Z","repository":{"id":62501795,"uuid":"118360788","full_name":"chippyash/simple-accounts-3","owner":"chippyash","description":"Third generation of simple accounts with Mariadb support using pure SQL with a PHP API","archived":false,"fork":false,"pushed_at":"2020-10-19T11:54:50.000Z","size":160,"stargazers_count":14,"open_issues_count":1,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-01-31T20:55:54.612Z","etag":null,"topics":["mariadb","php","sql"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","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":"2018-01-21T18:15:07.000Z","updated_at":"2025-01-16T13:11:06.000Z","dependencies_parsed_at":"2022-11-02T12:01:32.916Z","dependency_job_id":null,"html_url":"https://github.com/chippyash/simple-accounts-3","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2Fsimple-accounts-3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2Fsimple-accounts-3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2Fsimple-accounts-3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chippyash%2Fsimple-accounts-3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chippyash","download_url":"https://codeload.github.com/chippyash/simple-accounts-3/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238347926,"owners_count":19457017,"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":["mariadb","php","sql"],"created_at":"2024-09-24T13:45:15.747Z","updated_at":"2025-10-26T15:30:32.054Z","avatar_url":"https://github.com/chippyash.png","language":"PHP","readme":"# chippyash/simple-accounts-3\n\n## Quality Assurance\n\n\n![PHP 7.2](https://img.shields.io/badge/PHP-7.2-blue.svg)\n![PHP 7.3](https://img.shields.io/badge/PHP-7.3-blue.svg)\n![PHP 7.4](https://img.shields.io/badge/PHP-7.4-blue.svg)\n![MariaDb 10.0](https://img.shields.io/badge/MariaDb-10.0-blue.svg)\n![MySql 5.6](https://img.shields.io/badge/MySql-5.6-blue.svg)\n[![Build Status](https://travis-ci.org/chippyash/simple-accounts-3.svg?branch=master)](https://travis-ci.org/chippyash/simple-accounts-3)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/5811a42ebda892357fba/test_coverage)](https://codeclimate.com/github/chippyash/simple-accounts-3/test_coverage)\n[![Maintainability](https://api.codeclimate.com/v1/badges/5811a42ebda892357fba/maintainability)](https://codeclimate.com/github/chippyash/simple-accounts-3/maintainability)\n\n- Please note that developer support for PHP\u003c7.2 was withdrawn at V2 of this library\n- \n## What\n\nProvides a simple database backed general ledger accounting library that allows for a \nquick implementation of double entry book keeping into an application.\n\nThis library replaces [chippyash/simple-accounts](https://github.com/chippyash/simple-accounts)\n\nThis library does not provide sales ledgers, purchase ledgers, or other operational\nledgers.  Your application probably has these in one form or another.  This provides\nthe 'central' accounting functionality.\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 many years \nago to keep account of game points earned on a web site. Using the double entry \naccounting paradigm allowed the site owner to keep track of who had gathered points, \nand in which ways, whilst at the same time seeing what this meant to their business \nas game points translated into real world value for the customer by way of discounts \nand prizes.\n\n## Requirements\n\nSupport in this application is given for 2 flavours of SQL, MariaDb and MySql.\n\n### MariaDb\n\nThe MariaDb utilises a high performance plugin that greatly simplifies dealing with\nhierarchical data.\n\nYou will need MariaDB \u003e=10 with the [OQGraph plugin](https://mariadb.com/kb/en/library/oqgraph-storage-engine/)\ninstalled. Take a look at the `.travis.yml` build script for how we do this on the\nTravis build servers.  One 'gotcha' that we know about is the setting of the user\ncreating the triggers. Depending on your MariaDb setup, you may need to give the database\ncreation script user 'SUPER' privileges.  There seems no rhyme nor reason as to why this\nis, but be aware.  For MariaDb 10 on the travis servers, it needs setting. See \n`scripts/test-user.sql` \n\nIf for some reason you cannot use the OQGraph plugin, please follow the instructions \nfor MySql.  It will work in MariaDb as well.\n\n### MySql\n\nRecognising that not everyone is able to utilise the MariaDb advantage, I have provided\nan alternate database implementation for plain MySql that utilises Nested Sets.  See\n[Mike Hillyer's blog](http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/)\nfor the basis of its implementation.\n\nPlease note that this is not as performant as the MariaDb solution.  Take a look at the \nstored procedure definitions for each DB to see the reason why.  If you can, use MariaDb.\nIf you can get the MySql code more performant, submit a pull request!\n \nPostgres users should be able to adapt the MySql code to implement the database. I rarely\nuse it, so no direct support is given in this library. If you want to contribute the\nPostgres SQL statements, please feel free to provide a pull request.  It would be\nwelcome.\n \nNo Windows variant support is provided at present.  If you want it, please feel free \nto make a pull request.  The library is developed under Linux.\n\n## How\n\n### Getting it up and running\n\nCreate a database, let's say 'test'.\n\nCreate a database user, 'test' with password 'test'. (You can run `scripts\\test-user.sql`\nto do this.)\n\nGive that user all rights to the test database. (see note above re SUPER privs)\n\nNow run the create script:\n\nFor MariaDb:\n\n`./createmariaddb.sh test test test` \n\nFor MySql:\n\n`./createmysqldb.sh test test test`\n\nto create the database components. NB - PHP Doctrine Migration users should read the\nPHP code basic section to utilise the supplied migrations.\n\nYou can run SQL tests by executing `./sqltest.sh test test test localhost`.\n\n- copy the `test/php/phpunit.xml` file to `test/php/local-phpunit.xml` and\nedit it to ensure that you have the correct database connection parameters\n\nYou can run PHP tests by executing `./build.sh`. This also generates the test contract\nin the ./docs directory if you have the [TestDox-Converter](https://github.com/chippyash/Testdox-Converter)\ninstalled. If you don't then it may fail.  Inspect the script contents to run the raw\nPHPUnit command.\n\nYou can run the `examples/currency-example.php` program to see\nhow you can convert between floating and integer types.  \n\u003cpre\u003e\ncd examples\nchmod u+x currency-example.php\n./currency-example.php\n\n\u003c/pre\u003e\nThe library and supporting database only handle integers, so if you need float support,\nuse [Chippyash\\Currency](https://github.com/chippyash/currency) or provide your own handlers.\n\n### Coding Basics- Terminology\n\nTo keep things concise and avoid confusion, particularly if you are an Accountant and\nused to different terminology, here is a definition of terms used in this readme.\n\n- SA: Simple Accounts, this library\n- COA: Chart of Account.  This is an entire chart.  It has ledgers.  A COA is hierarchical\nin nature, with a `root` ledger, normally called 'COA'.  It generally has 2 main child\nledgers, the balance sheet (BS) and the profit and loss account (P\u0026L).  Under these, various\nother ledgers will exist.  You can find numerous references to COA construction on\nt'internet. \n- Ledger or Account: Used interchangeably. A line in the COA that holds the balance of \nall Journal transactions that have been made on the Ledger. In SA, the guiding principle \nis that if you update a child ledger, then it will update its parents all the way to\nthe root ledger, thus keeping the the entire COA in balance.\n- Nominal or Nominal code: In General Ledger (GL), ledgers are often refered to by their\n`nominal code` or `nominal`.  This is accountant or book keeper short code for a ledger.\nEach Ledger in this system has a Nominal Code.  From a database point of view, it provides\npart of the ledger unique key along with the chart id. By convention, it is a Digit String\nand is usually from 4 digits upwards.  Nominals are used to group related Ledgers\ntogether.  By default this library supports up to a 10 digit Nominal Code.  The example\nprograms only use 4 digits which is more than sufficient for everyday usage.  See the\nchart of account xml files for examples.   \n- Journal or Journal Entry or Transaction: A record of a change in the balance on a\nLedger.  It comprises two parts, the details of the reason for the entry, and the details\nof the changes to each ledger that it effects. A Journal must be balanced.  That is\nits debit and credit amounts must be equal.  The system will bork if they are not. This\nis a principle defence for double entry book keeping.  \n   \n### Coding Basics (SQL)\nAs mentioned elsewhere, the fundamentals of this library lay in the SQL code, which\nruns on MariaDb with the OQGraph plugin installed or MySql.\n\nThe SQL API is provided via stored procedures.  If you want to provide variants, please\nrespect the API.  \n\nFor MariaDb see:\n - the procedure definitions in the [src/sql/mariadb/build-procs](https://github.com/chippyash/simple-accounts-3/blob/master/src/sql/mariadb/build-procs.sql)\n - the trigger that maintains the account balances in the [src/sql/mariadb/build-triggers](https://github.com/chippyash/simple-accounts-3/blob/master/src/sql/mariadb/build-triggers.sql)\n   script.\n \nOtherwise the SQL is pretty straight forward.  Study the OQGraph\ndocs for an understanding of how it's being used. Magic underneath, but simple to use - my kind of code ;-) \n\nFor MySql see:\n - the procedure definitions in the [src/sql/mysql/build-procs](https://github.com/chippyash/simple-accounts-3/blob/master/src/sql/mysql/build-procs.sql)\n - the trigger that maintains the account balances in the [src/sql/mysql/build-triggers](https://github.com/chippyash/simple-accounts-3/blob/master/src/sql/mysql/build-triggers.sql)\n   script.\n\nOne slightly baffling procedure is `sa_fu_add_txn`. In particular the parameters, \n- arNominals TEXT,\n- arAmounts TEXT,\n- arTxnType TEXT\n\nThese require a matching set of comma delimited values, which is the only way of getting an array into SQL.:\n- arNominals: the list of nominals to effect\n- arAmounts: the list of amounts to use\n- arTxnType: lst of dr or cr for each nominal\n\nThe php code deals with this by imploding values into a string before calling the SP:\n\nSee Accountant::writeTransaction() method.\nSee test/sql/add_transaction_test.sql circa L17 for how the SQL proc is called natively.\n\nIf you are a better SQL Head than me (not hard!), then I'd appreciate any suggestions\nfor operational efficiency.\n\n### Coding Basics (PHP)\n\nWhilst what follows will give you an introduction to what you can do with the library,\nyou should always look to the tests to gain further insight.\n\n#### Changes from previous library versions\n##### Organisations\nUnlike the previous version of this library, we don't support the concepts of\norganisations.  Organisations are outside of the remit of this\nlibrary as your implementation of them will differ according to your needs. Instead\nyou should plan on creating some form of one to many join between your organisations\nand any chart of accounts (COA) that they use.  The `sa_coa` table can hold an \ninfinite number of COAs, so it shouldn't be too much of a problem.\n\n#### Doctrine Migrations\n\nIf you are using Doctrine Migrations and Mariadb, you can take advantage of the supplied migration \nfiles in `src\\php\\SAccounts\\Doctrine`.\n\nFor development of this library you can migrate up the required DB structure into the \ntest database by navigating to the root of this library and running\n\n`vendor/bin/doctrine-migrations migrations:migrate --configuration doctrine-migrations.xml --db-configuration doctrine-db.php`\n\nTo migrate down use:\n\n`vendor/bin/doctrine-migrations migrations:migrate prev --configuration doctrine-migrations.xml --db-configuration doctrine-db.php`\n\nFor production use, either copy the migration files into your own migrations directory, \n(files are in src/php/SAccounts/Doctrine), or possible more conveniently by creating \nyour own migration classes in your existing structure and the extending them from the \nsupplied migrations. That will keep them in your sequence.\n\nBe aware that new features may result in additional migrations so if you update this \nlibrary to a new feature version, check for new ones.\n \n##### Control accounts\nLike Organisations, we don't support the concept of control accounts in this library.\nThey are again an implementation detail between your application and this library,\nmore usually a configuration issue.  So add config linking where you need such functionality.\nAnother problem was the use of the term.  Too many accountants objected to it being\nused in its previous incarnation, that it was safer to leave it out.\n \n#### The Accountant\nThe Accountant is responsible for the majority of operations that you can carry out\nin Simple Accounts and needs to be created before anything else can happen.  The \nAccountant requires a Zend Db Adapter as a construction parameter.\n\n\u003cpre\u003e\nuse SAccounts\\Accountant;\nuse Zend\\Db\\Adapter\\Adapter;\n\n$accountant = new Accountant(\n\tnew Adapter(\n\t\t[\n\t\t\t'driver' =\u003e 'Pdo_mysql',\n\t\t\t'database' =\u003e 'test',\n\t\t\t'username' =\u003e 'test',\n\t\t\t'password' =\u003e 'test'\t\t\n\t\t]\n\t)\n);\n\u003c/pre\u003e\n\n#### Creating a new chart of accounts\n\nYou create a new chart of accounts (COA) by supplying a ChartDefinition.  The\nChartDefinition is supplied with an XML definition file. An example of a definition\ncan be found in `src\\xml\\personal.xml` along with the XSD that is used to validate\nany definitions in `src\\xsd\\chart-definition.xsd`.\n\n\u003cpre\u003e\nuse SAccounts\\ChartDefinition;\n\n$definition = new ChartDefinition('src/xml/personal.xml');\n\n$chartId = $accountant-\u003ecreateChart('Personal', $definition);\n\u003c/pre\u003e\n\nThis will create the entries in the `sa_coa` table and return you the id of the\nnew chart.  You will probably want to store this in your own tables so you can\nretrieve it later.\n\nThe Accountant is now tied to that COA.  To use another COA you will\nneed to create another Accountant.  To create the Accountant and tell it to use an\nexisting COA, simply give the chart id  as the second parameter\nwhen constructing the Accountant.\n\nPlease note that you never have to explicitly save the COA.  It is done transactionally\nby the Accountant when you carry out operations with it.\n\n#### Accountant operations\n\nMost operations on the COA are carried out via the Accountant.\n\nOperations on the COA invariably require you to give the Nominal code for the Account\nwhich is to say, the Account identifier. Whilst in the database primary integer\nids are used, externally we operate using the Nominal code.\n\n##### Adding an Account ledger to the COA\n\u003cpre\u003e\nuse SAccounts\\Nominal;\nuse SAccounts\\Account;\n\n$nominal = new Nominal('7700');\n$prntNominal = new Nominal(('7000'));\n\n$accountant-\u003eaddAccount(\n\t$nominal,  \t\t//nominal code\n\tAccountType::EXPENSE(), //account type\n\tnew StringType('foo'),\t//account name\n\t$prntNominal\t\t//parent account nominal code (or null)\n\t);\n\u003c/pre\u003e\n\nThe parent Nominal must exist already with one exception. In a brand new COA you can\nadd the root Account and leave out the parent Nominal parameter.  For a root Account\nthe AccountType must be AccountType::REAL(). Trying to add a second\nroot Account will throw an exception.\n\nThe AccountType is important and must be appropriate for the Account you are adding.\nIt controls how the balance on the Account is derived.  It also allows you to display\nappropriate labels for the debit and credit values on an account. Take a look at the \n`src\\xml\\personal.xml` file for an example of how AccountTypes are used.\n\nUnder typical circumstances, the root account is a REAL account, and has two children,\nthe Balance Sheet (type DR) and the Profit \u0026 Loss (type CR).  All other accounts are\nchildren of these two.  There is however nothing stopping you configuring your chart\nas you wish.\n\nAll DR (debit) type accounts derive their balance as dr amount - cr amount.  All CR (credit)\ntype accounts derive their baslance as cr amount - dr amount. REAL accounts derive their\nbalance as abs(cr amount - dr amount), which is the same as abs(dr amount - cr amount)\nand should usually equal zero.\n\n##### Deleting an Account ledger from the COA\n\nYou can delete an Account ledger only if its balance is zero. Attempting to delete\na non zero ledger will throw an exception.  NB. Deleting a ledger will delete all of \nits child ledgers as well.\n\nBy zero, it is meant that both the debit and credit account values == zero.  You cannot\ntherefore delete account ledgers for which any transactions have been made for it or\nany child accounts.  This is a simple security measure to ensure that data is not lost.\n\n\u003cpre\u003e\n$accountant-\u003edelAccount(new Nominal('7000'));\n\u003c/pre\u003e\n\n#### Fetching the COA\n\nHaving created the COA or instantiated the Accountant with the chart id, you can fetch\nthe COA simply with:\n\n\u003cpre\u003e\nuse SAccounts\\Chart;\n\n/* @var Chart $chart */\n$chart = $accountant-\u003efetchChart(); \n\u003c/pre\u003e\n\n#### Operations on the COA\n\n##### Basic COA operations\n\n\u003cpre\u003e\n//get an Account from the Chart\n/* @var Account $acount */\n$account = $chart-\u003egetAccount(new Nominal('2000'));\n\n//get the parent account of an Account\n$account = $chart-\u003egetAccount($chart-\u003egetParentId(new Nominal('2000')))\n//or\n$subAccount = $chart-\u003egetAccount(new Nominal('2000'));\n$prntAccount = $chart-\u003egetAccount($chart-\u003egetParentId($account-\u003egetNominal()));\n\n//testing if an account exists in the COA\n//returns true or false\n$exists = $chart-\u003ehasAccount(new Nominal('3000'));\n\n//get the name of the COA\n/* @var StringType $name */\n$name = $chart-\u003egetName();\n\n//get a ledger's values\n$account = $chart-\u003egetAccount(new Nominal('2000'));\n/* @var IntType $dr */\n$dr = $account-\u003edr();\n/* @var IntType $cr */\n$cr = $account-\u003ecr();\n\n//NB getting the balance of the root COA account should return zero.  If not\n//then your accounts are out of balance and need investigating. Perhaps something\n//outside of SA made an update, or a database glitch occurred.\n/* @var IntType $balance */\n$balance = $account-\u003egetBalance();\n\n/* @var Nominal $nom */\n$nom = $account-\u003egetNominal();\n/* @var StringType $name */\n$name = $account-\u003egetName();\n/* @var AccountType $type */\n$type = $account-\u003egetType();\n\n\u003c/pre\u003e\n\n##### The COA as a Tree\n\nUnder the covers, the chart is kept as a [nicmart/Tree](https://github.com/nicmart/Tree)\nwhich I do recommend to you if you need to carry out Tree operations. Gaining access\nto it is useful for a variety of tasks, such as displaying a trial balance. For this\nwe use tree Visitors. You can see a full working example of this in the \n`examples\\currency-example.php` script.  The line of interest is:\n\n\u003cpre\u003e\n$accountant-\u003efetchChart()-\u003egetTree()-\u003eaccept(new ChartPrinter(Crcy::create($crcyCd)));\n\u003c/pre\u003e\n\nTwo end user Visitors are supplied: \n - `SAccounts\\Visitor\\ChartPrinter` which prints the COA to the console\n - `SAccounts\\Visitor\\ChartArray` which returns the COA as an array of values and \n account balances\n \nOther Visitors are used internally in the Chart, but they should all give you a firm\ngrasp on how to create your own if you need to.\n\n#### Journal Entries\n\n##### Creating Entries\n\nYou create Journal entries in your accounts by adding Transactions to the system. A\nTransaction is made up of two parts, the Journal description and a list of transaction\nentries, one for each account that is effected by the transaction.  Those transactions\nhave a debit or credit amount.  The sum of all debits must equal the sum of all\ncredits so that the transaction balances in order for the Transaction to be accepted by\nthe system.\n\nThe basic Transaction type is the SplitTransaction:\n\n\u003cpre\u003e\n    /**\n     * Constructor\n     *\n     * @param string $note Defaults to '' if not set\n     * @param string $src  user defined source of transaction\n     * @param int $ref user defined reference for transaction\n     * @param \\DateTime $date Defaults to today if not set\n     */\n    public function __construct(\n        string $note = null,\n        string $src = null,\n        int $ref = null,\n        \\DateTime $date = null\n    )\n\u003c/pre\u003e\n\nAfter construction, you add transaction entries by passing an Entry object to the addEntry()\nmethod.\n\n\u003cpre\u003e\nuse SAccounts\\Transaction\\SplitTransaction;\nuse SAccounts\\Transaction\\Entry;\n\n$amount = new IntType(100);\n$txn = (new SplitTransaction())\n     -\u003eaddEntry(new Entry(new Nominal('0000'), $amount, AccountType::DR()))\n     -\u003eaddEntry(new Entry(new Nominal('1000'), $amount, AccountType::CR()))\n\u003c/pre\u003e\n\nHere, we added two entries for same amount to two accounts, but with the transaction\ntype being debit for one and credit for the other.  You can check that the\ntransaction is balanced with the `checkBalance()` method which will return true\nif the transaction is balanced or false otherwise.\n\nWhilst the SplitTransaction is useful for adding transactions that comprise of many\nentries (e.g. a sale comprises of sale account, vat account and a bank account entries),\nfor a simple two account entry(like a transfer between bank accounts) you can use the\nSimpleTransaction, which is a child of SplitTransaction.\n\n\u003cpre\u003e\n    /**\n     * Constructor\n     *\n     * @param Nominal $drAc Account to debit\n     * @param Nominal $crAc Account to credit\n     * @param int $amount Transaction amount\n     * @param string $note Defaults to '' if not set\n     * @param int $ref Defaults to 0 if not set\n     * @param \\DateTime $date Defaults to today if not set\n     */\n    public function __construct(\n        Nominal $drAc,\n        Nominal $crAc,\n        int $amount,\n        ?string $note = null,\n        ?string $src = null,\n        ?int $ref = null,\n        ?\\DateTime $date = null\n    )\n\u003c/pre\u003e\n\nThus:\n\n\u003cpre\u003e\nuse SAccounts\\Transaction\\SimpleTransaction;\n\n$txn = new SimpleTransaction(new Nominal('0000'), new Nominal('1000'), 1226);\n\u003c/pre\u003e\n\nHaving created your transaction by whatever means, you can then add it to the accounts \nwith:\n\n\u003cpre\u003e\n$txnId = $accountant-\u003ewriteTransaction($txn);\n\u003c/pre\u003e\n\nWriting a transaction automatically updates the COA ledger balances.\n\n##### Retrieving Entries\n\nYou retrieve a single transaction from the accounts with\n\n\u003cpre\u003e\n/* @var SplitTransaction $txn */\n$txn = $accountant-\u003efetchTransaction(102);\n\u003c/pre\u003e\n\nTo retrieve all entries for an account ledger:\n\u003cpre\u003e\n/** @var Ds\\Set $transactions */\n$transactions = $accountant-\u003efetchAccountJournals(new Nominal('2000'));\n\u003c/pre\u003e\n\nThe Set contains SplitTransactions with Entries reflecting only the side of the\ndouble entry that the transaction acted up for that journal entry.  You can see an\nexample of how this works in `examples/journal-entries-example.php`.\n\n## Notes\n\nThe library is built to rely on pure SQL in the database.  Whilst I'm providing\na PHP API layer to it, you can use the underlaying SQL from any language.  If you \nare a Python, Java or other developer, please feel free to add your own\nlanguage API under the `src` directory\n\nMy references here apply to the fact that I develop primarily in PHP.  If they don't \napply to your dev language of choice, ignore them.\n\nFinally, if in doubt, read the source code. It's well documented.  \n\n## Further documentation\n\n[Test Contract](https://github.com/chippyash/simple-accounts-3/blob/master/docs/Test-Contract.md) in the docs directory.\n\nThis library makes use of the Standard [PHP DS extension](https://www.php.net/manual/en/book.ds.php)\n\nIt also employs a great deal of functional programming derived from the [Monad](https://github.com/chippyash/monad)\nand [Assembly](https://github.com/chippyash/Assembly-Builder) libraries. \n\nIf you are unfamiliar with them, please take a moment to study them. \n\nAs the library only deals with integers as values (to ensure numerical accuracy) you \nmay want to have a look at the [Currency](https://github.com/chippyash/currency) library \nthat is used in the example scripts.\n\nCheck out [ZF4 Packages](http://zf4.biz/packages?utm_source=github\u0026utm_medium=web\u0026utm_campaign=blinks\u0026utm_content=simpleaccounts3) for more packages\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-3). It is\navailable at [Packagist.org](https://packagist.org/packages/chippyash/simple-accounts-3)\n\n### Installation (PHP)\n\nInstall [Composer](https://getcomposer.org/)\n\n#### For production\n\n\u003cpre\u003e\n    \"chippyash/simple-accounts-3\": \"~2.0\"\n\u003c/pre\u003e\n \n`composer install --no-dev`\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-3.git simple-accounts\n    cd simple-accounts\n    composer update\n\u003c/pre\u003e\n\n- copy the `test/php/phpunit.xml` file to `test/php/local-phpunit.xml` and\nedit it to ensure that you have the correct database connection parameters\n\n- To run the tests: `composer test:run`\n- To lint the code: `composer lint:run`\n- To fix lint issues: `composer lint:fix`\n\n## License\n\nThis software library is released under the [BSD 3 Clause license](https://opensource.org/licenses/BSD-3-Clause)\n\nThis software library is Copyright (c) 2017-2020, Ashley Kitson, UK\n\n## History\n\nV1.0.0 First production release\n\nV1.0.1 Documentation for first release\n\nV1.1.0 Add PHP Doctrine Migrations\n\nV1.1.1 Change namespace for migrations\n\nV1.1.2 Support PHP 7.0 \u0026 7.1\n\nV1.1.3 Support PHP 7.2\n\nV1.2.0 Add ability to retrieve all transactions for an account\n\nV1.2.1 docs licenses update\n\nV1.3.0 Support for MySql\n\nV1.3.1 File path amend for mariadb migration\n\nV1.3.2 Remove ambiguity for treatment of real account balances\n\nV1.4.0 Change of license from GPL V3 to BSD 3 Clause \n\nV1.4.1 Fix issue 1\n\nV2.0.0 BC Break. PHP\u003c7.2 support withdrawn. Remove dependency on chippyash/strongtype.\n\nV2.0.1 Remove dependency on chippyash/identity","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchippyash%2Fsimple-accounts-3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchippyash%2Fsimple-accounts-3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchippyash%2Fsimple-accounts-3/lists"}