| 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 | 9905 |
| Technical Name |
eh_log_l10n_bh_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 | 9905 |
| Technical Name |
eh_log_l10n_bh_customs |
| License | LGPL-3 |
| Website | https://www.erpheritage.com.au/ |
Bahrain Customs OFFS Adapter
The Bahrain customs pack for the logistics suite: an OFFS single window adapter plus country-scoped declaration types and HS overlays, mock-ready on a fresh install.
Why this module
Bahrain Customs OFFS Adapter
OFFS contract, not a stub
A concrete adapter that serialises declarations into the OFFS single window JSON envelope and parses the regulator response, surfacing the issued reference, accept or reject status, and per-field error list. Submit, status, and health message types are wired.
Mock mode on first boot
A default OFFS profile is seeded in mock mode at install, so the same code path that talks to the regulator replays captured fixtures deterministically in CI and in a fresh database. No live endpoint required to evaluate the flow.
Bahrain types and HS, appended
Six Bahrain declaration types (import, export, transit, re-export, temporary admission, GCC inter-state) and a starter HS overlay with Bahrain duty and VAT rates are added on top of the shared masters. Country packs append, they never replace.
Day in the life
A broker submits a Bahrain import declaration
The operator builds an import declaration on the shared customs model, picks the Bahrain import type, and dispatches. The OFFS adapter serialises the parties, totals, and HS-coded lines into the single window JSON envelope and posts over HTTPS, with timeout, retry, exponential backoff with jitter, and a circuit breaker all handled by the shared engine. The regulator response is parsed: an accepted declaration surfaces its OFFS reference number, a rejected one surfaces the per-field error list (for example a missing HS code on a line). Every request and response writes an append-only audit row with auth headers redacted. In mock mode the same path replays a shipped fixture, so a fresh install demonstrates the round trip with zero network.
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.
When OFFS rejects a declaration, the adapter parses the structured error array into code, message, and field, so a missing-HS-code rejection points the operator at the exact line rather than a generic failure.
A non-JSON or truncated submit response raises a typed validation error with the parse detail, instead of silently returning an empty or half-built result.
The adapter pins the OFFS API version and refuses to instantiate against a profile whose api_version differs, so a regulator schema bump becomes a deliberate adapter upgrade, not a silent wire break.
The bearer token resolves through environment variable, then encrypted config parameter, then the param key, scoped to the profile company, so one install can dispatch to two companies' OFFS accounts without cross-talk.
After a configurable run of consecutive failures the shared breaker opens for a cooldown window and short-circuits further calls into a dead-letter row, protecting the regulator endpoint and surfacing the outage.
The Bahrain import declaration type carries the requires-deferment flag, so the shared customs core can guard an import that lacks a configured deferment account before it is submitted.
What is inside
Built to do the job, end to end.
- OFFS adapter (offs.py). A concrete subclass of the shared base adapter. Serialises declaration_submit into the OFFS JSON envelope (type, broker reference, date, currency, importer and exporter parties, totals, and numbered HS-coded lines), serialises declaration_status, and parses submit, status, and health responses. Self-registers under the offs provider code at import time.
- Six Bahrain declaration types. Country-scoped records for import, export, transit, re-export, temporary admission, and GCC inter-state movement, each bound to Bahrain with a display sequence. The import type sets the requires-deferment flag.
- Bahrain HS overlay. A starter set of Bahrain-scoped HS subheadings (smartphones, portable computers, small passenger vehicles, cigarettes under excise, medicaments) seeded with per-code duty and VAT rates against the 10 percent Bahrain VAT baseline.
- Seeded mock profile. A default OFFS adapter profile in mock environment, with sandbox endpoint, API key auth method, and the shared timeout, retry, and circuit-breaker settings, so the module is operable the moment it installs.
- Shared transport engine (inherited). HTTPS dispatch via the base adapter with timeout, retry, exponential backoff with jitter, a database-backed circuit breaker, dead-letter logging, and append-only audit rows with redacted auth headers. The Bahrain module supplies only the OFFS specifics.
- Adapter tests and fixtures. A test suite covering registry lookup, profile seeding, JSON serialisation, accepted and rejected response parsing, and a full mock-mode round trip, backed by shipped success, rejection, and health fixtures.
Honest about the edges
What this does not do, so nothing surprises you.
- This is an add-on, not a standalone app. It requires the logistics base, the customs core, and the Bahrain localisation, and it auto-installs only when all are present.
- The adapter covers three OFFS message types: declaration submit, status, and health check. It does not ship an amendment or cancellation message.
- There is no scheduled status-polling job in this module. The status message type exists, but calling it is driven by the surrounding customs workflow, not by a cron shipped here.
- The adapter passes through the duty and VAT amounts it is handed in the payload. It does not itself compute VAT on import or post journal entries to a deferment account; that accounting belongs to the customs core and accounting modules.
- The default profile ships in mock mode against a sandbox endpoint. Production use requires configuring real OFFS credentials and switching the profile environment.
- The HS overlay is a starter set of representative subheadings for demonstration and a seed, not a complete Bahrain tariff schedule.
- This module ships no views, models, or menus of its own. Declaration and HS records are managed through the shared customs core screens.
Bahrain customs, OFFS single window, Bahrain Customs Affairs, Odoo customs declaration, GCC freight forwarding, customs adapter Odoo 19, HS code overlay Bahrain, declaration type import export transit, NBR VAT on import Bahrain, 3PL logistics Odoo, freight broker customs integration, customs declaration submission, mock mode adapter, circuit breaker integration, re-export temporary admission GCC
Please log in to comment on this module