fix: use task-specific service report context
Some checks failed
ERP CI/CD Pipeline / test (push) Has been cancelled
ERP CI/CD Pipeline / Deploy (server git pull + compose) (push) Has been cancelled

Ensure service report DOCX/PDF headers and monthly ZIP archives use task/work-order context, with async fallback when the broker is unavailable.
This commit is contained in:
mariomitte
2026-08-07 01:15:31 +02:00
parent 8b90916641
commit cb165df30c
2 changed files with 104 additions and 23 deletions

View File

@@ -927,17 +927,6 @@ def _build_work_order_pdf(work_order):
def _build_work_order_service_records_pdf(work_order, related_tasks=None):
vehicle = work_order.vehicle
client_name = getattr(vehicle.client, 'name', None) or '-'
manufacturer_str = str(vehicle.make or '-')
model_str = str(vehicle.model or '-')
serial_str = str(vehicle.crane_serial_number or '-')
upgrade_hours_str = str(getattr(vehicle, 'superstructure_working_hours', '-') or '-')
chassis_hours_str = str(getattr(vehicle, 'chassis_working_hours', '-') or '-')
mileage_str = str(vehicle.current_mileage or '-')
nalog_str = _work_order_display_code(work_order)
generated_date_str = timezone.localtime(timezone.now()).strftime('%d.%m.%Y')
HEADER_H = 86
FOOTER_H = 72
MARGIN = 28
@@ -946,6 +935,16 @@ def _build_work_order_service_records_pdf(work_order, related_tasks=None):
related_tasks = list(_work_order_related_tasks_queryset(work_order))
else:
related_tasks = list(related_tasks)
context = _build_service_report_context(work_order, related_tasks)
client_name = context['client_name']
manufacturer_str = context['manufacturer']
model_str = context['model_name']
serial_str = context['serial']
upgrade_hours_str = context['upgrade_hours']
chassis_hours_str = context['chassis_hours']
mileage_str = context['mileage']
nalog_str = context['work_order_display_code']
generated_date_str = timezone.localtime(timezone.now()).strftime('%d.%m.%Y')
# Collect service records for all task vehicles (supports cross-crane work orders)
task_vehicle_ids = list({task.vehicle_id for task in related_tasks if task.vehicle_id})
service_rows = list(
@@ -1083,8 +1082,8 @@ def _build_work_order_service_records_pdf(work_order, related_tasks=None):
y = content_top
table1 = [
["Naziv Tvrtke:", client_name, "Lokacija intervencije:", work_order.location or '-'],
["Serviser:", _user_display_name(work_order.creator) or '-', "Asistirao:", '-'],
["Naziv Tvrtke:", client_name, "Lokacija intervencije:", context['location']],
["Serviser:", context['servicer_name'], "Asistirao:", '-'],
]
y = draw_table(
y,
@@ -1102,10 +1101,9 @@ def _build_work_order_service_records_pdf(work_order, related_tasks=None):
]),
)
completion_label = "Da ☒ Ne ☐" if work_order.status == 'closed' else "Da ☐ Ne ☒"
table2 = [
["Prijevozno sredstvo:", "Registracija:", "Broj narudžbe klijenta:", "Posao završen"],
[work_order.servicer_vehicle_make_model or '-', work_order.servicer_vehicle_registration or '-', "-", completion_label],
[context['servicer_vehicle_make_model'], context['servicer_vehicle_registration'], "-", context['completion_label']],
]
y = draw_table(
y,
@@ -1839,7 +1837,7 @@ def _docx_remove_empty_page_break_paragraphs(document):
body.remove(element)
def _build_service_report_docx_context(work_order, related_tasks):
def _build_service_report_context(work_order, related_tasks):
primary_task = related_tasks[0] if len(related_tasks) == 1 else None
context_work_order = getattr(primary_task, 'work_order', None) if primary_task else None
if context_work_order is None:
@@ -1849,10 +1847,9 @@ def _build_service_report_docx_context(work_order, related_tasks):
if context_vehicle is None:
context_vehicle = getattr(context_work_order, 'vehicle', None) or work_order.vehicle
model_parts = [
str(getattr(context_vehicle, 'make', '') or '').strip(),
str(getattr(context_vehicle, 'model', '') or '').strip(),
]
manufacturer = str(getattr(context_vehicle, 'make', '') or '').strip()
model_name = str(getattr(context_vehicle, 'model', '') or '').strip()
model_parts = [manufacturer, model_name]
model_label = " ".join(part for part in model_parts if part) or '-'
return {
'work_order': context_work_order,
@@ -1863,6 +1860,8 @@ def _build_service_report_docx_context(work_order, related_tasks):
'servicer_vehicle_make_model': getattr(context_work_order, 'servicer_vehicle_make_model', None) or '-',
'servicer_vehicle_registration': getattr(context_work_order, 'servicer_vehicle_registration', None) or '-',
'completion_label': "Da ☒ Ne ☐" if getattr(context_work_order, 'status', None) == 'closed' else "Da ☐ Ne ☒",
'manufacturer': manufacturer or '-',
'model_name': model_name or '-',
'model': model_label,
'serial': str(getattr(context_vehicle, 'crane_serial_number', None) or '-'),
'upgrade_hours': str(getattr(context_vehicle, 'superstructure_working_hours', None) or '-'),
@@ -1951,7 +1950,7 @@ def _build_work_order_service_records_docx_bytes(work_order, related_tasks=None)
related_tasks = list(_work_order_related_tasks_queryset(work_order).select_related('work_hours_table'))
else:
related_tasks = list(related_tasks)
context = _build_service_report_docx_context(work_order, related_tasks)
context = _build_service_report_context(work_order, related_tasks)
_populate_service_report_docx_header(doc, context)
normalized_rows = []
for task in related_tasks:
@@ -2986,6 +2985,17 @@ def _latest_monthly_archive_source_update(*, user, archive_type, year, month):
return max(latest_values)
def _schedule_monthly_archive_local_fallback(generated_archive_id):
def _runner():
try:
build_monthly_archive_cached_task.apply(args=[generated_archive_id]).get()
cleanup_expired_generated_archives_task.apply().get()
except Exception as exc:
logger.exception("Lokalni fallback za ZIP arhivu nije uspio: %s", exc)
threading.Thread(target=_runner, daemon=True).start()
def _request_monthly_archive_generation(*, request, archive_type):
year, month = _parse_year_month_params(request)
_cleanup_expired_generated_archive_records()
@@ -3076,8 +3086,7 @@ def _request_monthly_archive_generation(*, request, archive_type):
build_monthly_archive_cached_task.delay(str(generated_archive.pk))
cleanup_expired_generated_archives_task.delay()
except KombuOperationalError:
build_monthly_archive_cached_task.apply(args=[str(generated_archive.pk)]).get()
cleanup_expired_generated_archives_task.apply().get()
_schedule_monthly_archive_local_fallback(str(generated_archive.pk))
return {
'status': 'processing',