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/

SimpleAPI GitHub Repo (Forum Post):

 https://github.com/andresamayadiaz/FrontAccountingSimpleAPI

The changes made to inventory.inc in the above repo on 2013-02-12 are personal to the author and has the GL Item Accounts hardcoded and hence must be reverted to the previous version till it is fixed.

2013-07-15: Additional changes started in forum post and the relevant GitHub commit.

API Quick Start

  1. Just copy the files into the modules directory under a folder called api (hardcoded in the api files).
  2. 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
  3. 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.
  4. 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:

SimpleAPI Syntax of Available Methods
TypeActionFunction
Items
GET/inventory/Get list of All Inventory Items
GET/inventory/:idGet details of Inventory Item = id
POST/inventory/Add inventory items
PUT/inventory/:idEdit Inventory Item = id
DELETE/inventory/:idDelete Inventory Items = id
Inventory Movements
GET/movementtypes/Get list of All Inventory Movement Types
Locations
GET/locations/Get list of All Locations
POST/locations/Add Location
Stock Adjustments
POST/stock/Add Stock Adjustment
Items Categories
GET/category/Get list of All Item Categories
GET/category/:idGet details of Item Category = id
POST/category/Add Item Categories
PUT/category/:idEdit Item Category = id
DELETE/category/:idDelete 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/:idGet details of Bank Account ID = id
Customers
GET/customers/:idGet details of Customer ID = id
GET/customers/:id/branches/Get Branch list for Customer ID = id
POST/customers/Add Customer
PUT/customers/:idEdit Customer ID = id
DELETE/customers/:idDelete Customer ID = id
Suppliers
GET/suppliers/:idGet details of Supplier ID = id
GET/suppliers/:id/contacts/Get Contact list for Supplier ID = id
POST/suppliers/Add Supplier
PUT/suppliers/:idEdit Supplier ID = id
DELETE/suppliers/:idDelete Supplier ID = id
GL Accounts
GET/glaccounts/Get list of All GL Accounts
GET/glaccounts/:idGet 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/:idGet details of Currency ID = id
Exchange Rates
GET/exrates/:curr_abrevGet Last Exchange Rate for Currency Abbreviation = curr_abrev
Item Costs
GET/itemcosts/:idGet cost of Item ID = id
PUT/itemcosts/:idEdit cost of Item ID = id
Fixed Assets
GET/assets/:idGet 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/:idGet 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

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

Support and Contact

  • Any question about this you can always contact the author Andres Amaya Diaz at andres.amaya.diaz@gmail.com