From 65fd7f85ffabc6b383ec866165cbe99820655fad Mon Sep 17 00:00:00 2001 From: souplearn Date: Sat, 25 Jul 2026 03:18:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=AD=A3=E7=A9=BA=E7=99=BD?= =?UTF-8?q?=E5=8A=A0=E7=8F=AD=E9=A4=90=E6=89=A3=E5=BD=92=E5=B1=9E=E8=AE=A1?= =?UTF-8?q?=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/services/report_allocations.py | 8 ++++++-- tests/test_report_allocations.py | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/services/report_allocations.py b/app/services/report_allocations.py index 14078c4..597c119 100644 --- a/app/services/report_allocations.py +++ b/app/services/report_allocations.py @@ -11,7 +11,6 @@ from app.services.metrics import ( SHIFT_BUCKETS, SHIFT_LABELS, _blank_overtime_intervals, - _covered_meal_overlap_minutes, _iter_shift_base_dates, _overlap_minutes, _schedule_interval, @@ -101,8 +100,13 @@ def _range_allocation_minutes( if overlap_end <= overlap_start: continue meal_minutes = sum( - _covered_meal_overlap_minutes(start_at, end_at, meal_start, meal_end) + _overlap_minutes(overlap_start, overlap_end, meal_start, meal_end) for meal_start, meal_end in meal_intervals + if ( + start_at <= meal_start + and end_at >= meal_end + and end_at > meal_end + timedelta(minutes=5) + ) ) minutes = max(0.0, minutes_between(overlap_start, overlap_end) - meal_minutes) _add_minutes(rows, overlap_start.date(), "overtime", minutes) diff --git a/tests/test_report_allocations.py b/tests/test_report_allocations.py index 9ebd668..4ed94d7 100644 --- a/tests/test_report_allocations.py +++ b/tests/test_report_allocations.py @@ -221,6 +221,23 @@ def test_night_allocation_uses_meal_deducted_minutes_with_previous_date_rules(): ] +def test_blank_overtime_meal_deduction_is_clipped_like_metrics(): + start_at = datetime(2026, 7, 25, 6, 0) + end_at = datetime(2026, 7, 25, 19, 0) + item = _item(id=1, good_qty=680) + report = _report(start_at, end_at, item) + + metrics = calculate_report_metrics(start_at, end_at, [item]) + rows = build_report_allocation_drafts(report) + + assert metrics["effective_minutes"] == 680 + assert metrics["shift_day_minutes"] == 500 + assert metrics["shift_overtime_minutes"] == 180 + assert [(row.effective_minutes, row.day_minutes, row.overtime_minutes, row.night_minutes) for row in rows] == [ + (680, 500, 180, 0), + ] + + 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(