mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-29 03:40:56 +00:00
feat(eims): file issued invoices on a cron sweep, off by default
Invoices are produced by the freight workflow rather than by a person, so the production path for filing is a sweep, not the manual endpoint. A @Cron picks the oldest never-submitted invoice and hands it to the existing EimsInvoiceRegistrationService -- no registration logic is duplicated, and the durable reservation still decides whether the submission may proceed. Sweeping rather than hooking the eleven places an invoice can be created or issued keeps the workflow untouched, puts the HTTP call outside the invoice transaction by construction, and lets a crash or restart be picked up on the next tick. invoices.eims_status is the queue; nothing new is persisted. Only NOT_SUBMITTED is eligible: UNKNOWN is never retried automatically because the document may already be filed, and FAILED waits for an explicit retry policy. The tick also refuses to start while eims_system_state holds an in-flight submission or a block, and only one invoice is filed per tick so a misconfiguration costs one rejected document rather than a burst. Requires both EIMS_ENABLED and EIMS_AUTO_SUBMIT; the second defaults to false so authentication can be live long before filing is. Logs carry the invoice number, status and IRN only. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -33,6 +33,18 @@ export interface EimsConfig {
|
||||
httpTimeoutMs: number;
|
||||
/** Re-authenticate this many ms before the access token actually expires. */
|
||||
tokenSkewMs: number;
|
||||
/**
|
||||
* Automatic submission of issued invoices, off by default.
|
||||
*
|
||||
* Invoices are produced by the workflow, so the production path is a sweep rather than a human
|
||||
* action — but enabling it starts filing real documents with the tax authority, which is
|
||||
* irreversible from our side. It therefore needs its own deliberate switch, separate from
|
||||
* `EIMS_ENABLED`, so that authentication can be live long before filing is.
|
||||
*/
|
||||
autoSubmit: boolean;
|
||||
autoSubmitCron: string;
|
||||
/** MoR rejects a document whose date is more than 3 days old; the sweep will not attempt those. */
|
||||
autoSubmitMaxAgeDays: number;
|
||||
/**
|
||||
* Seller identity and tax/business treatment for the invoice document.
|
||||
*
|
||||
@@ -119,6 +131,15 @@ export default registerAs("eims", (): EimsConfig => {
|
||||
certificatePath: process.env.EIMS_CERTIFICATE_PATH ?? "",
|
||||
httpTimeoutMs,
|
||||
tokenSkewMs,
|
||||
autoSubmit: (process.env.EIMS_AUTO_SUBMIT ?? "false").toLowerCase() === "true",
|
||||
// Every 5 minutes by default: filing is not latency-sensitive, and a slow cadence keeps a
|
||||
// misconfiguration from filing a burst of bad documents before anyone notices.
|
||||
autoSubmitCron: process.env.EIMS_AUTO_SUBMIT_CRON || "0 */5 * * * *",
|
||||
autoSubmitMaxAgeDays: positiveInt(
|
||||
process.env.EIMS_AUTO_SUBMIT_MAX_AGE_DAYS,
|
||||
3,
|
||||
"EIMS_AUTO_SUBMIT_MAX_AGE_DAYS",
|
||||
),
|
||||
invoice: {
|
||||
sellerLegalName: process.env.EIMS_SELLER_LEGAL_NAME ?? "",
|
||||
sellerVatNumber: process.env.EIMS_SELLER_VAT_NUMBER ?? "",
|
||||
|
||||
Reference in New Issue
Block a user