Files
plantillas-proyectos/backend/tests/e2e/test_inventory_flow_anexo24.py
AlexeerCT b750c35522 Add backend test job to CI workflow
- Introduced a new job in the CI workflow to run backend tests before the build process.
- Configured Python environment and installed dependencies from the backend requirements.
- Added a check for the TEST_DATABASE_URL secret to ensure it is defined before running tests.
- The test job must pass for the build job to execute, enhancing the reliability of the CI pipeline.
2026-03-24 12:33:21 -05:00

114 lines
4.7 KiB
Python

from decimal import Decimal
from api.v1.modules.a24.balance_movements.models import BalanceMovement, MovementType
from api.v1.modules.a24.discharges.models import DischargeDetail, DischargeHeader
from api.v1.modules.a76.invoices.imports.process import main_process as import_main
from api.v1.modules.a76.invoices.exports.process import main_process as export_main
from api.v1.modules.a76.invoices.exports.process import task as export_task
from tests.fixtures.builders import (
create_business_catalogs,
create_export_invoice_with_line,
create_import_invoice_with_line,
ensure_reference_data,
ensure_tenant_company,
)
def _patch_import_pipeline(monkeypatch, import_line):
monkeypatch.setattr(import_main, "pre_validators", lambda *args, **kwargs: [import_line])
monkeypatch.setattr(import_main, "review_classes", lambda *args, **kwargs: None)
monkeypatch.setattr(import_main, "review_exchange_rate", lambda *args, **kwargs: None)
monkeypatch.setattr(import_main, "review_weights_kgs", lambda *args, **kwargs: None)
monkeypatch.setattr(import_main, "review_weights_lbs", lambda *args, **kwargs: None)
monkeypatch.setattr(import_main, "_validate_sisimp_limits", lambda *args, **kwargs: None)
monkeypatch.setattr(import_main, "_validate_lines", lambda *args, **kwargs: ([], {}))
def _patch_export_pipeline(monkeypatch, export_line):
monkeypatch.setattr(export_main, "pre_validators", lambda *args, **kwargs: [export_line])
monkeypatch.setattr(export_main, "review_class", lambda *args, **kwargs: None)
monkeypatch.setattr(export_main, "review_exchange_rate", lambda *args, **kwargs: None)
monkeypatch.setattr(export_main, "assign_values", lambda *args, **kwargs: None)
monkeypatch.setattr(export_main, "review_qty_vs_weight", lambda *args, **kwargs: None)
monkeypatch.setattr(export_main, "review_unit_cost", lambda *args, **kwargs: None)
monkeypatch.setattr(export_main, "review_qty_series", lambda *args, **kwargs: None)
def test_e2e_inventory_flow_import_then_export(client, db_session, monkeypatch):
"""
E2E principal:
- Alta catálogos/base
- Procesa factura IMP -> genera entry
- Procesa factura EXP -> genera consumo/descarga
- Valida decremento de saldo sin negativos
"""
ensure_reference_data(db_session)
ensure_tenant_company(db_session, tenant_id=1, company_id=1)
catalogs = create_business_catalogs(db_session, tenant_id=1, company_id=1)
import_invoice, import_line = create_import_invoice_with_line(
db_session, 1, 1, catalogs, invoice_type="TEM", invoice_number="IMP-E2E-01", qty=Decimal("10")
)
_patch_import_pipeline(monkeypatch, import_line)
response = client.post(f"/api/v1/a76/invoices/{import_invoice.id}/process?company_id=1")
assert response.status_code == 200
entry_movements = (
db_session.query(BalanceMovement)
.filter(
BalanceMovement.import_invoice_id == import_invoice.id,
BalanceMovement.import_item_line_id == import_line.id,
BalanceMovement.movement_type == MovementType.ENTRY,
)
.all()
)
assert entry_movements
assert sum(Decimal(str(m.quantity or 0)) for m in entry_movements) > 0
export_invoice, export_line = create_export_invoice_with_line(
db_session, 1, 1, catalogs, import_invoice, import_line, qty=Decimal("4")
)
_patch_export_pipeline(monkeypatch, export_line)
response = client.post(f"/api/v1/a76/invoices/{export_invoice.id}/process?company_id=1")
assert response.status_code == 200
consumptions = (
db_session.query(BalanceMovement)
.filter(
BalanceMovement.source_invoice_id == export_invoice.id,
BalanceMovement.movement_type == MovementType.CONSUMPTION,
)
.all()
)
assert consumptions, "El proceso de exportación debe generar consumos"
discharge_headers = (
db_session.query(DischargeHeader)
.filter(DischargeHeader.source_invoice_id == export_invoice.id)
.all()
)
assert discharge_headers
discharge_details = (
db_session.query(DischargeDetail)
.filter(DischargeDetail.export_item_line_id == export_line.id)
.all()
)
assert discharge_details
assert all(detail.movement_id is not None for detail in discharge_details)
net_balance = db_session.query(BalanceMovement).filter(
BalanceMovement.import_item_line_id == import_line.id
).all()
signed = Decimal("0")
for mov in net_balance:
qty = Decimal(str(mov.quantity or 0))
if mov.movement_type in {MovementType.CONSUMPTION, MovementType.WASTE, MovementType.SCRAP, MovementType.DESTRUCTION}:
signed -= qty
else:
signed += qty
assert signed >= 0
assert signed < Decimal("10")