| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Invoicing (account)
• Sales (sale_management) • Purchase (purchase) • Discuss (mail) |
| Community Apps Dependencies | Show |
| Lines of code | 10285 |
| Technical Name |
eh_log_l10n_sa_customs |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
| Availability |
Odoo Online
Odoo.sh
On Premise
|
| Odoo Apps Dependencies |
•
Invoicing (account)
• Sales (sale_management) • Purchase (purchase) • Discuss (mail) |
| Community Apps Dependencies | Show |
| Lines of code | 10285 |
| Technical Name |
eh_log_l10n_sa_customs |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
KSA Customs FASAH Adapter
The Saudi customs country pack for the ERP Heritage logistics suite: a FASAH JSON adapter, seven KSA declaration types, and KSA HS overlays, auto-installed when both customs and the Saudi localization are present.
Why this module
KSA Customs FASAH Adapter
Appends, never replaces
KSA declaration types and HS overlays are layered on top of the suite's universal master data. The global hierarchy stays intact, so adding Saudi support does not disturb other country packs already installed.
Mock endpoint on a fresh install
The seeded FASAH profile defaults to mock environment against the sandbox host. The first declaration you export runs against fixtures, not the live regulator, until you configure real credentials and switch the environment.
Inherits the adapter framework
The FASAH adapter is a thin subclass of the suite's base adapter. Retry, circuit breaker, dead-letter handling, and the PII-redacted message log all come from the shared engine, so the KSA pack carries only the FASAH-specific serialise and parse logic.
Day in the life
A KSA import declaration, start to response
An operator builds a Saudi import declaration on the customs module, picks the KSA declaration type, and adds lines against KSA HS codes that carry the 5 or 0 percent duty and 15 percent VAT defaults. On submit, the FASAH adapter serialises the declaration into the FASAH JSON envelope, dispatches it, and parses the response into a structured result with the regulator reference, status, and any error rows. In mock mode the same path replays a captured sandbox fixture, so the flow is fully exercised before live credentials exist. Every exchange is logged by the suite engine with payloads redacted.
Edge cases
The cases most modules quietly ignore.
In the shipped code today, each one a place where a cheaper module silently does the wrong thing.
A FASAH rejection response is parsed into a typed result carrying the regulator status and a list of error rows (code, message, field). The bundled rejection fixture covers the importer-VAT-not-found case, so callers can surface the exact regulator complaint rather than a generic failure.
If FASAH returns non-JSON on a submission, the adapter raises a typed validation error (EHL-ADAPTER-VALIDATION-042) and leaves the raw payload in the message log, instead of swallowing a half-parsed envelope.
The adapter implements exactly three message types: declaration submit, status, and health check. Any other type raises a typed error naming what is implemented, so a caller never gets a silent no-op.
KSA declaration types include a distinct Import to Special Economic Zone variant alongside import, export, transit, re-export, temporary admission, and GCC inter-state movement, so SEZ movements are not forced through the plain import path.
The HS overlay marks prohibited imports (for example malt beer at a 100 percent rate) and excise goods (cigarettes, sweetened carbonated beverages) with their elevated duty figures, so the starter tariff reflects KSA reality rather than a flat default.
The FASAH API key is resolved per company through the suite credentials helper, with environment variable, encrypted parameter, and default precedence. One Odoo install can dispatch to two companies' FASAH accounts without crossing keys.
What is inside
Built to do the job, end to end.
- FASAH adapter (submit, status, health). A concrete subclass of the suite base adapter that serialises a declaration into the FASAH JSON envelope (parties, totals, and per-line HS, origin, quantity, duty, and VAT detail), dispatches over HTTPS, and parses submit, status, and health-check responses. API version is pinned to 1.4 on the class, so a schema bump is a new adapter version rather than a silent break.
- Seven KSA declaration types. Country-scoped variants appended to the customs declaration type catalog: import, export, transit, re-export, temporary admission, GCC inter-state movement, and import to a special economic zone, each scoped to Saudi Arabia with its own sequence.
- KSA HS overlays. A starter set of KSA-scoped HS subheadings (phones, laptops, vehicles, pharmaceuticals, plastics, plus prohibited and excise lines) carrying default duty rates and the 15 percent KSA standard VAT. Operators load the full national tariff from a separate data file when ready.
- Seeded mock-mode FASAH profile. An adapter profile record for FASAH is installed with the sandbox endpoint, mock environment, API key auth, a 60 second timeout, three retry attempts, and a circuit breaker (threshold 5, cooldown 120 seconds). Mock mode means a fresh install never accidentally calls the live FASAH endpoint.
- Fixture-backed offline tests. Tests cover adapter registration, the seeded profile, JSON serialisation across single and multi-line payloads, a successful parse, a documented rejection parse, malformed-JSON handling, and a full mock round trip that writes a message-log row. Live sandbox tests are written and skipped unless an environment flag and credentials are set.
- Suite engine, inherited. Because the adapter extends the shared base, it inherits retry, circuit breaker, dead-letter, mock fixture replay, and the PII-redacted message log. The declaration model's state-machine guards (missing HS lines, missing regulator profile, deferment balance) and regulator-reference surfacing come from the customs module this pack depends on.
Honest about the edges
What this does not do, so nothing surprises you.
- This module ships only the FASAH submit, status, and health-check message types. It does not implement a declaration amendment or re-submission message type.
- There is no status-polling cron in this module. Status is retrieved on demand through the status message type; scheduled polling would be configured separately.
- Despite the manifest noting ZATCA defaults, there is no ZATCA e-invoicing integration here. The only ZATCA-related artifact is the 15 percent standard VAT rate carried on the HS overlays.
- No SABER conformity adapter is included. The pack speaks FASAH only.
- This add-on carries no views, menus, wizards, or controllers of its own. All UI, search, kanban, and billing flows come from the customs module and the wider suite, not from this country pack.
- The HS overlay is a small starter set, not the full Saudi national tariff. Production use requires loading the complete tariff from your own data file.
- Out of the box the adapter targets a mock sandbox endpoint. Live submission requires configuring real FASAH credentials and switching the profile environment.
- This pack auto-installs only when both the customs module and the Saudi localization are already present; on its own it has nothing to bind to.
Saudi Arabia customs Odoo, FASAH adapter, KSA customs declaration, Saudi Customs integration, GCC customs Odoo, HS code KSA, customs duty VAT 15 percent, freight forwarding Odoo 19, 3PL customs module, Saudi import export declaration, special economic zone import KSA, Odoo 19 Community logistics, ERP Heritage logistics suite, customs broker software
Please log in to comment on this module