/** * 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_id?: number | null; pedimento_r1?: number | null; pedimento_k1?: number | null; remesa?: number | null; // Pedimento relationship data (when joined) pedimento?: { pedimento_number?: string; pedimento_code?: string; customs_office?: string; license?: string; year?: string; } | null; aduana?: string | null; port_of_entry?: string | null; destination?: string | null; manifest_number?: string | null; provider_header?: string | null; provider_id?: number | null; sold_to_header?: string | null; sold_to_id?: number | null; shipped_to_header?: string | null; shipped_to_id?: number | null; shipped_by_header?: string | null; shipped_by_id?: number | null; customs_broker_id?: number | null; customs_broker_us_id?: number | null; broker_invoice_num?: string | null; broker_invoice_date?: string | null; is_mixed?: boolean | null; waste_type?: string | null; scrap_type?: string | null; appendix_17?: number | null; is_regime_change?: boolean | null; which_exchange_rate?: string | null; value_method?: string | null; act_value?: string | null; is_pedimento_pending?: boolean | null; is_owner_of_goods?: string | null; generate_balances?: string | null; was_reviewed_by_company?: boolean | null; edocument?: string | null; code_signature?: string | null; electronic_signature?: string | null; certificate_number?: string | null; niu_number?: string | null; bill_of_lading_count?: string | null; addendum_vu?: string | null; origin_destination_cove?: string | null; vucem_operation_num?: string | null; customs_person_line?: number | null; contingency_mode?: boolean | null; enclosure?: string | null; guide_type_to_identify?: string | null; location?: string | null; dot_code?: string | null; subdivision?: string | null; acts_as?: string | null; movement_type?: string | null; office_document?: string | null; reason_export?: string | null; signature_key?: string | null; sem_id?: number | null; rule_3121_parties_ii?: boolean | null; } export interface InvoiceFinancials { id?: number; invoice_id?: number; currency?: string | null; currency_type?: string | null; exchange_rate?: number | null; exchange_rate_mm?: number | null; value_mn?: number | null; value_me?: number | null; value_mc?: number | null; customs_value_mn?: number | null; customs_value_me?: number | null; raw_material_value_mn?: number | null; raw_material_value_me?: number | null; aggregate_value_mn?: number | null; aggregate_value_me?: number | null; aggregate_value_mc?: number | null; mexican_value_mn?: number | null; mexican_value_me?: number | null; mexican_value_mc?: number | null; national_packaging_mn?: number | null; national_packaging_me?: number | null; national_packaging_mc?: number | null; freight?: number | null; insurance?: number | null; insurance_value?: number | null; packaging?: number | null; other_increments?: number | null; other_deductibles?: number | null; total_increments_mn?: number | null; total_increments_me?: number | null; iva_mn?: number | null; iva_me?: number | null; iva_mc?: number | null; iva_factor?: number | null; tax_value_me?: number | null; seal_value_2500?: boolean | null; total_quantity?: number | null; gross_weight?: number | null; net_weight?: number | null; bundle_count?: number | null; weight_factor?: number | null; } export interface InvoiceLogistics { id?: number; invoice_id?: number; carrier_id?: string | null; carrier_int_id?: number | null; transport_id?: string | null; transport_int_id?: number | null; transport_us_id?: string | null; transport_type?: TransportType | null; transport_num?: string | 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; license_plate_complete?: string | null; trailer_num?: string | null; trailer_int_id?: number | null; seal_number?: string | null; guide_number?: string | null; bill_number?: string | null; reference_number?: string | null; shipment_number?: string | null; incoterm?: string | null; identifier_1?: string | null; complement_1?: string | null; identifier_2?: string | null; complement_2?: string | null; weight_type?: string | null; container_types?: string | null; vehicle_data?: string | null; origin_location?: string | null; destination_location?: string | null; transport_itinerary?: string | null; destination_goods?: string | null; entry_exit_date?: string | null; delivery_date?: string | null; delivered_status?: string | null; received_by?: string | null; payment_date?: string | null; payment_receipt_num?: string | null; is_ctm_process?: string | null; is_subdivision?: boolean | null; acts_as_cd?: boolean | null; equipment_reviewed?: boolean | null; pedimento_arrived?: boolean | null; green_light_mx?: boolean | null; green_light_us?: boolean | null; red_light_mx?: boolean | null; red_light_us?: boolean | 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; system?: string | null; operation_type?: OperationType | null; invoice_type?: string | null; document_type?: string | null; invoice_number?: string | null; project_number?: string | null; purchase_order?: string | null; related_doc_id?: number | null; alternate_invoice?: string | null; invoice_ref?: string | null; proforma_number?: string | null; invoice_date?: string | null; capture_date: string; emission_date?: string | null; status?: "pending" | "processed" | "reversed" | boolean | null; processed_date?: string | null; who_processed?: string | null; capture_user?: string | null; traffic_light_status?: string | null; process_log?: string | null; status_rec?: number | null; status_rep?: string | null; observation_es?: string | null; observation_en?: string | null; comments_status?: string | null; vu_observations?: string | null; cfdi_uuid?: string | null; path_pdf?: string | null; path_xml?: string | null; subcompany?: string | null; party_count?: number | null; generate_id?: boolean | null; generate_desc_parties?: string | null; apply_manual_discount?: boolean | null; is_bulk?: boolean | null; download_substance?: boolean | null; download_class?: boolean | null; download_def?: boolean | null; total_items?: number | null; payment_terms?: string | null; handling_fees?: number | null; option_iv18?: string | null; enajenation_goods?: boolean | null; compliance_mx?: InvoiceComplianceMx | null; financials?: InvoiceFinancials | null; logistics?: InvoiceLogistics | null; details?: InvoiceSalesDetails[]; collections?: InvoiceCollections[]; // Client-side only properties is_selected?: boolean; } export interface InvoiceListResponse { items: Invoice[]; total: number; page: number; page_size: number; } export interface CreateInvoiceData { system: string; operation_type: OperationType; invoice_type: string; document_type: string; invoice_number: string; project_number?: string | null; purchase_order?: string | null; related_doc_id?: number | null; alternate_invoice?: string | null; invoice_ref?: string | null; proforma_number?: string | null; invoice_date?: string | null; emission_date?: string | null; status?: "pending" | "processed" | "reversed" | boolean | null; processed_date?: string | null; who_processed?: string | null; capture_user?: string | null; traffic_light_status?: string | null; process_log?: string | null; status_rec?: number | null; status_rep?: string | null; observation_es?: string | null; observation_en?: string | null; comments_status?: string | null; vu_observations?: string | null; cfdi_uuid?: string | null; path_pdf?: string | null; path_xml?: string | null; subcompany?: string | null; party_count?: number | null; generate_id?: boolean | null; generate_desc_parties?: string | null; apply_manual_discount?: boolean | null; is_bulk?: boolean | null; download_substance?: boolean | null; download_class?: boolean | null; download_def?: boolean | null; payment_terms?: string | null; handling_fees?: number | null; option_iv18?: string | null; enajenation_goods?: boolean | null; compliance_mx?: Omit | null; financials?: Omit | null; logistics?: Omit | null; details?: Omit[] | null; collections?: Omit[] | null; } export interface UpdateInvoiceData { id: number; // Required by backend operation_type?: OperationType | null; invoice_type?: string | null; document_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; status?: "pending" | "processed" | "reversed" | boolean | null; compliance_mx?: Partial | null; financials?: Partial | null; logistics?: Partial[] | null; details?: Partial[] | null; collections?: Partial[] | null; } /** * API para Facturas */ export const invoicesApi = { /** * Lista todas las facturas con paginación */ list: (companyId: number, page = 1, pageSize = 50, filters?: Record) => { 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(`/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(`/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(`/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(`/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()}`); }, /** * Obtiene datos para la creación de una factura (catálogos consolidados) */ getCreationData: (companyId: number, operationType: string, invoiceType?: string | null) => { const params = new URLSearchParams({ company_id: companyId.toString(), operation_type: operationType }); if (invoiceType) { params.set('invoice_type', invoiceType); } return api.get(`/v1/a76/invoices/creation-data?${params.toString()}`); }, /** * Obtiene datos para la edición de una factura (catálogos consolidados + factura) */ getEditionData: (invoiceId: number, companyId: number) => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.get(`/v1/a76/invoices/${invoiceId}/edition-data?${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(`/v1/a76/invoices/${invoiceId}/logistics/?${params.toString()}`); }, create: (invoiceId: number, companyId: number, data: Omit) => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.post(`/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(`/v1/a76/invoices/${invoiceId}/details/?${params.toString()}`); }, create: (invoiceId: number, companyId: number, data: Omit) => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.post(`/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(`/v1/a76/invoices/${invoiceId}/collections/?${params.toString()}`); }, create: (invoiceId: number, companyId: number, data: Omit) => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.post(`/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()}`); } }, processInvoice: (invoiceId: number, companyId: number) => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.post<{ task_id: string }>( `/v1/a76/invoices/${invoiceId}/process?${params.toString()}`, {} ); }, getProcessStatus: (taskId: string) => { return api.get<{ state: 'PROCESSING' | 'SUCCESS' | 'FAILURE'; info?: { current: number; status: string }; result?: { status: 'success' | 'validation_error' | 'error'; invoice_id?: number; message?: string; errors?: Array<{ field: string; message: string; code?: string; solution?: string[] }>; sql_errors?: Array<{ consecutive: number; error: string }>; }; }>(`/v1/a76/invoices/process/${taskId}/status`); }, revertInvoice: (invoiceId: number, companyId: number) => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.post<{ task_id: string }>( `/v1/a76/invoices/${invoiceId}/revert?${params.toString()}`, {} ); }, getRevertStatus: (taskId: string) => { return api.get<{ state: 'PROCESSING' | 'SUCCESS' | 'FAILURE'; info?: { current: number; status: string }; result?: { status: 'success' | 'validation_error' | 'error'; invoice_id?: number; message?: string; errors?: Array<{ field: string; message: string; code?: string; solution?: string[] }>; sql_errors?: Array<{ consecutive: number; error: string }>; }; }>(`/v1/a76/invoices/revert/${taskId}/status`); }, generateCove: (invoiceId: number, companyId: number, recipientEmail?: string | null) => { const params = new URLSearchParams({ company_id: companyId.toString() }); const body: Record = { company_id: companyId }; if (recipientEmail) { body.recipient_email = recipientEmail; } return api.post<{ task_id: string }>( `/v1/a76/factura-cove/invoices/${invoiceId}/cove?${params.toString()}`, body ); }, getCoveStatus: (taskId: string) => { return api.get<{ state: 'PROCESSING' | 'SUCCESS' | 'FAILURE'; info?: { current: number; status: string }; result?: { status: 'success' | 'validation_error' | 'error'; invoice_id?: number; cove_number?: string; vucem_operation_num?: string; message?: string; errors?: Array<{ field: string; message: string; code?: string; solution?: string[] }>; }; }>(`/v1/a76/factura-cove/invoices/cove/${taskId}/status`); }, checkCoveEligibility: (invoiceId: number, companyId: number) => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.get<{ can_generate: boolean; reasons: Array<{ field: string; message: string }>; }>(`/v1/a76/factura-cove/invoices/${invoiceId}/cove/eligibility?${params.toString()}`); }, getCoveReceipt: (invoiceId: number, companyId: number, forceRefresh = false): Promise => { const params = new URLSearchParams({ company_id: companyId.toString() }); if (forceRefresh) params.set('force_refresh', 'true'); return api.getBlob( `/v1/a76/factura-cove/invoices/${invoiceId}/cove/acuse?${params.toString()}` ); }, copyInvoice: (invoiceId: number, companyId: number, newInvoiceNumber?: string) => { const params = new URLSearchParams({ company_id: companyId.toString() }); if (newInvoiceNumber) params.set('new_invoice_number', newInvoiceNumber); return api.post(`/v1/a76/invoices/${invoiceId}/copy?${params.toString()}`, {}); }, copyInvoiceHeader: (invoiceId: number, companyId: number) => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.post(`/v1/a76/invoices/${invoiceId}/copy-header?${params.toString()}`, {}); }, exportItems: (invoiceId: number, companyId: number, format: 'csv' | 'xlsx' | 'txt'): Promise => { const params = new URLSearchParams({ company_id: companyId.toString(), format }); return api.getBlob(`/v1/a76/invoices/${invoiceId}/export?${params.toString()}`); }, downloadGmTransport: (invoiceId: number, companyId: number): Promise => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.getBlob(`/v1/a76/invoices/${invoiceId}/interfaces/gm-transport?${params.toString()}`); }, downloadCartaPorte: (invoiceId: number, companyId: number): Promise => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.getBlob(`/v1/a76/invoices/${invoiceId}/interfaces/carta-porte?${params.toString()}`); }, downloadTfc: (invoiceId: number, companyId: number): Promise => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.getBlob(`/v1/a76/invoices/${invoiceId}/interfaces/tfc?${params.toString()}`); }, downloadCartaPorteConsolidada: (invoiceId: number, companyId: number): Promise => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.getBlob(`/v1/a76/invoices/${invoiceId}/interfaces/carta-porte-consolidada?${params.toString()}`); }, downloadAvisoCruce: (invoiceId: number, companyId: number): Promise => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.getBlob(`/v1/a76/invoices/${invoiceId}/interfaces/aviso-cruce?${params.toString()}`); }, downloadAaduanalRs: (invoiceId: number, companyId: number): Promise => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.getBlob(`/v1/a76/invoices/${invoiceId}/interfaces/aaduanal-rs?${params.toString()}`); }, downloadCaaarem: (invoiceId: number, companyId: number): Promise => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.getBlob(`/v1/a76/invoices/${invoiceId}/interfaces/caaarem?${params.toString()}`); }, downloadCpGenesis: (invoiceId: number, companyId: number): Promise => { const params = new URLSearchParams({ company_id: companyId.toString() }); return api.getBlob(`/v1/a76/invoices/${invoiceId}/interfaces/cp-genesis?${params.toString()}`); } };