feat: 经理看板展示报工超额信息
This commit is contained in:
@@ -156,3 +156,237 @@ def test_export_dashboard_rows_writes_allocation_and_source_dates_with_warning_c
|
||||
assert sheet.cell(row=2, column=3).value == "2026-07-23、2026-07-25"
|
||||
assert sheet.cell(row=2, column=12).fill.fgColor.rgb == "FFFF6666"
|
||||
assert sheet.cell(row=2, column=15).fill.fgColor.rgb == "FFFF6666"
|
||||
|
||||
|
||||
def test_dashboard_rows_include_over_limit_summary_from_reports():
|
||||
report = SimpleNamespace(
|
||||
id=1,
|
||||
attendance_point_name="总厂",
|
||||
employee_phone="13800000000",
|
||||
report_date=date(2026, 7, 25),
|
||||
has_over_limit=True,
|
||||
over_limit_summary="1项超额",
|
||||
review_remark=None,
|
||||
employee=SimpleNamespace(name="张三", is_temporary=False),
|
||||
items=[],
|
||||
audit_logs=[],
|
||||
session=None,
|
||||
is_system_auto_submitted=False,
|
||||
is_voided=False,
|
||||
is_multi_person_assistant=False,
|
||||
)
|
||||
item = SimpleNamespace(
|
||||
id=1,
|
||||
report=report,
|
||||
report_id=1,
|
||||
attendance_point_name="总厂",
|
||||
device_no="A",
|
||||
project_no="P1",
|
||||
product_name="产品A",
|
||||
material_code="M1",
|
||||
material_name="材料A",
|
||||
raw_material_batch_no="LOT-1",
|
||||
process_name="1",
|
||||
remark=None,
|
||||
stamping_method="冲压",
|
||||
operator_count=1,
|
||||
process_unit_price_yuan=1,
|
||||
standard_beat=1,
|
||||
good_qty=60,
|
||||
defect_qty=0,
|
||||
scrap_qty=0,
|
||||
changeover_count=0,
|
||||
allocated_minutes=60,
|
||||
over_limit_status="exceeded",
|
||||
over_limit_reason="1序累计报工数量超过本批次材料可支撑数量",
|
||||
)
|
||||
report.items = [item]
|
||||
allocation = SimpleNamespace(
|
||||
report=report,
|
||||
item=item,
|
||||
report_id=1,
|
||||
allocation_date=date(2026, 7, 25),
|
||||
attendance_point_name="总厂",
|
||||
employee_phone="13800000000",
|
||||
good_qty=60,
|
||||
defect_qty=0,
|
||||
scrap_qty=0,
|
||||
effective_minutes=60,
|
||||
day_minutes=60,
|
||||
overtime_minutes=0,
|
||||
night_minutes=0,
|
||||
reference_wage=60,
|
||||
changeover_count=0,
|
||||
)
|
||||
|
||||
rows = dashboard._dashboard_rows_from_allocations([allocation])
|
||||
|
||||
assert rows[0].has_over_limit is True
|
||||
assert rows[0].over_limit_summary == "1项超额"
|
||||
assert rows[0].over_limit_reasons == "1序累计报工数量超过本批次材料可支撑数量"
|
||||
|
||||
|
||||
def test_export_dashboard_rows_writes_over_limit_columns():
|
||||
row = SimpleNamespace(
|
||||
attendance_point_name="总厂",
|
||||
report_date=date(2026, 7, 24),
|
||||
source_report_dates=[date(2026, 7, 24)],
|
||||
source_report_date=None,
|
||||
employee_name="张三",
|
||||
employee_phone="13800000000",
|
||||
worker_type="正式工",
|
||||
project_no="P1",
|
||||
product_name="23#",
|
||||
process_name="1",
|
||||
effective_minutes=60,
|
||||
shift_distribution_text="白班1小时",
|
||||
total_good_qty=50,
|
||||
total_defect_qty=2,
|
||||
expected_workload=100,
|
||||
actual_beat=20,
|
||||
standard_beat=10,
|
||||
profile_no="PF-1",
|
||||
material_code="M-1",
|
||||
material_name="铝材",
|
||||
raw_material_batch_no="BATCH-1",
|
||||
device_no="A-01",
|
||||
stamping_method="单冲",
|
||||
changeover_count=1,
|
||||
operator_count=1,
|
||||
process_unit_price_yuan=2,
|
||||
reference_wage=100,
|
||||
has_over_limit=True,
|
||||
over_limit_summary="1项超额",
|
||||
over_limit_reasons="1序累计报工数量超过本批次材料可支撑数量",
|
||||
is_voided=False,
|
||||
is_multi_person=False,
|
||||
is_continuous_die=False,
|
||||
correction_pairs=[],
|
||||
review_remark="复核通过",
|
||||
)
|
||||
|
||||
workbook = load_workbook(BytesIO(export_dashboard_rows([row])))
|
||||
sheet = workbook["报工看板"]
|
||||
headers = [sheet.cell(row=1, column=index).value for index in range(1, sheet.max_column + 1)]
|
||||
|
||||
assert "是否超额" in headers
|
||||
assert "超额摘要" in headers
|
||||
assert "超额原因" in headers
|
||||
assert sheet.cell(row=2, column=headers.index("是否超额") + 1).value == "是"
|
||||
assert sheet.cell(row=2, column=headers.index("超额摘要") + 1).value == "1项超额"
|
||||
assert sheet.cell(row=2, column=headers.index("超额原因") + 1).value == "1序累计报工数量超过本批次材料可支撑数量"
|
||||
|
||||
|
||||
def test_dashboard_over_limit_does_not_spread_to_other_items_in_same_report():
|
||||
report = SimpleNamespace(
|
||||
id=1,
|
||||
attendance_point_name="总厂",
|
||||
employee_phone="13800000000",
|
||||
report_date=date(2026, 7, 25),
|
||||
has_over_limit=True,
|
||||
over_limit_summary="1项超额",
|
||||
review_remark=None,
|
||||
employee=SimpleNamespace(name="张三", is_temporary=False),
|
||||
items=[],
|
||||
audit_logs=[],
|
||||
session=None,
|
||||
is_system_auto_submitted=False,
|
||||
is_voided=False,
|
||||
is_multi_person_assistant=False,
|
||||
)
|
||||
exceeded_item = SimpleNamespace(
|
||||
id=1,
|
||||
report=report,
|
||||
report_id=1,
|
||||
attendance_point_name="总厂",
|
||||
device_no="A",
|
||||
project_no="P1",
|
||||
product_name="产品A",
|
||||
material_code="M1",
|
||||
material_name="材料A",
|
||||
raw_material_batch_no="LOT-1",
|
||||
process_name="1",
|
||||
remark=None,
|
||||
stamping_method="冲压",
|
||||
operator_count=1,
|
||||
process_unit_price_yuan=1,
|
||||
standard_beat=1,
|
||||
good_qty=60,
|
||||
defect_qty=0,
|
||||
scrap_qty=0,
|
||||
changeover_count=0,
|
||||
allocated_minutes=60,
|
||||
over_limit_status="exceeded",
|
||||
over_limit_reason="1序累计报工数量超过本批次材料可支撑数量",
|
||||
)
|
||||
normal_item = SimpleNamespace(
|
||||
id=2,
|
||||
report=report,
|
||||
report_id=1,
|
||||
attendance_point_name="总厂",
|
||||
device_no="B",
|
||||
project_no="P1",
|
||||
product_name="产品A",
|
||||
material_code="M1",
|
||||
material_name="材料A",
|
||||
raw_material_batch_no="LOT-1",
|
||||
process_name="2",
|
||||
remark=None,
|
||||
stamping_method="冲压",
|
||||
operator_count=1,
|
||||
process_unit_price_yuan=1,
|
||||
standard_beat=1,
|
||||
good_qty=40,
|
||||
defect_qty=0,
|
||||
scrap_qty=0,
|
||||
changeover_count=0,
|
||||
allocated_minutes=40,
|
||||
over_limit_status="ok",
|
||||
over_limit_reason=None,
|
||||
)
|
||||
report.items = [exceeded_item, normal_item]
|
||||
allocations = [
|
||||
SimpleNamespace(
|
||||
report=report,
|
||||
item=exceeded_item,
|
||||
report_id=1,
|
||||
allocation_date=date(2026, 7, 25),
|
||||
attendance_point_name="总厂",
|
||||
employee_phone="13800000000",
|
||||
good_qty=60,
|
||||
defect_qty=0,
|
||||
scrap_qty=0,
|
||||
effective_minutes=60,
|
||||
day_minutes=60,
|
||||
overtime_minutes=0,
|
||||
night_minutes=0,
|
||||
reference_wage=60,
|
||||
changeover_count=0,
|
||||
),
|
||||
SimpleNamespace(
|
||||
report=report,
|
||||
item=normal_item,
|
||||
report_id=1,
|
||||
allocation_date=date(2026, 7, 25),
|
||||
attendance_point_name="总厂",
|
||||
employee_phone="13800000000",
|
||||
good_qty=40,
|
||||
defect_qty=0,
|
||||
scrap_qty=0,
|
||||
effective_minutes=40,
|
||||
day_minutes=40,
|
||||
overtime_minutes=0,
|
||||
night_minutes=0,
|
||||
reference_wage=40,
|
||||
changeover_count=0,
|
||||
),
|
||||
]
|
||||
|
||||
rows = dashboard._dashboard_rows_from_allocations(allocations)
|
||||
rows_by_process = {row.process_name: row for row in rows}
|
||||
|
||||
assert rows_by_process["1"].has_over_limit is True
|
||||
assert rows_by_process["1"].over_limit_reasons == "1序累计报工数量超过本批次材料可支撑数量"
|
||||
assert rows_by_process["2"].has_over_limit is False
|
||||
assert rows_by_process["2"].over_limit_summary is None
|
||||
assert rows_by_process["2"].over_limit_reasons is None
|
||||
|
||||
Reference in New Issue
Block a user