Api Documentation
API Controller Documentation
File: /controllers/api.php
Purpose: RESTful API endpoints for mobile app and external integrations
Last Updated: December 20, 2024
Total Functions: 14+
Lines of Code: ~455
---
๐ Overview
The API Controller provides JSON-based REST API endpoints for mobile applications and third-party integrations. It handles:
- โข User authentication and session management
- โข Customer authentication for mobile apps
- โข Product catalog retrieval with search and pagination
- โข Sales order creation and management (offer system)
- โข Customer debt reports and transaction history
- โข Cross-Origin Resource Sharing (CORS) support
- โข Multi-language responses (Arabic/English)
- โข Real-time sales order processing
Primary Functions
- โ User login authentication
- โ Customer login authentication
- โ Product catalog API with search
- โ Sales offer creation and management
- โ Real-time product addition to offers
- โ Customer debt reporting
- โ Barcode collection for POS systems
- โ Order total calculations with tax
- โ Order deletion and modification
- โ CORS headers for web applications
Related Controllers
- โข sellbillController.php - Sales operations
- โข clientController.php - Customer management
- โข productController.php - Product management
- โข clientReportsController.php - Customer reports
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **user** | System user authentication | userid, username, password, employeename, usergroupid, conditions | |
| **client** | Customer authentication & data | clientid, clientname, clientphone, password, priceTypeId, conditions | |
| **product** | Product catalog | productId, productName, productBuyPrice, productSellAllPrice, productSellHalfPrice, productSellUnitPrice, parcode, productCatId | |
| **collectedparcodestemp** | Temporary barcode storage | userid, sellerid, parcodes, sysdate, conditions |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **sellbilloffer** | Sales offers/draft orders | sellbillid, sellbillclientid, sellbillserial, sellbilltotalbill, sellbillaftertotalbill, orderSavedBillId, tax | |
| **sellbilldetailoffer** | Sales offer line items | sellbilldetailid, sellbillid, sellbilldetailproductid, sellbilldetailquantity, sellbilldetailprice, sellbilldetailtotalprice |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **clientdebtchange** | Customer debt transactions | clientdebtchangeid, clientid, clientdebtchangeamount, clientdebtchangetype, tablename, clientdebtchangemodelid | |
| **sellbill** | Completed sales bills | sellbillid, sellbillclientid, sellbilltotalbill, sellbillaftertotalbill, sellbilltotalpayed | |
| **returnsellbill** | Sales return bills | returnsellbillid, returnsellbillclientid, returnsellbilltotalbill, returnsellbillaftertotalbill | |
| **sellbillandrutern** | Combined sell/return bills | sellbillid, sellbillclientid, sellbillprice, returnsellbillprice |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **programsettings** | System settings | programsettingsid, settingkey, settingvalue, vatValue | |
| **checkdeposit** | Check deposits | checkdepositid, clientid, bankname, accountname, checkamount | |
| **bills** | Service bills | billid, clientid, productstotalprice, finalnetbillvalue |
๐ Key Functions
1. User Authentication - do=user
Location: Line 49
Purpose: Retrieve user information for mobile app authentication
Request Parameters:
$id = $get_request->id; // Single user ID
$usergroupid = $get_request->group; // User group ID
// No parameters = all users
Response Format:
// Single user
{"id": 123, "name": "John Doe"}
// Multiple users
[
{"id": 123, "name": "John Doe"},
{"id": 124, "name": "Jane Smith"}
]
Process Flow:
1. Parse request parameters from JSON
2. Query user table based on parameters
3. Filter active users (conditions = 0)
4. Return JSON response with user data
---
2. User Login - do=login
Location: Line 88
Purpose: Authenticate system users for mobile applications
Request Parameters:
$username = $get_request->username;
$password = $get_request->password;
Response Format:
{
"status": 1, // 1=success, 2=error, 3=missing data
"reason": "success",
"id": 123,
"name": "John Doe"
}
Security Features:
- โข Direct SQL query with parameter binding
- โข Active user validation (conditions = 0)
- โข Password comparison (plain text - legacy system)
- โข Structured error responses
---
3. Customer Login - do=clientlogin
Location: Line 143
Purpose: Authenticate customers for mobile app access
Request Parameters:
$phone = $get_request->phone;
$password = $get_request->password;
Response Format:
{
"status": 1,
"reason": "ุชู
ุชุณุฌูู ุงูุฏุฎูู", // Arabic success message
"clientid": 456,
"clientname": "Customer Name"
}
Features:
- โข Phone-based authentication
- โข Multi-language responses (Arabic)
- โข Client status validation
- โข Mobile-optimized responses
---
4. Product Catalog - do=product
Location: Line 162
Purpose: Retrieve product catalog with search and pagination
Request Parameters:
$id = $get_request->id; // Single product ID
$text = $get_request->search; // Search term
$start_item = $get_request->start_item; // Pagination offset
$page_no = $get_request->page_no; // Items per page
$show_all = $get_request->show_all; // Disable pagination
Response Modes:
// Single product
{"productId": 123, "productName": "Item", "productSellAllPrice": 100.00}
// Search results (paginated)
[
{"productId": 123, "productName": "Item 1", "productSellAllPrice": 100.00},
{"productId": 124, "productName": "Item 2", "productSellAllPrice": 150.00}
]
Search Features:
- โข LIKE search on product names
- โข Pagination support (default 20 items)
- โข Active product filtering (conditions = 0)
- โข Flexible result formats
---
5. Customer Report - do=clientreport
Location: Line 189
Purpose: Generate customer debt and transaction reports
Request Parameters:
$clientid = $get_request->clientid;
$startDate = $get_request->from;
$endDate = $get_request->to;
$order = $get_request->order;
Process Flow:
1. Build dynamic WHERE clause based on filters
2. Join clientdebtchange with client tables
3. Calculate running debt totals
4. Link transactions to source documents
5. Load additional data based on transaction type
6. Return enriched transaction array
Transaction Types Handled:
- โข
sellbillController.php- Sales bills - โข
returnsellbillController.php- Sales returns - โข
depositcheckController.php- Check deposits - โข
clientPayedDeptController.php- Customer payments - โข
billreceiptController.php- Bill receipts
---
6. Create Sales Offer - do=createsellbillid
Location: Line 301
Purpose: Create new sales order/offer for customer
Request Parameters:
$clientid = $get_request->clientid;
Process Flow:
1. Validate customer exists
2. Generate unique serial number using uniqid()
3. Insert new sellbilloffer record
4. Set default values (tax = 15%, billnameid = 7)
5. Return new offer ID for subsequent operations
Response Format:
{
"status": 1,
"reason": "ุชู
ุจูุฌุงุญ",
"sellbillid": 12345
}
---
7. Add Product to Offer - do=addsellbilloffer
Location: Line 333
Purpose: Add or update product in existing sales offer
Request Parameters:
$productid = $get_request->productid;
$quantity = $get_request->quantity;
$sellbillid = $get_request->sellbillid;
Process Flow:
1. Check if offer is still editable (orderSavedBillId = 0)
2. Load product and customer data
3. Determine price based on customer's price type:
- -1 or 0: All price (wholesale)
- 2: Half price
- 1: Unit price (retail)
4. Check if product already exists in offer
5. Insert new or update existing line item
6. Recalculate offer totals with tax
7. Update offer header with new totals
Tax Calculation:
$vatValue = R::getCell("SELECT vatValue FROM programsettings WHERE programsettingsid = 1");
$taxPer = $vatValue / 100;
$taxPerPlusOne = $taxPer + 1;
$sellbilltotalbill = $sellbilldetailtotalprice - (($sellbilldetailtotalprice * $taxPer) / $taxPerPlusOne);
---
8. Barcode Collection - do=collectparcodes
Location: Line 110
Purpose: Store scanned barcodes for later processing
Request Parameters:
$userid = $get_request->userid;
$sellerid = $get_request->casherid;
$parcodes = $get_request->parcodes; // "00001,00002,00003"
Use Case: Mobile app scans multiple product barcodes, stores them temporarily, then processes all at once on main POS system.
Response Format:
{
"status": 1,
"reason": "sucess",
"id": 789
}
---
๐ Workflows
Workflow 1: Mobile Sales Order Creation
---
Workflow 2: Customer Debt Report Access
---
๐ URL Routes & Actions
| URL Parameter | Function | Description | HTTP Method | |
|---|---|---|---|---|
| `do=user` | User lookup | Get user information by ID, group, or all | GET/POST | |
| `do=login` | User authentication | System user login | POST | |
| `do=clientlogin` | Customer authentication | Customer mobile login | POST | |
| `do=product` | Product catalog | Search products with pagination | GET/POST | |
| `do=clientreport` | Customer reports | Generate debt/transaction reports | POST | |
| `do=createsellbillid` | Create offer | Start new sales offer | POST | |
| `do=addsellbilloffer` | Add to offer | Add product to existing offer | POST | |
| `do=sellbilloffer` | List offers | Get customer's active offers | GET/POST | |
| `do=sellbilldetailoffer` | Offer details | Get offer header and line items | GET/POST | |
| `do=deletesellbilloffer` | Delete offer | Remove entire offer | POST | |
| `do=deletesellbilldetailoffer` | Delete line | Remove product from offer | POST | |
| `do=collectparcodes` | Store barcodes | Temporary barcode storage | POST |
๐งฎ Calculation Methods
Customer Pricing Logic
// Price determination based on customer type
if ($client['priceTypeId'] == -1 || $client['priceTypeId'] == 0) {
$price = $product['productSellAllPrice']; // Wholesale
$pricetype = 0;
} elseif ($client['priceTypeId'] == 2) {
$price = $product['productSellHalfPrice']; // Half price
$pricetype = 2;
} else {
$price = $product['productSellUnitPrice']; // Retail
$pricetype = 1;
}
Tax Calculation (VAT)
$vatValue = R::getCell("SELECT vatValue FROM programsettings WHERE programsettingsid = 1");
$taxPer = $vatValue / 100;
$taxPerPlusOne = $taxPer + 1;
// Calculate price excluding tax
$sellbilltotalbill = $sellbilldetailtotalprice - (($sellbilldetailtotalprice * $taxPer) / $taxPerPlusOne);
Debt Balance Calculation
$total = 0;
foreach ($send_data as $data) {
if ($data->clientdebtchangetype == 0) {
$total = $total + $data->clientdebtchangeamount; // Debt increase
} else {
$total = $total - $data->clientdebtchangeamount; // Payment/decrease
}
}
---
๐ Security & Permissions
CORS Configuration
if (isset($_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Max-Age: 86400'); // cache for 1 day
}
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");
exit(0);
}
Input Handling
// Multi-platform request parsing
$post_data = file_get_contents("php://input");
if (empty($post_data)) {
$get_request = json_decode(json_encode($_POST)); // iOS
} else {
$get_request = json_decode($post_data); // Android
}
Authentication Methods
- โข Users: Username + password validation
- โข Customers: Phone + password validation
- โข Active Status: All queries filter
conditions = 0 - โข SQL Injection: Uses RedBeanPHP parameterized queries
---
๐ Performance Considerations
Database Optimization
1. Indexes Required:
- user(username, conditions)
- client(clientphone, conditions)
- product(productName, conditions)
- clientdebtchange(clientid, clientdebtchangedate)
2. Query Efficiency:
- Product search uses LIKE with leading wildcard (slower)
- Pagination implemented for large result sets
- Active record filtering on all queries
3. Memory Management:
- JSON responses can be large for full catalogs
- Debt reports may return extensive transaction histories
- Consider implementing result limits for mobile apps
API Response Times
-- Fast queries (< 10ms)
SELECT * FROM user WHERE userid = ? AND conditions = 0;
-- Moderate queries (10-100ms)
SELECT * FROM product WHERE productName LIKE '%term%' AND conditions = 0 LIMIT 20;
-- Slower queries (100ms+)
SELECT clientdebtchange.*, client.clientname FROM clientdebtchange
JOIN client ON client.clientid = clientdebtchange.clientid
WHERE clientdebtchange.clientid = ? ORDER BY clientdebtchangedate DESC;
---
๐ Common Issues & Troubleshooting
1. CORS Errors in Web Applications
Issue: Browser blocks API requests from different domains
Cause: Missing or incorrect CORS headers
Fix: Headers are already configured for * origin, but check:
// Verify these headers are sent
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Credentials: true
2. Empty API Responses
Issue: API returns empty arrays or null responses
Cause: Database connection issues or incorrect table filtering
Debug:
-- Check table data exists
SELECT COUNT(*) FROM user WHERE conditions = 0;
SELECT COUNT(*) FROM product WHERE conditions = 0;
SELECT COUNT(*) FROM client WHERE conditions = 0;
3. Tax Calculation Errors
Issue: Incorrect price calculations in offers
Cause: VAT setting missing or misconfigured
Fix:
-- Verify VAT setting exists
SELECT vatValue FROM programsettings WHERE programsettingsid = 1;
-- Should return value like 15.00 for 15% VAT
INSERT INTO programsettings (programsettingsid, vatValue) VALUES (1, 15.00)
ON DUPLICATE KEY UPDATE vatValue = 15.00;
4. Mobile Authentication Failures
Issue: Login always returns status = 2
Cause: Password encoding mismatch or inactive accounts
Debug:
-- Check user exists and is active
SELECT userid, username, conditions FROM user WHERE username = 'testuser';
-- Check client exists and is active
SELECT clientid, clientphone, conditions FROM client WHERE clientphone = '1234567890';
---
๐งช Testing Scenarios
API Endpoint Testing
Test User Authentication:
curl -X POST http://localhost/erp19/controllers/api.php?do=login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"123456"}'
Test Product Search:
curl -X GET "http://localhost/erp19/controllers/api.php?do=product&search=laptop&page_no=10"
Test Sales Offer Creation:
curl -X POST http://localhost/erp19/controllers/api.php?do=createsellbillid \
-H "Content-Type: application/json" \
-d '{"clientid":123}'
Integration Testing
1. Complete Sales Flow: Login โ Browse โ Create Offer โ Add Products โ Review
2. Customer Report Flow: Customer Login โ Request Report โ Process Results
3. Error Handling: Invalid credentials, missing parameters, database errors
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข sellbillController.md - Sales operations
- โข clientReportsController.md - Customer reporting
- โข productController.md - Product management
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When API endpoints change or new mobile features added