fix: 对齐报工归属有效工时分配
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user