import { DomainValidationError } from "@erp/core/api"; import { ValueObject } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; interface ICustomerInvoiceStatusProps { value: string; } export enum INVOICE_STATUS { DRAFT = "draft", EMITTED = "emitted", SENT = "sent", RECEIVED = "received", REJECTED = "rejected", } export class CustomerInvoiceStatus extends ValueObject { private static readonly ALLOWED_STATUSES = ["draft", "emitted", "sent", "received", "rejected"]; private static readonly FIELD = "invoiceStatus"; private static readonly ERROR_CODE = "INVALID_INVOICE_STATUS"; private static readonly TRANSITIONS: Record = { draft: [INVOICE_STATUS.EMITTED], emitted: [INVOICE_STATUS.SENT, INVOICE_STATUS.REJECTED, INVOICE_STATUS.DRAFT], sent: [INVOICE_STATUS.RECEIVED, INVOICE_STATUS.REJECTED], received: [], rejected: [], }; static create(value: string): Result { if (!CustomerInvoiceStatus.ALLOWED_STATUSES.includes(value)) { const detail = `Estado de la factura no válido: ${value}`; return Result.fail( new DomainValidationError( CustomerInvoiceStatus.ERROR_CODE, CustomerInvoiceStatus.FIELD, detail ) ); } return Result.ok( value === "rejected" ? CustomerInvoiceStatus.createRejected() : value === "sent" ? CustomerInvoiceStatus.createSent() : value === "emitted" ? CustomerInvoiceStatus.createSent() : value === "" ? CustomerInvoiceStatus.createReceived() : CustomerInvoiceStatus.createDraft() ); } public static createDraft(): CustomerInvoiceStatus { return new CustomerInvoiceStatus({ value: INVOICE_STATUS.DRAFT }); } public static createEmitted(): CustomerInvoiceStatus { return new CustomerInvoiceStatus({ value: INVOICE_STATUS.EMITTED }); } public static createSent(): CustomerInvoiceStatus { return new CustomerInvoiceStatus({ value: INVOICE_STATUS.SENT }); } public static createReceived(): CustomerInvoiceStatus { return new CustomerInvoiceStatus({ value: INVOICE_STATUS.RECEIVED }); } public static createRejected(): CustomerInvoiceStatus { return new CustomerInvoiceStatus({ value: INVOICE_STATUS.REJECTED }); } isDraft(): boolean { return this.props.value === INVOICE_STATUS.DRAFT } getProps(): string { return this.props.value; } toPrimitive() { return this.getProps(); } canTransitionTo(nextStatus: string): boolean { return CustomerInvoiceStatus.TRANSITIONS[this.props.value].includes(nextStatus); } transitionTo(nextStatus: string): Result { if (!this.canTransitionTo(nextStatus)) { return Result.fail( new Error(`Transición no permitida de ${this.props.value} a ${nextStatus}`) ); } return CustomerInvoiceStatus.create(nextStatus); } toString(): string { return this.getProps(); } }