mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
114 lines
5.0 KiB
TypeScript
114 lines
5.0 KiB
TypeScript
import { Body, Controller, Get, Param, ParseUUIDPipe, Post } from "@nestjs/common";
|
|
import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger";
|
|
|
|
import { BookingStaff } from "../../common/booking-guards";
|
|
import { FREIGHT_PERMS } from "../../seed/freight-permissions.registry";
|
|
import { CancelEimsRegistrationDto } from "./dto/cancel-eims-registration.dto";
|
|
import { RegisterSalesReceiptDto } from "./dto/register-sales-receipt.dto";
|
|
import { RegisterWithholdingReceiptDto } from "./dto/register-withholding-receipt.dto";
|
|
import { ResolveEimsRegistrationDto } from "./dto/resolve-eims-registration.dto";
|
|
import { EimsCancellationService } from "./eims-cancellation.service";
|
|
import { EimsInvoiceRegistrationService } from "./eims-invoice-registration.service";
|
|
import { EimsReceiptService } from "./eims-receipt.service";
|
|
|
|
/**
|
|
* Manual EIMS actions on an existing invoice.
|
|
*
|
|
* Invoices are produced by the freight workflow, not by a person, so these routes are **not** the
|
|
* normal production path — they exist for controlled testing and exceptional operations. Automatic
|
|
* submission after an invoice is issued is a separate phase; nothing here is called by it.
|
|
*
|
|
* `eims_register`, `eims_resolve`, `eims_cancel` and `eims_receipt_register` are intentionally left
|
|
* out of every role preset and assigned to named admins instead. They are also separate
|
|
* permissions: resolving clears the system-wide chain block and can record an IRN against an
|
|
* invoice, cancelling is its own irreversible-at-MoR action, and filing a receipt is a third —
|
|
* none follows from the right to register. Only `eims/status` and `eims/receipts` ride on the
|
|
* ordinary `invoices:view`.
|
|
*
|
|
* Filing gets its own permission (`invoices:eims_register`) rather than riding on an existing key:
|
|
* registration is irreversible at MoR, so it must not follow from the right to download a PDF.
|
|
* The key is seeded through FINANCE_PERMISSIONS, which reaches `iam.permissions` via
|
|
* ADVANCED_BACKOFFICE_PERMISSIONS → BOOKING_RULE_ENGINE_PERMISSIONS → EDR_FREIGHT_PERMISSIONS.
|
|
*/
|
|
@ApiTags("eims")
|
|
@ApiBearerAuth()
|
|
@Controller("invoices")
|
|
export class EimsInvoiceController {
|
|
constructor(
|
|
private readonly registration: EimsInvoiceRegistrationService,
|
|
private readonly cancellation: EimsCancellationService,
|
|
private readonly receipts: EimsReceiptService,
|
|
) {}
|
|
|
|
@Post(":id/eims/register")
|
|
@BookingStaff(FREIGHT_PERMS.invoices.eimsRegister)
|
|
@ApiOperation({
|
|
summary:
|
|
"Register the invoice with MoR EIMS. Idempotent — an invoice that already has an IRN is returned unchanged.",
|
|
})
|
|
register(@Param("id", ParseUUIDPipe) id: string) {
|
|
return this.registration.registerInvoiceWithEims(id);
|
|
}
|
|
|
|
@Post(":id/eims/verify")
|
|
@BookingStaff(FREIGHT_PERMS.invoices.eimsRegister)
|
|
@ApiOperation({ summary: "Verify the invoice's stored IRN against EIMS" })
|
|
verify(@Param("id", ParseUUIDPipe) id: string) {
|
|
return this.registration.verifyInvoiceWithEims(id);
|
|
}
|
|
|
|
@Post(":id/eims/resolve")
|
|
@BookingStaff(FREIGHT_PERMS.invoices.eimsResolve)
|
|
@ApiOperation({
|
|
summary:
|
|
"Resolve an unacknowledged submission: record the IRN confirmed with MoR, or discard it. Clears the system-wide block.",
|
|
})
|
|
resolve(
|
|
@Param("id", ParseUUIDPipe) id: string,
|
|
@Body() dto: ResolveEimsRegistrationDto,
|
|
) {
|
|
return this.registration.resolveEimsRegistration(id, dto);
|
|
}
|
|
|
|
@Get(":id/eims/status")
|
|
@BookingStaff(FREIGHT_PERMS.invoices.view)
|
|
@ApiOperation({ summary: "EIMS registration status, IRN and last error for the invoice" })
|
|
status(@Param("id", ParseUUIDPipe) id: string) {
|
|
return this.registration.getEimsStatus(id);
|
|
}
|
|
|
|
@Post(":id/eims/cancel")
|
|
@BookingStaff(FREIGHT_PERMS.invoices.eimsCancel)
|
|
@ApiOperation({
|
|
summary:
|
|
"Cancel the invoice's registered EIMS document. Idempotent — an already-cancelled invoice is returned unchanged.",
|
|
})
|
|
cancel(@Param("id", ParseUUIDPipe) id: string, @Body() dto: CancelEimsRegistrationDto) {
|
|
return this.cancellation.cancelInvoiceWithEims(id, dto.reasonCode, dto.remark);
|
|
}
|
|
|
|
@Post(":id/eims/receipt/sales")
|
|
@BookingStaff(FREIGHT_PERMS.invoices.eimsReceiptRegister)
|
|
@ApiOperation({ summary: "Register a sales receipt with MoR EIMS against a registered invoice" })
|
|
registerSalesReceipt(@Param("id", ParseUUIDPipe) id: string, @Body() dto: RegisterSalesReceiptDto) {
|
|
return this.receipts.registerSalesReceipt(id, dto);
|
|
}
|
|
|
|
@Post(":id/eims/receipt/withholding")
|
|
@BookingStaff(FREIGHT_PERMS.invoices.eimsReceiptRegister)
|
|
@ApiOperation({ summary: "Register a withholding receipt with MoR EIMS against a registered invoice" })
|
|
registerWithholdingReceipt(
|
|
@Param("id", ParseUUIDPipe) id: string,
|
|
@Body() dto: RegisterWithholdingReceiptDto,
|
|
) {
|
|
return this.receipts.registerWithholdingReceipt(id, dto);
|
|
}
|
|
|
|
@Get(":id/eims/receipts")
|
|
@BookingStaff(FREIGHT_PERMS.invoices.view)
|
|
@ApiOperation({ summary: "List every EIMS receipt filed against this invoice, newest first" })
|
|
listReceipts(@Param("id", ParseUUIDPipe) id: string) {
|
|
return this.receipts.listReceipts(id);
|
|
}
|
|
}
|