This is a very Simple FrontAccounting API. The concept of FA <=> POS integration is explained in this Forum Post.
Some basic integration functions needed to connect to another software. This resulted in creation of this REST API and contributed to the FrontAccounting team. It is based on the Slim Framework for PHP5. The database helpers defined in *.inc files in respective includes/db folders are used here.
A fully implemented FA <-> POS system set of features (not using SimpleAPI) are listed are at: http://www.cartbooks.com/frontaccounting-point-of-sale/
Repo
https://github.com/andresamayadiaz/FrontAccountingSimpleAPI
API Quick Start
- Just copy the files into the modules directory under a folder called api (hardcoded in the api files).
- Edit the file util.php and change the $company, $username and $password variables so you can test and then comment out the test lines for actual use. Use it at your own risk, to provide login from another software you need to send X_company, X_user and X_password headers in the request and the API will use those credentials, if they're wrong you will get a nice message telling Bad Login
- Try to access the API, for example, try the Items Category List taken from the stock_category table, type this on your explorer: http://YOUR_FA_URL/modules/api/category/ ---> You will see a JSON with all you're items categories. If not check the util.php file. A sample output is here.
- Do not use MultiViews in the Apache Config file which should have a stanza like the following one: <IfModule mod_rewrite.c>
<Location /modules/api/> Options -MultiViews RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [QSA,L] </Location>
- </IfModule>
Error Codes implemented in SimpleAPI
- 200 OK
- 201 Create Response
- 400 Invalid table ID
- 403 Bad Login For Company
- 412 Field is required
- 500 Could Not Change Database Contents
Methods
Currently implemented are:
Type | Action | Function |
---|---|---|
Items | ||
GET | /inventory/ | Get list of All Inventory Items |
GET | /inventory/:id | Get details of Inventory Item = id |
POST | /inventory/ | Add inventory items |
PUT | /inventory/:id | Edit Inventory Item = id |
DELETE | /inventory/:id | Delete Inventory Items = id |
Inventory Movements | ||
GET | /movementtypes/ | Get list of All Inventory Movement Types |
Locations | ||
GET | /locations/ | Get list of All Locations |
Stock Adjustments | ||
POST | /stock/ | Add Stock Adjustment |
Items Categories | ||
GET | /category/ | Get list of All Item Categories |
GET | /category/:id | Get details of Item Category = id |
POST | /category/ | Add Item Categories |
PUT | /category/:id | Edit Item Category = id |
DELETE | /category/:id | Delete Item Category = id |
Tax Groups | ||
GET | /taxgroups/ | Get list of All Tax Groups |
Tax Types | ||
GET | /taxtypes/ | Get list of All Tax Types |
Bank Accounts | ||
GET | /bankaccounts/ | Get list of Bank Accounts |
GET | /bankaccounts/:id | Get details of Bank Account ID = id |
Customers | ||
GET | /customers/:id | Get details of Customer ID = id |
GET | /customers/:id/branches/ | Get Branch list for Customer ID = id |
POST | /customers/ | Add Customer |
PUT | /customers/:id | Edit Customer ID = id |
DELETE | /customers/:id | Delete Customer ID = id |
Suppliers | ||
GET | /suppliers/:id | Get details of Supplier ID = id |
GET | /suppliers/:id/contacts/ | Get Contact list for Supplier ID = id |
POST | /suppliers/ | Add Supplier |
PUT | /suppliers/:id | Edit Supplier ID = id |
DELETE | /suppliers/:id | Delete Supplier ID = id |
GL Accounts | ||
GET | /glaccounts/ | Get list of All GL Accounts |
GET | /glaccounts/:id | Get details of GL Account ID = id |
GL Account Types | ||
GET | /glaccounttypes/ | Get list of GL Account Types |
Currencies | ||
GET | /currencies/ | Get list of All Currencies |
GET | /currencies/:id | Get details of Currency ID = id |
Exchange Rates | ||
GET | /exrates/:curr_abrev | Get Last Exchange Rate for Currency Abbreviation = curr_abrev |
Item Costs | ||
GET | /itemcosts/:id | Get cost of Item ID = id |
PUT | /itemcosts/:id | Edit cost of Item ID = id |
Fixed Assets | ||
GET | /assets/:id | Get details of Fixed Asset ID = id |
POST | /assets/ | Add Fixed Asset |
Asset Types | ||
GET | /assettypes/ | Get list of All Asset Types |
Sales Quotes | ||
GET | /salesquotes/:id | Get Sales Quote ID = id |
POST | /salesquotes/ | Add Sales Quote - WIP |
Some of them have not been tested yet so be careful.
Sample Usage
Create a testslim.php file with the following contents and place it in the modules/api folder and execute it in a browser:
<?php // Usage: // http://www.mydomain.com/modules/api/testslim.php/hello/Alpha/Beta // Will output: // Hello, Alpha, Beta include_once ("Slim/Slim.php"); \Slim\Slim::registerAutoloader(); $app = new \Slim\Slim(); $app->get('/hello/:name/:name2', function ($nameone,$two) { echo "Hello, $nameone, $two"; }); $app->run(); ?>
Testing Access from external server
Extract the FA REST Bridge files into another server's webroot (or any folder path in it). Change the fabridge.php's constants with values in the first few lines to suit your FA server's access details).
Contents of fabridge.php:
<?php /* FrontAccounting Bridge Function Ref: http://singletonio.blogspot.in/2009/07/simple-php-rest-client-using-curl.html Author: Ap.Muthu Website: http://www.apmuthu.com Release Date: 2012-11-28 */ define("REST_URL", "http://www.mydomain.com/modules/api"); define("COMPANY_NO", "0"); define("REST_USER", "admin"); define("REST_PWD", "123456"); function fa_bridge($method="g", $action, $record="", $filter=false, $data=false) { $url = REST_URL . "/$action/$record"; if ($filter) $url .= "/$filter"; # headers and data (this is API dependent, some uses XML) $headers = array(); /* // optional headers $headers[] = "Accept: application/json"; $headers[] = "Content-Type: application/json"; */ $headers[] = "X_company: " . COMPANY_NO; $headers[] = "X_user: " . REST_USER; $headers[] = "X_password: " . REST_PWD; $handle = curl_init(); curl_setopt($handle, CURLOPT_URL, $url); curl_setopt($handle, CURLOPT_HEADER, 0); curl_setopt($handle, CURLOPT_HTTPHEADER, $headers); curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false); switch($method) { case 'g': break; case 'p': curl_setopt($handle, CURLOPT_POST, true); curl_setopt($handle, CURLOPT_POSTFIELDS, $data); break; case 't': curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($handle, CURLOPT_POSTFIELDS, $data); break; case 'd': curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'DELETE'); break; } // grab URL and pass it to the variable and not browser ob_start(); curl_exec($handle); $content = ob_get_contents(); ob_end_clean(); $code = curl_getinfo($handle, CURLINFO_HTTP_CODE); // close cURL resource, and free up system resources curl_close($handle); $content = ($code == "200") ? json_decode($content, true) : false; return $content; } ?>
Contents of facurlrest.php file:
<?php // FrontAccounting Bridge REST Test Script // Author: Ap.Muthu // Website: www.apmuthu.com // Release Date: 2012-11-28 include_once "fabridge.php"; $method = isset($_GET['m']) ? $_GET['m'] : 'g'; // g, p, t, d => GET, POST, PUT, DELETE $action = isset($_GET['a']) ? $_GET['a'] : ''; $record = isset($_GET['r']) ? $_GET['r'] : ''; $filter = isset($_GET['f']) ? $_GET['f'] : false; // Sample Data for POST $data = json_encode(array( 'firstName'=> 'John', 'lastName'=> 'Doe' )); $output = fa_bridge($method, $action, $record, $filter, $data); echo print_r($output, true); ?>
Now execute http://IP_OF_OTHER_SERVER/REST_PATH/facurlrest.php?a=category in a browser as an example to get all the category details and the output would contain all records and be like:
Array ( [0] => Array ( [category_id] => 1 [description] => Components [dflt_tax_type] => 1 [dflt_units] => each [dflt_mb_flag] => B [dflt_sales_act] => 4010 [dflt_cogs_act] => 5010 [dflt_inventory_act] => 1510 [dflt_adjustment_act] => 5040 [dflt_assembly_act] => 1530 [dflt_no_sale] => 0 ) [1] => Array ( [category_id] => 2 [description] => Charges [dflt_tax_type] => 1 [dflt_units] => each [dflt_mb_flag] => D [dflt_sales_act] => 4010 [dflt_cogs_act] => 5010 [dflt_inventory_act] => 1510 [dflt_adjustment_act] => 5040 [dflt_assembly_act] => 1530 [dflt_no_sale] => 0 ) [2] => Array ( [category_id] => 3 [description] => Systems [dflt_tax_type] => 1 [dflt_units] => each [dflt_mb_flag] => M [dflt_sales_act] => 4010 [dflt_cogs_act] => 5010 [dflt_inventory_act] => 1510 [dflt_adjustment_act] => 5040 [dflt_assembly_act] => 1530 [dflt_no_sale] => 0 ) [3] => Array ( [category_id] => 4 [description] => Services [dflt_tax_type] => 1 [dflt_units] => hrs [dflt_mb_flag] => D [dflt_sales_act] => 4010 [dflt_cogs_act] => 5010 [dflt_inventory_act] => 1510 [dflt_adjustment_act] => 5040 [dflt_assembly_act] => 1530 [dflt_no_sale] => 0 ) )
If a record number is specified we get the specific record. On appending &r=2 in the url and executing it, we get the details of the the Item Category 2 - the data is available as ASSOCiated and Index Numbered:
Array ( [0] => 2 [category_id] => 2 [1] => Charges [description] => Charges [2] => 1 [dflt_tax_type] => 1 [3] => each [dflt_units] => each [4] => D [dflt_mb_flag] => D [5] => 4010 [dflt_sales_act] => 4010 [6] => 5010 [dflt_cogs_act] => 5010 [7] => 1510 [dflt_inventory_act] => 1510 [8] => 5040 [dflt_adjustment_act] => 5040 [9] => 1530 [dflt_assembly_act] => 1530 [10] => 0 [dflt_dim1] => 0 [11] => 0 [dflt_dim2] => 0 [12] => 0 [inactive] => 0 [13] => 0 [dflt_no_sale] => 0 )
Example URIs for REST Access
- http://IP_OF_OTHER_SERVER/REST_PATH/facurlrest.php?a=category
- http://IP_OF_OTHER_SERVER/REST_PATH/facurlrest.php?a=category&r=1
- http://IP_OF_OTHER_SERVER/REST_PATH/facurlrest.php?a=locations
- http://IP_OF_OTHER_SERVER/REST_PATH/facurlrest.php?exrates&r=INR
If m=t (Edit), m=p (Add) or m=d (Delete) are used in the URL, then the $data array must have the field values set in the script accordingly. The actual field subscripts used in the $data array can be taken from the respective *.inc files included in the SimpleAPI module.
REST Clients
- PHP HTTP Client
- RESTful CRUD
- REST Client @GoogleCode
- PEST PHP REST Client
- PHP cURL REST Client - Used in this article
- Guzzle
- Tutorials - 1, 2
Support and Contact
- Any question about this you can always contact the author Andres Amaya Diaz at andres.amaya.diaz@gmail.com