feat: Implement invoice management features including data table, dialogs for viewing, editing, and deleting invoices, and server-side loading of invoice data

This commit is contained in:
2025-12-11 11:30:44 -06:00
parent 76b9325713
commit e5f6162ffb
14 changed files with 2381 additions and 82 deletions

View File

@@ -0,0 +1,318 @@
/**
* API Client para Facturas (Invoices)
* Gestiona las operaciones CRUD para facturas y sus relaciones
*/
import { api } from '$lib/api';
export type OperationType = 'imp' | 'exp';
export type TransportType = 'none' | 'transport' | 'box' | 'licence plates' | 'truck' | 'vessel' | 'rail barge' | 'container' | 'airplane' | 'gondola' | 'flatbed';
// --- Interfaces ---
export interface InvoiceComplianceMx {
invoice_id?: number;
pedimento?: string | null;
pedimento_code?: string | null;
remesa?: number | null;
aduana?: string | null;
provider_header?: string | null;
provider_id?: string | null;
sold_to_header?: string | null;
sold_to_id?: string | null;
shipped_to_header?: string | null;
shipped_to_id?: string | null;
shipped_by_header?: string | null;
shipped_by_id?: string | null;
customs_broker_id?: string | null;
is_mixed?: boolean | null;
waste_type?: string | null;
appendix_17?: number | null;
edocument?: string | null;
electronic_signature?: string | null;
sem_id?: number | null;
}
export interface InvoiceFinancials {
id?: number;
invoice_id?: number;
currency?: string | null;
currency_type?: string | null;
exchange_rate?: number | null;
value_mn?: number | null;
value_me?: number | null;
customs_value_mn?: number | null;
freight?: number | null;
insurance?: number | null;
iva_mn?: number | null;
iva_factor?: number | null;
total_quantity?: number | null;
gross_weight?: number | null;
net_weight?: number | null;
bundle_count?: number | null;
}
export interface InvoiceLogistics {
id?: number;
invoice_id?: number;
carrier_id?: string | null;
transport_type?: TransportType | null;
transport_mode?: string | null;
driver_name?: string | null;
is_rail?: string | null;
rail_id?: string | null;
vehicle_num?: string | null;
license_plate?: string | null;
seal_number?: string | null;
guide_number?: string | null;
entry_exit_date?: string | null;
}
export interface InvoiceSalesDetails {
id?: number;
invoice_id?: number;
line_number: number;
sales_order?: string | null;
colors_description?: string | null;
square_color_code?: string | null;
line_bundles?: number | null;
}
export interface InvoiceCollections {
id?: number;
invoice_id?: number;
concept?: string | null;
is_collected?: number | null;
collection_date?: string | null;
amount?: number | null;
collector_user?: string | null;
}
export interface Invoice {
id: number;
tenant_id: number;
company_id: number;
operation_type?: OperationType | null;
invoice_type?: string | null;
invoice_number?: string | null;
project_number?: string | null;
purchase_order?: string | null;
related_doc_id?: number | null;
invoice_date?: string | null;
capture_date: string;
is_updated?: boolean | null;
updated_date?: string | null;
who_updated?: string | null;
traffic_light_status?: string | null;
process_log?: string | null;
observation_es?: string | null;
observation_en?: string | null;
comments_status?: string | null;
cfdi_uuid?: string | null;
path_pdf?: string | null;
path_xml?: string | null;
compliance_mx?: InvoiceComplianceMx | null;
financials?: InvoiceFinancials | null;
logistics?: InvoiceLogistics[];
details?: InvoiceSalesDetails[];
collections?: InvoiceCollections[];
}
export interface InvoiceListResponse {
items: Invoice[];
total: number;
page: number;
page_size: number;
}
export interface CreateInvoiceData {
operation_type?: OperationType | null;
invoice_type?: string | null;
invoice_number?: string | null;
project_number?: string | null;
purchase_order?: string | null;
related_doc_id?: number | null;
invoice_date?: string | null;
traffic_light_status?: string | null;
process_log?: string | null;
observation_es?: string | null;
observation_en?: string | null;
comments_status?: string | null;
cfdi_uuid?: string | null;
path_pdf?: string | null;
path_xml?: string | null;
compliance_mx?: Omit<InvoiceComplianceMx, 'invoice_id'> | null;
financials?: Omit<InvoiceFinancials, 'id' | 'invoice_id'> | null;
logistics?: Omit<InvoiceLogistics, 'id' | 'invoice_id'>[] | null;
details?: Omit<InvoiceSalesDetails, 'id' | 'invoice_id'>[] | null;
collections?: Omit<InvoiceCollections, 'id' | 'invoice_id'>[] | null;
}
export interface UpdateInvoiceData {
operation_type?: OperationType | null;
invoice_type?: string | null;
invoice_number?: string | null;
project_number?: string | null;
purchase_order?: string | null;
related_doc_id?: number | null;
invoice_date?: string | null;
traffic_light_status?: string | null;
process_log?: string | null;
observation_es?: string | null;
observation_en?: string | null;
comments_status?: string | null;
cfdi_uuid?: string | null;
path_pdf?: string | null;
path_xml?: string | null;
compliance_mx?: Partial<InvoiceComplianceMx> | null;
financials?: Partial<InvoiceFinancials> | null;
logistics?: Partial<InvoiceLogistics>[] | null;
details?: Partial<InvoiceSalesDetails>[] | null;
collections?: Partial<InvoiceCollections>[] | null;
}
/**
* API para Facturas
*/
export const invoicesApi = {
/**
* Lista todas las facturas con paginación
*/
list: (companyId: number, page = 1, pageSize = 50, filters?: Record<string, any>) => {
const params = new URLSearchParams({
company_id: companyId.toString(),
page: page.toString(),
page_size: pageSize.toString()
});
// Agregar filtros si existen
if (filters) {
Object.entries(filters).forEach(([key, value]) => {
if (value !== null && value !== undefined && value !== '') {
params.append(key, String(value));
}
});
}
return api.get<InvoiceListResponse>(`/v1/a76/invoices?${params.toString()}`);
},
/**
* Obtiene una factura por ID
*/
get: (invoiceId: number, companyId: number) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.get<Invoice>(`/v1/a76/invoices/${invoiceId}?${params.toString()}`);
},
/**
* Crea una nueva factura
*/
create: (companyId: number, data: CreateInvoiceData) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.post<Invoice>(`/v1/a76/invoices?${params.toString()}`, data);
},
/**
* Actualiza una factura existente
*/
update: (invoiceId: number, companyId: number, data: UpdateInvoiceData) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.put<Invoice>(`/v1/a76/invoices/${invoiceId}?${params.toString()}`, data);
},
/**
* Elimina una factura
*/
delete: (invoiceId: number, companyId: number) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.delete(`/v1/a76/invoices/${invoiceId}?${params.toString()}`);
},
// --- Nested Resources ---
/**
* Logística de factura
*/
logistics: {
list: (invoiceId: number, companyId: number) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.get<InvoiceLogistics[]>(`/v1/a76/invoices/${invoiceId}/logistics?${params.toString()}`);
},
create: (invoiceId: number, companyId: number, data: Omit<InvoiceLogistics, 'id' | 'invoice_id'>) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.post<InvoiceLogistics>(`/v1/a76/invoices/${invoiceId}/logistics?${params.toString()}`, data);
},
delete: (invoiceId: number, logisticsId: number, companyId: number) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.delete(`/v1/a76/invoices/${invoiceId}/logistics/${logisticsId}?${params.toString()}`);
}
},
/**
* Detalles de venta de factura
*/
details: {
list: (invoiceId: number, companyId: number) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.get<InvoiceSalesDetails[]>(`/v1/a76/invoices/${invoiceId}/details?${params.toString()}`);
},
create: (invoiceId: number, companyId: number, data: Omit<InvoiceSalesDetails, 'id' | 'invoice_id'>) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.post<InvoiceSalesDetails>(`/v1/a76/invoices/${invoiceId}/details?${params.toString()}`, data);
},
delete: (invoiceId: number, detailId: number, companyId: number) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.delete(`/v1/a76/invoices/${invoiceId}/details/${detailId}?${params.toString()}`);
}
},
/**
* Cobranzas de factura
*/
collections: {
list: (invoiceId: number, companyId: number) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.get<InvoiceCollections[]>(`/v1/a76/invoices/${invoiceId}/collections?${params.toString()}`);
},
create: (invoiceId: number, companyId: number, data: Omit<InvoiceCollections, 'id' | 'invoice_id'>) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.post<InvoiceCollections>(`/v1/a76/invoices/${invoiceId}/collections?${params.toString()}`, data);
},
delete: (invoiceId: number, collectionId: number, companyId: number) => {
const params = new URLSearchParams({
company_id: companyId.toString()
});
return api.delete(`/v1/a76/invoices/${invoiceId}/collections/${collectionId}?${params.toString()}`);
}
}
};