fix: 按设备匹配顺序拆分归属工时
This commit is contained in:
@@ -52,14 +52,14 @@ def _item(
|
||||
)
|
||||
|
||||
|
||||
def _device(scanned_at: datetime):
|
||||
def _device(scanned_at: datetime, *, device_no: str = "23#", process_name: str = "冲压", sort_order: int = 0):
|
||||
return SimpleNamespace(
|
||||
device_no="23#",
|
||||
process_name="冲压",
|
||||
device_no=device_no,
|
||||
process_name=process_name,
|
||||
scanned_at=scanned_at,
|
||||
released_at=None,
|
||||
release_reason=None,
|
||||
sort_order=0,
|
||||
sort_order=sort_order,
|
||||
)
|
||||
|
||||
|
||||
@@ -262,6 +262,41 @@ def test_same_device_item_split_inside_meal_is_rescaled_to_metrics_effective_min
|
||||
assert sum(row.effective_minutes for row in rows) == 240
|
||||
|
||||
|
||||
def test_matched_meal_split_and_unmatched_device_range_follow_metrics_order():
|
||||
start_at = datetime(2026, 7, 25, 8, 0)
|
||||
second_started_at = datetime(2026, 7, 25, 12, 0)
|
||||
switch_at = datetime(2026, 7, 25, 13, 0)
|
||||
end_at = datetime(2026, 7, 25, 20, 0)
|
||||
devices = [
|
||||
_device(start_at, device_no="23#", sort_order=0),
|
||||
_device(switch_at, device_no="77#", sort_order=1),
|
||||
]
|
||||
first_item = _item(id=1, good_qty=240, device_no="23#", started_at=start_at)
|
||||
second_item = _item(id=2, good_qty=60, device_no="23#", started_at=second_started_at)
|
||||
unmatched_item = _item(id=3, good_qty=320, device_no="99#")
|
||||
items = [first_item, second_item, unmatched_item]
|
||||
report = _report(start_at, end_at, items, devices=devices)
|
||||
|
||||
metrics = calculate_report_metrics(start_at, end_at, items, devices=devices)
|
||||
rows = build_report_allocation_drafts(report)
|
||||
|
||||
assert metrics["effective_minutes"] == 620
|
||||
assert {item.id: item.allocated_minutes for item in items} == {
|
||||
1: 240,
|
||||
2: 60,
|
||||
3: 320,
|
||||
}
|
||||
assert {
|
||||
item_id: round(sum(row.effective_minutes for row in rows if row.report_item_id == item_id), 2)
|
||||
for item_id in [1, 2, 3]
|
||||
} == {
|
||||
1: 240,
|
||||
2: 60,
|
||||
3: 320,
|
||||
}
|
||||
assert round(sum(row.effective_minutes for row in rows), 2) == metrics["effective_minutes"]
|
||||
|
||||
|
||||
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(
|
||||
|
||||
Reference in New Issue
Block a user