Architecture & Technical Design
The application is structured as a standard Frappe app with the following components:
Custom Doctypes
- TIMs INCOTEX Settings: A per-company singleton doctype that stores API credentials, environment, and endpoint URLs.
- Custom fields added to Sales Invoice: for
System Invoice Number,CU Invoice Number,is_filed,Verify URL, and the QR code. - Custom fields added to Sales Invoice Item: for the
hs_codefield per line item. - Custom fields added to the Item Doctype's taxes child table: for
TIMs HS Codeper Item Tax Template. - Custom fields added to Item Group: a matching taxes table for group-level HS Code fallback.
Hooks
The app uses Frappe's doc_events hooks to intercept the on_submit event of the Sales Invoice Doctype. This is the trigger point that calls the INCOTEX API. A similar hook fires for Credit Notes.
API Layer
The integration communicates with INCOTEX over HTTP using a RESTful API, authenticating via an API Key. The request payload is constructed from the ERPNext invoice data and serialised to JSON before being posted to the appropriate endpoint. The response is parsed and used to update the invoice record.
Scheduler / Background Jobs
A Frappe scheduler job runs periodically to auto-submit any invoices that may be pending submission for example, invoices that were posted while the INCOTEX device was offline.
Dashboard
A custom workspace/dashboard provides number cards to give administrators a real-time view of submission statuses across the system.
Language Distribution
The app is predominantly Python (server-side logic, API calls, Frappe hooks, data transformations) with JavaScript used for client-side form enhancements (auto-populating HS codes, triggering manual re-submission, health check buttons).