diff --git a/backend/api/v1/modules/a76/invoices/imports/temporary/validators/create.py b/backend/api/v1/modules/a76/invoices/imports/temporary/validators/create.py index b52049e7..79a6f0cb 100644 --- a/backend/api/v1/modules/a76/invoices/imports/temporary/validators/create.py +++ b/backend/api/v1/modules/a76/invoices/imports/temporary/validators/create.py @@ -14,7 +14,7 @@ def validate_create(db: Session, invoice: InvoiceHeaderCreate, tenant_id: int, c if not invoice.invoice_type: errors.add_required_error("invoice_type") - if not invoice.document_type: + if not invoice.document_type and invoice.invoice_type != "MEX": errors.add_required_error("document_type") if not invoice.invoice_number: diff --git a/backend/api/v1/modules/a76/invoices/imports/temporary/validators/update.py b/backend/api/v1/modules/a76/invoices/imports/temporary/validators/update.py index da4cc970..97ee1843 100644 --- a/backend/api/v1/modules/a76/invoices/imports/temporary/validators/update.py +++ b/backend/api/v1/modules/a76/invoices/imports/temporary/validators/update.py @@ -224,9 +224,10 @@ def validate_update( else: invoice_data.compliance_mx.aduana = existing_invoice.compliance_mx.aduana if existing_invoice.compliance_mx else None - # Validar que aduana sea obligatorio - if not invoice_data.compliance_mx or not invoice_data.compliance_mx.aduana: - errors.add_required_error("aduana") + # Validar que aduana sea obligatorio (excepto para MEX) + if existing_invoice.invoice_type != "MEX": + if not invoice_data.compliance_mx or not invoice_data.compliance_mx.aduana: + errors.add_required_error("aduana") # Columna AC: Sección de Despacho / Puerto de Entrada (Opcional) if invoice_data.compliance_mx and invoice_data.compliance_mx.port_of_entry: diff --git a/backend/api/v1/modules/a76/invoices/models.py b/backend/api/v1/modules/a76/invoices/models.py index 402054a1..f3f9e0c7 100644 --- a/backend/api/v1/modules/a76/invoices/models.py +++ b/backend/api/v1/modules/a76/invoices/models.py @@ -58,7 +58,7 @@ class TransportType(str, Enum): PLATES = "licence plates" TRUCK = "truck" VESSEL = "vessel" - BARGE = "rail barge" + BARGE = "rail_barge" CONTAINER = "container" AIRPLANE = "airplane" GONDOLA = "gondola" @@ -82,9 +82,10 @@ class InvoiceHeader(Base, TenantScopedMixin, TimestampMixin): invoice_type: Mapped[str] = mapped_column( ForeignKey("public.invoice_types.key") ) # TIPOFACTURA / TIPODOC - document_type: Mapped[str] = mapped_column( - ForeignKey("public.pedimento_regimens.code") - ) # CLAVEDOCUMENTO / Clave de documento + document_type: Mapped[Optional[str]] = mapped_column( + ForeignKey("public.pedimento_regimens.code"), nullable=True + ) + # CLAVEDOCUMENTO / Clave de documento invoice_number: Mapped[str] = mapped_column( String(100) ) # FACTURAIMPO/FACTURAEXPO/FACTURAREMISION/FACTURAENVIO/FACTURASALIDA @@ -299,6 +300,9 @@ class InvoiceComplianceMx(Base, TenantScopedMixin, TimestampMixin): act_value: Mapped[Optional[str]] = mapped_column( String(5) ) # ACTVALOR / Actualizar valor + rule_3121_parties_ii: Mapped[Optional[bool]] = mapped_column( + Boolean, default=False, server_default="false" + ) # REGLA3121PARTESII / Regla 3.1.21 Partes II is_pedimento_pending: Mapped[Optional[bool]] = mapped_column( Boolean, default=False, server_default="false" ) # PED_PENDIENTE_ASIGNAR (Mapear 1 -> True, 0 -> False) @@ -375,7 +379,7 @@ class InvoiceComplianceMx(Base, TenantScopedMixin, TimestampMixin): String(1) ) # RAZONEXPORTACION / Razón de exportación signature_key: Mapped[Optional[str]] = mapped_column( - String(10) + String(100) ) # CLAVEFIRMA / Clave de firma # SM specific diff --git a/backend/api/v1/modules/a76/invoices/schemas.py b/backend/api/v1/modules/a76/invoices/schemas.py index 1c3995df..1ac300c9 100644 --- a/backend/api/v1/modules/a76/invoices/schemas.py +++ b/backend/api/v1/modules/a76/invoices/schemas.py @@ -22,8 +22,8 @@ class InvoiceHeaderBase(BaseModel): invoice_type: Optional[str] = Field( None, max_length=5, description="Invoice type key" ) - document_type: str = Field( - ..., max_length=3, description="Document type (Regimen Aduanero)" + document_type: Optional[str] = Field( + None, max_length=3, description="Document type (Regimen Aduanero)" ) invoice_number: Optional[str] = Field( None, max_length=100, description="Invoice number" @@ -139,6 +139,9 @@ class InvoiceComplianceMxBase(BaseModel): which_exchange_rate: Optional[str] = Field( None, max_length=5, description="Which exchange rate" ) + rule_3121_parties_ii: Optional[bool] = Field( + False, description="Is Rule 3.1.21 Parties II" + ) value_method: Optional[str] = Field(None, max_length=2, description="Value method") act_value: Optional[str] = Field(None, max_length=5, description="Act value") is_pedimento_pending: bool = Field(..., description="Is pedimento pending") @@ -187,7 +190,7 @@ class InvoiceComplianceMxBase(BaseModel): None, max_length=1, description="Reason for export" ) signature_key: Optional[str] = Field( - None, max_length=10, description="Signature key" + None, max_length=100, description="Signature key" ) sem_id: Optional[int] = Field(None, description="SEM ID") diff --git a/backend/api/v1/modules/a76/invoices/services.py b/backend/api/v1/modules/a76/invoices/services.py index 273049af..f3b0681b 100644 --- a/backend/api/v1/modules/a76/invoices/services.py +++ b/backend/api/v1/modules/a76/invoices/services.py @@ -128,6 +128,10 @@ class InvoiceService: invoice_dict = clean_dict(raw_invoice_dict) invoice_dict["tenant_id"] = tenant_id invoice_dict["company_id"] = company_id + + # Ensure document_type respects DB constraints for MEX invoices (bypass clean_dict) + if invoice_dict.get("invoice_type") == "MEX" and not invoice_dict.get("document_type"): + invoice_dict["document_type"] = None new_invoice = models.InvoiceHeader(**invoice_dict) diff --git a/backend/api/v1/modules/public/reference_data/invoice_types/seed.py b/backend/api/v1/modules/public/reference_data/invoice_types/seed.py index 151163dd..1b42742a 100644 --- a/backend/api/v1/modules/public/reference_data/invoice_types/seed.py +++ b/backend/api/v1/modules/public/reference_data/invoice_types/seed.py @@ -28,6 +28,13 @@ seed = [ "both", "imp", ), + ( + "REP", + "REPARACION", + "REPARACION DE ACTIVOS FIJOS", + "fixed asset", + "imp", + ), # === TIPOS DE EXPORTACION === ("DONAC", "DONACION", "", "both", "exp"), diff --git a/backend/sync_invoice_types.py b/backend/sync_invoice_types.py new file mode 100644 index 00000000..cdcf23b5 --- /dev/null +++ b/backend/sync_invoice_types.py @@ -0,0 +1,35 @@ +from core.database import CoreSessionLocal +from api.v1.modules.public.reference_data.invoice_types.models import InvoiceType +from api.v1.modules.public.reference_data.invoice_types.seed import seed + +def sync_invoice_types(): + db = CoreSessionLocal() + try: + for s in seed: + key, description, note, type_, operation = s + obj = db.query(InvoiceType).filter(InvoiceType.key == key).first() + if obj: + print(f"Updating {key}...") + obj.description = description + obj.note = note + obj.type = type_ + obj.operation = operation + else: + print(f"Creating {key}...") + obj = InvoiceType( + key=key, + description=description, + note=note, + type=type_, + operation=operation + ) + db.add(obj) + db.commit() + except Exception as e: + print(f"Error: {e}") + db.rollback() + finally: + db.close() + +if __name__ == "__main__": + sync_invoice_types() diff --git a/frontend/messages/en.json b/frontend/messages/en.json index e2563ba5..8abbec08 100644 --- a/frontend/messages/en.json +++ b/frontend/messages/en.json @@ -82,7 +82,8 @@ "temporary": "Temporary", "definitive": "Definitive", "mexican_purchases": "Mexican Purchases", - "regime_change": "Regime Change" + "regime_change": "Regime Change", + "repair": "Repair" }, "export_invoices": { "title": "Export Invoices", diff --git a/frontend/messages/es.json b/frontend/messages/es.json index 1caa7503..3be2f6be 100644 --- a/frontend/messages/es.json +++ b/frontend/messages/es.json @@ -82,7 +82,8 @@ "temporary": "Temporal", "definitive": "Definitiva", "mexican_purchases": "Compras mexicanas", - "regime_change": "Cambio de régimen" + "regime_change": "Cambio de régimen", + "repair": "Reparación" }, "export_invoices": { "title": "Facturas de exportación", diff --git a/frontend/src/lib/api/dashboard/a76/invoices.ts b/frontend/src/lib/api/dashboard/a76/invoices.ts index 6b00d38b..99973e13 100644 --- a/frontend/src/lib/api/dashboard/a76/invoices.ts +++ b/frontend/src/lib/api/dashboard/a76/invoices.ts @@ -73,6 +73,7 @@ export interface InvoiceComplianceMx { reason_export?: string | null; signature_key?: string | null; sem_id?: number | null; + rule_3121_parties_ii?: boolean | null; } export interface InvoiceFinancials { diff --git a/frontend/src/lib/components/dashboard/export/manifest/manifest-form.svelte b/frontend/src/lib/components/dashboard/export/manifest/manifest-form.svelte index 3bb3f9b4..9a57d055 100644 --- a/frontend/src/lib/components/dashboard/export/manifest/manifest-form.svelte +++ b/frontend/src/lib/components/dashboard/export/manifest/manifest-form.svelte @@ -269,7 +269,7 @@ // Helper to check if Repar request const isRepar = (t: string | undefined) => { - return t && t.toUpperCase().includes('REPAR'); + return t === 'REPAR'; }; // Categorize diff --git a/frontend/src/lib/components/dashboard/invoices/edit/PortSelectorModal.svelte b/frontend/src/lib/components/dashboard/invoices/edit/PortSelectorModal.svelte new file mode 100644 index 00000000..73308ed6 --- /dev/null +++ b/frontend/src/lib/components/dashboard/invoices/edit/PortSelectorModal.svelte @@ -0,0 +1,108 @@ + + + + + + Seleccionar Puerto (Aduana/Sección) + Busca y selecciona una sección aduanera de la lista. + + +
+
+ + +
+ +
+ {#if loading} +
+ +
+ {:else if filteredSections.length > 0} + + + + + + + + + + {#each filteredSections as section} + handleSelect(section)}> + + + + + {/each} + +
CódigoNombre / Sección
{section.customs_code}{section.section_name} + +
+ {:else} +
No se encontraron resultados
+ {/if} +
+
+ + + + +
+
diff --git a/frontend/src/lib/components/dashboard/invoices/edit/continuation-tab-form.svelte b/frontend/src/lib/components/dashboard/invoices/edit/continuation-tab-form.svelte index 0df763c5..1f89d8fc 100644 --- a/frontend/src/lib/components/dashboard/invoices/edit/continuation-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/invoices/edit/continuation-tab-form.svelte @@ -4,18 +4,22 @@ import { Checkbox } from '$lib/components/ui/checkbox'; import { RadioGroup, RadioGroupItem } from '$lib/components/ui/radio-group'; import { Button } from '$lib/components/ui/button'; + import { Search } from 'lucide-svelte'; + import PortSelectorModal from './PortSelectorModal.svelte'; import type { Invoice } from '$lib/api/dashboard/a76/invoices'; let { invoice, formData = $bindable(), exists = $bindable(), - operationType = undefined + operationType = undefined, + invoiceType = undefined }: { invoice: Invoice | null; formData?: any; exists?: boolean; operationType?: number; + invoiceType?: string; } = $props(); if (!formData && invoice) { @@ -28,6 +32,7 @@ cantidad_guias_embarque: invoice.logistics?.guide_number || null, destino_origen: invoice.logistics?.destination_location || '', puerto_entrada: invoice.logistics?.origin_location || '', + vehicle_data: invoice.logistics?.vehicle_data || '', // Checkboxes fue_revisado_equipo: invoice.logistics?.equipment_reviewed || false, sub_division: invoice.logistics?.is_subdivision || false, @@ -60,6 +65,7 @@ cantidad_guias_embarque: null, destino_origen: '', puerto_entrada: '', + vehicle_data: '', // Checkboxes fue_revisado_equipo: false, sub_division: false, @@ -84,6 +90,11 @@ }; exists = false; } + let showPortModal = $state(false); + + function handlePortSelect(section: any) { + formData.puerto_entrada = section.customs_code; + } @@ -104,7 +115,8 @@
- + +
@@ -147,7 +159,7 @@ />
- {#if operationType === 1} + {#if operationType === 1 || invoiceType === 'CR' || invoiceType === 'REP'}
@@ -164,14 +176,28 @@ {/if}
- {#if operationType !== 1} + {#if operationType !== 1 && invoiceType !== 'CR'}
- +
+ + +
{/if} - {#if operationType === 1} + {#if operationType === 1 || invoiceType === 'CR'}
@@ -216,25 +242,25 @@
- {#if operationType !== 1} + {#if operationType !== 1 && invoiceType !== 'CR'}
-
- - -
-
- - -
- {/if} - {#if operationType !== 1} -
- - -
+ {#if invoiceType !== 'REP' && invoiceType !== 'REPAR'} +
+ + +
+
+ + +
+
+ + +
+ {/if} {/if}
@@ -305,7 +331,7 @@
- {#if operationType === 1} + {#if operationType === 1 || invoiceType === 'CR'}

@@ -327,3 +353,5 @@ {/if}

+ + diff --git a/frontend/src/lib/components/dashboard/invoices/edit/general-tab-form.svelte b/frontend/src/lib/components/dashboard/invoices/edit/general-tab-form.svelte index c79b530c..626a106d 100644 --- a/frontend/src/lib/components/dashboard/invoices/edit/general-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/invoices/edit/general-tab-form.svelte @@ -4,7 +4,7 @@ import * as Select from '$lib/components/ui/select'; import * as RadioGroup from '$lib/components/ui/radio-group'; import { Button } from '$lib/components/ui/button'; - import { Search } from 'lucide-svelte'; + import { Search, Upload } from 'lucide-svelte'; import ManifestSelectorModal from './ManifestSelectorModal.svelte'; import type { Invoice } from '$lib/api/dashboard/a76/invoices'; import type { InvoiceType } from '$lib/api/dashboard/reference_data/invoice_types'; @@ -32,7 +32,8 @@ codePedimentoRegimens = [], operationType = undefined, defaultOperationType = undefined, - exchangeRate = undefined + exchangeRate = undefined, + invoiceType = undefined }: { invoice: Invoice | null; formData?: any; @@ -52,6 +53,7 @@ defaultInvoiceType?: string | null; operationType?: number | null; exchangeRate?: number | null; + invoiceType?: string; } = $props(); let showManifestModal = $state(false); @@ -96,7 +98,9 @@ transport_num: invoice.logistics?.vehicle_num || '', aduana: invoice.compliance_mx?.aduana || '', document_type: invoice.document_type || '', - manifest_number: invoice.compliance_mx?.manifest_number || '' + manifest_number: invoice.compliance_mx?.manifest_number || '', + code_signature: invoice.compliance_mx?.signature_key || '', + electronic_signature: invoice.compliance_mx?.electronic_signature || '' }; } else { // Creando una nueva factura @@ -126,7 +130,9 @@ transport_num: '', aduana: '', document_type: '', - manifest_number: '' + manifest_number: '', + code_signature: '', + electronic_signature: '' }; } } else { @@ -176,7 +182,7 @@ ]; const soldToHeaderOptions = $derived( - operationType === 1 + operationType === 1 || invoiceType === 'CR' ? [ { value: 'consignado_a', label: 'Consignado a' }, { value: 'vendido_a', label: 'Vendido a' }, @@ -190,7 +196,7 @@ ); const shippedToHeaderOptions = $derived( - operationType === 1 + operationType === 1 || invoiceType === 'CR' ? [ { value: 'enviado_a', label: 'Enviado a' }, { value: 'transferido_a', label: 'Transferido a' }, @@ -204,7 +210,7 @@ ); const shippedByHeaderOptions = $derived( - operationType === 1 + operationType === 1 || invoiceType === 'CR' ? [ { value: 'enviado_por', label: 'Enviado Por' }, { value: 'vendido_por', label: 'Vendido Por' }, @@ -296,25 +302,27 @@
-

Datos del pedimento

-
-
- Fecha del: -

{formData.fecha_pedimento_del || '-'}

+ {#if invoiceType !== 'MEX'} +

Datos del pedimento

+
+
+ Fecha del: +

{formData.fecha_pedimento_del || '-'}

+
+
+ Fecha al: +

{formData.fecha_pedimento_al || '-'}

+
+
+ Clave: +

{formData.clave_pedimento || '-'}

+
+
+ Régimen: +

{formData.regimen_pedimento || '-'}

+
-
- Fecha al: -

{formData.fecha_pedimento_al || '-'}

-
-
- Clave: -

{formData.clave_pedimento || '-'}

-
-
- Régimen: -

{formData.regimen_pedimento || '-'}

-
-
+ {/if}

@@ -471,7 +479,7 @@ *

- {#if operationType === 1} + {#if operationType === 1 || invoiceType === 'CR'}
- {#if operationType !== 1} + {#if operationType !== 1 && invoiceType !== 'MEX' && invoiceType !== 'CR' && invoiceType !== 'REP' && invoiceType !== 'REPAR'}
{/if} - {#if operationType === 1} + {#if operationType === 1 || invoiceType === 'CR'}
@@ -719,37 +727,39 @@

Transportista

-
- - { - formData.carrier_id = v || null; - }} - > - - - {#if formData.carrier_id} - {transporters.find( - (t) => String(t.transporter_key) === String(formData.carrier_id) - )?.name || formData.carrier_id} - {:else if transporters.length > 0} - Selecciona transportista... - {:else} - Sin datos - {/if} - - - - {#each transporters as transporter} - - {transporter.transporter_key} - - {/each} - - -
+ {#if invoiceType !== 'MEX'} +
+ + { + formData.carrier_id = v || null; + }} + > + + + {#if formData.carrier_id} + {transporters.find( + (t) => String(t.transporter_key) === String(formData.carrier_id) + )?.name || formData.carrier_id} + {:else if transporters.length > 0} + Selecciona transportista... + {:else} + Sin datos + {/if} + + + + {#each transporters as transporter} + + {transporter.transporter_key} + + {/each} + + +
+ {/if}
@@ -872,71 +882,91 @@
-
- - { - formData.aduana = v ?? ''; - }} - > - - - {#if formData.aduana} - {customsSections.find((cs) => cs.customs_code === formData.aduana)?.section_name || - formData.aduana} - {:else if customsSections.length > 0} - Selecciona aduana... - {:else} - Sin datos - {/if} - - - - {#each customsSections as section} - - {section.customs_code} - {section.section_name} - - {/each} - - -
+ {#if invoiceType !== 'MEX'} +
+ + { + formData.aduana = v ?? ''; + }} + > + + + {#if formData.aduana} + {customsSections.find((cs) => cs.customs_code === formData.aduana) + ?.section_name || formData.aduana} + {:else if customsSections.length > 0} + Selecciona aduana... + {:else} + Sin datos + {/if} + + + + {#each customsSections as section} + + {section.customs_code} - {section.section_name} + + {/each} + + +
+ {/if} -
- - { - formData.document_type = v ?? ''; - }} - > - - - {#if formData.document_type} - {codePedimentoRegimens.find((r) => r.regimen_code === formData.document_type) - ?.regimen_code || formData.document_type} - {:else if filteredRegimens.length > 0} - Selecciona régimen... - {:else if operationType} - Sin regímenes para tipo {operationType} - {:else} - Selecciona tipo de operación primero - {/if} - - - - {#each filteredRegimens as regimen} - - {regimen.regimen_code} - - {/each} - - -
+ {#if invoiceType !== 'MEX'} +
+ + { + formData.document_type = v ?? ''; + }} + > + + + {#if formData.document_type} + {codePedimentoRegimens.find((r) => r.regimen_code === formData.document_type) + ?.regimen_code || formData.document_type} + {:else if filteredRegimens.length > 0} + Selecciona régimen... + {:else if operationType} + Sin regímenes para tipo {operationType} + {:else} + Selecciona tipo de operación primero + {/if} + + + + {#each filteredRegimens as regimen} + + {regimen.regimen_code} + + {/each} + + +
+ {/if} + + {#if invoiceType === 'MEX'} +
+ +
+ + +
+
+ {/if}
diff --git a/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte b/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte index cbbad85e..82adf098 100644 --- a/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte +++ b/frontend/src/lib/components/dashboard/invoices/edit/invoice-top-fields.svelte @@ -13,7 +13,8 @@ invoiceTypes = [], pedimentos = [], defaultOperationType = undefined, - defaultInvoiceType = undefined + defaultInvoiceType = undefined, + invoiceType = undefined }: { invoice: Invoice | null; formData?: any; @@ -21,6 +22,7 @@ pedimentos?: Pedimento[]; defaultOperationType?: string | null; defaultInvoiceType?: string | null; + invoiceType?: string; } = $props(); function handlePedimentoChange(pedimentoId: string) { @@ -81,7 +83,10 @@ fecha_pedimento_del: '', fecha_pedimento_al: '', clave_pedimento: '', - regimen_pedimento: '' + regimen_pedimento: '', + // Campos específicos para MEX + iva_factor: invoice?.financials?.iva_factor || '', + alternate_invoice: invoice?.alternate_invoice || '' }; } else { // Si formData ya existe pero operation_type está vacío, usar defaultOperationType @@ -92,7 +97,29 @@ ) { formData.operation_type = defaultOperationType; } + // Ensure new fields exist if formData was created before + if (formData.iva_factor === undefined) + formData.iva_factor = invoice?.financials?.iva_factor || ''; + if (formData.alternate_invoice === undefined) + formData.alternate_invoice = invoice?.alternate_invoice || ''; } + // Filter invoice types based on operation type + let filteredInvoiceTypes = $derived( + invoiceTypes.filter((type) => { + if (!formData.operation_type) return true; + return type.operation === 'both' || type.operation === formData.operation_type; + }) + ); + + // Reset invoice_type if not valid for new operation_type + $effect(() => { + if (formData.operation_type && formData.invoice_type) { + const isValid = filteredInvoiceTypes.some((t) => t.key === formData.invoice_type); + if (!isValid) { + formData.invoice_type = ''; + } + } + }); @@ -136,7 +163,7 @@ - {#each invoiceTypes as type} + {#each filteredInvoiceTypes as type} {type.key} - {type.description} @@ -145,47 +172,52 @@ -
- - { - formData.is_pedimento_pending = checked; - }} - /> -
-
- - { - formData.pedimento_id = v ? parseInt(v) : null; - if (v) { - handlePedimentoChange(v); - } - }} - > - - - {formData.pedimento || 'Selecciona pedimento...'} - - - - {#each pedimentos as pedimento} - - {pedimento.customs_office?.slice(0, 2)}-{pedimento.license}-{pedimento.pedimento_number} - - {/each} - - -
+ {#if invoiceType !== 'MEX'} +
+ + { + formData.is_pedimento_pending = checked; + }} + /> +
+
+ + { + formData.pedimento_id = v ? parseInt(v) : null; + if (v) { + handlePedimentoChange(v); + } + }} + > + + + {formData.pedimento || 'Selecciona pedimento...'} + + + + {#each pedimentos as pedimento} + + {pedimento.customs_office?.slice( + 0, + 2 + )}-{pedimento.license}-{pedimento.pedimento_number} + + {/each} + + +
-
- - -
+
+ + +
+ {/if}
+ + {#if invoiceType === 'MEX'} +
+ + +
+
+ + +
+ {/if} diff --git a/frontend/src/lib/components/dashboard/invoices/edit/items/items-tab-form.svelte b/frontend/src/lib/components/dashboard/invoices/edit/items/items-tab-form.svelte index 37815876..cce7734a 100644 --- a/frontend/src/lib/components/dashboard/invoices/edit/items/items-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/invoices/edit/items/items-tab-form.svelte @@ -16,12 +16,14 @@ invoice, formData = $bindable(), exists = $bindable(), - operationType = undefined + operationType = undefined, + invoiceType = undefined }: { invoice: Invoice | null; formData?: any; exists?: boolean; operationType?: number; + invoiceType?: string; } = $props(); let imported = 0; @@ -258,10 +260,10 @@ } // Load part number data - if (line.part_number_id) { + if (line.part_number) { try { const response = await fetch( - `/api-sveltekit/parts/${line.part_number_id}?company_id=${activeCompanyId}`, + `/api-sveltekit/parts/${line.part_number}?company_id=${activeCompanyId}`, { method: 'GET', headers: { 'Content-Type': 'application/json' } } ); if (response.ok) { @@ -733,6 +735,30 @@ Descripción Esp. Subpartidas Partida Princ. + {:else if invoiceType === 'CR'} + Línea + Factura Impo + Lin Impo + P/S + Cantidad Exportada + Clase + Número de Parte + Descripción en Español + Contiene Subpartida + Partida Principal + {:else if invoiceType === 'REP' || invoiceType === 'REPAR'} + Línea + No. Factura Expo + Línea Expo + P/S + Clase + Num. Parte + Descripción en Español + Cantidad Importada + UM + Preferencia + Contiene Subpartida + Partida Principal {:else} Línea P/S @@ -782,6 +808,40 @@ {item.fa_data?.contains_subitems ? 'Sí' : 'No'} {item.warehouse || '-'} + {:else if invoiceType === 'CR'} + {item.line_number} + {item.fa_data?.search_invoice || '-'} + {item.fa_data?.search_line || '-'} + {item.is_subitem ? 'S' : 'P'} + {item.quantity?.quantity || '0'} + {item.class_code || '-'} + {item.part_number || '-'} + + {item.description?.description_spanish || '-'} + + {item.fa_data?.contains_subitems ? 'Sí' : 'No'} + {item.warehouse || '-'} + {:else if invoiceType === 'REP' || invoiceType === 'REPAR'} + {item.line_number} + {item.fa_data?.search_invoice || '-'} + {item.fa_data?.search_line || '-'} + {item.is_subitem ? 'S' : 'P'} + {item.class_code || '-'} + {item.part_number || '-'} + + {item.description?.description_spanish || '-'} + + {item.quantity?.quantity || '0'} + {item.unit_of_measure_code || '-'} + {item.reference_number || '-'} + {item.fa_data?.contains_subitems ? 'Sí' : 'No'} + {item.warehouse || '-'} {:else} {item.line_number} {item.is_subitem ? 'S' : 'P'} diff --git a/frontend/src/lib/components/dashboard/invoices/edit/observations-tab-form.svelte b/frontend/src/lib/components/dashboard/invoices/edit/observations-tab-form.svelte index 7d69bef7..87405e85 100644 --- a/frontend/src/lib/components/dashboard/invoices/edit/observations-tab-form.svelte +++ b/frontend/src/lib/components/dashboard/invoices/edit/observations-tab-form.svelte @@ -12,7 +12,8 @@ seals = [], incoterms = [], enclosure = [], - operationType = undefined + operationType = undefined, + invoiceType = undefined }: { invoice: Invoice | null; formData?: any; @@ -21,6 +22,7 @@ incoterms?: any[]; enclosure?: any[]; operationType?: number; + invoiceType?: string; } = $props(); if (!formData && invoice) { @@ -53,7 +55,8 @@ complement_1: invoice.logistics?.complement_1 || '', identifier_2: invoice.logistics?.identifier_2 || '', complement_2: invoice.logistics?.complement_2 || '', - office_document: invoice.compliance_mx?.office_document || '' + office_document: invoice.compliance_mx?.office_document || '', + is_mixed: invoice.compliance_mx?.is_mixed || false }; exists = true; } else if (!formData) { @@ -86,7 +89,8 @@ complement_1: '', identifier_2: '', complement_2: '', - office_document: '' + office_document: '', + is_mixed: false }; exists = false; } @@ -99,9 +103,11 @@

- {operationType === 1 + {operationType === 1 || invoiceType === 'CR' ? 'Observaciones de la factura mexicana:' - : 'Observacion de la factura mexicana y bilingue:'} + : invoiceType === 'MEX' + ? 'Observacion de la factura mexicana y bilingue:' + : 'Observacion de la factura mexicana y bilingue:'}