fix: 对齐报工归属有效工时分配

This commit is contained in:
souplearn
2026-07-25 03:13:06 +08:00
parent e4dd01bc72
commit 63ea6fdcc5
3 changed files with 72 additions and 23 deletions
+56 -3
View File
@@ -7,11 +7,13 @@ from sqlalchemy.orm import sessionmaker
from app.database import Base
from app.models import ProductionReport, ProductionReportAllocation, ProductionReportItem
from app.services.metrics import calculate_report_metrics
from app.services.report_allocations import (
allocation_summary_text,
build_report_allocation_drafts,
refresh_report_allocations,
)
from app.services.work_schedule import WorkScheduleConfig
@compiles(BigInteger, "sqlite")
@@ -28,12 +30,15 @@ def _item(
changeover_count: float = 0,
process_unit_price_yuan: float = 0,
started_at: datetime | None = None,
device_no: str = "23#",
product_name: str | None = None,
process_name: str | None = "冲压",
):
return SimpleNamespace(
id=id,
device_no="23#",
product_name="23#",
process_name="冲压",
device_no=device_no,
product_name=product_name or device_no,
process_name=process_name,
started_at=started_at,
standard_beat=1,
standard_workload=0,
@@ -168,6 +173,54 @@ def test_items_sharing_same_started_at_split_the_segment_minutes():
]
def test_device_matched_and_unmatched_items_match_metrics_remaining_minutes():
start_at = datetime(2026, 7, 25, 8, 0)
end_at = datetime(2026, 7, 25, 11, 0)
matching_item = _item(id=1, good_qty=10, device_no="23#")
unmatched_item = _item(id=2, good_qty=20, device_no="99#")
report = _report(start_at, end_at, [matching_item, unmatched_item], devices=[_device(start_at)])
calculate_report_metrics(start_at, end_at, [matching_item, unmatched_item], devices=[_device(start_at)])
rows = build_report_allocation_drafts(report)
assert {matching_item.id: matching_item.allocated_minutes, unmatched_item.id: unmatched_item.allocated_minutes} == {
1: 180,
2: 0,
}
assert {row.report_item_id: row.effective_minutes for row in rows} == {
1: 180,
2: 0,
}
def test_night_allocation_uses_meal_deducted_minutes_with_previous_date_rules():
schedule = WorkScheduleConfig(
day_start="08:00",
day_end="17:20",
lunch_start="11:40",
lunch_end="12:40",
dinner_start="21:00",
dinner_end="21:30",
overtime_start="18:00",
overtime_end="20:00",
night_start="20:00",
night_end="06:00",
)
start_at = datetime(2026, 7, 25, 20, 0)
end_at = datetime(2026, 7, 25, 22, 0)
item = _item(id=1, good_qty=90)
report = _report(start_at, end_at, item)
metrics = calculate_report_metrics(start_at, end_at, [item], schedule=schedule)
rows = build_report_allocation_drafts(report, schedule=schedule)
assert metrics["effective_minutes"] == 90
assert metrics["shift_night_minutes"] == 90
assert [(row.allocation_date, row.night_minutes, row.effective_minutes) for row in rows] == [
(date(2026, 7, 25), 90, 90),
]
def test_zero_effective_minutes_falls_back_to_original_report_date():
item = _item(good_qty=5, defect_qty=1, scrap_qty=0.5, changeover_count=2, process_unit_price_yuan=3)
report = _report(