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", REJECTED = "rejected", } export class CustomerInvoiceStatus extends ValueObject { private static readonly ALLOWED_STATUSES = ["draft", "emitted", "sent", "rejected"]; private static readonly TRANSITIONS: Record = { draft: [INVOICE_STATUS.EMITTED], emitted: [INVOICE_STATUS.SENT, INVOICE_STATUS.REJECTED, INVOICE_STATUS.DRAFT], sent: [INVOICE_STATUS.REJECTED], rejected: [], }; static create(value: string): Result { if (!CustomerInvoiceStatus.ALLOWED_STATUSES.includes(value)) { return Result.fail(new Error(`Estado de la factura no válido: ${value}`)); } return Result.ok( value === "rejected" ? CustomerInvoiceStatus.createRejected() : value === "sent" ? CustomerInvoiceStatus.createSent() : value === "emitted" ? CustomerInvoiceStatus.createSent() : 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 createRejected(): CustomerInvoiceStatus { return new CustomerInvoiceStatus({ value: INVOICE_STATUS.REJECTED }); } getValue(): string { return this.props.value; } toPrimitive() { return this.getValue(); } 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.getValue(); } }