Enhance invoice processing and validation logic
- Updated `InvoiceService` to accurately reflect the number of line items in `party_count` for invoices. - Modified weight calculations in the create and update validators to ensure consistent handling of weight types, now using lowercase comparison for "KGS". - Adjusted invoice data structure in the frontend to include `total_items` and refined logistics handling. - Improved table rendering in the invoice edit component for better sticky header behavior and item visibility. These changes aim to improve data integrity and user experience in invoice management.
This commit is contained in:
@@ -61,7 +61,7 @@ def review_qty_vs_weight(
|
||||
continue
|
||||
|
||||
qty = line.quantity.quantity or Decimal(0)
|
||||
net_weight = getattr(line.quantity.quantity, None) or Decimal(0)
|
||||
net_weight = line.quantity.net_weight or Decimal(0)
|
||||
|
||||
if net_weight != qty:
|
||||
errors.add_error(
|
||||
|
||||
@@ -198,7 +198,7 @@ def _update_invoice_totals(invoice: InvoiceHeader) -> None:
|
||||
|
||||
# Marcar la factura como procesada
|
||||
invoice.status = InvoiceStatus.PROCESSED
|
||||
invoice.party_count = len(invoice.financials.__dict__) # se sobreescribirá con el conteo real
|
||||
invoice.party_count = len(lines)
|
||||
|
||||
# TODO: SSisGen:ActSeguridad = 1 → invoice.updated_by = current_user
|
||||
# TODO: SSisGen:CalValBaseTCPed = 1 →
|
||||
|
||||
@@ -10,6 +10,7 @@ from .imports.validators.update import validate_update as validate_update_import
|
||||
from .exports.validators.create import validate_create as validate_create_export
|
||||
from .exports.validators.update import validate_update as validate_update_export
|
||||
from .common.common_validators import invoice_exists
|
||||
from api.v1.modules.a76.items.models import LineItem
|
||||
|
||||
from . import models, schemas
|
||||
|
||||
@@ -166,6 +167,25 @@ class InvoiceService:
|
||||
|
||||
total = query.count()
|
||||
items = query.offset(skip).limit(limit).all()
|
||||
|
||||
# Keep party_count aligned with the real number of line items.
|
||||
# This avoids stale values stored in invoice_header.party_count.
|
||||
if items:
|
||||
invoice_ids = [inv.id for inv in items]
|
||||
counts = (
|
||||
db.query(LineItem.invoice_id, func.count(LineItem.id))
|
||||
.filter(
|
||||
LineItem.invoice_id.in_(invoice_ids),
|
||||
LineItem.tenant_id == tenant_id,
|
||||
LineItem.company_id == company_id,
|
||||
)
|
||||
.group_by(LineItem.invoice_id)
|
||||
.all()
|
||||
)
|
||||
count_map = {invoice_id: int(count) for invoice_id, count in counts}
|
||||
for inv in items:
|
||||
inv.party_count = count_map.get(inv.id, 0)
|
||||
|
||||
return items, total
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -248,18 +248,18 @@ def validate_create(
|
||||
|
||||
# Calcular peso neto en kilogramos (estándar interno)
|
||||
if unit_is_kgs:
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.net_weight = quantity
|
||||
else: # invoice en libras
|
||||
line.quantity.net_weight = quantity * Decimal("2.204624")
|
||||
elif unit_is_lbs:
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.net_weight = quantity / Decimal("2.204624")
|
||||
else: # invoice en libras
|
||||
line.quantity.net_weight = quantity
|
||||
else:
|
||||
# Otra unidad de medida - usar peso capturado y convertir si es necesario
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
# El peso capturado está en kilos
|
||||
line.quantity.net_weight = net_weight_input
|
||||
else:
|
||||
@@ -289,7 +289,7 @@ def validate_create(
|
||||
|
||||
# Si no se proporcionó peso bruto, calcularlo
|
||||
if not gross_weight_input or gross_weight_input == 0:
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.gross_weight = line.quantity.net_weight + (
|
||||
package_weight_unit * package_quantity
|
||||
)
|
||||
@@ -299,7 +299,7 @@ def validate_create(
|
||||
)
|
||||
else:
|
||||
# Convertir peso bruto capturado según tipo de factura
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.gross_weight = gross_weight_input
|
||||
else: # libras
|
||||
line.quantity.gross_weight = gross_weight_input / Decimal("2.204624")
|
||||
|
||||
@@ -95,21 +95,19 @@ def validate_update(
|
||||
# Se proporcionó nuevo peso neto, convertir según tipo
|
||||
net_weight_input = line.quantity.net_weight
|
||||
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.net_weight = net_weight_input
|
||||
else: # libras, convertir a kilos
|
||||
line.quantity.net_weight = net_weight_input / Decimal("2.204624")
|
||||
else:
|
||||
# Mantener peso existente
|
||||
line.quantity.net_weight = existing_line.quantity.net_weight
|
||||
|
||||
print(f"After weight conversion: net_weight={line.quantity.net_weight}, gross_weight={line.quantity.gross_weight}, weight_type={invoice_weight_type}")
|
||||
line.quantity.net_weight = existing_line.quantity.net_weight
|
||||
|
||||
# Convertir peso bruto si se proporcionó
|
||||
if line.quantity.gross_weight is not None:
|
||||
gross_weight_input = line.quantity.gross_weight
|
||||
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.gross_weight = gross_weight_input
|
||||
else: # libras, convertir a kilos
|
||||
line.quantity.gross_weight = gross_weight_input / Decimal("2.204624")
|
||||
|
||||
@@ -232,18 +232,18 @@ def validate_create(
|
||||
|
||||
# Calcular peso neto en kilogramos (estándar interno)
|
||||
if unit_is_kgs:
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.net_weight = quantity
|
||||
else: # invoice en libras
|
||||
line.quantity.net_weight = quantity * Decimal("2.204624")
|
||||
elif unit_is_lbs:
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.net_weight = quantity / Decimal("2.204624")
|
||||
else: # invoice en libras
|
||||
line.quantity.net_weight = quantity
|
||||
else:
|
||||
# Otra unidad de medida - usar peso capturado y convertir si es necesario
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
# El peso capturado está en kilos
|
||||
line.quantity.net_weight = net_weight_input
|
||||
else:
|
||||
@@ -273,7 +273,7 @@ def validate_create(
|
||||
|
||||
# Si no se proporcionó peso bruto, calcularlo
|
||||
if not gross_weight_input or gross_weight_input == 0:
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.gross_weight = line.quantity.net_weight + (
|
||||
package_weight_unit * package_quantity
|
||||
)
|
||||
@@ -283,7 +283,7 @@ def validate_create(
|
||||
)
|
||||
else:
|
||||
# Convertir peso bruto capturado según tipo de factura
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.gross_weight = gross_weight_input
|
||||
else: # libras
|
||||
line.quantity.gross_weight = gross_weight_input / Decimal("2.204624")
|
||||
|
||||
@@ -94,21 +94,19 @@ def validate_update(
|
||||
# Se proporcionó nuevo peso neto, convertir según tipo
|
||||
net_weight_input = line.quantity.net_weight
|
||||
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.net_weight = net_weight_input
|
||||
else: # libras, convertir a kilos
|
||||
line.quantity.net_weight = net_weight_input / Decimal("2.204624")
|
||||
else:
|
||||
# Mantener peso existente
|
||||
line.quantity.net_weight = existing_line.quantity.net_weight
|
||||
|
||||
print(f"After weight conversion: net_weight={line.quantity.net_weight}, gross_weight={line.quantity.gross_weight}, weight_type={invoice_weight_type}")
|
||||
line.quantity.net_weight = existing_line.quantity.net_weight
|
||||
|
||||
# Convertir peso bruto si se proporcionó
|
||||
if line.quantity.gross_weight is not None:
|
||||
gross_weight_input = line.quantity.gross_weight
|
||||
|
||||
if invoice_weight_type == "KGS":
|
||||
if invoice_weight_type.lower() == "kgs":
|
||||
line.quantity.gross_weight = gross_weight_input
|
||||
else: # libras, convertir a kilos
|
||||
line.quantity.gross_weight = gross_weight_input / Decimal("2.204624")
|
||||
|
||||
Reference in New Issue
Block a user