mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
feat(eims): add invoice mapper and signed EIMS transport
Map EDR invoices onto the MoR EIMS /v1/register document and add the cryptographic transport needed to talk to core.mor.gov.et. Mapper: DTOs mirror the supplied Postman collection section by section. Tax is resolved per line via a caller-supplied resolver and throws when unresolved -- the app models no tax at all (invoice.taxAmount is always 0, invoice_lines and the rate catalogue carry no fiscal columns), so a zero-rated default would assert a tax position the codebase cannot support. Seller identity, document number, counters and previous IRN are passed in explicitly; the mapper stays pure. Transport: config, credential loading, RSA-SHA512 signing and /auth/login with an in-memory token cache. Signing reproduces the process that produced a working live token -- compact JSON of the inner request only, exact UTF-8 bytes, base64 signature, and base64 of the certificate file's exact bytes with no parsing or re-encoding. Concurrent callers share one login via an in-flight promise. Refresh is deliberately unimplemented: the collection shows an unsigned refresh body but also ships unsigned examples of calls that do require signing, so an expired token re-logs in instead. Errors normalise to EimsApiException carrying only the gateway's own error fields; secrets, signature, certificate and tokens never reach logs. Key and certificate file patterns are gitignored. Nothing calls EIMS automatically and no invoice entity, migration or UI is touched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -126,3 +126,56 @@ EMAIL_QUEUE=email_queue
|
||||
# Shared secret for service-to-service calls (payment microservice <-> freight).
|
||||
# Required at boot; set ALLOW_UNAUTH_INTERNAL=true instead ONLY for local dev.
|
||||
SERVICE_AUTH_TOKEN=change-me
|
||||
|
||||
# ── MoR EIMS e-invoicing (core.mor.gov.et) ─────────────────────────────────
|
||||
# Disabled by default; every EIMS call fails fast with EIMS_NOT_CONFIGURED until enabled.
|
||||
EIMS_ENABLED=false
|
||||
EIMS_BASE_URL=https://core.mor.gov.et
|
||||
EIMS_CLIENT_ID=
|
||||
EIMS_CLIENT_SECRET=
|
||||
EIMS_API_KEY=
|
||||
EIMS_TIN=
|
||||
# MoR-issued source-system identifiers (used once invoice registration lands)
|
||||
EIMS_SYSTEM_NUMBER=
|
||||
EIMS_SYSTEM_TYPE=
|
||||
# Absolute paths to the INSA-issued credentials. Keep them OUTSIDE the repo; the file
|
||||
# patterns are gitignored, but a path outside the working tree is safer still.
|
||||
# The certificate is transmitted as base64 of this file's exact bytes — do not convert it.
|
||||
EIMS_PRIVATE_KEY_PATH=
|
||||
EIMS_CERTIFICATE_PATH=
|
||||
# Optional tuning
|
||||
EIMS_HTTP_TIMEOUT_MS=30000
|
||||
EIMS_TOKEN_SKEW_SECONDS=45
|
||||
|
||||
# ── EIMS invoice registration (required only to register invoices) ─────────
|
||||
# Seller identity: EDR's own legal details are not modelled anywhere in the DB.
|
||||
# Region and Wereda are MoR *codes* (e.g. 13 / 574), not names.
|
||||
EIMS_SELLER_LEGAL_NAME=
|
||||
EIMS_SELLER_VAT_NUMBER=
|
||||
EIMS_SELLER_PHONE=
|
||||
EIMS_SELLER_EMAIL=
|
||||
EIMS_SELLER_REGION=
|
||||
EIMS_SELLER_WEREDA=
|
||||
# Optional seller address parts; sent as null when unset.
|
||||
EIMS_SELLER_CITY=
|
||||
EIMS_SELLER_SUBCITY=
|
||||
EIMS_SELLER_HOUSE_NUMBER=
|
||||
EIMS_SELLER_LOCALITY=
|
||||
# Tax treatment — REQUIRES FINANCE SIGN-OFF. The application models no tax at all
|
||||
# (invoice.taxAmount is always 0), so nothing here is defaulted: registration fails
|
||||
# locally, naming the missing variables, until these are set.
|
||||
EIMS_TAX_CODE=
|
||||
EIMS_TAX_RATE_PERCENT=
|
||||
EIMS_EXCISE_TAX_VALUE=0
|
||||
EIMS_INCOME_WITHHOLD_VALUE=0
|
||||
EIMS_TRANSACTION_WITHHOLD_VALUE=0
|
||||
# Document classification and payment presentation.
|
||||
EIMS_TRANSACTION_TYPE=B2B
|
||||
EIMS_NATURE_OF_SUPPLIES=Service
|
||||
EIMS_PAYMENT_MODE=CASH
|
||||
EIMS_PAYMENT_TERM=IMMIDIATE
|
||||
EIMS_UNIT_DEFAULT=PCS
|
||||
# MoR numeric country code for the buyer; our companies store the country name.
|
||||
EIMS_BUYER_COUNTRY_CODE=
|
||||
EIMS_CASHIER_NAME=
|
||||
EIMS_SALESPERSON_NAME=
|
||||
|
||||
Reference in New Issue
Block a user