feat: enhance item validation by adding checks for valuation method and part number existence

This commit is contained in:
2026-02-11 14:30:10 -06:00
parent ef4f3cdeac
commit db85b91549
2 changed files with 58 additions and 8 deletions

View File

@@ -1,7 +1,7 @@
import logging
from typing import Optional, List, Tuple
from fastapi import HTTPException
from sqlalchemy import and_, or_
from sqlalchemy import and_, exists, or_
from sqlalchemy.exc import IntegrityError
from sqlalchemy.orm import Session, joinedload
from api.v1.modules.a76.invoices.common.common_validators import invoice_exists
@@ -25,6 +25,8 @@ from api.v1.modules.a76.general_catalogs.units_of_measure.models import UnitOfMe
from api.v1.modules.a76.general_catalogs.packages.models import Package
from api.v1.modules.public.reference_data.countries.models import Country
from api.v1.modules.public.reference_data.sectors.models import Sector
from api.v1.modules.public.reference_data.valuation_methods.models import ValuationMethod
from api.v1.modules.a76.parts.models import Part
from api.v1.modules.a76.general_catalogs.company.models import Company
def validate_common(
@@ -35,11 +37,13 @@ def validate_common(
errors: ErrorCollector,
line_number: int,
):
item_header = db.query(Item).filter(Item.id == line.item_id).first()
invoice: InvoiceHeader = invoice_exists(
db, line.invoice_id, tenant_id, company_id, errors
db, item_header.invoice_id, tenant_id, company_id, errors
)
line_item: LineItem = item_exists(
db, line.invoice_id, line.line_item, tenant_id, company_id
db, item_header.invoice_id, line.line_number, tenant_id, company_id
)
fecha_factura = invoice.invoice_date if invoice else None
@@ -245,9 +249,7 @@ def validate_common(
sector_db: Sector = (
db.query(Sector)
.filter(
Class.sector_code == sector,
Class.tenant_id == tenant_id,
Class.company_id == company_id,
Sector.key == sector
)
.scalar()
)
@@ -277,6 +279,53 @@ def validate_common(
)
if fraction:
search_fraction_preference()
search_fraction_preference(db=db, country=country, fraccion=fraction, fraction_type=fraction_type, sector=sector, invoice_date=fecha_factura, errors=errors)
if line.customs.american_fraction:
american_fraction_exists = db.query(exists().where(LineCustom.american_fraction == line.customs.american_fraction)).scalar()
if not american_fraction_exists:
errors.add_error(
field=f"line[{line_number}].customs.american_fraction",
message="La fracción americana especificada no existe.",
solution=["Proporciona una fracción americana valida."],
code="AMERICAN_FRACTION_NOT_FOUND",
)
if item_header and item_header.order:
if len(item_header.order) > 20:
errors.add_error(
field=f"item.order",
message="El campo orden no debe exceder los 20 caracteres.",
solution=["Proporciona un valor valido para el campo orden."],
code="ORDER_EXCEEDS_MAX_LENGTH",
)
unit_of_measure = line.unit_of_measure or (class_.unit_of_measure if class_ else None)
if unit_of_measure == "PZA" and line.quantity.quantity % 1 != 0:
errors.add_error(
field=f"line[{line_number}].quantity.quantity",
message="La cantidad debe ser un número entero cuando la unidad de medida es PZA.",
solution=["Proporciona una cantidad entera."],
code="QUANTITY_MUST_BE_INTEGER_FOR_PIECES",
)
if line.valuation_method:
valuation_method_exists = db.query(exists().where(ValuationMethod.key == line.valuation_method)).scalar()
if not valuation_method_exists:
errors.add_error(
field=f"line[{line_number}].valuation_method",
message="El método de valoración especificado no existe.",
solution=["Proporciona un método de valoración valido."],
code="VALUATION_METHOD_NOT_FOUND",
)
if line.part_number_id:
part_exists = db.query(exists().where(Part.id == line.part_number_id)).scalar()
if not part_exists:
errors.add_error(
field=f"line[{line_number}].part_number_id",
message="El número de parte especificado no existe.",
solution=["Proporciona un número de parte valido."],
code="PART_NUMBER_NOT_FOUND",
)

View File

@@ -46,6 +46,7 @@ class LineItemBase(BaseModel):
model_config = ConfigDict(populate_by_name=True)
item_id: int = Field(..., description="ID of the parent item")
line_number: int = Field(..., description="Line number")
# Part identification