fix: 按指标结果校准归属工时
This commit is contained in:
@@ -17,6 +17,7 @@ from app.services.metrics import (
|
||||
_mold_key,
|
||||
_overlap_minutes,
|
||||
_schedule_interval,
|
||||
calculate_report_metrics,
|
||||
format_hours,
|
||||
item_time_ranges,
|
||||
minutes_between,
|
||||
@@ -129,6 +130,18 @@ def _item_reference_wage(item) -> float:
|
||||
return as_float(getattr(item, "good_qty", 0)) * as_float(getattr(item, "process_unit_price_yuan", 0))
|
||||
|
||||
|
||||
def _item_target_minutes(report, items: list, schedule: WorkScheduleConfig | None = None) -> dict[int, float]:
|
||||
calculate_report_metrics(
|
||||
getattr(report, "start_at"),
|
||||
getattr(report, "end_at"),
|
||||
items,
|
||||
break_minutes=as_float(getattr(report, "break_minutes", 0)),
|
||||
devices=_report_devices(report),
|
||||
schedule=schedule,
|
||||
)
|
||||
return {id(item): as_float(getattr(item, "allocated_minutes", 0)) for item in items}
|
||||
|
||||
|
||||
def _minutes_total(rows: dict[date, dict[str, float]]) -> float:
|
||||
return sum(sum(minutes.get(key, 0.0) for key in SHIFT_BUCKETS) for minutes in rows.values())
|
||||
|
||||
@@ -180,6 +193,21 @@ def _scale_item_minutes_to_bucket_targets(
|
||||
minutes[key] = minutes.get(key, 0.0) * scale
|
||||
|
||||
|
||||
def _scale_item_minutes_to_item_targets(
|
||||
minutes_by_item: dict[int, dict[date, dict[str, float]]],
|
||||
target_minutes_by_item: dict[int, float],
|
||||
) -> None:
|
||||
for item_id, rows_by_date in minutes_by_item.items():
|
||||
raw_total = _minutes_total(rows_by_date)
|
||||
target_total = target_minutes_by_item.get(item_id, raw_total)
|
||||
if raw_total <= 0 or abs(raw_total - target_total) <= 0.000001:
|
||||
continue
|
||||
scale = target_total / raw_total
|
||||
for minutes in rows_by_date.values():
|
||||
for key in SHIFT_BUCKETS:
|
||||
minutes[key] = minutes.get(key, 0.0) * scale
|
||||
|
||||
|
||||
def _items_by_device(items: list) -> dict[str, list]:
|
||||
grouped: dict[str, list] = defaultdict(list)
|
||||
for item in items:
|
||||
@@ -305,6 +333,7 @@ def build_report_allocation_drafts(report, schedule: WorkScheduleConfig | None =
|
||||
minutes_by_item = _device_minutes_by_item(report, items, schedule)
|
||||
if minutes_by_item is None:
|
||||
minutes_by_item = _range_minutes_by_item(report, items, schedule)
|
||||
_scale_item_minutes_to_item_targets(minutes_by_item, _item_target_minutes(report, items, schedule))
|
||||
|
||||
rows: list[ReportAllocationDraft] = []
|
||||
for item in items:
|
||||
|
||||
Reference in New Issue
Block a user