import { Result, ValueObject } from "@rdx/core"; interface IInvoiceStatusProps { value: string; } export enum INVOICE_STATUS { DRAFT = "draft", EMITTED = "emitted", SENT = "sent", REJECTED = "rejected", } export class InvoiceStatus 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 (!this.ALLOWED_STATUSES.includes(value)) { return Result.fail(new Error(`Estado de la factura no válido: ${value}`)); } return Result.ok( value === "rejected" ? InvoiceStatus.createRejected() : value === "sent" ? InvoiceStatus.createSent() : value === "emitted" ? InvoiceStatus.createSent() : InvoiceStatus.createDraft() ); } public static createDraft(): InvoiceStatus { return new InvoiceStatus({ value: INVOICE_STATUS.DRAFT }); } public static createEmitted(): InvoiceStatus { return new InvoiceStatus({ value: INVOICE_STATUS.EMITTED }); } public static createSent(): InvoiceStatus { return new InvoiceStatus({ value: INVOICE_STATUS.SENT }); } public static createRejected(): InvoiceStatus { return new InvoiceStatus({ value: INVOICE_STATUS.REJECTED }); } getValue(): string { return this.props.value; } toPrimitive() { return this.getValue(); } canTransitionTo(nextStatus: string): boolean { return InvoiceStatus.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 InvoiceStatus.create(nextStatus); } toString(): string { return this.getValue(); } }