JhHardwareWRS_BackPoint/tests/test_reconciliation_allocations.py
2026-07-25 05:16:59 +08:00

224 lines
6.2 KiB
Python

from datetime import date, datetime
from sqlalchemy import BigInteger, create_engine
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.orm import sessionmaker
from app.database import Base
from app.models import (
ProductionReport,
ProductionReportAllocation,
ProductionReportItem,
ReportStatus,
)
from app.routers import reconciliation
@compiles(BigInteger, "sqlite")
def _compile_big_integer_for_sqlite(type_, compiler, **kw):
return "INTEGER"
def _sqlite_db():
engine = create_engine("sqlite+pysqlite:///:memory:", future=True)
Base.metadata.create_all(engine)
SessionLocal = sessionmaker(bind=engine, future=True)
return SessionLocal()
def _report(
*,
id: int,
status: ReportStatus = ReportStatus.approved,
is_voided: bool = False,
):
return ProductionReport(
id=id,
session_id=id,
attendance_point_name="嘉恒",
employee_phone="13800000000",
report_date=date(2026, 7, 31),
start_at=datetime(2026, 7, 31, 20, 0),
end_at=datetime(2026, 8, 1, 2, 0),
duration_minutes=360,
break_minutes=0,
effective_minutes=360,
total_good_qty=650,
total_output_qty=650,
actual_beat=1,
standard_beat=1,
expected_workload=0,
pace_rate=0,
workload_rate=0,
status=status,
is_voided=is_voided,
submitted_at=datetime(2026, 8, 1, 2, 1),
)
def _item(
*,
id: int,
report_id: int,
process_name: str = "2序",
):
return ProductionReportItem(
id=id,
report_id=report_id,
attendance_point_name="嘉恒",
device_no="A-01",
project_no="P1",
product_name="产品A",
process_name=process_name,
operator_count=1,
process_unit_price_yuan=1,
standard_beat=1,
standard_workload=0,
good_qty=650,
defect_qty=0,
scrap_qty=0,
allocated_minutes=360,
)
def _allocation(
*,
id: int,
report_id: int,
report_item_id: int,
allocation_date: date,
good_qty: float,
):
return ProductionReportAllocation(
id=id,
report_id=report_id,
report_item_id=report_item_id,
attendance_point_name="嘉恒",
employee_phone="13800000000",
allocation_date=allocation_date,
day_minutes=0,
overtime_minutes=0,
night_minutes=0,
effective_minutes=0,
good_qty=good_qty,
defect_qty=0,
scrap_qty=0,
changeover_count=0,
reference_wage=0,
)
def test_fold_reported_good_quantity_rows_uses_allocation_month_for_latest_process_only():
rows = [
("嘉恒", "产品A", "1序", 7, 999),
("嘉恒", "产品A", "2序", 7, 350),
("嘉恒", "产品A", "2序", 8, 300),
]
latest_processes = {("嘉恒", "产品A"): {"2序"}}
totals = reconciliation._fold_reported_good_quantity_rows(rows, latest_processes)
assert totals[("嘉恒", "产品A", 7)] == 350
assert totals[("嘉恒", "产品A", 8)] == 300
def test_reported_good_quantities_groups_by_allocation_month_for_approved_unvoided_latest_process():
db = _sqlite_db()
try:
approved = _report(id=1)
pending = _report(id=2, status=ReportStatus.pending)
voided = _report(id=3, is_voided=True)
latest_item = _item(id=1, report_id=approved.id, process_name="2序")
earlier_item = _item(id=2, report_id=approved.id, process_name="1序")
pending_item = _item(id=3, report_id=pending.id, process_name="2序")
voided_item = _item(id=4, report_id=voided.id, process_name="2序")
db.add_all([
approved,
pending,
voided,
latest_item,
earlier_item,
pending_item,
voided_item,
_allocation(
id=1,
report_id=approved.id,
report_item_id=latest_item.id,
allocation_date=date(2026, 7, 31),
good_qty=350,
),
_allocation(
id=2,
report_id=approved.id,
report_item_id=latest_item.id,
allocation_date=date(2026, 8, 1),
good_qty=300,
),
_allocation(
id=3,
report_id=approved.id,
report_item_id=earlier_item.id,
allocation_date=date(2026, 7, 31),
good_qty=999,
),
_allocation(
id=4,
report_id=pending.id,
report_item_id=pending_item.id,
allocation_date=date(2026, 7, 31),
good_qty=111,
),
_allocation(
id=5,
report_id=voided.id,
report_item_id=voided_item.id,
allocation_date=date(2026, 8, 1),
good_qty=222,
),
])
db.commit()
totals = reconciliation._reported_good_quantities(
db,
year=2026,
product_keys=[("嘉恒", "产品A")],
latest_processes={("嘉恒", "产品A"): {"2序"}},
)
assert totals[("嘉恒", "产品A", 7)] == 350
assert totals[("嘉恒", "产品A", 8)] == 300
finally:
db.close()
def test_reported_good_quantities_ignores_mismatched_allocation_report_item_rows():
db = _sqlite_db()
try:
approved = _report(id=1)
other_report = _report(id=2, status=ReportStatus.pending)
other_item = _item(id=2, report_id=other_report.id, process_name="2序")
db.add_all([
approved,
other_report,
other_item,
_allocation(
id=1,
report_id=approved.id,
report_item_id=other_item.id,
allocation_date=date(2026, 7, 31),
good_qty=123,
),
])
db.commit()
totals = reconciliation._reported_good_quantities(
db,
year=2026,
product_keys=[("嘉恒", "产品A")],
latest_processes={("嘉恒", "产品A"): {"2序"}},
)
assert totals == {}
finally:
db.close()