This is a very Simple FrontAccounting API. The concept of FA <=> POS integration is explained in this Forum Post.

Slim2 Hello World starter pack for FA.

Slim v2.64 based REST API for FA v2.4.x | 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

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. 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>
    
  4. 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.

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

NOTE: methods below that say "get list of all" are actually paginated. You must retrieve pages one at time by adding "?page=XX" to the end of the URL. The API is hard-coded to return 2 items per page.

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 Item = id
Inventory Movements (FA 2.3.x only)
GET/movementtypes/Get list of All Inventory Movement Types
Inventory Locations
GET/locations/Get list of All Locations
POST/locations/Add Location
Stock Adjustments
POST/stock/Add Stock Adjustment
Item Categories
GET/category/Get list of All Item Categories
GET/category/:idGet details of Item Category = id
POST/category/Add Item Category
PUT/category/:idEdit Item Category = id
DELETE/category/:idDelete Item Category = id
Tax Types
GET/taxtypes/Get list of All Tax Types
GET/taxtypes/:idGet details of Tax Type = id
Tax Groups
GET/taxgroups/Get list of All Tax Groups
Customers
GET/customers/Get list of All Customers
GET/customers/:idGet details of Customer ID = id
POST/customers/Add Customer
PUT/customers/:idEdit Customer ID = id
DELETE/customers/:idDelete Customer ID = id
GET/customers/:id/branches/Get Branch list for Customer ID = id
Suppliers
GET/suppliers/Get list of All Suppliers
GET/suppliers/:idGet details of Supplier ID = id
POST/suppliers/Add Supplier
PUT/suppliers/:idEdit Supplier ID = id
DELETE/suppliers/:idDelete Supplier ID = id
GET/suppliers/:id/contacts/Get Contact list for Supplier ID = id
Bank Accounts
GET/bankaccounts/Get list of Bank Accounts
GET/bankaccounts/:idGet details of Bank Account ID = id
POST/bankaccounts/Add Bank Account
PUT/bankaccounts/:idEdit Bank Account ID = id
DELETE/bankaccounts/:idDelete Bank Account ID = id
GL Accounts
GET/glaccounts/Get list of All GL Accounts
GET/glaccounts/:idGet details of GL Account ID = id
POST/glaccounts/Add GL Account
PUT/glaccounts/:idEdit GL Account ID = id
DELETE/glaccounts/:idDelete 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 (FA 2.3.x only)
GET/salesquotes/:idGet Sales Quote ID = id
POST/salesquotes/Add Sales Quote - WIP
Sales
GET/sales/:trans_no/:trans_typeGet Sales Header and Details for trans_no, trans_type
POST/sales/Add Sales Header and Details
PUT/sales/:trans_no/:trans_typeEdit Sales Header and Details for trans_no, trans_type
DELETE/sales/:branch_id/:uuidCancel Sales branch_id, uuid
GET/sales/:trans_type/Get All Sales Header and Details for trans_no
Dimensions
GET/dimensions/Get list of All Dimensions
GET/dimensions/:refGet details of Dimension = ref
POST/dimensions/Add Dimension
PUT/dimensions/:refEdit Dimension = ref
DELETE/dimensions/:refDelete Dimension = ref
Journals
GET/journal/Get list of All Journals
GET/journal/:type/:idGet details of Journal type, id
POST/journal/Add Journal
PUT/journal/:idEdit Journal ID = id
DELETE/journal/:type/:idDelete Journal type, id

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'
));

$data = http_build_query($data);

$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

FA on CLI using bash

USERNAME=XXX
PWDCODE=YYYY
COMPANY=1

wget -q --save-cookies tmp/cookies$$.txt \
     --keep-session-cookies \
     --post-data 'user_name_entry_field=${USERNAME}&password=${PWDCODE}&company_login_name=${COMPANY}' \
     --delete-after \
     http://localhost/frontac24/index.php

## To get the Customer List using '''rep103.php''':
wget -q --load-cookies tmp/cookies$$.txt \
    -O - http://localhost/frontac24/reporting/rep103.php \
    --post-data "PARAM_0=09/13/2014&PARAM_1=&PARAM_2=&PARAM_3=&PARAM_4=&PARAM_5=&PARAM_6=&PARAM_7=0&REP_ID=103" > /tmp/foo.pdf

Support and Contact

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