Goods Stock Records Query (Conditional) (T147)
Query historical stock records filtered by date, supplier, or keywords for the current branch only. This endpoint differs from T145 by restricting results to the authenticated branch context and offering alternative search filters like combineKeywords. Request and response are encrypted.
Endpoint Overview
| Property | Value |
|---|---|
| Interface Code | T147 |
| Request Encrypted | ✅ Yes |
| Response Encrypted | ✅ Yes |
| Request Body | { "combineKeywords": "...", "stockInType": "...", "startDate": "...", "endDate": "...", "pageNo": 1, "pageSize": 10 } |
| Response Format | JSON with pagination |
Flow Description
- Client submits query with optional filters (
combineKeywords,stockInType,supplierTin, date range) and pagination parameters. - Server validates the request against the current branch context (authenticated branch).
- Server queries stock records matching the criteria for the current branch only.
- Server returns paginated results with supplier details, stock-in information, and amounts.
- Client displays records or uses data for branch-specific audit/compliance reporting.
💡 Tip: Use T147 instead of T145 when you need to query stock records specifically for the current branch context. T145 queries across all branches.
- PHP
- JavaScript / TypeScript
- Python
try {
// Call T147: Goods Stock Records Query (Conditional/Current Branch)
$filters = [
'combineKeywords' => '425502528294126235', // Optional: referenceNo or supplierName
'stockInType' => '101', // Optional: 101=Import, 102=Local Purchase, etc.
'startDate' => '2025-02-19', // Optional: Start date
'endDate' => '2025-02-19', // Optional: End date
'supplierTin' => '1000029771', // Optional: Supplier TIN
'supplierName' => 'UGANDA REVENUE AUTHORITY', // Optional: Supplier Name
'pageNo' => 1,
'pageSize' => 10
];
$response = $client->queryStockRecordsAlt($filters);
$content = $response['data']['content'] ?? $response;
$records = $content['records'] ?? [];
$page = $content['page'] ?? [];
if (!empty($records)) {
echo "✅ Retrieved " . count($records) . " stock record(s)\n";
echo " Page: {$page['pageNo']}/{$page['pageCount']} (Total: {$page['totalSize']})\n";
foreach ($records as $record) {
echo " • Supplier: {$record['supplierName']} (TIN: {$record['supplierTin']})\n";
echo " Stock-In Type: {$record['stockInType']}\n";
echo " Date: {$record['stockInDate']}\n";
echo " Invoice: {$record['invoiceNo']}\n";
echo " Amount: {$record['totalAmount']}\n";
echo " Branch: {$record['branchName']}\n";
echo " ID: {$record['id']}\n";
echo "\n";
}
} else {
echo "⚠️ No stock records found for provided criteria\n";
}
} catch (\UraEfrisSdk\Exceptions\APIException $e) {
echo "❌ Query failed: " . $e->getMessage() . "\n";
echo " Return Code: " . $e->getReturnCode() . "\n";
}
try {
// Call T147: Goods Stock Records Query (Conditional/Current Branch)
const filters = {
combineKeywords: '425502528294126235', // Optional: referenceNo or supplierName
stockInType: '101', // Optional: 101=Import, 102=Local Purchase, etc.
startDate: '2025-02-19', // Optional: Start date
endDate: '2025-02-19', // Optional: End date
supplierTin: '1000029771', // Optional: Supplier TIN
supplierName: 'UGANDA REVENUE AUTHORITY', // Optional: Supplier Name
pageNo: 1,
pageSize: 10
};
const response = await client.queryStockRecordsAlt(filters);
const content = response?.data?.content ?? response;
const records = content?.records ?? [];
const page = content?.page ?? {};
if (records.length > 0) {
console.log(`✅ Retrieved ${records.length} stock record(s)`);
console.log(` Page: ${page.pageNo}/${page.pageCount} (Total: ${page.totalSize})`);
for (const record of records) {
console.log(` • Supplier: ${record.supplierName} (TIN: ${record.supplierTin})`);
console.log(` Stock-In Type: ${record.stockInType}`);
console.log(` Date: ${record.stockInDate}`);
console.log(` Invoice: ${record.invoiceNo}`);
console.log(` Amount: ${record.totalAmount}`);
console.log(` Branch: ${record.branchName}`);
console.log(` ID: ${record.id}`);
console.log('');
}
return content;
} else {
console.warn('⚠️ No stock records found for provided criteria');
return { records: [], page };
}
} catch (error: any) {
console.error(`❌ Query failed: ${error.message}`);
if (error.returnCode) {
console.error(` Return Code: ${error.returnCode}`);
}
throw error;
}
try:
# Call T147: Goods Stock Records Query (Conditional/Current Branch)
filters = {
"combineKeywords": "425502528294126235", # Optional: referenceNo or supplierName
"stockInType": "101", # Optional: 101=Import, 102=Local Purchase, etc.
"startDate": "2025-02-19", # Optional: Start date
"endDate": "2025-02-19", # Optional: End date
"supplierTin": "1000029771", # Optional: Supplier TIN
"supplierName": "UGANDA REVENUE AUTHORITY", # Optional: Supplier Name
"pageNo": 1,
"pageSize": 10
}
response = client.query_stock_records_alt(filters)
content = response.get("data", {}).get("content", response)
records = content.get("records", [])
page = content.get("page", {})
if records:
print(f"✅ Retrieved {len(records)} stock record(s)")
print(f" Page: {page.get('pageNo')}/{page.get('pageCount')} (Total: {page.get('totalSize')})")
for record in records:
print(f" • Supplier: {record['supplierName']} (TIN: {record['supplierTin']})")
print(f" Stock-In Type: {record['stockInType']}")
print(f" Date: {record['stockInDate']}")
print(f" Invoice: {record['invoiceNo']}")
print(f" Amount: {record['totalAmount']}")
print(f" Branch: {record['branchName']}")
print(f" ID: {record['id']}")
print()
else:
print("⚠️ No stock records found for provided criteria")
except Exception as e:
print(f"❌ Query failed: {e}")
if hasattr(e, "return_code"):
print(f" Return Code: {e.return_code}")
raise
Request Structure
{
"data": {
"content": "BASE64_ENCRYPTED_PAYLOAD",
"signature": "JKQWJK34K32JJEK2JQWJ5678",
"dataDescription": {
"codeType": "1",
"encryptCode": "2",
"zipCode": "0"
}
},
"globalInfo": {
"interfaceCode": "T147",
"appId": "AP04",
"version": "1.1.20191201",
"tin": "1000029771",
"deviceNo": "TCS9e0df01728335239",
"taxpayerID": "1"
}
}
Request Fields (Encrypted Payload)
| Field | Required | Type | Length | Description |
|---|---|---|---|---|
combineKeywords | ❌ No | String | ≤50 | Search keyword containing referenceNo or supplierName |
stockInType | ❌ No | String (3) | 3 | Filter by stock-in type: 101=Import, 102=Local Purchase, 103=Manufacture/Assembling, 104=Opening Stock |
startDate | ❌ No | Date | - | Start date for filtering (yyyy-MM-dd) |
endDate | ❌ No | Date | - | End date for filtering (yyyy-MM-dd) |
pageNo | ✅ Yes | Number | ≤10 | Current page number (starts from 1) |
pageSize | ✅ Yes | Number | ≤3 | Records per page; cannot exceed 100 |
supplierTin | ❌ No | String | ≤50 | Filter by supplier TIN |
supplierName | ❌ No | String | ≤100 | Filter by supplier name |
💡 Tip: Unlike T145, T147 does not require
productionBatchNo,invoiceNo, orreferenceNoas mandatory search keys. It uses broader filters scoped to the current branch.
Response Structure
{
"data": {
"content": {
"page": {
"pageNo": "1",
"pageSize": "10",
"totalSize": "50",
"pageCount": "5"
},
"records": [
{
"supplierTin": "1000029771",
"supplierName": "UGANDA REVENUE AUTHORITY",
"remarks": "Increase inventory",
"stockInDate": "2020-09-01",
"stockInType": "101",
"productionBatchNo": "1200983",
"productionDate": "2025-02-19",
"branchId": "2020090132456",
"invoiceNo": "320001127399",
"referenceNo": "425502528294126235",
"branchName": "PARAMOUR COSMETICS LIMITED",
"totalAmount": "1000.00",
"id": "425502528294126235"
}
]
}
},
"globalInfo": {
"interfaceCode": "T147",
"returnStateInfo": {
"returnCode": "00",
"returnMessage": "SUCCESS"
}
}
}
Response Fields
Pagination Object
| Field | Required | Type | Description |
|---|---|---|---|
pageNo | ✅ Yes | Number | Current page number |
pageSize | ✅ Yes | Number | Records per page |
totalSize | ✅ Yes | Number | Total number of matching records |
pageCount | ✅ Yes | Number | Total number of pages |
Stock Records Array Items
| Field | Required | Type | Length | Description |
|---|---|---|---|---|
id | ✅ Yes | String | ≤18 | Unique stock record identifier (use for T148 detail query) |
supplierTin | ❌ No | String | ≤50 | Supplier's Taxpayer Identification Number |
supplierName | ❌ No | String | ≤100 | Supplier name/business name |
remarks | ❌ No | String | ≤1024 | Stock record remarks/notes |
stockInDate | ❌ No | Date | - | Stock-in date (yyyy-MM-dd) |
stockInType | ❌ No | String (3) | 3 | 101=Import, 102=Local Purchase, 103=Manufacture/Assembling, 104=Opening Stock |
productionBatchNo | ❌ No | String | ≤50 | Production batch number (populated if stockInType=103) |
productionDate | ❌ No | Date | - | Production date (yyyy-MM-dd; populated if stockInType=103) |
branchId | ❌ No | String | ≤18 | Branch identifier (will match current branch context) |
branchName | ❌ No | String | ≤500 | Branch name |
invoiceNo | ❌ No | String | ≤20 | Associated invoice number |
referenceNo | ❌ No | String | ≤50 | Seller's reference number |
totalAmount | ❌ No | Number | - | Total stock-in amount |
💡 Tip: The
idfield in the response is required to query full stock record details via T148.
Return Codes
| Code | Message | Description |
|---|---|---|
00 | SUCCESS | Stock records retrieved successfully |
99 | Unknown error | Generic server error |
400 | Device does not exist | deviceNo not registered for this TIN |
402 | Device key expired | Device credentials expired; re-run T102 |
403 | Device status is abnormal | Device blocked or suspended |
1521 | pageNo:cannot be empty! | Missing page number in request |
1522 | pageNo:The byte length cannot be less than 0 and cannot be greater than 20! | Page number format error |
1523 | pageNo:Cannot be greater than -1! | Page number must be positive |
1524 | pageSize:cannot be empty! | Missing page size in request |
1525 | pageSize:The byte length cannot be less than 0 and cannot be greater than 3! | Page size format error |
1526 | pageSize:Cannot be greater than 100! | Page size exceeds maximum (100) |
2879 | combineKeywords: cannot be empty! | Keyword search required in some contexts (check validation) |
2880 | combineKeywords: Byte length cannot be greater than 50! | Keyword exceeds length limit |
💡 Tip: While
combineKeywordsis marked optional in the field table, error code2879suggests it may be required in certain validation contexts. Handle gracefully.
Common Use Cases
-
Branch-Specific Stock Auditing
Query stock records for the current branch only without retrieving data from other branches (unlike T145). -
Supplier Transaction Tracking
Filter records bysupplierTinorsupplierNameto track all stock-ins from a specific supplier for the current branch. -
Date-Range Reporting
Generate stock-in reports for specific periods (e.g., monthly, quarterly) usingstartDateandendDate. -
Keyword Search
Quickly locate stock records using partial matches on reference numbers or supplier names viacombineKeywords. -
Stock-In Type Analysis
Filter bystockInTypeto analyze import vs. local purchase vs. manufacturing stock flows. -
Record Detail Lookup
Retrieve theidfrom T147 results to fetch full item-level details via T148.
Integration Checklist
✅ Ensure pageNo ≥ 1 and pageSize ≤ 100 before submitting request
✅ Handle empty records array gracefully (no matching records found)
✅ Implement pagination logic using pageCount and totalSize from response
✅ Validate date format is yyyy-MM-dd for startDate and endDate
✅ Use T147 for current-branch queries; use T145 for all-branches queries
✅ Cache frequently-queried stock records to reduce API calls
✅ Log query parameters for audit trail compliance
✅ Use response id field to call T148 for detailed item information
✅ Validate stockInType values against T115 dictionary for display purposes
✅ Handle potential 2879 error if combineKeywords validation is enforced