diff --git a/modules/customer-invoices/src/api/application/helpers.bak/map-dto-to-customer-invoice-items-props.ts b/modules/customer-invoices/src/api/application/helpers.bak/map-dto-to-customer-invoice-items-props.ts index 7312ca82..b25f3344 100644 --- a/modules/customer-invoices/src/api/application/helpers.bak/map-dto-to-customer-invoice-items-props.ts +++ b/modules/customer-invoices/src/api/application/helpers.bak/map-dto-to-customer-invoice-items-props.ts @@ -2,7 +2,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; @@ -12,7 +12,7 @@ import { type IssuedInvoiceItemProps, ItemAmount, ItemDescription, - ItemDiscount, + ItemDiscountPercentage, ItemQuantity, } from "../../domain"; @@ -28,25 +28,27 @@ export function mapDTOToCustomerInvoiceItemsProps( const path = (field: string) => `items[${index}].${field}`; const description = extractOrPushError( - maybeFromNullableVO(item.description, (value) => ItemDescription.create(value)), + maybeFromNullableResult(item.description, (value) => ItemDescription.create(value)), path("description"), errors ); const quantity = extractOrPushError( - maybeFromNullableVO(item.quantity, (value) => ItemQuantity.create({ value })), + maybeFromNullableResult(item.quantity, (value) => ItemQuantity.create({ value })), path("quantity"), errors ); const unitAmount = extractOrPushError( - maybeFromNullableVO(item.unit_amount, (value) => ItemAmount.create({ value })), + maybeFromNullableResult(item.unit_amount, (value) => ItemAmount.create({ value })), path("unit_amount"), errors ); const discountPercentage = extractOrPushError( - maybeFromNullableVO(item.discount_percentage, (value) => ItemDiscount.create({ value })), + maybeFromNullableResult(item.discount_percentage, (value) => + ItemDiscountPercentage.create({ value }) + ), path("discount_percentage"), errors ); diff --git a/modules/customer-invoices/src/api/application/helpers.bak/map-dto-to-customer-invoice-props.ts b/modules/customer-invoices/src/api/application/helpers.bak/map-dto-to-customer-invoice-props.ts index 5a785199..ea309dea 100644 --- a/modules/customer-invoices/src/api/application/helpers.bak/map-dto-to-customer-invoice-props.ts +++ b/modules/customer-invoices/src/api/application/helpers.bak/map-dto-to-customer-invoice-props.ts @@ -5,7 +5,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; @@ -30,12 +30,12 @@ export function mapDTOToCustomerInvoiceProps(dto: CreateCustomerInvoiceRequestDT const invoiceId = extractOrPushError(UniqueID.create(dto.id), "id", errors); const invoiceNumber = extractOrPushError( - maybeFromNullableVO(dto.invoice_number, (value) => InvoiceNumber.create(value)), + maybeFromNullableResult(dto.invoice_number, (value) => InvoiceNumber.create(value)), "invoice_number", errors ); const invoiceSeries = extractOrPushError( - maybeFromNullableVO(dto.series, (value) => InvoiceSerie.create(value)), + maybeFromNullableResult(dto.series, (value) => InvoiceSerie.create(value)), "invoice_series", errors ); @@ -45,7 +45,7 @@ export function mapDTOToCustomerInvoiceProps(dto: CreateCustomerInvoiceRequestDT errors ); const operationDate = extractOrPushError( - maybeFromNullableVO(dto.operation_date, (value) => UtcDate.createFromISO(value)), + maybeFromNullableResult(dto.operation_date, (value) => UtcDate.createFromISO(value)), "operation_date", errors ); diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot-builder.ts index c13a9221..b5547912 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-full-snapshot-builder.ts @@ -1,5 +1,5 @@ import type { ISnapshotBuilder } from "@erp/core/api"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import { InvoiceAmount, type IssuedInvoice } from "../../../../domain"; @@ -87,14 +87,14 @@ export class IssuedInvoiceFullSnapshotBuilder implements IIssuedInvoiceFullSnaps is_proforma: invoice.isProforma ? "true" : "false", invoice_number: invoice.invoiceNumber.toString(), status: invoice.status.toPrimitive(), - series: toEmptyString(invoice.series, (value) => value.toString()), + series: maybeToEmptyString(invoice.series, (value) => value.toString()), invoice_date: invoice.invoiceDate.toDateString(), - operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()), + operation_date: maybeToEmptyString(invoice.operationDate, (value) => value.toDateString()), - reference: toEmptyString(invoice.reference, (value) => value.toString()), - description: toEmptyString(invoice.description, (value) => value.toString()), - notes: toEmptyString(invoice.notes, (value) => value.toString()), + reference: maybeToEmptyString(invoice.reference, (value) => value.toString()), + description: maybeToEmptyString(invoice.description, (value) => value.toString()), + notes: maybeToEmptyString(invoice.notes, (value) => value.toString()), language_code: invoice.languageCode.toString(), currency_code: invoice.currencyCode.toString(), diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-items-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-items-full-snapshot-builder.ts index e939ea8b..0a8d0f6a 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-items-full-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-items-full-snapshot-builder.ts @@ -1,5 +1,5 @@ import type { ISnapshotBuilder } from "@erp/core/api"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { IssuedInvoiceItem, IssuedInvoiceItems } from "../../../../domain"; @@ -16,7 +16,7 @@ export class IssuedInvoiceItemsFullSnapshotBuilder id: invoiceItem.id.toPrimitive(), is_valued: String(invoiceItem.isValued), position: String(index), - description: toEmptyString(invoiceItem.description, (value) => value.toPrimitive()), + description: maybeToEmptyString(invoiceItem.description, (value) => value.toPrimitive()), quantity: invoiceItem.quantity.match( (quantity) => quantity.toObjectString(), diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-recipient-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-recipient-full-snapshot-builder.ts index b269d5b3..ee2d09dc 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-recipient-full-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/full/issued-invoice-recipient-full-snapshot-builder.ts @@ -1,5 +1,5 @@ import type { ISnapshotBuilder } from "@erp/core/api"; -import { DomainValidationError, toEmptyString } from "@repo/rdx-ddd"; +import { DomainValidationError, maybeToEmptyString } from "@repo/rdx-ddd"; import type { InvoiceRecipient, IssuedInvoice } from "../../../../domain"; @@ -23,12 +23,12 @@ export class IssuedInvoiceRecipientFullSnapshotBuilder id: invoice.customerId.toString(), name: recipient.name.toString(), tin: recipient.tin.toString(), - street: toEmptyString(recipient.street, (v) => v.toString()), - street2: toEmptyString(recipient.street2, (v) => v.toString()), - city: toEmptyString(recipient.city, (v) => v.toString()), - province: toEmptyString(recipient.province, (v) => v.toString()), - postal_code: toEmptyString(recipient.postalCode, (v) => v.toString()), - country: toEmptyString(recipient.country, (v) => v.toString()), + street: maybeToEmptyString(recipient.street, (v) => v.toString()), + street2: maybeToEmptyString(recipient.street2, (v) => v.toString()), + city: maybeToEmptyString(recipient.city, (v) => v.toString()), + province: maybeToEmptyString(recipient.province, (v) => v.toString()), + postal_code: maybeToEmptyString(recipient.postalCode, (v) => v.toString()), + country: maybeToEmptyString(recipient.country, (v) => v.toString()), }), () => ({ id: "", diff --git a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/list/issued-invoice-list-item-snapshot-builder.ts b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/list/issued-invoice-list-item-snapshot-builder.ts index 4507443c..9c6a6507 100644 --- a/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/list/issued-invoice-list-item-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/issued-invoices/snapshot-builders/list/issued-invoice-list-item-snapshot-builder.ts @@ -1,5 +1,5 @@ import type { ISnapshotBuilder } from "@erp/core/api"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { IssuedInvoiceListDTO } from "../../dtos"; @@ -30,12 +30,12 @@ export class IssuedInvoiceListItemSnapshotBuilder implements IIssuedInvoiceListI invoice_number: invoice.invoiceNumber.toString(), status: invoice.status.toPrimitive(), - series: toEmptyString(invoice.series, (v) => v.toString()), + series: maybeToEmptyString(invoice.series, (v) => v.toString()), invoice_date: invoice.invoiceDate.toDateString(), - operation_date: toEmptyString(invoice.operationDate, (v) => v.toDateString()), - reference: toEmptyString(invoice.reference, (v) => v.toString()), - description: toEmptyString(invoice.description, (v) => v.toString()), + operation_date: maybeToEmptyString(invoice.operationDate, (v) => v.toDateString()), + reference: maybeToEmptyString(invoice.reference, (v) => v.toString()), + description: maybeToEmptyString(invoice.description, (v) => v.toString()), recipient, diff --git a/modules/customer-invoices/src/api/application/proformas/mappers/create-proforma-props.mapper.ts b/modules/customer-invoices/src/api/application/proformas/mappers/create-proforma-props.mapper.ts index 2ee2d7fe..af296d79 100644 --- a/modules/customer-invoices/src/api/application/proformas/mappers/create-proforma-props.mapper.ts +++ b/modules/customer-invoices/src/api/application/proformas/mappers/create-proforma-props.mapper.ts @@ -11,7 +11,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; @@ -28,7 +28,7 @@ import { type IssuedInvoiceItemProps, ItemAmount, ItemDescription, - ItemDiscount, + ItemDiscountPercentage, ItemQuantity, } from "../../../domain"; @@ -79,7 +79,7 @@ export class CreateProformaPropsMapper { ); const series = extractOrPushError( - maybeFromNullableVO(dto.series, (value) => InvoiceSerie.create(value)), + maybeFromNullableResult(dto.series, (value) => InvoiceSerie.create(value)), "series", this.errors ); @@ -91,25 +91,25 @@ export class CreateProformaPropsMapper { ); const operationDate = extractOrPushError( - maybeFromNullableVO(dto.operation_date, (value) => UtcDate.createFromISO(value)), + maybeFromNullableResult(dto.operation_date, (value) => UtcDate.createFromISO(value)), "operation_date", this.errors ); const reference = extractOrPushError( - maybeFromNullableVO(dto.reference, (value) => Result.ok(String(value))), + maybeFromNullableResult(dto.reference, (value) => Result.ok(String(value))), "reference", this.errors ); const description = extractOrPushError( - maybeFromNullableVO(dto.reference, (value) => Result.ok(String(value))), + maybeFromNullableResult(dto.reference, (value) => Result.ok(String(value))), "description", this.errors ); const notes = extractOrPushError( - maybeFromNullableVO(dto.notes, (value) => TextValue.create(value)), + maybeFromNullableResult(dto.notes, (value) => TextValue.create(value)), "notes", this.errors ); @@ -127,7 +127,7 @@ export class CreateProformaPropsMapper { ); const paymentMethod = extractOrPushError( - maybeFromNullableVO(dto.payment_method, (value) => + maybeFromNullableResult(dto.payment_method, (value) => InvoicePaymentMethod.create({ paymentDescription: value }) ), "payment_method", @@ -195,25 +195,27 @@ export class CreateProformaPropsMapper { items.forEach((item, index) => { const description = extractOrPushError( - maybeFromNullableVO(item.description, (value) => ItemDescription.create(value)), + maybeFromNullableResult(item.description, (value) => ItemDescription.create(value)), "description", this.errors ); const quantity = extractOrPushError( - maybeFromNullableVO(item.quantity, (value) => ItemQuantity.create(value)), + maybeFromNullableResult(item.quantity, (value) => ItemQuantity.create(value)), "quantity", this.errors ); const unitAmount = extractOrPushError( - maybeFromNullableVO(item.unit_amount, (value) => ItemAmount.create(value)), + maybeFromNullableResult(item.unit_amount, (value) => ItemAmount.create(value)), "unit_amount", this.errors ); const discountPercentage = extractOrPushError( - maybeFromNullableVO(item.discount_percentage, (value) => ItemDiscount.create(value)), + maybeFromNullableResult(item.discount_percentage, (value) => + ItemDiscountPercentage.create(value) + ), "discount_percentage", this.errors ); diff --git a/modules/customer-invoices/src/api/application/proformas/mappers/update-proforma-props.mapper.ts b/modules/customer-invoices/src/api/application/proformas/mappers/update-proforma-props.mapper.ts index 7b3f3168..30fb650c 100644 --- a/modules/customer-invoices/src/api/application/proformas/mappers/update-proforma-props.mapper.ts +++ b/modules/customer-invoices/src/api/application/proformas/mappers/update-proforma-props.mapper.ts @@ -8,7 +8,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Result, isNullishOrEmpty, toPatchField } from "@repo/rdx-utils"; @@ -36,7 +36,7 @@ export function UpdateProformaPropsMapper(dto: UpdateProformaByIdRequestDTO) { toPatchField(dto.series).ifSet((series) => { props.series = extractOrPushError( - maybeFromNullableVO(series, (value) => CustomerInvoiceSerie.create(value)), + maybeFromNullableResult(series, (value) => CustomerInvoiceSerie.create(value)), "reference", errors ); @@ -56,7 +56,7 @@ export function UpdateProformaPropsMapper(dto: UpdateProformaByIdRequestDTO) { toPatchField(dto.operation_date).ifSet((operation_date) => { props.operationDate = extractOrPushError( - maybeFromNullableVO(operation_date, (value) => UtcDate.createFromISO(value)), + maybeFromNullableResult(operation_date, (value) => UtcDate.createFromISO(value)), "operation_date", errors ); @@ -72,7 +72,7 @@ export function UpdateProformaPropsMapper(dto: UpdateProformaByIdRequestDTO) { toPatchField(dto.reference).ifSet((reference) => { props.reference = extractOrPushError( - maybeFromNullableVO(reference, (value) => Result.ok(String(value))), + maybeFromNullableResult(reference, (value) => Result.ok(String(value))), "reference", errors ); @@ -80,7 +80,7 @@ export function UpdateProformaPropsMapper(dto: UpdateProformaByIdRequestDTO) { toPatchField(dto.description).ifSet((description) => { props.description = extractOrPushError( - maybeFromNullableVO(description, (value) => Result.ok(String(value))), + maybeFromNullableResult(description, (value) => Result.ok(String(value))), "description", errors ); @@ -88,7 +88,7 @@ export function UpdateProformaPropsMapper(dto: UpdateProformaByIdRequestDTO) { toPatchField(dto.notes).ifSet((notes) => { props.notes = extractOrPushError( - maybeFromNullableVO(notes, (value) => TextValue.create(value)), + maybeFromNullableResult(notes, (value) => TextValue.create(value)), "notes", errors ); diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts index fa1a267f..eda68119 100644 --- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-full-snapshot-builder.ts @@ -1,5 +1,5 @@ import type { ISnapshotBuilder } from "@erp/core/api"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import { InvoiceAmount, type Proforma } from "../../../../domain"; @@ -86,14 +86,14 @@ export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder is_proforma: invoice.isProforma ? "true" : "false", invoice_number: invoice.invoiceNumber.toString(), status: invoice.status.toPrimitive(), - series: toEmptyString(invoice.series, (value) => value.toString()), + series: maybeToEmptyString(invoice.series, (value) => value.toString()), invoice_date: invoice.invoiceDate.toDateString(), - operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()), + operation_date: maybeToEmptyString(invoice.operationDate, (value) => value.toDateString()), - reference: toEmptyString(invoice.reference, (value) => value.toString()), - description: toEmptyString(invoice.description, (value) => value.toString()), - notes: toEmptyString(invoice.notes, (value) => value.toString()), + reference: maybeToEmptyString(invoice.reference, (value) => value.toString()), + description: maybeToEmptyString(invoice.description, (value) => value.toString()), + notes: maybeToEmptyString(invoice.notes, (value) => value.toString()), language_code: invoice.languageCode.toString(), currency_code: invoice.currencyCode.toString(), diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-items-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-items-full-snapshot-builder.ts index 6d28f202..dd8a7921 100644 --- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-items-full-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-items-full-snapshot-builder.ts @@ -1,5 +1,5 @@ import type { ISnapshotBuilder } from "@erp/core/api"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { CustomerInvoiceItems, IssuedInvoiceItem } from "../../../../domain"; @@ -16,7 +16,7 @@ export class ProformaItemsFullSnapshotBuilder implements IProformaItemsFullSnaps id: invoiceItem.id.toPrimitive(), is_valued: String(invoiceItem.isValued), position: String(index), - description: toEmptyString(invoiceItem.description, (value) => value.toPrimitive()), + description: maybeToEmptyString(invoiceItem.description, (value) => value.toPrimitive()), quantity: invoiceItem.quantity.match( (quantity) => quantity.toObjectString(), diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-recipient-full-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-recipient-full-snapshot-builder.ts index ff224915..0ef74363 100644 --- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-recipient-full-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/full/proforma-recipient-full-snapshot-builder.ts @@ -1,5 +1,5 @@ import type { ISnapshotBuilder } from "@erp/core/api"; -import { DomainValidationError, toEmptyString } from "@repo/rdx-ddd"; +import { DomainValidationError, maybeToEmptyString } from "@repo/rdx-ddd"; import type { InvoiceRecipient, Proforma } from "../../../../domain"; import type { ProformaRecipientFullSnapshot } from "../../application-models"; @@ -20,12 +20,12 @@ export class ProformaRecipientFullSnapshotBuilder implements IProformaRecipientF id: invoice.customerId.toString(), name: recipient.name.toString(), tin: recipient.tin.toString(), - street: toEmptyString(recipient.street, (v) => v.toString()), - street2: toEmptyString(recipient.street2, (v) => v.toString()), - city: toEmptyString(recipient.city, (v) => v.toString()), - province: toEmptyString(recipient.province, (v) => v.toString()), - postal_code: toEmptyString(recipient.postalCode, (v) => v.toString()), - country: toEmptyString(recipient.country, (v) => v.toString()), + street: maybeToEmptyString(recipient.street, (v) => v.toString()), + street2: maybeToEmptyString(recipient.street2, (v) => v.toString()), + city: maybeToEmptyString(recipient.city, (v) => v.toString()), + province: maybeToEmptyString(recipient.province, (v) => v.toString()), + postal_code: maybeToEmptyString(recipient.postalCode, (v) => v.toString()), + country: maybeToEmptyString(recipient.country, (v) => v.toString()), }), () => ({ id: "", diff --git a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/list/proforma-list-item-snapshot-builder.ts b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/list/proforma-list-item-snapshot-builder.ts index e0cb852e..7e5705ef 100644 --- a/modules/customer-invoices/src/api/application/proformas/snapshot-builders/list/proforma-list-item-snapshot-builder.ts +++ b/modules/customer-invoices/src/api/application/proformas/snapshot-builders/list/proforma-list-item-snapshot-builder.ts @@ -1,5 +1,5 @@ import type { ISnapshotBuilder } from "@erp/core/api"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { CustomerInvoiceListDTO } from "../../../../infrastructure"; import type { ProformaListItemSnapshot } from "../../application-models"; @@ -19,12 +19,12 @@ export class ProformaListItemSnapshotBuilder implements IProformaListItemSnapsho invoice_number: proforma.invoiceNumber.toString(), status: proforma.status.toPrimitive(), - series: toEmptyString(proforma.series, (value) => value.toString()), + series: maybeToEmptyString(proforma.series, (value) => value.toString()), invoice_date: proforma.invoiceDate.toDateString(), - operation_date: toEmptyString(proforma.operationDate, (value) => value.toDateString()), - reference: toEmptyString(proforma.reference, (value) => value.toString()), - description: toEmptyString(proforma.description, (value) => value.toString()), + operation_date: maybeToEmptyString(proforma.operationDate, (value) => value.toDateString()), + reference: maybeToEmptyString(proforma.reference, (value) => value.toString()), + description: maybeToEmptyString(proforma.description, (value) => value.toString()), recipient, diff --git a/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma-items.full.presenter.ts b/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma-items.full.presenter.ts index 70f9b370..c048d99f 100644 --- a/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma-items.full.presenter.ts +++ b/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma-items.full.presenter.ts @@ -1,6 +1,6 @@ import { SnapshotBuilder } from "@erp/core/api"; import type { GetProformaByIdResponseDTO } from "@erp/customer-invoices/common"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { ArrayElement } from "@repo/rdx-utils"; import type { CustomerInvoiceItems, IssuedInvoiceItem } from "../../../../domain"; @@ -15,7 +15,7 @@ export class ProformaItemsFullPresenter extends SnapshotBuilder { id: proformaItem.id.toPrimitive(), is_valued: String(proformaItem.isValued), position: String(index), - description: toEmptyString(proformaItem.description, (value) => value.toPrimitive()), + description: maybeToEmptyString(proformaItem.description, (value) => value.toPrimitive()), quantity: proformaItem.quantity.match( (quantity) => quantity.toObjectString(), diff --git a/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma-recipient.full.presenter.ts b/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma-recipient.full.presenter.ts index 0a043eb5..ecf03b4e 100644 --- a/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma-recipient.full.presenter.ts +++ b/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma-recipient.full.presenter.ts @@ -1,5 +1,5 @@ import { SnapshotBuilder } from "@erp/core/api"; -import { DomainValidationError, toEmptyString } from "@repo/rdx-ddd"; +import { DomainValidationError, maybeToEmptyString } from "@repo/rdx-ddd"; import type { GetIssuedInvoiceByIdResponseDTO as GetProformaByIdResponseDTO } from "../../../../../common/dto"; import type { InvoiceRecipient, Proforma } from "../../../../domain"; @@ -20,12 +20,12 @@ export class ProformaRecipientFullPresenter extends SnapshotBuilder { id: proforma.customerId.toString(), name: recipient.name.toString(), tin: recipient.tin.toString(), - street: toEmptyString(recipient.street, (value) => value.toString()), - street2: toEmptyString(recipient.street2, (value) => value.toString()), - city: toEmptyString(recipient.city, (value) => value.toString()), - province: toEmptyString(recipient.province, (value) => value.toString()), - postal_code: toEmptyString(recipient.postalCode, (value) => value.toString()), - country: toEmptyString(recipient.country, (value) => value.toString()), + street: maybeToEmptyString(recipient.street, (value) => value.toString()), + street2: maybeToEmptyString(recipient.street2, (value) => value.toString()), + city: maybeToEmptyString(recipient.city, (value) => value.toString()), + province: maybeToEmptyString(recipient.province, (value) => value.toString()), + postal_code: maybeToEmptyString(recipient.postalCode, (value) => value.toString()), + country: maybeToEmptyString(recipient.country, (value) => value.toString()), }; }, () => { diff --git a/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma.full.presenter.ts b/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma.full.presenter.ts index 734af9c9..8328dda7 100644 --- a/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma.full.presenter.ts +++ b/modules/customer-invoices/src/api/application/snapshot-builders/domain/proformas/proforma.full.presenter.ts @@ -1,5 +1,5 @@ import { Presenter } from "@erp/core/api"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { GetProformaByIdResponseDTO } from "../../../../../common/dto"; import { InvoiceAmount, type Proforma } from "../../../../domain"; @@ -87,14 +87,14 @@ export class ProformaFullPresenter extends Presenter value.toString()), + series: maybeToEmptyString(proforma.series, (value) => value.toString()), invoice_date: proforma.invoiceDate.toDateString(), - operation_date: toEmptyString(proforma.operationDate, (value) => value.toDateString()), + operation_date: maybeToEmptyString(proforma.operationDate, (value) => value.toDateString()), - reference: toEmptyString(proforma.reference, (value) => value.toString()), - description: toEmptyString(proforma.description, (value) => value.toString()), - notes: toEmptyString(proforma.notes, (value) => value.toString()), + reference: maybeToEmptyString(proforma.reference, (value) => value.toString()), + description: maybeToEmptyString(proforma.description, (value) => value.toString()), + notes: maybeToEmptyString(proforma.notes, (value) => value.toString()), language_code: proforma.languageCode.toString(), currency_code: proforma.currencyCode.toString(), diff --git a/modules/customer-invoices/src/api/application/snapshot-builders/queries/issued-invoices/issued-invoice.list.presenter.ts b/modules/customer-invoices/src/api/application/snapshot-builders/queries/issued-invoices/issued-invoice.list.presenter.ts index 730d6339..b7d4e2bc 100644 --- a/modules/customer-invoices/src/api/application/snapshot-builders/queries/issued-invoices/issued-invoice.list.presenter.ts +++ b/modules/customer-invoices/src/api/application/snapshot-builders/queries/issued-invoices/issued-invoice.list.presenter.ts @@ -1,5 +1,5 @@ import type { Criteria } from "@repo/rdx-criteria/server"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { ArrayElement, Collection } from "@repo/rdx-utils"; import type { ListIssuedInvoicesResponseDTO } from "../../../../../common/dto"; @@ -26,12 +26,12 @@ export class IssuedInvoiceListPresenter extends Presenter { invoice_number: invoice.invoiceNumber.toString(), status: invoice.status.toPrimitive(), - series: toEmptyString(invoice.series, (value) => value.toString()), + series: maybeToEmptyString(invoice.series, (value) => value.toString()), invoice_date: invoice.invoiceDate.toDateString(), - operation_date: toEmptyString(invoice.operationDate, (value) => value.toDateString()), - reference: toEmptyString(invoice.reference, (value) => value.toString()), - description: toEmptyString(invoice.description, (value) => value.toString()), + operation_date: maybeToEmptyString(invoice.operationDate, (value) => value.toDateString()), + reference: maybeToEmptyString(invoice.reference, (value) => value.toString()), + description: maybeToEmptyString(invoice.description, (value) => value.toString()), recipient: recipientDTO, diff --git a/modules/customer-invoices/src/api/application/snapshot-builders/queries/proformas/proforma.list.presenter.ts b/modules/customer-invoices/src/api/application/snapshot-builders/queries/proformas/proforma.list.presenter.ts index aabb6cab..eca0249e 100644 --- a/modules/customer-invoices/src/api/application/snapshot-builders/queries/proformas/proforma.list.presenter.ts +++ b/modules/customer-invoices/src/api/application/snapshot-builders/queries/proformas/proforma.list.presenter.ts @@ -1,6 +1,6 @@ import { Presenter } from "@erp/core/api"; import type { Criteria } from "@repo/rdx-criteria/server"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { ArrayElement, Collection } from "@repo/rdx-utils"; import type { ListProformasResponseDTO } from "../../../../../common/dto"; @@ -18,12 +18,12 @@ export class ProformaListPresenter extends Presenter { invoice_number: proforma.invoiceNumber.toString(), status: proforma.status.toPrimitive(), - series: toEmptyString(proforma.series, (value) => value.toString()), + series: maybeToEmptyString(proforma.series, (value) => value.toString()), invoice_date: proforma.invoiceDate.toDateString(), - operation_date: toEmptyString(proforma.operationDate, (value) => value.toDateString()), - reference: toEmptyString(proforma.reference, (value) => value.toString()), - description: toEmptyString(proforma.description, (value) => value.toString()), + operation_date: maybeToEmptyString(proforma.operationDate, (value) => value.toDateString()), + reference: maybeToEmptyString(proforma.reference, (value) => value.toString()), + description: maybeToEmptyString(proforma.description, (value) => value.toString()), recipient: recipientDTO, diff --git a/modules/customer-invoices/src/api/domain/common/value-objects/index.ts b/modules/customer-invoices/src/api/domain/common/value-objects/index.ts index 72ab96d5..e833b316 100644 --- a/modules/customer-invoices/src/api/domain/common/value-objects/index.ts +++ b/modules/customer-invoices/src/api/domain/common/value-objects/index.ts @@ -1,12 +1,15 @@ export * from "./invoice-address-type.vo"; export * from "./invoice-amount.vo"; +export * from "./invoice-discount-percentage.vo"; export * from "./invoice-number.vo"; export * from "./invoice-recipient"; export * from "./invoice-serie.vo"; export * from "./invoice-status.vo"; export * from "./invoice-tax-group.vo"; +export * from "./invoice-tax-percentage.vo"; export * from "./item-amount.vo"; export * from "./item-description.vo"; -export * from "./item-discount.vo"; +export * from "./item-discount-percentage.vo"; export * from "./item-quantity.vo"; export * from "./item-tax-group.vo"; +export * from "./item-tax-percentage.vo"; diff --git a/modules/customer-invoices/src/api/domain/common/value-objects/invoice-discount-percentage.vo.ts b/modules/customer-invoices/src/api/domain/common/value-objects/invoice-discount-percentage.vo.ts new file mode 100644 index 00000000..5bcc8864 --- /dev/null +++ b/modules/customer-invoices/src/api/domain/common/value-objects/invoice-discount-percentage.vo.ts @@ -0,0 +1,19 @@ +import { Percentage, type PercentageProps } from "@repo/rdx-ddd"; +import type { Result } from "@repo/rdx-utils"; + +type InvoiceDiscountPercentageProps = Pick; + +export class InvoiceDiscountPercentage extends Percentage { + static DEFAULT_SCALE = 2; + + static create({ value }: InvoiceDiscountPercentageProps): Result { + return Percentage.create({ + value, + scale: InvoiceDiscountPercentage.DEFAULT_SCALE, + }); + } + + static zero() { + return InvoiceDiscountPercentage.create({ value: 0 }).data; + } +} diff --git a/modules/customer-invoices/src/api/domain/common/value-objects/invoice-recipient/invoice-recipient.vo.ts b/modules/customer-invoices/src/api/domain/common/value-objects/invoice-recipient/invoice-recipient.vo.ts index 403c1942..f5169e20 100644 --- a/modules/customer-invoices/src/api/domain/common/value-objects/invoice-recipient/invoice-recipient.vo.ts +++ b/modules/customer-invoices/src/api/domain/common/value-objects/invoice-recipient/invoice-recipient.vo.ts @@ -7,7 +7,7 @@ import { type Street, type TINNumber, ValueObject, - toEmptyString, + maybeToEmptyString, } from "@repo/rdx-ddd"; import { type Maybe, Result } from "@repo/rdx-utils"; @@ -90,12 +90,12 @@ export class InvoiceRecipient extends ValueObject { return { tin: this.tin.toString(), name: this.name.toString(), - street: toEmptyString(this.street, (value) => value.toString()), - street2: toEmptyString(this.street2, (value) => value.toString()), - city: toEmptyString(this.city, (value) => value.toString()), - postal_code: toEmptyString(this.postalCode, (value) => value.toString()), - province: toEmptyString(this.province, (value) => value.toString()), - country: toEmptyString(this.country, (value) => value.toString()), + street: maybeToEmptyString(this.street, (value) => value.toString()), + street2: maybeToEmptyString(this.street2, (value) => value.toString()), + city: maybeToEmptyString(this.city, (value) => value.toString()), + postal_code: maybeToEmptyString(this.postalCode, (value) => value.toString()), + province: maybeToEmptyString(this.province, (value) => value.toString()), + country: maybeToEmptyString(this.country, (value) => value.toString()), }; } } diff --git a/modules/customer-invoices/src/api/domain/common/value-objects/invoice-tax-percentage.vo.ts b/modules/customer-invoices/src/api/domain/common/value-objects/invoice-tax-percentage.vo.ts new file mode 100644 index 00000000..2cbf7818 --- /dev/null +++ b/modules/customer-invoices/src/api/domain/common/value-objects/invoice-tax-percentage.vo.ts @@ -0,0 +1,19 @@ +import { Percentage, type PercentageProps } from "@repo/rdx-ddd"; +import type { Result } from "@repo/rdx-utils"; + +type InvoiceTaxPercentageProps = Pick; + +export class InvoiceTaxPercentage extends Percentage { + static DEFAULT_SCALE = 2; + + static create({ value }: InvoiceTaxPercentageProps): Result { + return Percentage.create({ + value, + scale: InvoiceTaxPercentage.DEFAULT_SCALE, + }); + } + + static zero() { + return InvoiceTaxPercentage.create({ value: 0 }).data; + } +} diff --git a/modules/customer-invoices/src/api/domain/common/value-objects/item-discount-percentage.vo.ts b/modules/customer-invoices/src/api/domain/common/value-objects/item-discount-percentage.vo.ts new file mode 100644 index 00000000..fb184ae5 --- /dev/null +++ b/modules/customer-invoices/src/api/domain/common/value-objects/item-discount-percentage.vo.ts @@ -0,0 +1,19 @@ +import { Percentage, type PercentageProps } from "@repo/rdx-ddd"; +import type { Result } from "@repo/rdx-utils"; + +type ItemDiscountPercentageProps = Pick; + +export class ItemDiscountPercentage extends Percentage { + static DEFAULT_SCALE = 2; + + static create({ value }: ItemDiscountPercentageProps): Result { + return Percentage.create({ + value, + scale: ItemDiscountPercentage.DEFAULT_SCALE, + }); + } + + static zero() { + return ItemDiscountPercentage.create({ value: 0 }).data; + } +} diff --git a/modules/customer-invoices/src/api/domain/common/value-objects/item-discount.vo.ts b/modules/customer-invoices/src/api/domain/common/value-objects/item-discount.vo.ts deleted file mode 100644 index 78237aff..00000000 --- a/modules/customer-invoices/src/api/domain/common/value-objects/item-discount.vo.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Percentage, type PercentageProps } from "@repo/rdx-ddd"; -import type { Result } from "@repo/rdx-utils"; - -type ItemDiscountProps = Pick; - -export class ItemDiscount extends Percentage { - static DEFAULT_SCALE = 2; - - static create({ value }: ItemDiscountProps): Result { - return Percentage.create({ - value, - scale: ItemDiscount.DEFAULT_SCALE, - }); - } - - static zero() { - return ItemDiscount.create({ value: 0 }).data; - } -} diff --git a/modules/customer-invoices/src/api/domain/common/value-objects/item-tax-percentage.vo.ts b/modules/customer-invoices/src/api/domain/common/value-objects/item-tax-percentage.vo.ts new file mode 100644 index 00000000..8126cbac --- /dev/null +++ b/modules/customer-invoices/src/api/domain/common/value-objects/item-tax-percentage.vo.ts @@ -0,0 +1,19 @@ +import { Percentage, type PercentageProps } from "@repo/rdx-ddd"; +import type { Result } from "@repo/rdx-utils"; + +type ItemTaxPercentageProps = Pick; + +export class ItemTaxPercentage extends Percentage { + static DEFAULT_SCALE = 2; + + static create({ value }: ItemTaxPercentageProps): Result { + return Percentage.create({ + value, + scale: ItemTaxPercentage.DEFAULT_SCALE, + }); + } + + static zero() { + return ItemTaxPercentage.create({ value: 0 }).data; + } +} diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts b/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts index b03cf056..e41e79e2 100644 --- a/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts +++ b/modules/customer-invoices/src/api/domain/issued-invoices/aggregates/issued-invoice.aggregate.ts @@ -49,17 +49,12 @@ export type IssuedInvoiceProps = { subtotalAmount: InvoiceAmount; - itemDiscountAmount: InvoiceAmount; + itemsDiscountAmount: InvoiceAmount; globalDiscountPercentage: Percentage; globalDiscountAmount: InvoiceAmount; totalDiscountAmount: InvoiceAmount; taxableAmount: InvoiceAmount; - - ivaAmount: InvoiceAmount; - recAmount: InvoiceAmount; - retentionAmount: InvoiceAmount; - taxesAmount: InvoiceAmount; totalAmount: InvoiceAmount; @@ -173,8 +168,8 @@ export class IssuedInvoice extends AggregateRoot { return this.props.subtotalAmount; } - public get itemDiscountAmount(): InvoiceAmount { - return this.props.itemDiscountAmount; + public get itemsDiscountAmount(): InvoiceAmount { + return this.props.itemsDiscountAmount; } public get globalDiscountPercentage(): Percentage { diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-items/issued-invoice-item.entity.ts b/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-items/issued-invoice-item.entity.ts index 9953c304..da9f64da 100644 --- a/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-items/issued-invoice-item.entity.ts +++ b/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-items/issued-invoice-item.entity.ts @@ -1,13 +1,18 @@ -import { type CurrencyCode, DomainEntity, type LanguageCode, type UniqueID } from "@repo/rdx-ddd"; +import { + type CurrencyCode, + DomainEntity, + type LanguageCode, + type Percentage, + type UniqueID, +} from "@repo/rdx-ddd"; import { type Maybe, Result } from "@repo/rdx-utils"; import type { InvoiceAmount, ItemAmount, ItemDescription, - ItemDiscount, + ItemDiscountPercentage, ItemQuantity, - ItemTaxGroup, } from "../../../common"; /** @@ -26,26 +31,32 @@ export type IssuedInvoiceItemProps = { quantity: Maybe; unitAmount: Maybe; - subtotalAmount: InvoiceAmount; + subtotalAmount: Maybe; - itemDiscountPercentage: Maybe; - itemDiscountAmount: InvoiceAmount; + itemDiscountPercentage: Maybe; + itemDiscountAmount: Maybe; - globalDiscountPercentage: Maybe; - globalDiscountAmount: InvoiceAmount; + globalDiscountPercentage: Maybe; + globalDiscountAmount: Maybe; - totalDiscountAmount: InvoiceAmount; + totalDiscountAmount: Maybe; - taxableAmount: InvoiceAmount; + taxableAmount: Maybe; - ivaAmount: InvoiceAmount; - recAmount: InvoiceAmount; - retentionAmount: InvoiceAmount; + ivaCode: Maybe; + ivaPercentage: Maybe; + ivaAmount: Maybe; - taxesAmount: InvoiceAmount; - totalAmount: InvoiceAmount; + recCode: Maybe; + recPercentage: Maybe; + recAmount: Maybe; - taxes: ItemTaxGroup; + retentionCode: Maybe; + retentionPercentage: Maybe; + retentionAmount: Maybe; + + taxesAmount: Maybe; + totalAmount: Maybe; languageCode: LanguageCode; currencyCode: CurrencyCode; @@ -107,10 +118,6 @@ export class IssuedInvoiceItem extends DomainEntity { return this.props.globalDiscountAmount; } - get taxes() { - return this.props.taxes; - } - get languageCode() { return this.props.languageCode; } @@ -119,35 +126,53 @@ export class IssuedInvoiceItem extends DomainEntity { return this.props.currencyCode; } - public get subtotalAmount(): ItemAmount { + public get subtotalAmount() { return this.props.subtotalAmount; } - public get totalDiscountAmount(): ItemAmount { + public get totalDiscountAmount() { return this.props.totalDiscountAmount; } - public get taxableAmount(): ItemAmount { + public get taxableAmount() { return this.props.taxableAmount; } - public get ivaAmount(): InvoiceAmount { + public get ivaCode(): Maybe { + return this.props.ivaCode; + } + public get ivaPercentage(): Maybe { + return this.props.ivaPercentage; + } + public get ivaAmount(): Maybe { return this.props.ivaAmount; } - public get recAmount(): InvoiceAmount { + public get recCode(): Maybe { + return this.props.recCode; + } + public get recPercentage(): Maybe { + return this.props.recPercentage; + } + public get recAmount(): Maybe { return this.props.recAmount; } - public get retentionAmount(): InvoiceAmount { + public get retentionCode(): Maybe { + return this.props.retentionCode; + } + public get retentionPercentage(): Maybe { + return this.props.retentionPercentage; + } + public get retentionAmount(): Maybe { return this.props.retentionAmount; } - public get taxesAmount(): ItemAmount { + public get taxesAmount() { return this.props.taxesAmount; } - public get totalAmount(): ItemAmount { + public get totalAmount() { return this.props.totalAmount; } diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-items/issued-invoice-items.collection.ts b/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-items/issued-invoice-items.collection.ts index 9cd84309..6308bcfb 100644 --- a/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-items/issued-invoice-items.collection.ts +++ b/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-items/issued-invoice-items.collection.ts @@ -1,7 +1,7 @@ import type { CurrencyCode, LanguageCode, Percentage } from "@repo/rdx-ddd"; import { Collection } from "@repo/rdx-utils"; -import { InvoiceAmount, ItemDiscount } from "../../../common"; +import { InvoiceAmount, ItemDiscountPercentage } from "../../../common"; import type { IssuedInvoiceItem } from "./issued-invoice-item.entity"; @@ -47,7 +47,7 @@ export class IssuedInvoiceItems extends Collection { this._globalDiscountPercentage.equals( item.globalDiscountPercentage.match( (v) => v, - () => ItemDiscount.zero() + () => ItemDiscountPercentage.zero() ) ) ) diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-tax.entity.ts b/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-tax.entity.ts index fa2683bc..2a3152c6 100644 --- a/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-tax.entity.ts +++ b/modules/customer-invoices/src/api/domain/issued-invoices/entities/issued-invoice-tax.entity.ts @@ -12,11 +12,11 @@ export type IssuedInvoiceTaxProps = { recCode: Maybe; recPercentage: Maybe; - recAmount: InvoiceAmount; + recAmount: Maybe; retentionCode: Maybe; retentionPercentage: Maybe; - retentionAmount: InvoiceAmount; + retentionAmount: Maybe; taxesAmount: InvoiceAmount; }; @@ -49,7 +49,7 @@ export class IssuedInvoiceTax extends DomainEntity { public get recPercentage(): Maybe { return this.props.recPercentage; } - public get recAmount(): InvoiceAmount { + public get recAmount(): Maybe { return this.props.recAmount; } @@ -59,7 +59,7 @@ export class IssuedInvoiceTax extends DomainEntity { public get retentionPercentage(): Maybe { return this.props.retentionPercentage; } - public get retentionAmount(): InvoiceAmount { + public get retentionAmount(): Maybe { return this.props.retentionAmount; } diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/entities/verifactu-record.entity.ts b/modules/customer-invoices/src/api/domain/issued-invoices/entities/verifactu-record.entity.ts index 236a177b..505e50f0 100644 --- a/modules/customer-invoices/src/api/domain/issued-invoices/entities/verifactu-record.entity.ts +++ b/modules/customer-invoices/src/api/domain/issued-invoices/entities/verifactu-record.entity.ts @@ -1,4 +1,4 @@ -import { DomainEntity, type URLAddress, type UniqueID, toEmptyString } from "@repo/rdx-ddd"; +import { DomainEntity, type URLAddress, type UniqueID, maybeToEmptyString } from "@repo/rdx-ddd"; import { type Maybe, Result } from "@repo/rdx-utils"; import type { VerifactuRecordEstado } from "../value-objects/verifactu-status.vo"; @@ -53,10 +53,10 @@ export class VerifactuRecord extends DomainEntity { toObjectString() { return { status: this.estado.toString(), - url: toEmptyString(this.url, (value) => value.toString()), - qr_code: toEmptyString(this.qrCode, (value) => value.toString()), - uuid: toEmptyString(this.uuid, (value) => value.toString()), - operacion: toEmptyString(this.operacion, (value) => value.toString()), + url: maybeToEmptyString(this.url, (value) => value.toString()), + qr_code: maybeToEmptyString(this.qrCode, (value) => value.toString()), + uuid: maybeToEmptyString(this.uuid, (value) => value.toString()), + operacion: maybeToEmptyString(this.operacion, (value) => value.toString()), }; } } diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/index.ts b/modules/customer-invoices/src/api/domain/issued-invoices/index.ts index 38d1c552..59e9091f 100644 --- a/modules/customer-invoices/src/api/domain/issued-invoices/index.ts +++ b/modules/customer-invoices/src/api/domain/issued-invoices/index.ts @@ -1,4 +1,3 @@ export * from "./aggregates"; export * from "./entities"; -export * from "./errors"; export * from "./value-objects"; diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/index.ts b/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/index.ts index edb91e86..9b42f37f 100644 --- a/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/index.ts +++ b/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/index.ts @@ -1 +1,2 @@ +export * from "./issued-invoice-tax-group.vo"; export * from "./verifactu-status.vo"; diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/invoice-tax-group.vo b/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/invoice-tax-group.vo deleted file mode 100644 index 6db53fd6..00000000 --- a/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/invoice-tax-group.vo +++ /dev/null @@ -1,117 +0,0 @@ -import { type Percentage, ValueObject } from "@repo/rdx-ddd"; -import { type Maybe, Result } from "@repo/rdx-utils"; - -import type { InvoiceAmount } from "../../common"; - -export type IssuedInvoiceTaxGroupProps = { - ivaCode: string; - ivaPercentage: Percentage; - ivaAmount: InvoiceAmount; - - recCode: Maybe; - recPercentage: Maybe; - recAmount: InvoiceAmount; - - retentionCode: Maybe; - retentionPercentage: Maybe; - retentionAmount: InvoiceAmount; - - taxableAmount: InvoiceAmount; - totalAmount: InvoiceAmount; -}; - -export class IssuedInvoiceTaxGroup extends ValueObject { - static create(props: IssuedInvoiceTaxGroupProps) { - return Result.ok(new IssuedInvoiceTaxGroup(props)); - } - - // IVA - - get ivaCode(): string { - return this.props.ivaCode; - } - get ivaPercentage(): Percentage { - return this.props.ivaPercentage; - } - get ivaAmount(): InvoiceAmount { - return this.props.ivaAmount; - } - - // Recargo de equivalencia (rec) - - get recCode(): Maybe { - return this.props.recCode; - } - get recPercentage(): Maybe { - return this.props.recPercentage; - } - - get recAmount(): Maybe { - return this.props.recAmount; - } - - // Retención (ret) - - get retentionCode(): Maybe { - return this.props.retentionCode; - } - - get retentionPercentage(): Maybe { - return this.props.retentionPercentage; - } - - get retentionAmount(): Maybe { - return this.props.retentionAmount; - } - - // - - get taxableAmount(): InvoiceAmount { - return this.props.taxableAmount; - } - - get totalAmount(): InvoiceAmount { - return this.props.totalAmount; - } - - /** - * Devuelve únicamente los códigos existentes: ["iva_21", "rec_5_2"] - */ - public getCodesArray(): string[] { - const codes: string[] = []; - - // IVA - codes.push(this.props.ivaCode); - - this.props.rec.match( - (t) => codes.push(t.code), - () => { - // - } - ); - - this.props.retention.match( - (t) => codes.push(t.code), - () => { - // - } - ); - - return codes; - } - - /** - * Devuelve una cadena tipo: "iva_21, rec_5_2" - */ - public getCodesToString(): string { - return this.getCodesArray().join(", "); - } - - getProps() { - return this.props; - } - - toPrimitive() { - return this.getProps(); - } -} diff --git a/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/issued-invoice-tax-group.vo.ts b/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/issued-invoice-tax-group.vo.ts new file mode 100644 index 00000000..cc0e3ce7 --- /dev/null +++ b/modules/customer-invoices/src/api/domain/issued-invoices/value-objects/issued-invoice-tax-group.vo.ts @@ -0,0 +1,66 @@ +import type { Tax } from "@erp/core/api"; +import { ValueObject } from "@repo/rdx-ddd"; +import { type Maybe, Result } from "@repo/rdx-utils"; + +import type { InvoiceAmount } from "../../common"; + +export type IssuedInvoiceTaxGroupProps = { + taxableAmount: InvoiceAmount; + + iva: Tax; + ivaAmount: InvoiceAmount; + + rec: Maybe; // si existe + recAmount: Maybe; + + retention: Maybe; // si existe + retentionAmount: Maybe; + + taxesAmount: InvoiceAmount; +}; + +export class IssuedInvoiceTaxGroup extends ValueObject { + static create(props: IssuedInvoiceTaxGroupProps) { + return Result.ok(new IssuedInvoiceTaxGroup(props)); + } + + get taxableAmount(): InvoiceAmount { + return this.props.taxableAmount; + } + + get iva(): Tax { + return this.props.iva; + } + + get ivaAmount(): InvoiceAmount { + return this.props.ivaAmount; + } + + get rec(): Maybe { + return this.props.rec; + } + + get recAmount(): Maybe { + return this.props.recAmount; + } + + get retention(): Maybe { + return this.props.retention; + } + + get retentionAmount(): Maybe { + return this.props.retentionAmount; + } + + get taxesAmount(): InvoiceAmount { + return this.props.taxesAmount; + } + + getProps() { + return this.props; + } + + toPrimitive() { + return this.getProps(); + } +} diff --git a/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-item.entity.ts b/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-item.entity.ts index 514ab875..39120a62 100644 --- a/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-item.entity.ts +++ b/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-item.entity.ts @@ -4,7 +4,7 @@ import { type Maybe, Result } from "@repo/rdx-utils"; import { ItemAmount, type ItemDescription, - ItemDiscount, + ItemDiscountPercentage, ItemQuantity, type ItemTaxGroup, } from "../../../common"; @@ -31,8 +31,8 @@ export type ProformaItemProps = { quantity: Maybe; // Cantidad de unidades unitAmount: Maybe; // Precio unitario en la moneda de la factura - itemDiscountPercentage: Maybe; // % descuento - globalDiscountPercentage: Maybe; // % descuento de la cabecera + itemDiscountPercentage: Maybe; // % descuento + globalDiscountPercentage: Maybe; // % descuento de la cabecera taxes: ItemTaxGroup; @@ -128,7 +128,7 @@ export class ProformaItem extends DomainEntity { private _calculateItemDiscountAmount(subtotal: ItemAmount): ItemAmount { const discountPercentage = this.props.itemDiscountPercentage.match( (discount) => discount, - () => ItemDiscount.zero() + () => ItemDiscountPercentage.zero() ); return subtotal.percentage(discountPercentage); @@ -145,7 +145,7 @@ export class ProformaItem extends DomainEntity { const globalDiscount = this.props.globalDiscountPercentage.match( (discount) => discount, - () => ItemDiscount.zero() + () => ItemDiscountPercentage.zero() ); return amountAfterLineDiscount.percentage(globalDiscount); diff --git a/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-items.collection.ts b/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-items.collection.ts index 6fce7e80..dff594a1 100644 --- a/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-items.collection.ts +++ b/modules/customer-invoices/src/api/domain/proformas/entities/proforma-items/proforma-items.collection.ts @@ -1,7 +1,7 @@ import type { CurrencyCode, LanguageCode, Percentage } from "@repo/rdx-ddd"; import { Collection } from "@repo/rdx-utils"; -import { ItemAmount, ItemDiscount, type ItemTaxGroup } from "../../../common"; +import { ItemAmount, ItemDiscountPercentage, type ItemTaxGroup } from "../../../common"; import type { ProformaItem } from "./proforma-item.entity"; @@ -76,7 +76,7 @@ export class ProformaItems extends Collection { this.globalDiscountPercentage.equals( item.globalDiscountPercentage.match( (v) => v, - () => ItemDiscount.zero() + () => ItemDiscountPercentage.zero() ) ); diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice-item.mapper.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice-item.mapper.ts index bb9ee051..604916ad 100644 --- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice-item.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice-item.mapper.ts @@ -10,8 +10,8 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toNullable, + maybeFromNullableResult, + maybeToNullable, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; @@ -21,7 +21,7 @@ import { type IssuedInvoiceItemProps, ItemAmount, ItemDescription, - ItemDiscount, + ItemDiscountPercentage, ItemQuantity, ItemTaxGroup, type Proforma, @@ -78,19 +78,19 @@ export class CustomerInvoiceItemDomainMapper ); const description = extractOrPushError( - maybeFromNullableVO(source.description, (v) => ItemDescription.create(v)), + maybeFromNullableResult(source.description, (v) => ItemDescription.create(v)), `items[${index}].description`, errors ); const quantity = extractOrPushError( - maybeFromNullableVO(source.quantity_value, (v) => ItemQuantity.create({ value: v })), + maybeFromNullableResult(source.quantity_value, (v) => ItemQuantity.create({ value: v })), `items[${index}].quantity`, errors ); const unitAmount = extractOrPushError( - maybeFromNullableVO(source.unit_amount_value, (value) => + maybeFromNullableResult(source.unit_amount_value, (value) => ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) ), `items[${index}].unit_amount`, @@ -98,35 +98,39 @@ export class CustomerInvoiceItemDomainMapper ); const discountPercentage = extractOrPushError( - maybeFromNullableVO(source.discount_percentage_value, (v) => - ItemDiscount.create({ value: v }) + maybeFromNullableResult(source.discount_percentage_value, (v) => + ItemDiscountPercentage.create({ value: v }) ), `items[${index}].discount_percentage`, errors ); const globalDiscountPercentage = extractOrPushError( - maybeFromNullableVO(source.global_discount_percentage_value, (v) => - ItemDiscount.create({ value: v }) + maybeFromNullableResult(source.global_discount_percentage_value, (v) => + ItemDiscountPercentage.create({ value: v }) ), `items[${index}].discount_percentage`, errors ); const iva = extractOrPushError( - maybeFromNullableVO(source.iva_code, (code) => Tax.createFromCode(code, this._taxCatalog)), + maybeFromNullableResult(source.iva_code, (code) => + Tax.createFromCode(code, this._taxCatalog) + ), `items[${index}].iva_code`, errors ); const rec = extractOrPushError( - maybeFromNullableVO(source.rec_code, (code) => Tax.createFromCode(code, this._taxCatalog)), + maybeFromNullableResult(source.rec_code, (code) => + Tax.createFromCode(code, this._taxCatalog) + ), `items[${index}].rec_code`, errors ); const retention = extractOrPushError( - maybeFromNullableVO(source.retention_code, (code) => + maybeFromNullableResult(source.retention_code, (code) => Tax.createFromCode(code, this._taxCatalog) ), `items[${index}].retention_code`, @@ -216,40 +220,42 @@ export class CustomerInvoiceItemDomainMapper invoice_id: parent.id.toPrimitive(), position: index, - description: toNullable(source.description, (v) => v.toPrimitive()), + description: maybeToNullable(source.description, (v) => v.toPrimitive()), - quantity_value: toNullable(source.quantity, (v) => v.toPrimitive().value), + quantity_value: maybeToNullable(source.quantity, (v) => v.toPrimitive().value), quantity_scale: - toNullable(source.quantity, (v) => v.toPrimitive().scale) ?? ItemQuantity.DEFAULT_SCALE, + maybeToNullable(source.quantity, (v) => v.toPrimitive().scale) ?? + ItemQuantity.DEFAULT_SCALE, - unit_amount_value: toNullable(source.unitAmount, (v) => v.toPrimitive().value), + unit_amount_value: maybeToNullable(source.unitAmount, (v) => v.toPrimitive().value), unit_amount_scale: - toNullable(source.unitAmount, (v) => v.toPrimitive().scale) ?? ItemAmount.DEFAULT_SCALE, + maybeToNullable(source.unitAmount, (v) => v.toPrimitive().scale) ?? + ItemAmount.DEFAULT_SCALE, subtotal_amount_value: allAmounts.subtotalAmount.value, subtotal_amount_scale: allAmounts.subtotalAmount.scale, // - discount_percentage_value: toNullable( + discount_percentage_value: maybeToNullable( source.itemDiscountPercentage, (v) => v.toPrimitive().value ), discount_percentage_scale: - toNullable(source.itemDiscountPercentage, (v) => v.toPrimitive().scale) ?? - ItemDiscount.DEFAULT_SCALE, + maybeToNullable(source.itemDiscountPercentage, (v) => v.toPrimitive().scale) ?? + ItemDiscountPercentage.DEFAULT_SCALE, discount_amount_value: allAmounts.itemDiscountAmount.value, discount_amount_scale: allAmounts.itemDiscountAmount.scale, // - global_discount_percentage_value: toNullable( + global_discount_percentage_value: maybeToNullable( source.globalDiscountPercentage, (v) => v.toPrimitive().value ), global_discount_percentage_scale: - toNullable(source.globalDiscountPercentage, (v) => v.toPrimitive().scale) ?? - ItemDiscount.DEFAULT_SCALE, + maybeToNullable(source.globalDiscountPercentage, (v) => v.toPrimitive().scale) ?? + ItemDiscountPercentage.DEFAULT_SCALE, global_discount_amount_value: allAmounts.globalDiscountAmount.value, global_discount_amount_scale: allAmounts.globalDiscountAmount.scale, @@ -263,29 +269,32 @@ export class CustomerInvoiceItemDomainMapper taxable_amount_scale: allAmounts.taxableAmount.scale, // IVA - iva_code: toNullable(source.taxes.iva, (v) => v.code), + iva_code: maybeToNullable(source.taxes.iva, (v) => v.code), - iva_percentage_value: toNullable(source.taxes.iva, (v) => v.percentage.value), - iva_percentage_scale: toNullable(source.taxes.iva, (v) => v.percentage.scale) ?? 2, + iva_percentage_value: maybeToNullable(source.taxes.iva, (v) => v.percentage.value), + iva_percentage_scale: maybeToNullable(source.taxes.iva, (v) => v.percentage.scale) ?? 2, iva_amount_value: taxesAmounts.ivaAmount.value, iva_amount_scale: taxesAmounts.ivaAmount.scale, // REC - rec_code: toNullable(source.taxes.rec, (v) => v.code), + rec_code: maybeToNullable(source.taxes.rec, (v) => v.code), - rec_percentage_value: toNullable(source.taxes.rec, (v) => v.percentage.value), - rec_percentage_scale: toNullable(source.taxes.rec, (v) => v.percentage.scale) ?? 2, + rec_percentage_value: maybeToNullable(source.taxes.rec, (v) => v.percentage.value), + rec_percentage_scale: maybeToNullable(source.taxes.rec, (v) => v.percentage.scale) ?? 2, rec_amount_value: taxesAmounts.recAmount.value, rec_amount_scale: taxesAmounts.recAmount.scale, // RET - retention_code: toNullable(source.taxes.retention, (v) => v.code), + retention_code: maybeToNullable(source.taxes.retention, (v) => v.code), - retention_percentage_value: toNullable(source.taxes.retention, (v) => v.percentage.value), + retention_percentage_value: maybeToNullable( + source.taxes.retention, + (v) => v.percentage.value + ), retention_percentage_scale: - toNullable(source.taxes.retention, (v) => v.percentage.scale) ?? 2, + maybeToNullable(source.taxes.retention, (v) => v.percentage.scale) ?? 2, retention_amount_value: taxesAmounts.retentionAmount.value, retention_amount_scale: taxesAmounts.retentionAmount.scale, diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice-taxes.mapper.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice-taxes.mapper.ts index 521f827c..33c41ef5 100644 --- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice-taxes.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice-taxes.mapper.ts @@ -1,6 +1,6 @@ import type { JsonTaxCatalogProvider } from "@erp/core"; import { type MapperParamsType, SequelizeDomainMapper } from "@erp/core/api"; -import { UniqueID, type ValidationErrorDetail, toNullable } from "@repo/rdx-ddd"; +import { UniqueID, type ValidationErrorDetail, maybeToNullable } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import type { InvoiceTaxGroup, Proforma } from "../../../../../../domain"; @@ -120,19 +120,20 @@ export class CustomerInvoiceTaxesDomainMapper extends SequelizeDomainMapper< iva_amount_scale: ivaAmount.scale, // REC - rec_code: toNullable(source.rec, (v) => v.code), + rec_code: maybeToNullable(source.rec, (v) => v.code), - rec_percentage_value: toNullable(source.rec, (v) => v.percentage.value), - rec_percentage_scale: toNullable(source.rec, (v) => v.percentage.scale) ?? 2, + rec_percentage_value: maybeToNullable(source.rec, (v) => v.percentage.value), + rec_percentage_scale: maybeToNullable(source.rec, (v) => v.percentage.scale) ?? 2, rec_amount_value: recAmount.value, rec_amount_scale: recAmount.scale, // RET - retention_code: toNullable(source.retention, (v) => v.code), + retention_code: maybeToNullable(source.retention, (v) => v.code), - retention_percentage_value: toNullable(source.retention, (v) => v.percentage.value), - retention_percentage_scale: toNullable(source.retention, (v) => v.percentage.scale) ?? 2, + retention_percentage_value: maybeToNullable(source.retention, (v) => v.percentage.value), + retention_percentage_scale: + maybeToNullable(source.retention, (v) => v.percentage.scale) ?? 2, retention_amount_value: retentionAmount.value, retention_amount_scale: retentionAmount.scale, diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice.mapper.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice.mapper.ts index e602b7c0..627960be 100644 --- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/customer-invoice.mapper.ts @@ -13,8 +13,8 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toNullable, + maybeFromNullableResult, + maybeToNullable, } from "@repo/rdx-ddd"; import { Maybe, Result, isNullishOrEmpty } from "@repo/rdx-utils"; @@ -79,7 +79,7 @@ export class CustomerInvoiceDomainMapper const isProforma = Boolean(source.is_proforma); const proformaId = extractOrPushError( - maybeFromNullableVO(source.proforma_id, (v) => UniqueID.create(v)), + maybeFromNullableResult(source.proforma_id, (v) => UniqueID.create(v)), "proforma_id", errors ); @@ -87,7 +87,7 @@ export class CustomerInvoiceDomainMapper const status = extractOrPushError(InvoiceStatus.create(source.status), "status", errors); const series = extractOrPushError( - maybeFromNullableVO(source.series, (v) => InvoiceSerie.create(v)), + maybeFromNullableResult(source.series, (v) => InvoiceSerie.create(v)), "series", errors ); @@ -106,7 +106,7 @@ export class CustomerInvoiceDomainMapper ); const operationDate = extractOrPushError( - maybeFromNullableVO(source.operation_date, (v) => UtcDate.createFromISO(v)), + maybeFromNullableResult(source.operation_date, (v) => UtcDate.createFromISO(v)), "operation_date", errors ); @@ -126,19 +126,19 @@ export class CustomerInvoiceDomainMapper // Textos opcionales const reference = extractOrPushError( - maybeFromNullableVO(source.reference, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.reference, (value) => Result.ok(String(value))), "reference", errors ); const description = extractOrPushError( - maybeFromNullableVO(source.description, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.description, (value) => Result.ok(String(value))), "description", errors ); const notes = extractOrPushError( - maybeFromNullableVO(source.notes, (value) => TextValue.create(value)), + maybeFromNullableResult(source.notes, (value) => TextValue.create(value)), "notes", errors ); @@ -362,19 +362,19 @@ export class CustomerInvoiceDomainMapper // Flags / estado / serie / número is_proforma: source.isProforma, - proforma_id: toNullable(source.proformaId, (v) => v.toPrimitive()), + proforma_id: maybeToNullable(source.proformaId, (v) => v.toPrimitive()), status: source.status.toPrimitive(), - series: toNullable(source.series, (v) => v.toPrimitive()), + series: maybeToNullable(source.series, (v) => v.toPrimitive()), invoice_number: source.invoiceNumber.toPrimitive(), invoice_date: source.invoiceDate.toPrimitive(), - operation_date: toNullable(source.operationDate, (v) => v.toPrimitive()), + operation_date: maybeToNullable(source.operationDate, (v) => v.toPrimitive()), language_code: source.languageCode.toPrimitive(), currency_code: source.currencyCode.toPrimitive(), - reference: toNullable(source.reference, (reference) => reference), - description: toNullable(source.description, (description) => description), - notes: toNullable(source.notes, (v) => v.toPrimitive()), + reference: maybeToNullable(source.reference, (reference) => reference), + description: maybeToNullable(source.description, (description) => description), + notes: maybeToNullable(source.notes, (v) => v.toPrimitive()), subtotal_amount_value: allAmounts.subtotalAmount.value, subtotal_amount_scale: allAmounts.subtotalAmount.scale, @@ -394,8 +394,11 @@ export class CustomerInvoiceDomainMapper total_amount_value: allAmounts.totalAmount.value, total_amount_scale: allAmounts.totalAmount.scale, - payment_method_id: toNullable(source.paymentMethod, (payment) => payment.toObjectString().id), - payment_method_description: toNullable( + payment_method_id: maybeToNullable( + source.paymentMethod, + (payment) => payment.toObjectString().id + ), + payment_method_description: maybeToNullable( source.paymentMethod, (payment) => payment.toObjectString().payment_description ), diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/invoice-recipient.mapper.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/invoice-recipient.mapper.ts index db80a9d3..fa003a79 100644 --- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/invoice-recipient.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/invoice-recipient.mapper.ts @@ -10,8 +10,8 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toNullable, + maybeFromNullableResult, + maybeToNullable, } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; @@ -59,37 +59,37 @@ export class InvoiceRecipientDomainMapper { const customerTin = extractOrPushError(TINNumber.create(_tin!), "customer_tin", errors); const customerStreet = extractOrPushError( - maybeFromNullableVO(_street, (value) => Street.create(value)), + maybeFromNullableResult(_street, (value) => Street.create(value)), "customer_street", errors ); const customerStreet2 = extractOrPushError( - maybeFromNullableVO(_street2, (value) => Street.create(value)), + maybeFromNullableResult(_street2, (value) => Street.create(value)), "customer_street2", errors ); const customerCity = extractOrPushError( - maybeFromNullableVO(_city, (value) => City.create(value)), + maybeFromNullableResult(_city, (value) => City.create(value)), "customer_city", errors ); const customerProvince = extractOrPushError( - maybeFromNullableVO(_province, (value) => Province.create(value)), + maybeFromNullableResult(_province, (value) => Province.create(value)), "customer_province", errors ); const customerPostalCode = extractOrPushError( - maybeFromNullableVO(_postal_code, (value) => PostalCode.create(value)), + maybeFromNullableResult(_postal_code, (value) => PostalCode.create(value)), "customer_postal_code", errors ); const customerCountry = extractOrPushError( - maybeFromNullableVO(_country, (value) => Country.create(value)), + maybeFromNullableResult(_country, (value) => Country.create(value)), "customer_country", errors ); @@ -167,12 +167,12 @@ export class InvoiceRecipientDomainMapper { return { customer_tin: recipient.tin.toPrimitive(), customer_name: recipient.name.toPrimitive(), - customer_street: toNullable(recipient.street, (v) => v.toPrimitive()), - customer_street2: toNullable(recipient.street2, (v) => v.toPrimitive()), - customer_city: toNullable(recipient.city, (v) => v.toPrimitive()), - customer_province: toNullable(recipient.province, (v) => v.toPrimitive()), - customer_postal_code: toNullable(recipient.postalCode, (v) => v.toPrimitive()), - customer_country: toNullable(recipient.country, (v) => v.toPrimitive()), + customer_street: maybeToNullable(recipient.street, (v) => v.toPrimitive()), + customer_street2: maybeToNullable(recipient.street2, (v) => v.toPrimitive()), + customer_city: maybeToNullable(recipient.city, (v) => v.toPrimitive()), + customer_province: maybeToNullable(recipient.province, (v) => v.toPrimitive()), + customer_postal_code: maybeToNullable(recipient.postalCode, (v) => v.toPrimitive()), + customer_country: maybeToNullable(recipient.country, (v) => v.toPrimitive()), }; } } diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/invoice-verifactu.mapper.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/invoice-verifactu.mapper.ts index b11268bd..0682e39f 100644 --- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/invoice-verifactu.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/domain/invoice-verifactu.mapper.ts @@ -6,8 +6,8 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toEmptyString, + maybeFromNullableResult, + maybeToEmptyString, } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; @@ -58,25 +58,25 @@ export class CustomerInvoiceVerifactuDomainMapper ); const qr = extractOrPushError( - maybeFromNullableVO(source.qr, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.qr, (value) => Result.ok(String(value))), "qr", errors ); const url = extractOrPushError( - maybeFromNullableVO(source.url, (value) => URLAddress.create(value)), + maybeFromNullableResult(source.url, (value) => URLAddress.create(value)), "url", errors ); const uuid = extractOrPushError( - maybeFromNullableVO(source.uuid, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.uuid, (value) => Result.ok(String(value))), "uuid", errors ); const operacion = extractOrPushError( - maybeFromNullableVO(source.operacion, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.operacion, (value) => Result.ok(String(value))), "operacion", errors ); @@ -136,10 +136,10 @@ export class CustomerInvoiceVerifactuDomainMapper id: verifactu.id.toPrimitive(), invoice_id: parent.id.toPrimitive(), estado: verifactu.estado.toPrimitive(), - qr: toEmptyString(verifactu.qrCode, (v) => v), - url: toEmptyString(verifactu.url, (v) => v.toPrimitive()), - uuid: toEmptyString(verifactu.uuid, (v) => v), - operacion: toEmptyString(verifactu.operacion, (v) => v), + qr: maybeToEmptyString(verifactu.qrCode, (v) => v), + url: maybeToEmptyString(verifactu.url, (v) => v.toPrimitive()), + uuid: maybeToEmptyString(verifactu.uuid, (v) => v), + operacion: maybeToEmptyString(verifactu.operacion, (v) => v), }); } } diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/customer-invoice.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/customer-invoice.list.mapper.ts index c38b4b8f..6038e365 100644 --- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/customer-invoice.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/customer-invoice.list.mapper.ts @@ -12,7 +12,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; @@ -167,7 +167,7 @@ export class CustomerInvoiceListMapper const status = extractOrPushError(InvoiceStatus.create(raw.status), "status", errors); const series = extractOrPushError( - maybeFromNullableVO(raw.series, (value) => InvoiceSerie.create(value)), + maybeFromNullableResult(raw.series, (value) => InvoiceSerie.create(value)), "serie", errors ); @@ -185,19 +185,19 @@ export class CustomerInvoiceListMapper ); const operationDate = extractOrPushError( - maybeFromNullableVO(raw.operation_date, (value) => UtcDate.createFromISO(value)), + maybeFromNullableResult(raw.operation_date, (value) => UtcDate.createFromISO(value)), "operation_date", errors ); const reference = extractOrPushError( - maybeFromNullableVO(raw.reference, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.reference, (value) => Result.ok(String(value))), "description", errors ); const description = extractOrPushError( - maybeFromNullableVO(raw.description, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.description, (value) => Result.ok(String(value))), "description", errors ); diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/invoice-recipient.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/invoice-recipient.list.mapper.ts index 1fef5207..68abd1a8 100644 --- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/invoice-recipient.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/invoice-recipient.list.mapper.ts @@ -13,7 +13,7 @@ import { TINNumber, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import type { Result } from "@repo/rdx-utils"; @@ -67,37 +67,37 @@ export class InvoiceRecipientListMapper const customerTin = extractOrPushError(TINNumber.create(_tin), "customer_tin", errors); const customerStreet = extractOrPushError( - maybeFromNullableVO(_street, (value) => Street.create(value)), + maybeFromNullableResult(_street, (value) => Street.create(value)), "customer_street", errors ); const customerStreet2 = extractOrPushError( - maybeFromNullableVO(_street2, (value) => Street.create(value)), + maybeFromNullableResult(_street2, (value) => Street.create(value)), "customer_street2", errors ); const customerCity = extractOrPushError( - maybeFromNullableVO(_city, (value) => City.create(value)), + maybeFromNullableResult(_city, (value) => City.create(value)), "customer_city", errors ); const customerProvince = extractOrPushError( - maybeFromNullableVO(_province, (value) => Province.create(value)), + maybeFromNullableResult(_province, (value) => Province.create(value)), "customer_province", errors ); const customerPostalCode = extractOrPushError( - maybeFromNullableVO(_postal_code, (value) => PostalCode.create(value)), + maybeFromNullableResult(_postal_code, (value) => PostalCode.create(value)), "customer_postal_code", errors ); const customerCountry = extractOrPushError( - maybeFromNullableVO(_country, (value) => Country.create(value)), + maybeFromNullableResult(_country, (value) => Country.create(value)), "customer_country", errors ); diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/verifactu-record.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/verifactu-record.list.mapper.ts index 9a691a21..c44fc52b 100644 --- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/verifactu-record.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/mappers/list/verifactu-record.list.mapper.ts @@ -9,7 +9,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; @@ -35,25 +35,25 @@ export class VerifactuRecordListMapper const estado = extractOrPushError(VerifactuRecordEstado.create(raw.estado), "estado", errors); const qr = extractOrPushError( - maybeFromNullableVO(raw.qr, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.qr, (value) => Result.ok(String(value))), "qr", errors ); const url = extractOrPushError( - maybeFromNullableVO(raw.url, (value) => URLAddress.create(value)), + maybeFromNullableResult(raw.url, (value) => URLAddress.create(value)), "url", errors ); const uuid = extractOrPushError( - maybeFromNullableVO(raw.uuid, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.uuid, (value) => Result.ok(String(value))), "uuid", errors ); const operacion = extractOrPushError( - maybeFromNullableVO(raw.operacion, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.operacion, (value) => Result.ok(String(value))), "operacion", errors ); diff --git a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/customer-invoice-tax.model.ts b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/customer-invoice-tax.model.ts index e0fa9d92..54889812 100644 --- a/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/customer-invoice-tax.model.ts +++ b/modules/customer-invoices/src/api/infrastructure/common/persistence/sequelize/models/customer-invoice-tax.model.ts @@ -23,20 +23,20 @@ export class CustomerInvoiceTaxModel extends Model< declare invoice_id: string; // Taxable amount (base imponible) - declare taxable_amount_value: CreationOptional; + declare taxable_amount_value: number; declare taxable_amount_scale: number; // Código de impuestos // IVA percentage - declare iva_code: CreationOptional; + declare iva_code: string; - declare iva_percentage_value: CreationOptional; + declare iva_percentage_value: number; declare iva_percentage_scale: number; // IVA amount - declare iva_amount_value: CreationOptional; + declare iva_amount_value: number; declare iva_amount_scale: number; // Recargo de equivalencia percentage @@ -60,7 +60,7 @@ export class CustomerInvoiceTaxModel extends Model< declare retention_amount_scale: number; // Total taxes amount / taxes total - declare taxes_amount_value: CreationOptional; + declare taxes_amount_value: number; declare taxes_amount_scale: number; // Relaciones @@ -108,8 +108,8 @@ export default (database: Sequelize) => { taxable_amount_value: { type: new DataTypes.BIGINT(), // importante: evita problemas de precisión con valores grandes - allowNull: true, - defaultValue: null, + allowNull: false, + defaultValue: 0, }, taxable_amount_scale: { @@ -207,8 +207,8 @@ export default (database: Sequelize) => { taxes_amount_value: { type: new DataTypes.BIGINT(), // importante: evita problemas de precisión con valores grandes - allowNull: true, - defaultValue: null, + allowNull: false, + defaultValue: 0, }, taxes_amount_scale: { diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts index 71ea77d8..909c623a 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-domain.mapper.ts @@ -9,13 +9,14 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toNullable, + maybeFromNullableResult, + maybeToNullable, } from "@repo/rdx-ddd"; import { Maybe, Result, isNullishOrEmpty } from "@repo/rdx-utils"; import type { IIssuedInvoiceDomainMapper } from "../../../../../../application"; import { + InvoiceAmount, InvoiceNumber, InvoicePaymentMethod, InvoiceSerie, @@ -23,6 +24,7 @@ import { IssuedInvoice, IssuedInvoiceItems, type IssuedInvoiceProps, + IssuedInvoiceTaxes, } from "../../../../../../domain"; import type { CustomerInvoiceCreationAttributes, @@ -52,87 +54,83 @@ export class SequelizeIssuedInvoiceDomainMapper this._itemsMapper = new SequelizeIssuedInvoiceItemDomainMapper(params); // Instanciar el mapper de items this._recipientMapper = new SequelizeIssuedInvoiceRecipientDomainMapper(); - this._taxesMapper = new SequelizeIssuedInvoiceTaxesDomainMapper(); + this._taxesMapper = new SequelizeIssuedInvoiceTaxesDomainMapper(params); this._verifactuMapper = new SequelizeIssuedInvoiceVerifactuDomainMapper(); } - private _mapAttributesToDomain(source: CustomerInvoiceModel, params?: MapperParamsType) { + private _mapAttributesToDomain(raw: CustomerInvoiceModel, params?: MapperParamsType) { const { errors } = params as { errors: ValidationErrorDetail[]; }; - const invoiceId = extractOrPushError(UniqueID.create(source.id), "id", errors); - const companyId = extractOrPushError(UniqueID.create(source.company_id), "company_id", errors); + const invoiceId = extractOrPushError(UniqueID.create(raw.id), "id", errors); + const companyId = extractOrPushError(UniqueID.create(raw.company_id), "company_id", errors); - const customerId = extractOrPushError( - UniqueID.create(source.customer_id), - "customer_id", - errors - ); + const customerId = extractOrPushError(UniqueID.create(raw.customer_id), "customer_id", errors); - const isIssuedInvoice = Boolean(source.is_proforma); + const isIssuedInvoice = Boolean(raw.is_proforma); const proformaId = extractOrPushError( - maybeFromNullableVO(source.proforma_id, (v) => UniqueID.create(v)), + maybeFromNullableResult(raw.proforma_id, (v) => UniqueID.create(v)), "proforma_id", errors ); - const status = extractOrPushError(InvoiceStatus.create(source.status), "status", errors); + const status = extractOrPushError(InvoiceStatus.create(raw.status), "status", errors); const series = extractOrPushError( - maybeFromNullableVO(source.series, (v) => InvoiceSerie.create(v)), + maybeFromNullableResult(raw.series, (v) => InvoiceSerie.create(v)), "series", errors ); const invoiceNumber = extractOrPushError( - InvoiceNumber.create(source.invoice_number), + InvoiceNumber.create(raw.invoice_number), "invoice_number", errors ); // Fechas const invoiceDate = extractOrPushError( - UtcDate.createFromISO(source.invoice_date), + UtcDate.createFromISO(raw.invoice_date), "invoice_date", errors ); const operationDate = extractOrPushError( - maybeFromNullableVO(source.operation_date, (v) => UtcDate.createFromISO(v)), + maybeFromNullableResult(raw.operation_date, (v) => UtcDate.createFromISO(v)), "operation_date", errors ); // Idioma / divisa const languageCode = extractOrPushError( - LanguageCode.create(source.language_code), + LanguageCode.create(raw.language_code), "language_code", errors ); const currencyCode = extractOrPushError( - CurrencyCode.create(source.currency_code), + CurrencyCode.create(raw.currency_code), "currency_code", errors ); // Textos opcionales const reference = extractOrPushError( - maybeFromNullableVO(source.reference, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.reference, (value) => Result.ok(String(value))), "reference", errors ); const description = extractOrPushError( - maybeFromNullableVO(source.description, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.description, (value) => Result.ok(String(value))), "description", errors ); const notes = extractOrPushError( - maybeFromNullableVO(source.notes, (value) => TextValue.create(value)), + maybeFromNullableResult(raw.notes, (value) => TextValue.create(value)), "notes", errors ); @@ -140,16 +138,16 @@ export class SequelizeIssuedInvoiceDomainMapper // Método de pago (VO opcional con id + descripción) let paymentMethod = Maybe.none(); - if (!isNullishOrEmpty(source.payment_method_id)) { + if (!isNullishOrEmpty(raw.payment_method_id)) { const paymentId = extractOrPushError( - UniqueID.create(String(source.payment_method_id)), + UniqueID.create(String(raw.payment_method_id)), "paymentMethod.id", errors ); const paymentVO = extractOrPushError( InvoicePaymentMethod.create( - { paymentDescription: String(source.payment_method_description ?? "") }, + { paymentDescription: String(raw.payment_method_description ?? "") }, paymentId ?? undefined ), "payment_method_description", @@ -161,13 +159,78 @@ export class SequelizeIssuedInvoiceDomainMapper } } - // % descuento (VO) - const discountPercentage = extractOrPushError( - Percentage.create({ - value: Number(source.discount_percentage_value ?? 0), - scale: Number(source.discount_percentage_scale ?? 2), + const subtotalAmount = extractOrPushError( + InvoiceAmount.create({ + value: raw.subtotal_amount_value, + currency_code: currencyCode?.code, }), - "discount_percentage_value", + "subtotal_amount_value", + errors + ); + + // Total descuento de líneas + + const itemsDiscountAmount = extractOrPushError( + InvoiceAmount.create({ + value: Number(raw.items_discount_amount_value ?? 0), + currency_code: currencyCode?.code, + }), + "items_discount_amount_value", + errors + ); + + // % descuento global (VO) + const globalDiscountPercentage = extractOrPushError( + Percentage.create({ + value: Number(raw.global_discount_percentage_value ?? 0), + scale: Number(raw.global_discount_percentage_scale ?? 2), + }), + "global_discount_percentage_value", + errors + ); + + const globalDiscountAmount = extractOrPushError( + InvoiceAmount.create({ + value: Number(raw.global_discount_amount_value ?? 0), + currency_code: currencyCode?.code, + }), + "global_discount_amount_value", + errors + ); + + const totalDiscountAmount = extractOrPushError( + InvoiceAmount.create({ + value: raw.total_discount_amount_value, + currency_code: currencyCode?.code, + }), + "total_discount_amount_value", + errors + ); + + const taxableAmount = extractOrPushError( + InvoiceAmount.create({ + value: raw.taxable_amount_value, + currency_code: currencyCode?.code, + }), + "taxable_amount_value", + errors + ); + + const taxesAmount = extractOrPushError( + InvoiceAmount.create({ + value: raw.taxes_amount_value, + currency_code: currencyCode?.code, + }), + "taxes_amount_value", + errors + ); + + const totalAmount = extractOrPushError( + InvoiceAmount.create({ + value: raw.total_amount_value, + currency_code: currencyCode?.code, + }), + "total_amount_value", errors ); @@ -187,8 +250,16 @@ export class SequelizeIssuedInvoiceDomainMapper notes, languageCode, currencyCode, - discountPercentage, paymentMethod, + + subtotalAmount, + itemsDiscountAmount, + globalDiscountPercentage, + globalDiscountAmount, + totalDiscountAmount, + taxableAmount, + taxesAmount, + totalAmount, }; } @@ -227,7 +298,18 @@ export class SequelizeIssuedInvoiceDomainMapper } ); - // 5) Si hubo errores de mapeo, devolvemos colección de validación + // 5) Taxes (colección) + const taxesResults = this._taxesMapper.mapToDomainCollection( + source.taxes, + source.taxes.length, + { + errors, + attributes, + ...params, + } + ); + + // 6) Si hubo errores de mapeo, devolvemos colección de validación if (errors.length > 0) { return Result.fail( new ValidationErrorCollection("Customer invoice mapping failed [mapToDomain]", errors) @@ -239,10 +321,17 @@ export class SequelizeIssuedInvoiceDomainMapper const items = IssuedInvoiceItems.create({ languageCode: attributes.languageCode!, currencyCode: attributes.currencyCode!, - globalDiscountPercentage: attributes.discountPercentage!, + globalDiscountPercentage: attributes.globalDiscountPercentage!, items: itemsResults.data.getAll(), }); + const taxes = IssuedInvoiceTaxes.create({ + languageCode: attributes.languageCode!, + currencyCode: attributes.currencyCode!, + globalDiscountPercentage: attributes.globalDiscountPercentage!, + taxes: taxesResults.data.getAll(), + }); + const invoiceProps: IssuedInvoiceProps = { companyId: attributes.companyId!, @@ -263,11 +352,21 @@ export class SequelizeIssuedInvoiceDomainMapper languageCode: attributes.languageCode!, currencyCode: attributes.currencyCode!, - globalDiscountPercentage: attributes.discountPercentage!, + subtotalAmount: attributes.subtotalAmount!, + + itemsDiscountAmount: attributes.itemsDiscountAmount!, + globalDiscountPercentage: attributes.globalDiscountPercentage!, + globalDiscountAmount: attributes.globalDiscountAmount!, + totalDiscountAmount: attributes.totalDiscountAmount!, + + taxableAmount: attributes.taxableAmount!, + taxesAmount: attributes.taxesAmount!, + totalAmount: attributes.totalAmount!, paymentMethod: attributes.paymentMethod!, items, + taxes: taxesResults.data, verifactu: verifactuResult.data, }; @@ -354,22 +453,25 @@ export class SequelizeIssuedInvoiceDomainMapper // Flags / estado / serie / número is_proforma: false, status: source.status.toPrimitive(), - proforma_id: toNullable(source.proformaId, (v) => v.toPrimitive()), + proforma_id: maybeToNullable(source.proformaId, (v) => v.toPrimitive()), - series: toNullable(source.series, (v) => v.toPrimitive()), + series: maybeToNullable(source.series, (v) => v.toPrimitive()), invoice_number: source.invoiceNumber.toPrimitive(), invoice_date: source.invoiceDate.toPrimitive(), - operation_date: toNullable(source.operationDate, (v) => v.toPrimitive()), + operation_date: maybeToNullable(source.operationDate, (v) => v.toPrimitive()), language_code: source.languageCode.toPrimitive(), currency_code: source.currencyCode.toPrimitive(), - reference: toNullable(source.reference, (reference) => reference), - description: toNullable(source.description, (description) => description), + reference: maybeToNullable(source.reference, (reference) => reference), + description: maybeToNullable(source.description, (description) => description), - notes: toNullable(source.notes, (v) => v.toPrimitive()), + notes: maybeToNullable(source.notes, (v) => v.toPrimitive()), - payment_method_id: toNullable(source.paymentMethod, (payment) => payment.toObjectString().id), - payment_method_description: toNullable( + payment_method_id: maybeToNullable( + source.paymentMethod, + (payment) => payment.toObjectString().id + ), + payment_method_description: maybeToNullable( source.paymentMethod, (payment) => payment.toObjectString().payment_description ), diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-item-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-item-domain.mapper.ts index 62d748d3..8caa52ad 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-item-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-item-domain.mapper.ts @@ -1,12 +1,14 @@ import type { JsonTaxCatalogProvider } from "@erp/core"; -import { type MapperParamsType, SequelizeDomainMapper, Tax } from "@erp/core/api"; +import { type MapperParamsType, SequelizeDomainMapper } from "@erp/core/api"; import { UniqueID, ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toNullable, + maybeFromNullableOrEmptyString, + maybeFromNullableResult, + maybeToNullable, + maybeToNullableString, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; @@ -17,9 +19,9 @@ import { type IssuedInvoiceProps, ItemAmount, ItemDescription, - ItemDiscount, + ItemDiscountPercentage, ItemQuantity, - ItemTaxGroup, + ItemTaxPercentage, } from "../../../../../../domain"; import type { CustomerInvoiceItemCreationAttributes, @@ -31,7 +33,7 @@ export class SequelizeIssuedInvoiceItemDomainMapper extends SequelizeDomainMappe CustomerInvoiceItemCreationAttributes, IssuedInvoiceItem > { - private _taxCatalog!: JsonTaxCatalogProvider; + private taxCatalog!: JsonTaxCatalogProvider; constructor(params: MapperParamsType) { super(); @@ -40,14 +42,14 @@ export class SequelizeIssuedInvoiceItemDomainMapper extends SequelizeDomainMappe }; if (!taxCatalog) { - throw new Error('taxCatalog not defined ("CustomerInvoiceItemDomainMapper")'); + throw new Error('taxCatalog not defined ("SequelizeIssuedInvoiceItemDomainMapper")'); } - this._taxCatalog = taxCatalog; + this.taxCatalog = taxCatalog; } private mapAttributesToDomain( - source: CustomerInvoiceItemModel, + raw: CustomerInvoiceItemModel, params?: MapperParamsType ): Partial & { itemId?: UniqueID } { const { errors, index, attributes } = params as { @@ -57,83 +59,179 @@ export class SequelizeIssuedInvoiceItemDomainMapper extends SequelizeDomainMappe }; const itemId = extractOrPushError( - UniqueID.create(source.item_id), + UniqueID.create(raw.item_id), `items[${index}].item_id`, errors ); const description = extractOrPushError( - maybeFromNullableVO(source.description, (v) => ItemDescription.create(v)), + maybeFromNullableResult(raw.description, (v) => ItemDescription.create(v)), `items[${index}].description`, errors ); const quantity = extractOrPushError( - maybeFromNullableVO(source.quantity_value, (v) => ItemQuantity.create({ value: v })), - `items[${index}].quantity`, + maybeFromNullableResult(raw.quantity_value, (v) => ItemQuantity.create({ value: v })), + `items[${index}].quantity_value`, errors ); const unitAmount = extractOrPushError( - maybeFromNullableVO(source.unit_amount_value, (value) => + maybeFromNullableResult(raw.unit_amount_value, (value) => ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) ), - `items[${index}].unit_amount`, + `items[${index}].unit_amount_value`, errors ); - const discountPercentage = extractOrPushError( - maybeFromNullableVO(source.discount_percentage_value, (v) => - ItemDiscount.create({ value: v }) + const subtotalAmount = extractOrPushError( + maybeFromNullableResult(raw.subtotal_amount_value, (value) => + ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) ), - `items[${index}].discount_percentage`, + `items[${index}].subtotal_amount_value`, + errors + ); + + const itemDiscountPercentage = extractOrPushError( + maybeFromNullableResult(raw.discount_percentage_value, (v) => + ItemDiscountPercentage.create({ value: v }) + ), + `items[${index}].discount_percentage_value`, + errors + ); + + const itemDiscountAmount = extractOrPushError( + maybeFromNullableResult(raw.discount_amount_value, (value) => + ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) + ), + `items[${index}].discount_amount_value`, errors ); const globalDiscountPercentage = extractOrPushError( - maybeFromNullableVO(source.global_discount_percentage_value, (v) => - ItemDiscount.create({ value: v }) + maybeFromNullableResult(raw.global_discount_percentage_value, (v) => + ItemDiscountPercentage.create({ value: v }) ), - `items[${index}].discount_percentage`, + `items[${index}].global_discount_percentage_value`, errors ); - const iva = extractOrPushError( - maybeFromNullableVO(source.iva_code, (code) => Tax.createFromCode(code, this._taxCatalog)), - `items[${index}].iva_code`, - errors - ); - - const rec = extractOrPushError( - maybeFromNullableVO(source.rec_code, (code) => Tax.createFromCode(code, this._taxCatalog)), - `items[${index}].rec_code`, - errors - ); - - const retention = extractOrPushError( - maybeFromNullableVO(source.retention_code, (code) => - Tax.createFromCode(code, this._taxCatalog) + const globalDiscountAmount = extractOrPushError( + maybeFromNullableResult(raw.global_discount_amount_value, (value) => + ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) ), - `items[${index}].retention_code`, + `items[${index}].global_discount_amount_value`, + errors + ); + + const totalDiscountAmount = extractOrPushError( + maybeFromNullableResult(raw.total_discount_amount_value, (value) => + ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) + ), + `items[${index}].total_discount_amount_value`, + errors + ); + + const ivaCode = maybeFromNullableOrEmptyString(raw.iva_code); + + const ivaPercentage = extractOrPushError( + maybeFromNullableResult(raw.iva_percentage_value, (value) => + ItemTaxPercentage.create({ value }) + ), + `items[${index}].iva_percentage_value`, + errors + ); + + const ivaAmount = extractOrPushError( + maybeFromNullableResult(raw.iva_amount_value, (value) => + ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) + ), + `items[${index}].iva_amount_value`, + errors + ); + + const recCode = maybeFromNullableOrEmptyString(raw.rec_code); + + const recPercentage = extractOrPushError( + maybeFromNullableResult(raw.rec_percentage_value, (value) => + ItemTaxPercentage.create({ value }) + ), + `items[${index}].rec_percentage_value`, + errors + ); + + const recAmount = extractOrPushError( + maybeFromNullableResult(raw.rec_amount_value, (value) => + ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) + ), + `items[${index}].rec_amount_value`, + errors + ); + + const retentionCode = maybeFromNullableOrEmptyString(raw.retention_code); + + const retentionPercentage = extractOrPushError( + maybeFromNullableResult(raw.retention_percentage_value, (value) => + ItemTaxPercentage.create({ value }) + ), + `items[${index}].retention_percentage_value`, + errors + ); + + const retentionAmount = extractOrPushError( + maybeFromNullableResult(raw.retention_amount_value, (value) => + ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) + ), + `items[${index}].retention_amount_value`, + errors + ); + + const taxesAmount = extractOrPushError( + maybeFromNullableResult(raw.taxes_amount_value, (value) => + ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) + ), + `items[${index}].taxes_amount_value`, + errors + ); + + const totalAmount = extractOrPushError( + maybeFromNullableResult(raw.total_amount_value, (value) => + ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) + ), + `items[${index}].total_amount_value`, errors ); return { itemId, - languageCode: attributes.languageCode, currencyCode: attributes.currencyCode, description, + quantity, unitAmount, - itemDiscountPercentage: discountPercentage, - globalDiscountPercentage, + subtotalAmount, - taxes: ItemTaxGroup.create({ - iva: iva!, - rec: rec!, - retention: retention!, - }).data, + itemDiscountPercentage, + itemDiscountAmount, + globalDiscountPercentage, + globalDiscountAmount, + totalDiscountAmount, + + ivaCode, + ivaPercentage, + ivaAmount, + + recCode, + recPercentage, + recAmount, + + retentionCode, + retentionPercentage, + retentionAmount, + + taxesAmount, + totalAmount, }; } @@ -177,15 +275,21 @@ export class SequelizeIssuedInvoiceItemDomainMapper extends SequelizeDomainMappe taxableAmount: attributes.taxableAmount!, + ivaCode: attributes.ivaCode!, + ivaPercentage: attributes.ivaPercentage!, ivaAmount: attributes.ivaAmount!, + + recCode: attributes.recCode!, + recPercentage: attributes.recPercentage!, recAmount: attributes.recAmount!, + + retentionCode: attributes.retentionCode!, + retentionPercentage: attributes.retentionPercentage!, retentionAmount: attributes.retentionAmount!, taxesAmount: attributes.taxesAmount!, totalAmount: attributes.totalAmount!, - taxes: attributes.taxes!, - languageCode: attributes.languageCode!, currencyCode: attributes.currencyCode!, }, @@ -213,47 +317,52 @@ export class SequelizeIssuedInvoiceItemDomainMapper extends SequelizeDomainMappe errors: ValidationErrorDetail[]; }; - const taxesAmounts = source.taxes; - return Result.ok({ item_id: source.id.toPrimitive(), invoice_id: parent.id.toPrimitive(), position: index, - description: toNullable(source.description, (v) => v.toPrimitive()), + description: maybeToNullable(source.description, (v) => v.toPrimitive()), - quantity_value: toNullable(source.quantity, (v) => v.toPrimitive().value), + quantity_value: maybeToNullable(source.quantity, (v) => v.toPrimitive().value), quantity_scale: - toNullable(source.quantity, (v) => v.toPrimitive().scale) ?? ItemQuantity.DEFAULT_SCALE, + maybeToNullable(source.quantity, (v) => v.toPrimitive().scale) ?? + ItemQuantity.DEFAULT_SCALE, - unit_amount_value: toNullable(source.unitAmount, (v) => v.toPrimitive().value), + unit_amount_value: maybeToNullable(source.unitAmount, (v) => v.toPrimitive().value), unit_amount_scale: - toNullable(source.unitAmount, (v) => v.toPrimitive().scale) ?? ItemAmount.DEFAULT_SCALE, + maybeToNullable(source.unitAmount, (v) => v.toPrimitive().scale) ?? + ItemAmount.DEFAULT_SCALE, - subtotal_amount_value: source.subtotalAmount.value, - subtotal_amount_scale: source.subtotalAmount.scale, + subtotal_amount_value: maybeToNullable(source.subtotalAmount, (v) => v.toPrimitive().value), + subtotal_amount_scale: + maybeToNullable(source.subtotalAmount, (v) => v.toPrimitive().scale) ?? + ItemAmount.DEFAULT_SCALE, + + // Te has quedado aquí --- IGNORE --- + // !!!!!!!!!!!!!!!!!!! // - discount_percentage_value: toNullable( + discount_percentage_value: maybeToNullable( source.itemDiscountPercentage, (v) => v.toPrimitive().value ), discount_percentage_scale: - toNullable(source.itemDiscountPercentage, (v) => v.toPrimitive().scale) ?? - ItemDiscount.DEFAULT_SCALE, + maybeToNullable(source.itemDiscountPercentage, (v) => v.toPrimitive().scale) ?? + ItemDiscountPercentage.DEFAULT_SCALE, discount_amount_value: source.itemDiscountAmount.value, discount_amount_scale: source.itemDiscountAmount.scale, // - global_discount_percentage_value: toNullable( + global_discount_percentage_value: maybeToNullable( source.globalDiscountPercentage, (v) => v.toPrimitive().value ), global_discount_percentage_scale: - toNullable(source.globalDiscountPercentage, (v) => v.toPrimitive().scale) ?? - ItemDiscount.DEFAULT_SCALE, + maybeToNullable(source.globalDiscountPercentage, (v) => v.toPrimitive().scale) ?? + ItemDiscountPercentage.DEFAULT_SCALE, global_discount_amount_value: source.globalDiscountAmount.value, global_discount_amount_scale: source.globalDiscountAmount.scale, @@ -267,32 +376,38 @@ export class SequelizeIssuedInvoiceItemDomainMapper extends SequelizeDomainMappe taxable_amount_scale: source.taxableAmount.scale, // IVA - iva_code: toNullable(source.taxes.iva, (v) => v.code), + iva_code: maybeToNullableString(source.ivaCode), - iva_percentage_value: toNullable(source.taxes.iva, (v) => v.percentage.value), - iva_percentage_scale: toNullable(source.taxes.iva, (v) => v.percentage.scale) ?? 2, + iva_percentage_value: maybeToNullable(source.ivaPercentage, (v) => v.toPrimitive().value), + iva_percentage_scale: + maybeToNullable(source.ivaPercentage, (v) => v.toPrimitive().scale) ?? 2, - iva_amount_value: taxesAmounts.ivaAmount.value, - iva_amount_scale: taxesAmounts.ivaAmount.scale, + iva_amount_value: maybeToNullable(source.ivaAmount, (v) => v.toPrimitive().value), + iva_amount_scale: maybeToNullable(source.ivaAmount, (v) => v.toPrimitive().scale) ?? 4, // REC - rec_code: toNullable(source.taxes.rec, (v) => v.code), + rec_code: maybeToNullableString(source.recCode), - rec_percentage_value: toNullable(source.taxes.rec, (v) => v.percentage.value), - rec_percentage_scale: toNullable(source.taxes.rec, (v) => v.percentage.scale) ?? 2, + rec_percentage_value: maybeToNullable(source.recPercentage, (v) => v.toPrimitive().value), + rec_percentage_scale: + maybeToNullable(source.recPercentage, (v) => v.toPrimitive().scale) ?? 2, - rec_amount_value: taxesAmounts.recAmount.value, - rec_amount_scale: taxesAmounts.recAmount.scale, + rec_amount_value: maybeToNullable(source.recAmount, (v) => v.toPrimitive().value), + rec_amount_scale: maybeToNullable(source.recAmount, (v) => v.toPrimitive().scale) ?? 4, // RET - retention_code: toNullable(source.taxes.retention, (v) => v.code), + retention_code: maybeToNullableString(source.retentionCode), - retention_percentage_value: toNullable(source.taxes.retention, (v) => v.percentage.value), + retention_percentage_value: maybeToNullable( + source.retentionPercentage, + (v) => v.toPrimitive().value + ), retention_percentage_scale: - toNullable(source.taxes.retention, (v) => v.percentage.scale) ?? 2, + maybeToNullable(source.retentionPercentage, (v) => v.toPrimitive().scale) ?? 2, - retention_amount_value: taxesAmounts.retentionAmount.value, - retention_amount_scale: taxesAmounts.retentionAmount.scale, + retention_amount_value: maybeToNullable(source.retentionAmount, (v) => v.toPrimitive().value), + retention_amount_scale: + maybeToNullable(source.retentionAmount, (v) => v.toPrimitive().scale) ?? 4, // taxes_amount_value: source.taxesAmount.value, diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-recipient-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-recipient-domain.mapper.ts index b6a1a827..9c4b1ef0 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-recipient-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-recipient-domain.mapper.ts @@ -10,8 +10,8 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toNullable, + maybeFromNullableResult, + maybeToNullable, } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; @@ -51,37 +51,37 @@ export class SequelizeIssuedInvoiceRecipientDomainMapper { const customerTin = extractOrPushError(TINNumber.create(_tin!), "customer_tin", errors); const customerStreet = extractOrPushError( - maybeFromNullableVO(_street, (value) => Street.create(value)), + maybeFromNullableResult(_street, (value) => Street.create(value)), "customer_street", errors ); const customerStreet2 = extractOrPushError( - maybeFromNullableVO(_street2, (value) => Street.create(value)), + maybeFromNullableResult(_street2, (value) => Street.create(value)), "customer_street2", errors ); const customerCity = extractOrPushError( - maybeFromNullableVO(_city, (value) => City.create(value)), + maybeFromNullableResult(_city, (value) => City.create(value)), "customer_city", errors ); const customerProvince = extractOrPushError( - maybeFromNullableVO(_province, (value) => Province.create(value)), + maybeFromNullableResult(_province, (value) => Province.create(value)), "customer_province", errors ); const customerPostalCode = extractOrPushError( - maybeFromNullableVO(_postal_code, (value) => PostalCode.create(value)), + maybeFromNullableResult(_postal_code, (value) => PostalCode.create(value)), "customer_postal_code", errors ); const customerCountry = extractOrPushError( - maybeFromNullableVO(_country, (value) => Country.create(value)), + maybeFromNullableResult(_country, (value) => Country.create(value)), "customer_country", errors ); @@ -145,12 +145,12 @@ export class SequelizeIssuedInvoiceRecipientDomainMapper { return { customer_tin: recipient.tin.toPrimitive(), customer_name: recipient.name.toPrimitive(), - customer_street: toNullable(recipient.street, (v) => v.toPrimitive()), - customer_street2: toNullable(recipient.street2, (v) => v.toPrimitive()), - customer_city: toNullable(recipient.city, (v) => v.toPrimitive()), - customer_province: toNullable(recipient.province, (v) => v.toPrimitive()), - customer_postal_code: toNullable(recipient.postalCode, (v) => v.toPrimitive()), - customer_country: toNullable(recipient.country, (v) => v.toPrimitive()), + customer_street: maybeToNullable(recipient.street, (v) => v.toPrimitive()), + customer_street2: maybeToNullable(recipient.street2, (v) => v.toPrimitive()), + customer_city: maybeToNullable(recipient.city, (v) => v.toPrimitive()), + customer_province: maybeToNullable(recipient.province, (v) => v.toPrimitive()), + customer_postal_code: maybeToNullable(recipient.postalCode, (v) => v.toPrimitive()), + customer_country: maybeToNullable(recipient.country, (v) => v.toPrimitive()), }; } } diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-taxes-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-taxes-domain.mapper.ts index 81902d27..50a5e8b5 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-taxes-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-issued-invoice-taxes-domain.mapper.ts @@ -1,8 +1,24 @@ +import type { JsonTaxCatalogProvider } from "@erp/core"; import { type MapperParamsType, SequelizeDomainMapper } from "@erp/core/api"; -import { UniqueID, type ValidationErrorDetail, toNullable } from "@repo/rdx-ddd"; +import { + UniqueID, + ValidationErrorCollection, + type ValidationErrorDetail, + extractOrPushError, + maybeFromNullableOrEmptyString, + maybeFromNullableResult, + maybeToNullable, + maybeToNullableString, +} from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; -import type { InvoiceTaxGroup, IssuedInvoice } from "../../../../../../domain"; +import { + InvoiceAmount, + InvoiceTaxPercentage, + type IssuedInvoice, + type IssuedInvoiceProps, + IssuedInvoiceTax, +} from "../../../../../../domain"; import type { CustomerInvoiceTaxCreationAttributes, CustomerInvoiceTaxModel, @@ -23,17 +39,145 @@ import type { export class SequelizeIssuedInvoiceTaxesDomainMapper extends SequelizeDomainMapper< CustomerInvoiceTaxModel, CustomerInvoiceTaxCreationAttributes, - InvoiceTaxGroup + IssuedInvoiceTax > { + private taxCatalog!: JsonTaxCatalogProvider; + + constructor(params: MapperParamsType) { + super(); + const { taxCatalog } = params as { + taxCatalog: JsonTaxCatalogProvider; + }; + + if (!taxCatalog) { + throw new Error('taxCatalog not defined ("SequelizeIssuedInvoiceTaxesDomainMapper")'); + } + + this.taxCatalog = taxCatalog; + } + public mapToDomain( source: CustomerInvoiceTaxModel, params?: MapperParamsType - ): Result { - throw new Error("Se calcula a partir de las líneas de detalle"); + ): Result { + const { errors, index, attributes } = params as { + index: number; + errors: ValidationErrorDetail[]; + attributes: Partial; + }; + + const taxableAmount = extractOrPushError( + InvoiceAmount.create({ + value: source.taxable_amount_value, + currency_code: attributes.currencyCode?.code, + }), + `taxes[${index}].taxable_amount_value`, + errors + ); + + const ivaCode = source.iva_code; + + const ivaPercentage = extractOrPushError( + InvoiceTaxPercentage.create({ + value: source.iva_percentage_value, + }), + `taxes[${index}].iva_percentage_value`, + errors + ); + + const ivaAmount = extractOrPushError( + InvoiceAmount.create({ + value: source.iva_amount_value, + currency_code: attributes.currencyCode?.code, + }), + `taxes[${index}].iva_amount_value`, + errors + ); + + const recCode = maybeFromNullableOrEmptyString(source.rec_code); + + const recPercentage = extractOrPushError( + maybeFromNullableResult(source.rec_percentage_value, (value) => + InvoiceTaxPercentage.create({ value }) + ), + `taxes[${index}].rec_percentage_value`, + errors + ); + + const recAmount = extractOrPushError( + maybeFromNullableResult(source.rec_amount_value, (value) => + InvoiceAmount.create({ value, currency_code: attributes.currencyCode?.code }) + ), + `taxes[${index}].rec_amount_value`, + errors + ); + + const retentionCode = maybeFromNullableOrEmptyString(source.retention_code); + + const retentionPercentage = extractOrPushError( + maybeFromNullableResult(source.retention_percentage_value, (value) => + InvoiceTaxPercentage.create({ value }) + ), + `taxes[${index}].retention_percentage_value`, + errors + ); + + const retentionAmount = extractOrPushError( + maybeFromNullableResult(source.retention_amount_value, (value) => + InvoiceAmount.create({ value, currency_code: attributes.currencyCode?.code }) + ), + `taxes[${index}].retention_amount_value`, + errors + ); + + const taxesAmount = extractOrPushError( + InvoiceAmount.create({ + value: source.taxes_amount_value, + currency_code: attributes.currencyCode?.code, + }), + `taxes[${index}].taxes_amount_value`, + errors + ); + + // Si hubo errores de mapeo, devolvemos colección de validación + if (errors.length > 0) { + return Result.fail( + new ValidationErrorCollection("Customer invoice tax mapping failed [mapToDomain]", errors) + ); + } + + // 2) Construcción del elemento de dominio + const createResult = IssuedInvoiceTax.create({ + taxableAmount: taxableAmount!, + + ivaCode: ivaCode!, + ivaPercentage: ivaPercentage!, + ivaAmount: ivaAmount!, + + recCode: recCode, + recPercentage: recPercentage!, + recAmount: recAmount!, + + retentionCode: retentionCode, + retentionPercentage: retentionPercentage!, + retentionAmount: retentionAmount!, + + taxesAmount: taxesAmount!, + }); + + if (createResult.isFailure) { + return Result.fail( + new ValidationErrorCollection("Invoice tax group entity creation failed", [ + { path: `taxes[${index}]`, message: "Invoice tax group entity creation failed" }, + ]) + ); + } + + return createResult; } public mapToPersistence( - source: InvoiceTaxGroup, + source: IssuedInvoiceTax, params?: MapperParamsType ): Result { const { errors, parent } = params as { @@ -42,10 +186,6 @@ export class SequelizeIssuedInvoiceTaxesDomainMapper extends SequelizeDomainMapp }; try { - const { ivaAmount, recAmount, retentionAmount } = source; - - const totalTaxes = ivaAmount.add(recAmount).add(retentionAmount); - const dto: CustomerInvoiceTaxCreationAttributes = { tax_id: UniqueID.generateNewID().toPrimitive(), invoice_id: parent.id.toPrimitive(), @@ -55,35 +195,44 @@ export class SequelizeIssuedInvoiceTaxesDomainMapper extends SequelizeDomainMapp taxable_amount_scale: source.taxableAmount.scale, // IVA - iva_code: source.iva.code, + iva_code: source.ivaCode, - iva_percentage_value: source.iva.value, - iva_percentage_scale: source.iva.scale, + iva_percentage_value: source.ivaPercentage.value, + iva_percentage_scale: source.ivaPercentage.scale, - iva_amount_value: ivaAmount.value, - iva_amount_scale: ivaAmount.scale, + iva_amount_value: source.ivaAmount.value, + iva_amount_scale: source.ivaAmount.scale, // REC - rec_code: toNullable(source.rec, (v) => v.code), + rec_code: maybeToNullableString(source.recCode), - rec_percentage_value: toNullable(source.rec, (v) => v.percentage.value), - rec_percentage_scale: toNullable(source.rec, (v) => v.percentage.scale) ?? 2, + rec_percentage_value: maybeToNullable(source.recPercentage, (v) => v.toPrimitive().value), + rec_percentage_scale: + maybeToNullable(source.recPercentage, (v) => v.toPrimitive().scale) ?? 2, - rec_amount_value: recAmount.value, - rec_amount_scale: recAmount.scale, + rec_amount_value: maybeToNullable(source.recAmount, (v) => v.toPrimitive().value), + rec_amount_scale: maybeToNullable(source.recAmount, (v) => v.toPrimitive().scale) ?? 4, // RET - retention_code: toNullable(source.retention, (v) => v.code), + retention_code: maybeToNullableString(source.retentionCode), - retention_percentage_value: toNullable(source.retention, (v) => v.percentage.value), - retention_percentage_scale: toNullable(source.retention, (v) => v.percentage.scale) ?? 2, + retention_percentage_value: maybeToNullable( + source.retentionPercentage, + (v) => v.toPrimitive().value + ), + retention_percentage_scale: + maybeToNullable(source.retentionPercentage, (v) => v.toPrimitive().scale) ?? 2, - retention_amount_value: retentionAmount.value, - retention_amount_scale: retentionAmount.scale, + retention_amount_value: maybeToNullable( + source.retentionAmount, + (v) => v.toPrimitive().value + ), + retention_amount_scale: + maybeToNullable(source.retentionAmount, (v) => v.toPrimitive().scale) ?? 4, // TOTAL - taxes_amount_value: totalTaxes.value, - taxes_amount_scale: totalTaxes.scale, + taxes_amount_value: source.taxesAmount.value, + taxes_amount_scale: source.taxesAmount.scale, }; return Result.ok(dto); diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-verifactu-record-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-verifactu-record-domain.mapper.ts index 838ba69f..d76b9deb 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-verifactu-record-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/domain/sequelize-verifactu-record-domain.mapper.ts @@ -6,8 +6,8 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toEmptyString, + maybeFromNullableResult, + maybeToEmptyString, } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; @@ -48,25 +48,25 @@ export class SequelizeIssuedInvoiceVerifactuDomainMapper extends SequelizeDomain ); const qr = extractOrPushError( - maybeFromNullableVO(source.qr, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.qr, (value) => Result.ok(String(value))), "qr", errors ); const url = extractOrPushError( - maybeFromNullableVO(source.url, (value) => URLAddress.create(value)), + maybeFromNullableResult(source.url, (value) => URLAddress.create(value)), "url", errors ); const uuid = extractOrPushError( - maybeFromNullableVO(source.uuid, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.uuid, (value) => Result.ok(String(value))), "uuid", errors ); const operacion = extractOrPushError( - maybeFromNullableVO(source.operacion, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.operacion, (value) => Result.ok(String(value))), "operacion", errors ); @@ -126,10 +126,10 @@ export class SequelizeIssuedInvoiceVerifactuDomainMapper extends SequelizeDomain id: verifactu.id.toPrimitive(), invoice_id: parent.id.toPrimitive(), estado: verifactu.estado.toPrimitive(), - qr: toEmptyString(verifactu.qrCode, (v) => v), - url: toEmptyString(verifactu.url, (v) => v.toPrimitive()), - uuid: toEmptyString(verifactu.uuid, (v) => v), - operacion: toEmptyString(verifactu.operacion, (v) => v), + qr: maybeToEmptyString(verifactu.qrCode, (v) => v), + url: maybeToEmptyString(verifactu.url, (v) => v.toPrimitive()), + uuid: maybeToEmptyString(verifactu.uuid, (v) => v), + operacion: maybeToEmptyString(verifactu.operacion, (v) => v), }); } } diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice-recipient.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice-recipient.list.mapper.ts index 1451fed8..47e0d596 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice-recipient.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice-recipient.list.mapper.ts @@ -10,7 +10,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; @@ -59,37 +59,37 @@ export class SequelizeIssuedInvoiceRecipientListMapper extends SequelizeQueryMap const customerTin = extractOrPushError(TINNumber.create(_tin!), "customer_tin", errors); const customerStreet = extractOrPushError( - maybeFromNullableVO(_street, (value) => Street.create(value)), + maybeFromNullableResult(_street, (value) => Street.create(value)), "customer_street", errors ); const customerStreet2 = extractOrPushError( - maybeFromNullableVO(_street2, (value) => Street.create(value)), + maybeFromNullableResult(_street2, (value) => Street.create(value)), "customer_street2", errors ); const customerCity = extractOrPushError( - maybeFromNullableVO(_city, (value) => City.create(value)), + maybeFromNullableResult(_city, (value) => City.create(value)), "customer_city", errors ); const customerProvince = extractOrPushError( - maybeFromNullableVO(_province, (value) => Province.create(value)), + maybeFromNullableResult(_province, (value) => Province.create(value)), "customer_province", errors ); const customerPostalCode = extractOrPushError( - maybeFromNullableVO(_postal_code, (value) => PostalCode.create(value)), + maybeFromNullableResult(_postal_code, (value) => PostalCode.create(value)), "customer_postal_code", errors ); const customerCountry = extractOrPushError( - maybeFromNullableVO(_country, (value) => Country.create(value)), + maybeFromNullableResult(_country, (value) => Country.create(value)), "customer_country", errors ); diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice.list.mapper.ts index 112257bf..60d011ac 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-issued-invoice.list.mapper.ts @@ -7,7 +7,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; @@ -126,7 +126,7 @@ export class SequelizeIssuedInvoiceListMapper const status = extractOrPushError(InvoiceStatus.create(raw.status), "status", errors); const series = extractOrPushError( - maybeFromNullableVO(raw.series, (value) => InvoiceSerie.create(value)), + maybeFromNullableResult(raw.series, (value) => InvoiceSerie.create(value)), "serie", errors ); @@ -144,19 +144,19 @@ export class SequelizeIssuedInvoiceListMapper ); const operationDate = extractOrPushError( - maybeFromNullableVO(raw.operation_date, (value) => UtcDate.createFromISO(value)), + maybeFromNullableResult(raw.operation_date, (value) => UtcDate.createFromISO(value)), "operation_date", errors ); const reference = extractOrPushError( - maybeFromNullableVO(raw.reference, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.reference, (value) => Result.ok(String(value))), "description", errors ); const description = extractOrPushError( - maybeFromNullableVO(raw.description, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.description, (value) => Result.ok(String(value))), "description", errors ); diff --git a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-verifactu-record.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-verifactu-record.list.mapper.ts index 32a7c6c3..e0e492a5 100644 --- a/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-verifactu-record.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/issued-invoices/persistence/sequelize/mappers/list/sequelize-verifactu-record.list.mapper.ts @@ -5,7 +5,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; @@ -26,25 +26,25 @@ export class SequelizeVerifactuRecordListMapper extends SequelizeQueryMapper< const estado = extractOrPushError(VerifactuRecordEstado.create(raw.estado), "estado", errors); const qr = extractOrPushError( - maybeFromNullableVO(raw.qr, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.qr, (value) => Result.ok(String(value))), "qr", errors ); const url = extractOrPushError( - maybeFromNullableVO(raw.url, (value) => URLAddress.create(value)), + maybeFromNullableResult(raw.url, (value) => URLAddress.create(value)), "url", errors ); const uuid = extractOrPushError( - maybeFromNullableVO(raw.uuid, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.uuid, (value) => Result.ok(String(value))), "uuid", errors ); const operacion = extractOrPushError( - maybeFromNullableVO(raw.operacion, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.operacion, (value) => Result.ok(String(value))), "operacion", errors ); diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-domain.mapper.ts index fa2bfb79..000b8120 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-domain.mapper.ts @@ -9,8 +9,8 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toNullable, + maybeFromNullableResult, + maybeToNullable, } from "@repo/rdx-ddd"; import { Maybe, Result, isNullishOrEmpty } from "@repo/rdx-utils"; @@ -66,7 +66,7 @@ export class SequelizeProformaDomainMapper const isProforma = Boolean(source.is_proforma); const proformaId = extractOrPushError( - maybeFromNullableVO(source.proforma_id, (v) => UniqueID.create(v)), + maybeFromNullableResult(source.proforma_id, (v) => UniqueID.create(v)), "proforma_id", errors ); @@ -74,7 +74,7 @@ export class SequelizeProformaDomainMapper const status = extractOrPushError(InvoiceStatus.create(source.status), "status", errors); const series = extractOrPushError( - maybeFromNullableVO(source.series, (v) => InvoiceSerie.create(v)), + maybeFromNullableResult(source.series, (v) => InvoiceSerie.create(v)), "series", errors ); @@ -93,7 +93,7 @@ export class SequelizeProformaDomainMapper ); const operationDate = extractOrPushError( - maybeFromNullableVO(source.operation_date, (v) => UtcDate.createFromISO(v)), + maybeFromNullableResult(source.operation_date, (v) => UtcDate.createFromISO(v)), "operation_date", errors ); @@ -113,19 +113,19 @@ export class SequelizeProformaDomainMapper // Textos opcionales const reference = extractOrPushError( - maybeFromNullableVO(source.reference, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.reference, (value) => Result.ok(String(value))), "reference", errors ); const description = extractOrPushError( - maybeFromNullableVO(source.description, (value) => Result.ok(String(value))), + maybeFromNullableResult(source.description, (value) => Result.ok(String(value))), "description", errors ); const notes = extractOrPushError( - maybeFromNullableVO(source.notes, (value) => TextValue.create(value)), + maybeFromNullableResult(source.notes, (value) => TextValue.create(value)), "notes", errors ); @@ -333,17 +333,17 @@ export class SequelizeProformaDomainMapper // Flags / estado / serie / número is_proforma: source.isProforma, status: source.status.toPrimitive(), - series: toNullable(source.series, (v) => v.toPrimitive()), + series: maybeToNullable(source.series, (v) => v.toPrimitive()), invoice_number: source.invoiceNumber.toPrimitive(), invoice_date: source.invoiceDate.toPrimitive(), - operation_date: toNullable(source.operationDate, (v) => v.toPrimitive()), + operation_date: maybeToNullable(source.operationDate, (v) => v.toPrimitive()), language_code: source.languageCode.toPrimitive(), currency_code: source.currencyCode.toPrimitive(), - reference: toNullable(source.reference, (reference) => reference), - description: toNullable(source.description, (description) => description), - notes: toNullable(source.notes, (v) => v.toPrimitive()), + reference: maybeToNullable(source.reference, (reference) => reference), + description: maybeToNullable(source.description, (description) => description), + notes: maybeToNullable(source.notes, (v) => v.toPrimitive()), subtotal_amount_value: allAmounts.subtotalAmount.value, subtotal_amount_scale: allAmounts.subtotalAmount.scale, @@ -369,8 +369,11 @@ export class SequelizeProformaDomainMapper total_amount_value: allAmounts.totalAmount.value, total_amount_scale: allAmounts.totalAmount.scale, - payment_method_id: toNullable(source.paymentMethod, (payment) => payment.toObjectString().id), - payment_method_description: toNullable( + payment_method_id: maybeToNullable( + source.paymentMethod, + (payment) => payment.toObjectString().id + ), + payment_method_description: maybeToNullable( source.paymentMethod, (payment) => payment.toObjectString().payment_description ), diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-item-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-item-domain.mapper.ts index 9bff6dc3..3cd132c8 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-item-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-item-domain.mapper.ts @@ -5,15 +5,15 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, - toNullable, + maybeFromNullableResult, + maybeToNullable, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { ItemAmount, ItemDescription, - ItemDiscount, + ItemDiscountPercentage, ItemQuantity, ItemTaxGroup, type Proforma, @@ -63,19 +63,19 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper< ); const description = extractOrPushError( - maybeFromNullableVO(source.description, (v) => ItemDescription.create(v)), + maybeFromNullableResult(source.description, (v) => ItemDescription.create(v)), `items[${index}].description`, errors ); const quantity = extractOrPushError( - maybeFromNullableVO(source.quantity_value, (v) => ItemQuantity.create({ value: v })), + maybeFromNullableResult(source.quantity_value, (v) => ItemQuantity.create({ value: v })), `items[${index}].quantity`, errors ); const unitAmount = extractOrPushError( - maybeFromNullableVO(source.unit_amount_value, (value) => + maybeFromNullableResult(source.unit_amount_value, (value) => ItemAmount.create({ value, currency_code: attributes.currencyCode?.code }) ), `items[${index}].unit_amount`, @@ -83,35 +83,39 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper< ); const discountPercentage = extractOrPushError( - maybeFromNullableVO(source.discount_percentage_value, (v) => - ItemDiscount.create({ value: v }) + maybeFromNullableResult(source.discount_percentage_value, (v) => + ItemDiscountPercentage.create({ value: v }) ), `items[${index}].discount_percentage`, errors ); const globalDiscountPercentage = extractOrPushError( - maybeFromNullableVO(source.global_discount_percentage_value, (v) => - ItemDiscount.create({ value: v }) + maybeFromNullableResult(source.global_discount_percentage_value, (v) => + ItemDiscountPercentage.create({ value: v }) ), `items[${index}].discount_percentage`, errors ); const iva = extractOrPushError( - maybeFromNullableVO(source.iva_code, (code) => Tax.createFromCode(code, this._taxCatalog)), + maybeFromNullableResult(source.iva_code, (code) => + Tax.createFromCode(code, this._taxCatalog) + ), `items[${index}].iva_code`, errors ); const rec = extractOrPushError( - maybeFromNullableVO(source.rec_code, (code) => Tax.createFromCode(code, this._taxCatalog)), + maybeFromNullableResult(source.rec_code, (code) => + Tax.createFromCode(code, this._taxCatalog) + ), `items[${index}].rec_code`, errors ); const retention = extractOrPushError( - maybeFromNullableVO(source.retention_code, (code) => + maybeFromNullableResult(source.retention_code, (code) => Tax.createFromCode(code, this._taxCatalog) ), `items[${index}].retention_code`, @@ -201,40 +205,42 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper< invoice_id: parent.id.toPrimitive(), position: index, - description: toNullable(source.description, (v) => v.toPrimitive()), + description: maybeToNullable(source.description, (v) => v.toPrimitive()), - quantity_value: toNullable(source.quantity, (v) => v.toPrimitive().value), + quantity_value: maybeToNullable(source.quantity, (v) => v.toPrimitive().value), quantity_scale: - toNullable(source.quantity, (v) => v.toPrimitive().scale) ?? ItemQuantity.DEFAULT_SCALE, + maybeToNullable(source.quantity, (v) => v.toPrimitive().scale) ?? + ItemQuantity.DEFAULT_SCALE, - unit_amount_value: toNullable(source.unitAmount, (v) => v.toPrimitive().value), + unit_amount_value: maybeToNullable(source.unitAmount, (v) => v.toPrimitive().value), unit_amount_scale: - toNullable(source.unitAmount, (v) => v.toPrimitive().scale) ?? ItemAmount.DEFAULT_SCALE, + maybeToNullable(source.unitAmount, (v) => v.toPrimitive().scale) ?? + ItemAmount.DEFAULT_SCALE, subtotal_amount_value: allAmounts.subtotalAmount.value, subtotal_amount_scale: allAmounts.subtotalAmount.scale, // - discount_percentage_value: toNullable( + discount_percentage_value: maybeToNullable( source.itemDiscountPercentage, (v) => v.toPrimitive().value ), discount_percentage_scale: - toNullable(source.itemDiscountPercentage, (v) => v.toPrimitive().scale) ?? - ItemDiscount.DEFAULT_SCALE, + maybeToNullable(source.itemDiscountPercentage, (v) => v.toPrimitive().scale) ?? + ItemDiscountPercentage.DEFAULT_SCALE, discount_amount_value: allAmounts.itemDiscountAmount.value, discount_amount_scale: allAmounts.itemDiscountAmount.scale, // - global_discount_percentage_value: toNullable( + global_discount_percentage_value: maybeToNullable( source.globalDiscountPercentage, (v) => v.toPrimitive().value ), global_discount_percentage_scale: - toNullable(source.globalDiscountPercentage, (v) => v.toPrimitive().scale) ?? - ItemDiscount.DEFAULT_SCALE, + maybeToNullable(source.globalDiscountPercentage, (v) => v.toPrimitive().scale) ?? + ItemDiscountPercentage.DEFAULT_SCALE, global_discount_amount_value: allAmounts.globalDiscountAmount.value, global_discount_amount_scale: allAmounts.globalDiscountAmount.scale, @@ -248,29 +254,32 @@ export class SequelizeProformaItemDomainMapper extends SequelizeDomainMapper< taxable_amount_scale: allAmounts.taxableAmount.scale, // IVA - iva_code: toNullable(source.taxes.iva, (v) => v.code), + iva_code: maybeToNullable(source.taxes.iva, (v) => v.code), - iva_percentage_value: toNullable(source.taxes.iva, (v) => v.percentage.value), - iva_percentage_scale: toNullable(source.taxes.iva, (v) => v.percentage.scale) ?? 2, + iva_percentage_value: maybeToNullable(source.taxes.iva, (v) => v.percentage.value), + iva_percentage_scale: maybeToNullable(source.taxes.iva, (v) => v.percentage.scale) ?? 2, iva_amount_value: taxesAmounts.ivaAmount.value, iva_amount_scale: taxesAmounts.ivaAmount.scale, // REC - rec_code: toNullable(source.taxes.rec, (v) => v.code), + rec_code: maybeToNullable(source.taxes.rec, (v) => v.code), - rec_percentage_value: toNullable(source.taxes.rec, (v) => v.percentage.value), - rec_percentage_scale: toNullable(source.taxes.rec, (v) => v.percentage.scale) ?? 2, + rec_percentage_value: maybeToNullable(source.taxes.rec, (v) => v.percentage.value), + rec_percentage_scale: maybeToNullable(source.taxes.rec, (v) => v.percentage.scale) ?? 2, rec_amount_value: taxesAmounts.recAmount.value, rec_amount_scale: taxesAmounts.recAmount.scale, // RET - retention_code: toNullable(source.taxes.retention, (v) => v.code), + retention_code: maybeToNullable(source.taxes.retention, (v) => v.code), - retention_percentage_value: toNullable(source.taxes.retention, (v) => v.percentage.value), + retention_percentage_value: maybeToNullable( + source.taxes.retention, + (v) => v.percentage.value + ), retention_percentage_scale: - toNullable(source.taxes.retention, (v) => v.percentage.scale) ?? 2, + maybeToNullable(source.taxes.retention, (v) => v.percentage.scale) ?? 2, retention_amount_value: taxesAmounts.retentionAmount.value, retention_amount_scale: taxesAmounts.retentionAmount.scale, diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-recipient-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-recipient-domain.mapper.ts index 877793ab..10dafda4 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-recipient-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-recipient-domain.mapper.ts @@ -10,7 +10,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; @@ -55,37 +55,37 @@ export class SequelizeProformaRecipientDomainMapper { const customerTin = extractOrPushError(TINNumber.create(_tin!), "customer_tin", errors); const customerStreet = extractOrPushError( - maybeFromNullableVO(_street, (value) => Street.create(value)), + maybeFromNullableResult(_street, (value) => Street.create(value)), "customer_street", errors ); const customerStreet2 = extractOrPushError( - maybeFromNullableVO(_street2, (value) => Street.create(value)), + maybeFromNullableResult(_street2, (value) => Street.create(value)), "customer_street2", errors ); const customerCity = extractOrPushError( - maybeFromNullableVO(_city, (value) => City.create(value)), + maybeFromNullableResult(_city, (value) => City.create(value)), "customer_city", errors ); const customerProvince = extractOrPushError( - maybeFromNullableVO(_province, (value) => Province.create(value)), + maybeFromNullableResult(_province, (value) => Province.create(value)), "customer_province", errors ); const customerPostalCode = extractOrPushError( - maybeFromNullableVO(_postal_code, (value) => PostalCode.create(value)), + maybeFromNullableResult(_postal_code, (value) => PostalCode.create(value)), "customer_postal_code", errors ); const customerCountry = extractOrPushError( - maybeFromNullableVO(_country, (value) => Country.create(value)), + maybeFromNullableResult(_country, (value) => Country.create(value)), "customer_country", errors ); diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-taxes-domain.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-taxes-domain.mapper.ts index 52ddaec7..e0d3b647 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-taxes-domain.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/domain/sequelize-proforma-taxes-domain.mapper.ts @@ -1,5 +1,5 @@ import { type MapperParamsType, SequelizeDomainMapper } from "@erp/core/api"; -import { UniqueID, type ValidationErrorDetail, toNullable } from "@repo/rdx-ddd"; +import { UniqueID, type ValidationErrorDetail, maybeToNullable } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import type { InvoiceTaxGroup, Proforma } from "../../../../../../domain"; @@ -64,19 +64,20 @@ export class SequelizeProformaTaxesDomainMapper extends SequelizeDomainMapper< iva_amount_scale: ivaAmount.scale, // REC - rec_code: toNullable(source.rec, (v) => v.code), + rec_code: maybeToNullable(source.rec, (v) => v.code), - rec_percentage_value: toNullable(source.rec, (v) => v.percentage.value), - rec_percentage_scale: toNullable(source.rec, (v) => v.percentage.scale) ?? 2, + rec_percentage_value: maybeToNullable(source.rec, (v) => v.percentage.value), + rec_percentage_scale: maybeToNullable(source.rec, (v) => v.percentage.scale) ?? 2, rec_amount_value: recAmount.value, rec_amount_scale: recAmount.scale, // RET - retention_code: toNullable(source.retention, (v) => v.code), + retention_code: maybeToNullable(source.retention, (v) => v.code), - retention_percentage_value: toNullable(source.retention, (v) => v.percentage.value), - retention_percentage_scale: toNullable(source.retention, (v) => v.percentage.scale) ?? 2, + retention_percentage_value: maybeToNullable(source.retention, (v) => v.percentage.value), + retention_percentage_scale: + maybeToNullable(source.retention, (v) => v.percentage.scale) ?? 2, retention_amount_value: retentionAmount.value, retention_amount_scale: retentionAmount.scale, diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/list/sequelize-proforma-recipient.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/list/sequelize-proforma-recipient.list.mapper.ts index 488d90f5..25980b91 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/list/sequelize-proforma-recipient.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/list/sequelize-proforma-recipient.list.mapper.ts @@ -14,7 +14,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; @@ -65,37 +65,37 @@ export class SequelizeInvoiceRecipientListMapper const customerTin = extractOrPushError(TINNumber.create(_tin!), "customer_tin", errors); const customerStreet = extractOrPushError( - maybeFromNullableVO(_street, (value) => Street.create(value)), + maybeFromNullableResult(_street, (value) => Street.create(value)), "customer_street", errors ); const customerStreet2 = extractOrPushError( - maybeFromNullableVO(_street2, (value) => Street.create(value)), + maybeFromNullableResult(_street2, (value) => Street.create(value)), "customer_street2", errors ); const customerCity = extractOrPushError( - maybeFromNullableVO(_city, (value) => City.create(value)), + maybeFromNullableResult(_city, (value) => City.create(value)), "customer_city", errors ); const customerProvince = extractOrPushError( - maybeFromNullableVO(_province, (value) => Province.create(value)), + maybeFromNullableResult(_province, (value) => Province.create(value)), "customer_province", errors ); const customerPostalCode = extractOrPushError( - maybeFromNullableVO(_postal_code, (value) => PostalCode.create(value)), + maybeFromNullableResult(_postal_code, (value) => PostalCode.create(value)), "customer_postal_code", errors ); const customerCountry = extractOrPushError( - maybeFromNullableVO(_country, (value) => Country.create(value)), + maybeFromNullableResult(_country, (value) => Country.create(value)), "customer_country", errors ); diff --git a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/list/sequelize-proforma.list.mapper.ts b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/list/sequelize-proforma.list.mapper.ts index a311a661..ba7a6814 100644 --- a/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/list/sequelize-proforma.list.mapper.ts +++ b/modules/customer-invoices/src/api/infrastructure/proformas/persistence/sequelize/mappers/list/sequelize-proforma.list.mapper.ts @@ -7,7 +7,7 @@ import { ValidationErrorCollection, type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; @@ -105,7 +105,7 @@ export class SequelizeProformaListMapper const status = extractOrPushError(InvoiceStatus.create(raw.status), "status", errors); const series = extractOrPushError( - maybeFromNullableVO(raw.series, (value) => InvoiceSerie.create(value)), + maybeFromNullableResult(raw.series, (value) => InvoiceSerie.create(value)), "serie", errors ); @@ -123,19 +123,19 @@ export class SequelizeProformaListMapper ); const operationDate = extractOrPushError( - maybeFromNullableVO(raw.operation_date, (value) => UtcDate.createFromISO(value)), + maybeFromNullableResult(raw.operation_date, (value) => UtcDate.createFromISO(value)), "operation_date", errors ); const reference = extractOrPushError( - maybeFromNullableVO(raw.reference, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.reference, (value) => Result.ok(String(value))), "description", errors ); const description = extractOrPushError( - maybeFromNullableVO(raw.description, (value) => Result.ok(String(value))), + maybeFromNullableResult(raw.description, (value) => Result.ok(String(value))), "description", errors ); diff --git a/modules/customers/src/api/application/presenters/domain/customer.full.presenter.ts b/modules/customers/src/api/application/presenters/domain/customer.full.presenter.ts index c2598f85..0bbebc8c 100644 --- a/modules/customers/src/api/application/presenters/domain/customer.full.presenter.ts +++ b/modules/customers/src/api/application/presenters/domain/customer.full.presenter.ts @@ -1,5 +1,5 @@ import { Presenter } from "@erp/core/api"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { GetCustomerByIdResponseDTO } from "../../../../common/dto"; import type { Customer } from "../../../domain"; @@ -12,33 +12,35 @@ export class CustomerFullPresenter extends Presenter value.toPrimitive()), + reference: maybeToEmptyString(customer.reference, (value) => value.toPrimitive()), is_company: String(customer.isCompany), name: customer.name.toPrimitive(), - trade_name: toEmptyString(customer.tradeName, (value) => value.toPrimitive()), + trade_name: maybeToEmptyString(customer.tradeName, (value) => value.toPrimitive()), - tin: toEmptyString(customer.tin, (value) => value.toPrimitive()), + tin: maybeToEmptyString(customer.tin, (value) => value.toPrimitive()), - street: toEmptyString(address.street, (value) => value.toPrimitive()), - street2: toEmptyString(address.street2, (value) => value.toPrimitive()), - city: toEmptyString(address.city, (value) => value.toPrimitive()), - province: toEmptyString(address.province, (value) => value.toPrimitive()), - postal_code: toEmptyString(address.postalCode, (value) => value.toPrimitive()), - country: toEmptyString(address.country, (value) => value.toPrimitive()), + street: maybeToEmptyString(address.street, (value) => value.toPrimitive()), + street2: maybeToEmptyString(address.street2, (value) => value.toPrimitive()), + city: maybeToEmptyString(address.city, (value) => value.toPrimitive()), + province: maybeToEmptyString(address.province, (value) => value.toPrimitive()), + postal_code: maybeToEmptyString(address.postalCode, (value) => value.toPrimitive()), + country: maybeToEmptyString(address.country, (value) => value.toPrimitive()), - email_primary: toEmptyString(customer.emailPrimary, (value) => value.toPrimitive()), - email_secondary: toEmptyString(customer.emailSecondary, (value) => value.toPrimitive()), - phone_primary: toEmptyString(customer.phonePrimary, (value) => value.toPrimitive()), - phone_secondary: toEmptyString(customer.phoneSecondary, (value) => value.toPrimitive()), - mobile_primary: toEmptyString(customer.mobilePrimary, (value) => value.toPrimitive()), - mobile_secondary: toEmptyString(customer.mobileSecondary, (value) => value.toPrimitive()), + email_primary: maybeToEmptyString(customer.emailPrimary, (value) => value.toPrimitive()), + email_secondary: maybeToEmptyString(customer.emailSecondary, (value) => value.toPrimitive()), + phone_primary: maybeToEmptyString(customer.phonePrimary, (value) => value.toPrimitive()), + phone_secondary: maybeToEmptyString(customer.phoneSecondary, (value) => value.toPrimitive()), + mobile_primary: maybeToEmptyString(customer.mobilePrimary, (value) => value.toPrimitive()), + mobile_secondary: maybeToEmptyString(customer.mobileSecondary, (value) => + value.toPrimitive() + ), - fax: toEmptyString(customer.fax, (value) => value.toPrimitive()), - website: toEmptyString(customer.website, (value) => value.toPrimitive()), + fax: maybeToEmptyString(customer.fax, (value) => value.toPrimitive()), + website: maybeToEmptyString(customer.website, (value) => value.toPrimitive()), - legal_record: toEmptyString(customer.legalRecord, (value) => value.toPrimitive()), + legal_record: maybeToEmptyString(customer.legalRecord, (value) => value.toPrimitive()), default_taxes: customer.defaultTaxes.getAll().map((tax) => tax.toString()), diff --git a/modules/customers/src/api/application/presenters/queries/list-customers.presenter.ts b/modules/customers/src/api/application/presenters/queries/list-customers.presenter.ts index 6ead151e..e62a0795 100644 --- a/modules/customers/src/api/application/presenters/queries/list-customers.presenter.ts +++ b/modules/customers/src/api/application/presenters/queries/list-customers.presenter.ts @@ -1,7 +1,7 @@ import type { CriteriaDTO } from "@erp/core"; import { Presenter } from "@erp/core/api"; import type { Criteria } from "@repo/rdx-criteria/server"; -import { toEmptyString } from "@repo/rdx-ddd"; +import { maybeToEmptyString } from "@repo/rdx-ddd"; import type { Collection } from "@repo/rdx-utils"; import type { ListCustomersResponseDTO } from "../../../../common/dto"; @@ -15,31 +15,33 @@ export class ListCustomersPresenter extends Presenter { id: customer.id.toPrimitive(), company_id: customer.companyId.toPrimitive(), - reference: toEmptyString(customer.reference, (value) => value.toPrimitive()), + reference: maybeToEmptyString(customer.reference, (value) => value.toPrimitive()), is_company: String(customer.isCompany), name: customer.name.toPrimitive(), - trade_name: toEmptyString(customer.tradeName, (value) => value.toPrimitive()), + trade_name: maybeToEmptyString(customer.tradeName, (value) => value.toPrimitive()), - tin: toEmptyString(customer.tin, (value) => value.toPrimitive()), + tin: maybeToEmptyString(customer.tin, (value) => value.toPrimitive()), - street: toEmptyString(address.street, (value) => value.toPrimitive()), - street2: toEmptyString(address.street2, (value) => value.toPrimitive()), - city: toEmptyString(address.city, (value) => value.toPrimitive()), - province: toEmptyString(address.province, (value) => value.toPrimitive()), - postal_code: toEmptyString(address.postalCode, (value) => value.toPrimitive()), - country: toEmptyString(address.country, (value) => value.toPrimitive()), + street: maybeToEmptyString(address.street, (value) => value.toPrimitive()), + street2: maybeToEmptyString(address.street2, (value) => value.toPrimitive()), + city: maybeToEmptyString(address.city, (value) => value.toPrimitive()), + province: maybeToEmptyString(address.province, (value) => value.toPrimitive()), + postal_code: maybeToEmptyString(address.postalCode, (value) => value.toPrimitive()), + country: maybeToEmptyString(address.country, (value) => value.toPrimitive()), - email_primary: toEmptyString(customer.emailPrimary, (value) => value.toPrimitive()), - email_secondary: toEmptyString(customer.emailSecondary, (value) => value.toPrimitive()), - phone_primary: toEmptyString(customer.phonePrimary, (value) => value.toPrimitive()), - phone_secondary: toEmptyString(customer.phoneSecondary, (value) => value.toPrimitive()), - mobile_primary: toEmptyString(customer.mobilePrimary, (value) => value.toPrimitive()), - mobile_secondary: toEmptyString(customer.mobileSecondary, (value) => value.toPrimitive()), + email_primary: maybeToEmptyString(customer.emailPrimary, (value) => value.toPrimitive()), + email_secondary: maybeToEmptyString(customer.emailSecondary, (value) => value.toPrimitive()), + phone_primary: maybeToEmptyString(customer.phonePrimary, (value) => value.toPrimitive()), + phone_secondary: maybeToEmptyString(customer.phoneSecondary, (value) => value.toPrimitive()), + mobile_primary: maybeToEmptyString(customer.mobilePrimary, (value) => value.toPrimitive()), + mobile_secondary: maybeToEmptyString(customer.mobileSecondary, (value) => + value.toPrimitive() + ), - fax: toEmptyString(customer.fax, (value) => value.toPrimitive()), - website: toEmptyString(customer.website, (value) => value.toPrimitive()), + fax: maybeToEmptyString(customer.fax, (value) => value.toPrimitive()), + website: maybeToEmptyString(customer.website, (value) => value.toPrimitive()), status: customer.status ? "active" : "inactive", language_code: customer.languageCode.toPrimitive(), diff --git a/modules/customers/src/api/application/use-cases/create/map-dto-to-create-customer-props.ts b/modules/customers/src/api/application/use-cases/create/map-dto-to-create-customer-props.ts index 98f476c2..6a4b72ec 100644 --- a/modules/customers/src/api/application/use-cases/create/map-dto-to-create-customer-props.ts +++ b/modules/customers/src/api/application/use-cases/create/map-dto-to-create-customer-props.ts @@ -17,13 +17,14 @@ import { URLAddress, UniqueID, ValidationErrorCollection, - ValidationErrorDetail, + type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Collection, Result, isNullishOrEmpty } from "@repo/rdx-utils"; -import { CreateCustomerRequestDTO } from "../../../../common"; -import { CustomerProps, CustomerStatus } from "../../../domain"; + +import type { CreateCustomerRequestDTO } from "../../../../common"; +import { type CustomerProps, CustomerStatus } from "../../../domain"; /** * Convierte el DTO a las props validadas (CustomerProps). @@ -45,7 +46,7 @@ export function mapDTOToCreateCustomerProps(dto: CreateCustomerRequestDTO) { const isCompany = dto.is_company === "true"; const reference = extractOrPushError( - maybeFromNullableVO(dto.reference, (value) => Name.create(value)), + maybeFromNullableResult(dto.reference, (value) => Name.create(value)), "reference", errors ); @@ -53,103 +54,103 @@ export function mapDTOToCreateCustomerProps(dto: CreateCustomerRequestDTO) { const name = extractOrPushError(Name.create(dto.name), "name", errors); const tradeName = extractOrPushError( - maybeFromNullableVO(dto.trade_name, (value) => Name.create(value)), + maybeFromNullableResult(dto.trade_name, (value) => Name.create(value)), "trade_name", errors ); const tinNumber = extractOrPushError( - maybeFromNullableVO(dto.tin, (value) => TINNumber.create(value)), + maybeFromNullableResult(dto.tin, (value) => TINNumber.create(value)), "tin", errors ); const street = extractOrPushError( - maybeFromNullableVO(dto.street, (value) => Street.create(value)), + maybeFromNullableResult(dto.street, (value) => Street.create(value)), "street", errors ); const street2 = extractOrPushError( - maybeFromNullableVO(dto.street2, (value) => Street.create(value)), + maybeFromNullableResult(dto.street2, (value) => Street.create(value)), "street2", errors ); const city = extractOrPushError( - maybeFromNullableVO(dto.city, (value) => City.create(value)), + maybeFromNullableResult(dto.city, (value) => City.create(value)), "city", errors ); const province = extractOrPushError( - maybeFromNullableVO(dto.province, (value) => Province.create(value)), + maybeFromNullableResult(dto.province, (value) => Province.create(value)), "province", errors ); const postalCode = extractOrPushError( - maybeFromNullableVO(dto.postal_code, (value) => PostalCode.create(value)), + maybeFromNullableResult(dto.postal_code, (value) => PostalCode.create(value)), "postal_code", errors ); const country = extractOrPushError( - maybeFromNullableVO(dto.country, (value) => Country.create(value)), + maybeFromNullableResult(dto.country, (value) => Country.create(value)), "country", errors ); const primaryEmailAddress = extractOrPushError( - maybeFromNullableVO(dto.email_primary, (value) => EmailAddress.create(value)), + maybeFromNullableResult(dto.email_primary, (value) => EmailAddress.create(value)), "email_primary", errors ); const secondaryEmailAddress = extractOrPushError( - maybeFromNullableVO(dto.email_secondary, (value) => EmailAddress.create(value)), + maybeFromNullableResult(dto.email_secondary, (value) => EmailAddress.create(value)), "email_secondary", errors ); const primaryPhoneNumber = extractOrPushError( - maybeFromNullableVO(dto.phone_primary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(dto.phone_primary, (value) => PhoneNumber.create(value)), "phone_primary", errors ); const secondaryPhoneNumber = extractOrPushError( - maybeFromNullableVO(dto.phone_secondary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(dto.phone_secondary, (value) => PhoneNumber.create(value)), "phone_secondary", errors ); const primaryMobileNumber = extractOrPushError( - maybeFromNullableVO(dto.mobile_primary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(dto.mobile_primary, (value) => PhoneNumber.create(value)), "mobile_primary", errors ); const secondaryMobileNumber = extractOrPushError( - maybeFromNullableVO(dto.mobile_secondary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(dto.mobile_secondary, (value) => PhoneNumber.create(value)), "mobile_secondary", errors ); const faxNumber = extractOrPushError( - maybeFromNullableVO(dto.fax, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(dto.fax, (value) => PhoneNumber.create(value)), "fax", errors ); const website = extractOrPushError( - maybeFromNullableVO(dto.website, (value) => URLAddress.create(value)), + maybeFromNullableResult(dto.website, (value) => URLAddress.create(value)), "website", errors ); const legalRecord = extractOrPushError( - maybeFromNullableVO(dto.legal_record, (value) => TextValue.create(value)), + maybeFromNullableResult(dto.legal_record, (value) => TextValue.create(value)), "legal_record", errors ); diff --git a/modules/customers/src/api/application/use-cases/update/map-dto-to-update-customer-props.ts b/modules/customers/src/api/application/use-cases/update/map-dto-to-update-customer-props.ts index 0dd55699..664c3d43 100644 --- a/modules/customers/src/api/application/use-cases/update/map-dto-to-update-customer-props.ts +++ b/modules/customers/src/api/application/use-cases/update/map-dto-to-update-customer-props.ts @@ -1,21 +1,13 @@ -import { - DomainError, - ValidationErrorCollection, - ValidationErrorDetail, - extractOrPushError, -} from "@repo/rdx-ddd"; -import { UpdateCustomerByIdRequestDTO } from "../../../../common"; -import { CustomerPatchProps } from "../../../domain"; - import { City, Country, CurrencyCode, + DomainError, EmailAddress, LanguageCode, Name, PhoneNumber, - PostalAddressPatchProps, + type PostalAddressPatchProps, PostalCode, Province, Street, @@ -23,10 +15,16 @@ import { TaxCode, TextValue, URLAddress, - maybeFromNullableVO, + ValidationErrorCollection, + type ValidationErrorDetail, + extractOrPushError, + maybeFromNullableResult, } from "@repo/rdx-ddd"; import { Collection, Result, isNullishOrEmpty, toPatchField } from "@repo/rdx-utils"; +import type { UpdateCustomerByIdRequestDTO } from "../../../../common"; +import type { CustomerPatchProps } from "../../../domain"; + /** * mapDTOToUpdateCustomerPatchProps * Convierte el DTO a las props validadas (CustomerProps). @@ -48,7 +46,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.reference).ifSet((reference) => { customerPatchProps.reference = extractOrPushError( - maybeFromNullableVO(reference, (value) => Name.create(value)), + maybeFromNullableResult(reference, (value) => Name.create(value)), "reference", errors ); @@ -76,7 +74,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.trade_name).ifSet((trade_name) => { customerPatchProps.tradeName = extractOrPushError( - maybeFromNullableVO(trade_name, (value) => Name.create(value)), + maybeFromNullableResult(trade_name, (value) => Name.create(value)), "trade_name", errors ); @@ -84,7 +82,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.tin).ifSet((tin) => { customerPatchProps.tin = extractOrPushError( - maybeFromNullableVO(tin, (value) => TINNumber.create(value)), + maybeFromNullableResult(tin, (value) => TINNumber.create(value)), "tin", errors ); @@ -92,7 +90,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.email_primary).ifSet((email_primary) => { customerPatchProps.emailPrimary = extractOrPushError( - maybeFromNullableVO(email_primary, (value) => EmailAddress.create(value)), + maybeFromNullableResult(email_primary, (value) => EmailAddress.create(value)), "email_primary", errors ); @@ -100,7 +98,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.email_secondary).ifSet((email_secondary) => { customerPatchProps.emailSecondary = extractOrPushError( - maybeFromNullableVO(email_secondary, (value) => EmailAddress.create(value)), + maybeFromNullableResult(email_secondary, (value) => EmailAddress.create(value)), "email_secondary", errors ); @@ -108,7 +106,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.mobile_primary).ifSet((mobile_primary) => { customerPatchProps.mobilePrimary = extractOrPushError( - maybeFromNullableVO(mobile_primary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(mobile_primary, (value) => PhoneNumber.create(value)), "mobile_primary", errors ); @@ -116,7 +114,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.mobile_secondary).ifSet((mobile_secondary) => { customerPatchProps.mobilePrimary = extractOrPushError( - maybeFromNullableVO(mobile_secondary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(mobile_secondary, (value) => PhoneNumber.create(value)), "mobile_secondary", errors ); @@ -124,7 +122,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.phone_primary).ifSet((phone_primary) => { customerPatchProps.phonePrimary = extractOrPushError( - maybeFromNullableVO(phone_primary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(phone_primary, (value) => PhoneNumber.create(value)), "phone_primary", errors ); @@ -132,7 +130,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.phone_secondary).ifSet((phone_secondary) => { customerPatchProps.phoneSecondary = extractOrPushError( - maybeFromNullableVO(phone_secondary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(phone_secondary, (value) => PhoneNumber.create(value)), "phone_secondary", errors ); @@ -140,7 +138,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.fax).ifSet((fax) => { customerPatchProps.fax = extractOrPushError( - maybeFromNullableVO(fax, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(fax, (value) => PhoneNumber.create(value)), "fax", errors ); @@ -148,7 +146,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.website).ifSet((website) => { customerPatchProps.website = extractOrPushError( - maybeFromNullableVO(website, (value) => URLAddress.create(value)), + maybeFromNullableResult(website, (value) => URLAddress.create(value)), "website", errors ); @@ -156,7 +154,7 @@ export function mapDTOToUpdateCustomerPatchProps(dto: UpdateCustomerByIdRequestD toPatchField(dto.legal_record).ifSet((legalRecord) => { customerPatchProps.legalRecord = extractOrPushError( - maybeFromNullableVO(legalRecord, (value) => TextValue.create(value)), + maybeFromNullableResult(legalRecord, (value) => TextValue.create(value)), "legal_record", errors ); @@ -231,7 +229,7 @@ function mapDTOToUpdatePostalAddressPatchProps( toPatchField(dto.street).ifSet((street) => { postalAddressPatchProps.street = extractOrPushError( - maybeFromNullableVO(street, (value) => Street.create(value)), + maybeFromNullableResult(street, (value) => Street.create(value)), "street", errors ); @@ -239,7 +237,7 @@ function mapDTOToUpdatePostalAddressPatchProps( toPatchField(dto.street2).ifSet((street2) => { postalAddressPatchProps.street2 = extractOrPushError( - maybeFromNullableVO(street2, (value) => Street.create(value)), + maybeFromNullableResult(street2, (value) => Street.create(value)), "street2", errors ); @@ -247,7 +245,7 @@ function mapDTOToUpdatePostalAddressPatchProps( toPatchField(dto.city).ifSet((city) => { postalAddressPatchProps.city = extractOrPushError( - maybeFromNullableVO(city, (value) => City.create(value)), + maybeFromNullableResult(city, (value) => City.create(value)), "city", errors ); @@ -255,7 +253,7 @@ function mapDTOToUpdatePostalAddressPatchProps( toPatchField(dto.province).ifSet((province) => { postalAddressPatchProps.province = extractOrPushError( - maybeFromNullableVO(province, (value) => Province.create(value)), + maybeFromNullableResult(province, (value) => Province.create(value)), "province", errors ); @@ -263,7 +261,7 @@ function mapDTOToUpdatePostalAddressPatchProps( toPatchField(dto.postal_code).ifSet((postalCode) => { postalAddressPatchProps.postalCode = extractOrPushError( - maybeFromNullableVO(postalCode, (value) => PostalCode.create(value)), + maybeFromNullableResult(postalCode, (value) => PostalCode.create(value)), "postal_code", errors ); @@ -271,7 +269,7 @@ function mapDTOToUpdatePostalAddressPatchProps( toPatchField(dto.country).ifSet((country) => { postalAddressPatchProps.country = extractOrPushError( - maybeFromNullableVO(country, (value) => Country.create(value)), + maybeFromNullableResult(country, (value) => Country.create(value)), "country", errors ); diff --git a/modules/customers/src/api/infrastructure/mappers/domain/customer.mapper.ts b/modules/customers/src/api/infrastructure/mappers/domain/customer.mapper.ts index 0332d7e1..3221d0dd 100644 --- a/modules/customers/src/api/infrastructure/mappers/domain/customer.mapper.ts +++ b/modules/customers/src/api/infrastructure/mappers/domain/customer.mapper.ts @@ -1,30 +1,35 @@ -import { ISequelizeDomainMapper, MapperParamsType, SequelizeDomainMapper } from "@erp/core/api"; +import { + type ISequelizeDomainMapper, + type MapperParamsType, + SequelizeDomainMapper, +} from "@erp/core/api"; import { City, Country, CurrencyCode, EmailAddress, - extractOrPushError, LanguageCode, - maybeFromNullableVO, Name, PhoneNumber, PostalAddress, PostalCode, Province, Street, + TINNumber, TaxCode, TextValue, - TINNumber, - toNullable, - UniqueID, URLAddress, + UniqueID, ValidationErrorCollection, - ValidationErrorDetail, + type ValidationErrorDetail, + extractOrPushError, + maybeFromNullableResult, + maybeToNullable, } from "@repo/rdx-ddd"; -import { Collection, isNullishOrEmpty, Result } from "@repo/rdx-utils"; -import { Customer, CustomerProps, CustomerStatus } from "../../../domain"; -import { CustomerCreationAttributes, CustomerModel } from "../../sequelize"; +import { Collection, Result, isNullishOrEmpty } from "@repo/rdx-utils"; + +import { Customer, type CustomerProps, CustomerStatus } from "../../../domain"; +import type { CustomerCreationAttributes, CustomerModel } from "../../sequelize"; export interface ICustomerDomainMapper extends ISequelizeDomainMapper {} @@ -47,7 +52,7 @@ export class CustomerDomainMapper const isCompany = source.is_company; const status = extractOrPushError(CustomerStatus.create(source.status), "status", errors); const reference = extractOrPushError( - maybeFromNullableVO(source.reference, (value) => Name.create(value)), + maybeFromNullableResult(source.reference, (value) => Name.create(value)), "reference", errors ); @@ -55,103 +60,103 @@ export class CustomerDomainMapper const name = extractOrPushError(Name.create(source.name), "name", errors); const tradeName = extractOrPushError( - maybeFromNullableVO(source.trade_name, (value) => Name.create(value)), + maybeFromNullableResult(source.trade_name, (value) => Name.create(value)), "trade_name", errors ); const tinNumber = extractOrPushError( - maybeFromNullableVO(source.tin, (value) => TINNumber.create(value)), + maybeFromNullableResult(source.tin, (value) => TINNumber.create(value)), "tin", errors ); const street = extractOrPushError( - maybeFromNullableVO(source.street, (value) => Street.create(value)), + maybeFromNullableResult(source.street, (value) => Street.create(value)), "street", errors ); const street2 = extractOrPushError( - maybeFromNullableVO(source.street2, (value) => Street.create(value)), + maybeFromNullableResult(source.street2, (value) => Street.create(value)), "street2", errors ); const city = extractOrPushError( - maybeFromNullableVO(source.city, (value) => City.create(value)), + maybeFromNullableResult(source.city, (value) => City.create(value)), "city", errors ); const province = extractOrPushError( - maybeFromNullableVO(source.province, (value) => Province.create(value)), + maybeFromNullableResult(source.province, (value) => Province.create(value)), "province", errors ); const postalCode = extractOrPushError( - maybeFromNullableVO(source.postal_code, (value) => PostalCode.create(value)), + maybeFromNullableResult(source.postal_code, (value) => PostalCode.create(value)), "postal_code", errors ); const country = extractOrPushError( - maybeFromNullableVO(source.country, (value) => Country.create(value)), + maybeFromNullableResult(source.country, (value) => Country.create(value)), "country", errors ); const emailPrimaryAddress = extractOrPushError( - maybeFromNullableVO(source.email_primary, (value) => EmailAddress.create(value)), + maybeFromNullableResult(source.email_primary, (value) => EmailAddress.create(value)), "email_primary", errors ); const emailSecondaryAddress = extractOrPushError( - maybeFromNullableVO(source.email_secondary, (value) => EmailAddress.create(value)), + maybeFromNullableResult(source.email_secondary, (value) => EmailAddress.create(value)), "email_secondary", errors ); const phonePrimaryNumber = extractOrPushError( - maybeFromNullableVO(source.phone_primary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(source.phone_primary, (value) => PhoneNumber.create(value)), "phone_primary", errors ); const phoneSecondaryNumber = extractOrPushError( - maybeFromNullableVO(source.phone_secondary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(source.phone_secondary, (value) => PhoneNumber.create(value)), "phone_secondary", errors ); const mobilePrimaryNumber = extractOrPushError( - maybeFromNullableVO(source.mobile_primary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(source.mobile_primary, (value) => PhoneNumber.create(value)), "mobile_primary", errors ); const mobileSecondaryNumber = extractOrPushError( - maybeFromNullableVO(source.mobile_secondary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(source.mobile_secondary, (value) => PhoneNumber.create(value)), "mobile_secondary", errors ); const faxNumber = extractOrPushError( - maybeFromNullableVO(source.fax, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(source.fax, (value) => PhoneNumber.create(value)), "fax", errors ); const website = extractOrPushError( - maybeFromNullableVO(source.website, (value) => URLAddress.create(value)), + maybeFromNullableResult(source.website, (value) => URLAddress.create(value)), "website", errors ); const legalRecord = extractOrPushError( - maybeFromNullableVO(source.legal_record, (value) => TextValue.create(value)), + maybeFromNullableResult(source.legal_record, (value) => TextValue.create(value)), "legal_record", errors ); @@ -241,22 +246,22 @@ export class CustomerDomainMapper id: source.id.toPrimitive(), company_id: source.companyId.toPrimitive(), - reference: toNullable(source.reference, (reference) => reference.toPrimitive()), + reference: maybeToNullable(source.reference, (reference) => reference.toPrimitive()), is_company: source.isCompany, name: source.name.toPrimitive(), - trade_name: toNullable(source.tradeName, (tradeName) => tradeName.toPrimitive()), - tin: toNullable(source.tin, (tin) => tin.toPrimitive()), + trade_name: maybeToNullable(source.tradeName, (tradeName) => tradeName.toPrimitive()), + tin: maybeToNullable(source.tin, (tin) => tin.toPrimitive()), - email_primary: toNullable(source.emailPrimary, (email) => email.toPrimitive()), - email_secondary: toNullable(source.emailSecondary, (email) => email.toPrimitive()), - phone_primary: toNullable(source.phonePrimary, (phone) => phone.toPrimitive()), - phone_secondary: toNullable(source.phoneSecondary, (phone) => phone.toPrimitive()), - mobile_primary: toNullable(source.mobilePrimary, (mobile) => mobile.toPrimitive()), - mobile_secondary: toNullable(source.mobileSecondary, (mobile) => mobile.toPrimitive()), - fax: toNullable(source.fax, (fax) => fax.toPrimitive()), - website: toNullable(source.website, (website) => website.toPrimitive()), + email_primary: maybeToNullable(source.emailPrimary, (email) => email.toPrimitive()), + email_secondary: maybeToNullable(source.emailSecondary, (email) => email.toPrimitive()), + phone_primary: maybeToNullable(source.phonePrimary, (phone) => phone.toPrimitive()), + phone_secondary: maybeToNullable(source.phoneSecondary, (phone) => phone.toPrimitive()), + mobile_primary: maybeToNullable(source.mobilePrimary, (mobile) => mobile.toPrimitive()), + mobile_secondary: maybeToNullable(source.mobileSecondary, (mobile) => mobile.toPrimitive()), + fax: maybeToNullable(source.fax, (fax) => fax.toPrimitive()), + website: maybeToNullable(source.website, (website) => website.toPrimitive()), - legal_record: toNullable(source.legalRecord, (legalRecord) => legalRecord.toPrimitive()), + legal_record: maybeToNullable(source.legalRecord, (legalRecord) => legalRecord.toPrimitive()), default_taxes: source.defaultTaxes.map((taxItem) => taxItem.toPrimitive()).join(", "), status: source.isActive ? "active" : "inactive", @@ -266,14 +271,14 @@ export class CustomerDomainMapper if (source.address) { Object.assign(customerValues, { - street: toNullable(source.address.street, (street) => street.toPrimitive()), - street2: toNullable(source.address.street2, (street2) => street2.toPrimitive()), - city: toNullable(source.address.city, (city) => city.toPrimitive()), - province: toNullable(source.address.province, (province) => province.toPrimitive()), - postal_code: toNullable(source.address.postalCode, (postalCode) => + street: maybeToNullable(source.address.street, (street) => street.toPrimitive()), + street2: maybeToNullable(source.address.street2, (street2) => street2.toPrimitive()), + city: maybeToNullable(source.address.city, (city) => city.toPrimitive()), + province: maybeToNullable(source.address.province, (province) => province.toPrimitive()), + postal_code: maybeToNullable(source.address.postalCode, (postalCode) => postalCode.toPrimitive() ), - country: toNullable(source.address.country, (country) => country.toPrimitive()), + country: maybeToNullable(source.address.country, (country) => country.toPrimitive()), }); } diff --git a/modules/customers/src/api/infrastructure/mappers/queries/customer.list.mapper.ts b/modules/customers/src/api/infrastructure/mappers/queries/customer.list.mapper.ts index 88678b54..46818758 100644 --- a/modules/customers/src/api/infrastructure/mappers/queries/customer.list.mapper.ts +++ b/modules/customers/src/api/infrastructure/mappers/queries/customer.list.mapper.ts @@ -1,5 +1,8 @@ -import { ValidationErrorCollection, ValidationErrorDetail } from "@repo/rdx-ddd"; - +import { + type ISequelizeQueryMapper, + type MapperParamsType, + SequelizeQueryMapper, +} from "@erp/core/api"; import { City, Country, @@ -16,15 +19,15 @@ import { TextValue, URLAddress, UniqueID, + ValidationErrorCollection, + type ValidationErrorDetail, extractOrPushError, - maybeFromNullableVO, + maybeFromNullableResult, } from "@repo/rdx-ddd"; +import { type Maybe, Result } from "@repo/rdx-utils"; -import { ISequelizeQueryMapper, MapperParamsType, SequelizeQueryMapper } from "@erp/core/api"; - -import { Maybe, Result } from "@repo/rdx-utils"; import { CustomerStatus } from "../../../domain"; -import { CustomerModel } from "../../sequelize"; +import type { CustomerModel } from "../../sequelize"; export type CustomerListDTO = { id: UniqueID; @@ -70,7 +73,7 @@ export class CustomerListMapper const isCompany = raw.is_company; const status = extractOrPushError(CustomerStatus.create(raw.status), "status", errors); const reference = extractOrPushError( - maybeFromNullableVO(raw.reference, (value) => Name.create(value)), + maybeFromNullableResult(raw.reference, (value) => Name.create(value)), "reference", errors ); @@ -78,103 +81,103 @@ export class CustomerListMapper const name = extractOrPushError(Name.create(raw.name), "name", errors); const tradeName = extractOrPushError( - maybeFromNullableVO(raw.trade_name, (value) => Name.create(value)), + maybeFromNullableResult(raw.trade_name, (value) => Name.create(value)), "trade_name", errors ); const tinNumber = extractOrPushError( - maybeFromNullableVO(raw.tin, (value) => TINNumber.create(value)), + maybeFromNullableResult(raw.tin, (value) => TINNumber.create(value)), "tin", errors ); const street = extractOrPushError( - maybeFromNullableVO(raw.street, (value) => Street.create(value)), + maybeFromNullableResult(raw.street, (value) => Street.create(value)), "street", errors ); const street2 = extractOrPushError( - maybeFromNullableVO(raw.street2, (value) => Street.create(value)), + maybeFromNullableResult(raw.street2, (value) => Street.create(value)), "street2", errors ); const city = extractOrPushError( - maybeFromNullableVO(raw.city, (value) => City.create(value)), + maybeFromNullableResult(raw.city, (value) => City.create(value)), "city", errors ); const province = extractOrPushError( - maybeFromNullableVO(raw.province, (value) => Province.create(value)), + maybeFromNullableResult(raw.province, (value) => Province.create(value)), "province", errors ); const postalCode = extractOrPushError( - maybeFromNullableVO(raw.postal_code, (value) => PostalCode.create(value)), + maybeFromNullableResult(raw.postal_code, (value) => PostalCode.create(value)), "postal_code", errors ); const country = extractOrPushError( - maybeFromNullableVO(raw.country, (value) => Country.create(value)), + maybeFromNullableResult(raw.country, (value) => Country.create(value)), "country", errors ); const emailPrimaryAddress = extractOrPushError( - maybeFromNullableVO(raw.email_primary, (value) => EmailAddress.create(value)), + maybeFromNullableResult(raw.email_primary, (value) => EmailAddress.create(value)), "email_primary", errors ); const emailSecondaryAddress = extractOrPushError( - maybeFromNullableVO(raw.email_secondary, (value) => EmailAddress.create(value)), + maybeFromNullableResult(raw.email_secondary, (value) => EmailAddress.create(value)), "email_secondary", errors ); const phonePrimaryNumber = extractOrPushError( - maybeFromNullableVO(raw.phone_primary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(raw.phone_primary, (value) => PhoneNumber.create(value)), "phone_primary", errors ); const phoneSecondaryNumber = extractOrPushError( - maybeFromNullableVO(raw.phone_secondary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(raw.phone_secondary, (value) => PhoneNumber.create(value)), "phone_secondary", errors ); const mobilePrimaryNumber = extractOrPushError( - maybeFromNullableVO(raw.mobile_primary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(raw.mobile_primary, (value) => PhoneNumber.create(value)), "mobile_primary", errors ); const mobileSecondaryNumber = extractOrPushError( - maybeFromNullableVO(raw.mobile_secondary, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(raw.mobile_secondary, (value) => PhoneNumber.create(value)), "mobile_secondary", errors ); const faxNumber = extractOrPushError( - maybeFromNullableVO(raw.fax, (value) => PhoneNumber.create(value)), + maybeFromNullableResult(raw.fax, (value) => PhoneNumber.create(value)), "fax", errors ); const website = extractOrPushError( - maybeFromNullableVO(raw.website, (value) => URLAddress.create(value)), + maybeFromNullableResult(raw.website, (value) => URLAddress.create(value)), "website", errors ); const legalRecord = extractOrPushError( - maybeFromNullableVO(raw.legal_record, (value) => TextValue.create(value)), + maybeFromNullableResult(raw.legal_record, (value) => TextValue.create(value)), "legal_record", errors ); diff --git a/packages/rdx-ddd/src/helpers/normalizers.ts b/packages/rdx-ddd/src/helpers/normalizers.ts index bbd16167..762460a5 100644 --- a/packages/rdx-ddd/src/helpers/normalizers.ts +++ b/packages/rdx-ddd/src/helpers/normalizers.ts @@ -3,37 +3,37 @@ import { Maybe, Result, isNullishOrEmpty } from "@repo/rdx-utils"; -/** any | null | undefined -> Maybe usando fábrica VO */ -export function maybeFromNullableVO( +/** any | null | undefined -> Maybe usando validación */ +export function maybeFromNullableResult( input: any, - voFactory: (raw: any) => Result + validate: (raw: any) => Result ): Result> { if (isNullishOrEmpty(input)) return Result.ok(Maybe.none()); - const vo = voFactory(input); - return vo.isSuccess ? Result.ok(Maybe.some(vo.data)) : Result.fail(vo.error); + const value = validate(input); + return value.isSuccess ? Result.ok(Maybe.some(value.data)) : Result.fail(value.error); } /** string | null | undefined -> Maybe (trim, vacío => None) */ -export function maybeFromNullableString(input?: string | null): Maybe { +export function maybeFromNullableOrEmptyString(input?: string | null): Maybe { if (isNullishOrEmpty(input)) return Maybe.none(); - const t = (input as string).trim(); + const t = input as string; return t ? Maybe.some(t) : Maybe.none(); } /** Maybe -> null para transporte */ -export function toNullable(m: Maybe, map: (t: T) => R): R | null { +export function maybeToNullable(m: Maybe, map: (t: T) => R): R | null { if (!m || m.isNone()) return null; return map(m.unwrap() as T); } -export function toNullable2(m: Maybe, map?: (t: T) => unknown): unknown | null { +export function maybeToNullableString(m: Maybe, map?: (t: T) => string): string | null { if (!m || m.isNone()) return null; const v = m.unwrap() as T; return map ? String(map(v)) : String(v); } /** Maybe -> "" para transporte */ -export function toEmptyString(m: Maybe, map?: (t: T) => string): string { +export function maybeToEmptyString(m: Maybe, map?: (t: T) => string): string { if (!m || m.isNone()) return ""; const v = m.unwrap() as T; return map ? map(v) : String(v); diff --git a/packages/rdx-ddd/src/value-objects/percentage.ts b/packages/rdx-ddd/src/value-objects/percentage.ts index 25e68d10..7695a752 100644 --- a/packages/rdx-ddd/src/value-objects/percentage.ts +++ b/packages/rdx-ddd/src/value-objects/percentage.ts @@ -1,6 +1,8 @@ import { Result } from "@repo/rdx-utils"; import { z } from "zod/v4"; + import { translateZodValidationError } from "../helpers"; + import { ValueObject } from "./value-object"; const DEFAULT_SCALE = 2; @@ -62,6 +64,10 @@ export class Percentage extends ValueObject { return Result.ok(new Percentage({ value, scale })); } + static zero() { + return Percentage.create({ value: 0, scale: Percentage.DEFAULT_SCALE }).data; + } + get value(): number { return this.props.value; } diff --git a/packages/rdx-ddd/src/value-objects/postal-address.ts b/packages/rdx-ddd/src/value-objects/postal-address.ts index 44517565..0a1594ac 100644 --- a/packages/rdx-ddd/src/value-objects/postal-address.ts +++ b/packages/rdx-ddd/src/value-objects/postal-address.ts @@ -1,10 +1,12 @@ -import { Maybe, Result } from "@repo/rdx-utils"; -import { toEmptyString } from "../helpers"; -import { City } from "./city"; -import { Country } from "./country"; -import { PostalCode } from "./postal-code"; -import { Province } from "./province"; -import { Street } from "./street"; +import { type Maybe, Result } from "@repo/rdx-utils"; + +import { maybeToEmptyString } from "../helpers"; + +import type { City } from "./city"; +import type { Country } from "./country"; +import type { PostalCode } from "./postal-code"; +import type { Province } from "./province"; +import type { Street } from "./street"; import { ValueObject } from "./value-object"; export interface PostalAddressProps { @@ -75,12 +77,12 @@ export class PostalAddress extends ValueObject { toString() { return { - street: toEmptyString(this.street, (value) => value.toString()), - street2: toEmptyString(this.street2, (value) => value.toString()), - city: toEmptyString(this.city, (value) => value.toString()), - postal_code: toEmptyString(this.postalCode, (value) => value.toString()), - province: toEmptyString(this.province, (value) => value.toString()), - country: toEmptyString(this.country, (value) => value.toString()), + street: maybeToEmptyString(this.street, (value) => value.toString()), + street2: maybeToEmptyString(this.street2, (value) => value.toString()), + city: maybeToEmptyString(this.city, (value) => value.toString()), + postal_code: maybeToEmptyString(this.postalCode, (value) => value.toString()), + province: maybeToEmptyString(this.province, (value) => value.toString()), + country: maybeToEmptyString(this.country, (value) => value.toString()), }; }