- Introduced a new fixture, `test_tenant`, to allocate ephemeral tenant and company IDs for tests, reducing conflicts with real data. - Updated various test functions to use the new `test_tenant` fixture, ensuring consistent tenant ID usage across tests. - Enhanced the `ensure_tenant_company` function to accept dynamic tenant and company IDs, improving flexibility in test scenarios. - Adjusted database interaction in tests to utilize the ephemeral IDs, streamlining the setup process and enhancing isolation.
121 lines
4.0 KiB
Python
121 lines
4.0 KiB
Python
from datetime import date
|
|
from decimal import Decimal
|
|
|
|
from api.v1.modules.a24.balance_movements.models import BalanceMovement, MovementType
|
|
from api.v1.modules.a76.invoices.exports.process.sub_process.compare_balances import compare_balances
|
|
from api.v1.modules.a76.invoices.exports.process.sub_process.discharge_types import (
|
|
AvailableLot,
|
|
DownloadEntry,
|
|
)
|
|
from api.v1.modules.a76.invoices.exports.process.sub_process.fill_available_balances import (
|
|
_net_balance_for_lot,
|
|
)
|
|
from core.exceptions import ErrorCollector
|
|
from tests.fixtures.builders import (
|
|
create_business_catalogs,
|
|
create_import_invoice_with_line,
|
|
ensure_reference_data,
|
|
)
|
|
|
|
|
|
def test_net_balance_accounts_for_returns_and_entry_void(db_session, test_tenant):
|
|
"""
|
|
Balance neto esperado:
|
|
entry 10 - consumption 4 + return 1 - entry_void 2 = 5
|
|
"""
|
|
tid, cid = test_tenant.tenant_id, test_tenant.company_id
|
|
ensure_reference_data(db_session)
|
|
catalogs = create_business_catalogs(db_session, tenant_id=tid, company_id=cid)
|
|
import_invoice, import_line = create_import_invoice_with_line(
|
|
db_session,
|
|
tid,
|
|
cid,
|
|
catalogs,
|
|
invoice_type="TEM",
|
|
invoice_number="IMP-UNIT-01",
|
|
qty=Decimal("10"),
|
|
)
|
|
|
|
line_id = import_line.id
|
|
tenant_id = import_invoice.tenant_id
|
|
company_id = import_invoice.company_id
|
|
import_invoice_id = import_invoice.id
|
|
for idx, (mtype, qty) in enumerate(
|
|
[
|
|
(MovementType.ENTRY, Decimal("10")),
|
|
(MovementType.CONSUMPTION, Decimal("4")),
|
|
(MovementType.RETURN, Decimal("1")),
|
|
(MovementType.ENTRY_VOID, Decimal("2")),
|
|
],
|
|
start=1,
|
|
):
|
|
db_session.add(
|
|
BalanceMovement(
|
|
id=10000 + idx,
|
|
tenant_id=tenant_id,
|
|
company_id=company_id,
|
|
import_invoice_id=import_invoice_id,
|
|
import_item_line_id=line_id,
|
|
movement_type=mtype,
|
|
quantity=qty,
|
|
order_peps=10000 + idx,
|
|
operation_date=date(2026, 3, 20),
|
|
)
|
|
)
|
|
db_session.flush()
|
|
|
|
balance = _net_balance_for_lot(db_session, line_id, date(2026, 3, 21))
|
|
assert balance == Decimal("5")
|
|
|
|
|
|
def test_fifo_consumption_algorithm_uses_oldest_lots_first(db_session, monkeypatch):
|
|
"""
|
|
Verifica distribución FIFO (PEPS):
|
|
- lote1 (order=1, qty=3), lote2 (order=2, qty=5), demanda=6
|
|
- resultado: lote1 consume 3, lote2 consume 3, faltante 0
|
|
"""
|
|
monkeypatch.setattr(
|
|
"api.v1.modules.a76.invoices.exports.process.sub_process.compare_balances._resolve_import_uom",
|
|
lambda db, import_item_line_id: "PZA",
|
|
)
|
|
|
|
entry = DownloadEntry(
|
|
origin_procedure="TEM",
|
|
export_line=1,
|
|
part_number="PN-1",
|
|
class_code="CLS",
|
|
quantity=Decimal("6"),
|
|
quantity_used=Decimal("0"),
|
|
unit_of_measure="PZA",
|
|
import_invoice="IMP-1",
|
|
import_line=1,
|
|
line_item_id=1,
|
|
available_lots=[
|
|
AvailableLot(
|
|
import_item_line_id=11,
|
|
import_invoice_id=101,
|
|
part_number_id=None,
|
|
available_qty=Decimal("3"),
|
|
value_me=Decimal("0"),
|
|
value_mn=Decimal("0"),
|
|
order_peps=1,
|
|
),
|
|
AvailableLot(
|
|
import_item_line_id=12,
|
|
import_invoice_id=101,
|
|
part_number_id=None,
|
|
available_qty=Decimal("5"),
|
|
value_me=Decimal("0"),
|
|
value_mn=Decimal("0"),
|
|
order_peps=2,
|
|
),
|
|
],
|
|
)
|
|
|
|
errors = ErrorCollector()
|
|
compare_balances(db_session, export_invoice=None, to_discharge=[entry], errors=errors) # type: ignore[arg-type]
|
|
assert not errors.has_errors()
|
|
assert entry.quantity_used == Decimal("6")
|
|
assert entry.available_lots[0].consumed_qty == Decimal("3")
|
|
assert entry.available_lots[1].consumed_qty == Decimal("3")
|