interaktivna Tablica radnih sati, db
This commit is contained in:
@@ -103,7 +103,9 @@ def _work_order_related_tasks_queryset(work_order):
|
||||
task_ids = list({*direct_task_ids, *inferred_task_ids})
|
||||
if not task_ids:
|
||||
return Task.objects.none()
|
||||
return Task.objects.filter(id__in=task_ids, is_active=True).select_related('assigned_to', 'vehicle', 'work_order').order_by('-created_at')
|
||||
return Task.objects.filter(id__in=task_ids, is_active=True).select_related(
|
||||
'assigned_to', 'vehicle', 'work_order', 'work_hours_table'
|
||||
).order_by('-created_at')
|
||||
|
||||
def _can_access_service_record(user, service_record):
|
||||
service_record_id = getattr(service_record, 'pk', service_record)
|
||||
@@ -523,31 +525,6 @@ def _build_work_order_service_records_pdf(work_order):
|
||||
HEADER_H = 86
|
||||
FOOTER_H = 72
|
||||
MARGIN = 28
|
||||
DAY_MAP = {
|
||||
0: 'PO',
|
||||
1: 'UT',
|
||||
2: 'SR',
|
||||
3: 'ČET',
|
||||
4: 'PET',
|
||||
5: 'SUB',
|
||||
6: 'NED',
|
||||
}
|
||||
|
||||
def _fmt_date(value):
|
||||
if not value:
|
||||
return '-'
|
||||
return value.strftime('%d.%m.%Y')
|
||||
|
||||
def _fmt_time(value):
|
||||
if not value:
|
||||
return '-'
|
||||
return value.astimezone(timezone.get_current_timezone()).strftime('%H:%M')
|
||||
|
||||
def _hours_between(start_at, end_at):
|
||||
if not start_at or not end_at:
|
||||
return 0.0
|
||||
delta = end_at - start_at
|
||||
return max(0.0, round(delta.total_seconds() / 3600.0, 2))
|
||||
|
||||
service_rows = list(
|
||||
VehicleServiceRecord.objects.filter(
|
||||
@@ -559,8 +536,6 @@ def _build_work_order_service_records_pdf(work_order):
|
||||
.order_by('service_date', 'created_at')
|
||||
)
|
||||
related_tasks = list(_work_order_related_tasks_queryset(work_order))
|
||||
travel_hours = _hours_between(work_order.travel_start_at, work_order.travel_end_at)
|
||||
travel_km = work_order.distance if work_order.distance is not None else 0
|
||||
task_titles = [row.task.title for row in service_rows if getattr(row, 'task', None) and row.task.title]
|
||||
notes_text = ' | '.join(task_titles[:2]) if task_titles else (work_order.notes or '')
|
||||
|
||||
@@ -627,6 +602,58 @@ def _build_work_order_service_records_pdf(work_order):
|
||||
description_style.fontSize = 8.2
|
||||
description_style.leading = 10.4
|
||||
|
||||
def _normalize_hours_table_row(row):
|
||||
if not isinstance(row, dict):
|
||||
return None
|
||||
return {
|
||||
'day': str(row.get('day', '') or '').strip() or '-',
|
||||
'date': str(row.get('date', '') or '').strip() or '-',
|
||||
'work_time': " - ".join(
|
||||
[
|
||||
str(row.get('work_time_from', '') or '').strip() or '-',
|
||||
str(row.get('work_time_to', '') or '').strip() or '-',
|
||||
]
|
||||
),
|
||||
'travel_time': " - ".join(
|
||||
[
|
||||
str(row.get('travel_time_from', '') or '').strip() or '-',
|
||||
str(row.get('travel_time_to', '') or '').strip() or '-',
|
||||
]
|
||||
),
|
||||
'break_hours': str(row.get('break_hours', '') or '').strip() or '-',
|
||||
'work_hours': str(row.get('work_hours', '') or '').strip() or '-',
|
||||
'travel_hours': str(row.get('travel_hours', '') or '').strip() or '-',
|
||||
'places': "\n".join([
|
||||
f"Polazak: {str(row.get('departure_place', '') or '').strip() or '-'}",
|
||||
f"Dolazak: {str(row.get('arrival_place', '') or '').strip() or '-'}",
|
||||
]),
|
||||
'vehicle_km': str(row.get('vehicle_km', '') or '').strip() or '-',
|
||||
}
|
||||
|
||||
def _parse_decimal(value):
|
||||
if value in (None, ''):
|
||||
return 0.0
|
||||
try:
|
||||
return float(str(value).replace(',', '.'))
|
||||
except (TypeError, ValueError):
|
||||
return 0.0
|
||||
|
||||
def _format_decimal(value):
|
||||
return f"{float(value):.1f}".replace('.', ',')
|
||||
|
||||
normalized_hours_rows = []
|
||||
for task in related_tasks:
|
||||
table_data = getattr(getattr(task, 'work_hours_table', None), 'data', None)
|
||||
if not isinstance(table_data, dict):
|
||||
continue
|
||||
rows = table_data.get('rows', [])
|
||||
if not isinstance(rows, list):
|
||||
continue
|
||||
for raw_row in rows:
|
||||
normalized = _normalize_hours_table_row(raw_row)
|
||||
if normalized:
|
||||
normalized_hours_rows.append(normalized)
|
||||
|
||||
y = content_top
|
||||
|
||||
table1 = [
|
||||
@@ -683,42 +710,29 @@ def _build_work_order_service_records_pdf(work_order):
|
||||
"Kilometri\nvozila",
|
||||
]
|
||||
table3_rows = [table3_headers]
|
||||
total_hours_travel = 0.0
|
||||
total_vehicle_km = 0.0
|
||||
|
||||
if work_order.travel_start_at or work_order.travel_end_at:
|
||||
day_idx = work_order.travel_start_at.weekday() if work_order.travel_start_at else None
|
||||
table3_rows.append([
|
||||
DAY_MAP.get(day_idx, '-'),
|
||||
_fmt_date(work_order.travel_start_at.date() if work_order.travel_start_at else work_order.date),
|
||||
"-",
|
||||
f"{_fmt_time(work_order.travel_start_at)} - {_fmt_time(work_order.travel_end_at)}",
|
||||
"-",
|
||||
"-",
|
||||
str(travel_hours).replace('.', ','),
|
||||
work_order.location or '-',
|
||||
str(travel_km or '-'),
|
||||
])
|
||||
if normalized_hours_rows:
|
||||
for row in normalized_hours_rows:
|
||||
table3_rows.append([
|
||||
row['day'],
|
||||
row['date'],
|
||||
row['work_time'],
|
||||
row['travel_time'],
|
||||
row['break_hours'],
|
||||
row['work_hours'],
|
||||
row['travel_hours'],
|
||||
row['places'],
|
||||
row['vehicle_km'],
|
||||
])
|
||||
total_hours_travel += _parse_decimal(row['travel_hours'])
|
||||
total_vehicle_km += _parse_decimal(row['vehicle_km'])
|
||||
else:
|
||||
for _ in range(12):
|
||||
table3_rows.append(["-", "-", "-", "-", "-", "-", "-", "Polazak: -\nDolazak: -", "-"])
|
||||
|
||||
for record in service_rows[:6]:
|
||||
day_idx = record.service_date.weekday() if record.service_date else None
|
||||
table3_rows.append([
|
||||
DAY_MAP.get(day_idx, '-'),
|
||||
_fmt_date(record.service_date),
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
"-",
|
||||
getattr(record.vehicle, 'registration_number', '-') or '-',
|
||||
str(record.mileage or '-'),
|
||||
])
|
||||
|
||||
if len(table3_rows) == 1:
|
||||
table3_rows.append(["-", "-", "-", "-", "-", "-", "-", "-", "-"])
|
||||
|
||||
total_hours_travel = str(travel_hours).replace('.', ',')
|
||||
for _ in range(6):
|
||||
table3_rows.append(["", "", "", "", "", "", "", "", ""])
|
||||
table3_rows.append(["UKUPNO", "", "", "", "", "", total_hours_travel, "", str(travel_km or 0)])
|
||||
table3_rows.append(["UKUPNO", "", "", "", "", "", _format_decimal(total_hours_travel), "", str(int(total_vehicle_km) if total_vehicle_km.is_integer() else total_vehicle_km).replace('.', ',')])
|
||||
y = draw_table(
|
||||
y,
|
||||
table3_rows,
|
||||
@@ -739,6 +753,8 @@ def _build_work_order_service_records_pdf(work_order):
|
||||
('LEFTPADDING', (0, 0), (-1, -1), 3),
|
||||
('RIGHTPADDING', (0, 0), (-1, -1), 3),
|
||||
('LEFTPADDING', (0, -1), (5, -1), 12),
|
||||
('VALIGN', (7, 1), (7, -2), 'TOP'),
|
||||
('ALIGN', (7, 1), (7, -2), 'LEFT'),
|
||||
]),
|
||||
)
|
||||
|
||||
@@ -1449,6 +1465,7 @@ class WorkOrderViewSet(viewsets.ModelViewSet):
|
||||
'description': task.description,
|
||||
'assigned_to_name': _user_display_name(task.assigned_to),
|
||||
'vehicle_registration': getattr(task.vehicle, 'registration_number', None),
|
||||
'work_hours_table': getattr(getattr(task, 'work_hours_table', None), 'data', None),
|
||||
'service_records': records_payload,
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user