import assert from "node:assert/strict"; import test from "node:test"; import { Name, UniqueID } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; import { DocumentSeries, DocumentSeriesCode, DocumentSeriesNumber, DocumentType, } from "../../domain"; import { DocumentSeriesAdminService } from "./document-series-admin.service"; const makeSeries = ( companyId: UniqueID, code: string, type = DocumentType.proforma(), active = true ) => DocumentSeries.create({ companyId, branchId: Maybe.none(), documentType: type, code: DocumentSeriesCode.create(code).data, name: Name.create(code).data, description: Maybe.none(), prefix: Maybe.none(), suffix: Maybe.none(), nextNumber: DocumentSeriesNumber.create(100).data, padding: 0, validFrom: Maybe.none(), validTo: Maybe.none(), isDefault: false, isActive: active, hasAssignedNumbers: false, createdAt: new Date(), updatedAt: new Date(), deletedAt: Maybe.none(), }).data; const build = (...series: DocumentSeries[]) => { const events: string[] = []; const repository = { getByIdInCompany: async (companyId: UniqueID, id: UniqueID) => { const found = series.find((item) => item.id.equals(id) && item.companyId.equals(companyId)); return found ? Result.ok(found) : Result.fail(new Error("not found")); }, save: async () => Result.ok(undefined), lockByCompanyAndDocumentType: async () => Result.ok(undefined), findDefaultInCompany: async ({ companyId, documentType, }: { companyId: UniqueID; documentType: DocumentType; }) => Result.ok( Maybe.fromNullable( series.find( (item) => item.companyId.equals(companyId) && item.documentType.equals(documentType) && item.isDefault ) ) ), }; const audit = { recordMutation: async ({ action }: { action: string }) => { events.push(action); return Result.ok(undefined); }, }; return { service: new DocumentSeriesAdminService(repository as never, audit as never), events }; }; test("advance persiste el contador, conserva la evidencia y audita", async () => { const companyId = UniqueID.generateNewID(); const series = makeSeries(companyId, "PF"); const { service, events } = build(series); const result = await service.advance({ companyId, id: series.id, nextNumber: DocumentSeriesNumber.create(150).data, transaction: {}, }); assert.equal(result.isSuccess, true); assert.equal(series.nextNumber.toPrimitive(), 150); assert.equal(series.hasAssignedNumbers, false); assert.deepEqual(events, ["document_series.number_advanced"]); assert.equal( ( await service.advance({ companyId, id: series.id, nextNumber: DocumentSeriesNumber.create(150).data, transaction: {}, }) ).isFailure, true ); }); test("setDefault sustituye únicamente el default del mismo tenant y tipo", async () => { const companyA = UniqueID.generateNewID(); const companyB = UniqueID.generateNewID(); const first = makeSeries(companyA, "A"); first.markAsDefault(); const second = makeSeries(companyA, "B"); const invoice = makeSeries(companyA, "F", DocumentType.issuedInvoice()); invoice.markAsDefault(); const foreign = makeSeries(companyB, "X"); foreign.markAsDefault(); const { service, events } = build(first, second, invoice, foreign); const result = await service.setDefault({ companyId: companyA, id: second.id, transaction: {} }); assert.equal(result.isSuccess, true); assert.equal(first.isDefault, false); assert.equal(second.isDefault, true); assert.equal(invoice.isDefault, true); assert.equal(foreign.isDefault, true); assert.deepEqual(events, ["document_series.default_unset", "document_series.default_set"]); }); test("rechaza default inactivo y aísla series de otro tenant", async () => { const companyA = UniqueID.generateNewID(); const companyB = UniqueID.generateNewID(); const inactive = makeSeries(companyA, "I", DocumentType.proforma(), false); const foreign = makeSeries(companyB, "X"); const { service } = build(inactive, foreign); assert.equal( (await service.setDefault({ companyId: companyA, id: inactive.id, transaction: {} })).isFailure, true ); assert.equal( ( await service.advance({ companyId: companyA, id: foreign.id, nextNumber: DocumentSeriesNumber.create(101).data, transaction: {}, }) ).isFailure, true ); }); test("disable desmarca default y enable no lo recupera", async () => { const companyId = UniqueID.generateNewID(); const series = makeSeries(companyId, "PF"); series.markAsDefault(); const { service, events } = build(series); await service.changeStatus({ companyId, id: series.id, action: "disable", transaction: {} }); assert.equal(series.isActive, false); assert.equal(series.isDefault, false); await service.changeStatus({ companyId, id: series.id, action: "enable", transaction: {} }); assert.equal(series.isActive, true); assert.equal(series.isDefault, false); assert.deepEqual(events, ["document_series.disabled", "document_series.enabled"]); });