Facturas de cliente

This commit is contained in:
David Arranz 2025-09-11 17:14:51 +02:00
parent cec3eba428
commit edecf0121b
12 changed files with 87 additions and 23 deletions

View File

@ -8,6 +8,24 @@
"description": "IVA general. Tipo estándar nacional.",
"aeat_code": "01"
},
{
"name": "IVA 18%",
"code": "iva_18",
"value": 1800,
"scale": 2,
"group": "IVA",
"description": "IVA general. Tipo estándar nacional hasta finales de 2011",
"aeat_code": null
},
{
"name": "IVA 16%",
"code": "iva_16",
"value": 1600,
"scale": 2,
"group": "IVA",
"description": "IVA general. Tipo estándar nacional hasta finales de 2009.",
"aeat_code": null
},
{
"name": "IVA 10%",
"code": "iva_10",

View File

@ -3,7 +3,7 @@ import { MoneyDTO } from "../../../common";
export const formatMoney = (value: MoneyDTO) => {
const money = DineroFactory({
amount: Number(value.amount),
amount: Number(value.value),
currency: value.currency_code as Currency,
precision: Number(value.scale),
});

View File

@ -29,6 +29,9 @@ export class ListCustomerInvoicesAssembler {
...recipientDTO,
},
language_code: invoice.languageCode.code,
currency_code: invoice.currencyCode.code,
taxes: invoice.taxes,
subtotal_amount: invoice.subtotalAmount.toObjectString(),

View File

@ -27,6 +27,7 @@ export class InvoiceAmount extends MoneyValue {
return {
value: String(this.value),
scale: String(this.scale),
currency_code: this.currencyCode,
};
}

View File

@ -1,4 +1,5 @@
import { ExpressController, authGuard, forbidQueryFieldGuard, tenantGuard } from "@erp/core/api";
import { Criteria } from "@repo/rdx-criteria/server";
import { ListCustomerInvoicesUseCase } from "../../../application";
export class ListCustomerInvoicesController extends ExpressController {
@ -8,9 +9,20 @@ export class ListCustomerInvoicesController extends ExpressController {
this.useGuards(authGuard(), tenantGuard(), forbidQueryFieldGuard("companyId"));
}
private _xxxx() {
if (this.criteria.hasOrder()) {
return this.criteria;
}
const { filters, pageSize, pageNumber } = this.criteria.toPrimitives();
return Criteria.fromPrimitives(filters, "invoice_date", "DESC", pageSize, pageNumber);
}
protected async executeImpl() {
const companyId = this.getTenantId()!; // garantizado por tenantGuard
const result = await this.useCase.execute({ criteria: this.criteria, companyId });
const criteria = this._xxxx();
const result = await this.useCase.execute({ criteria, companyId });
return result.match(
(data) =>

View File

@ -214,12 +214,12 @@ export class CustomerInvoiceRepository
},
];
const raws = await CustomerInvoiceModel.findAll({
const { rows, count } = await CustomerInvoiceModel.findAndCountAll({
...query,
transaction,
});
return mapper.mapToDTOCollection(raws, raws.length);
return mapper.mapToDTOCollection(rows, count);
} catch (err: unknown) {
return Result.fail(translateSequelizeError(err));
}

View File

@ -17,13 +17,12 @@ export const GetCustomerInvoiceByIdResponseSchema = z.object({
language_code: z.string(),
currency_code: z.string(),
taxes: z.string(),
subtotal_amount: AmountSchema,
discount_percentage: PercentageSchema,
discount_amount: AmountSchema,
taxable_amount: AmountSchema,
taxes: z.string(),
total_amount: AmountSchema,
items: z.array(

View File

@ -1,4 +1,4 @@
export * from "./create-customer-invoice.response.dto";
export * from "./customer-invoices-list.response.dto";
export * from "./get-customer-invoice-by-id.response.dto";
export * from "./list-customer-invoices.response.dto";
export * from "./update-customer-invoice-by-id.response.dto";

View File

@ -1,7 +1,7 @@
import { AmountSchema, MetadataSchema, createListViewResponseSchema } from "@erp/core";
import * as z from "zod/v4";
export const CustomerInvoiceListResponseSchema = createListViewResponseSchema(
export const ListCustomerInvoiceResponseSchema = createListViewResponseSchema(
z.object({
id: z.uuid(),
company_id: z.uuid(),
@ -14,6 +14,9 @@ export const CustomerInvoiceListResponseSchema = createListViewResponseSchema(
invoice_date: z.string(),
operation_date: z.string(),
language_code: z.string(),
currency_code: z.string(),
recipient: {
tin: z.string(),
name: z.string(),
@ -37,4 +40,4 @@ export const CustomerInvoiceListResponseSchema = createListViewResponseSchema(
})
);
export type CustomerInvoiceListResponseDTO = z.infer<typeof CustomerInvoiceListResponseSchema>;
export type CustomerInvoiceListResponseDTO = z.infer<typeof ListCustomerInvoiceResponseSchema>;

View File

@ -15,10 +15,10 @@
"description": "List all customer invoices",
"grid_columns": {
"invoice_number": "Inv. number",
"invoice_series": "Serie",
"invoice_status": "Status",
"series": "Serie",
"status": "Status",
"invoice_date": "Date",
"total_price": "Total price"
"total_amount": "Total price"
}
},
"create": {

View File

@ -23,16 +23,16 @@ export const CustomerInvoicesListGrid = () => {
// Column Definitions: Defines & controls grid columns.
const [colDefs] = useState<ColDef[]>([
{
field: "invoice_status",
field: "status",
filter: true,
headerName: t("pages.list.grid_columns.invoice_status"),
headerName: t("pages.list.grid_columns.status"),
cellRenderer: (params: ValueFormatterParams) => {
return <CustomerInvoiceStatusBadge status={params.value} />;
},
},
{ field: "invoice_number", headerName: t("pages.list.grid_columns.invoice_number") },
{ field: "invoice_series", headerName: t("pages.list.grid_columns.invoice_series") },
{ field: "series", headerName: t("pages.list.grid_columns.series") },
{
field: "invoice_date",
@ -41,9 +41,32 @@ export const CustomerInvoicesListGrid = () => {
return formatDate(params.value);
},
},
{ field: "recipient.tin" },
{ field: "recipient.name" },
{ field: "recipient.city" },
{ field: "recipient.province" },
{ field: "recipient.postal_code" },
{
field: "total_price",
headerName: t("pages.list.grid_columns.total_price"),
field: "taxable_amount",
headerName: t("pages.list.grid_columns.taxable_amount"),
valueFormatter: (params: ValueFormatterParams) => {
const rawValue: MoneyDTO = params.value;
return formatMoney(rawValue);
},
},
{
field: "taxes_amount",
headerName: t("pages.list.grid_columns.taxable_amount"),
valueFormatter: (params: ValueFormatterParams) => {
const rawValue: MoneyDTO = params.value;
return formatMoney(rawValue);
},
},
{
field: "total_amount",
headerName: t("pages.list.grid_columns.total_amount"),
valueFormatter: (params: ValueFormatterParams) => {
const rawValue: MoneyDTO = params.value;
return formatMoney(rawValue);
@ -54,11 +77,11 @@ export const CustomerInvoicesListGrid = () => {
const gridOptions: GridOptions = {
columnDefs: colDefs,
defaultColDef: {
editable: true,
editable: false,
flex: 1,
minWidth: 100,
filter: false,
sortable: false,
filter: true,
sortable: true,
resizable: true,
},
pagination: true,

View File

@ -35,12 +35,17 @@ export class Criteria extends BaseCriteria {
);
}
toJSON(): Record<string, any> {
toPrimitives() {
return {
filters: this.filters.toPrimitives(),
//order: this.order.
orderBy: this.order.orderBy.value,
orderType: this.order.orderType.value,
pageSize: this.pageSize,
pageNumber: this.pageNumber,
};
}
toJSON() {
return this.toPrimitives();
}
}