fix: include user-owned work orders in monthly archive
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 monthly ZIP generation includes work orders owned by the user even when the task is assigned to someone else, and add a regression spec covering the user-owned work-order case.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
mariomitte
2026-09-08 11:11:25 +02:00
parent fc2a683b9c
commit 1172dfabd7
2 changed files with 91 additions and 24 deletions

View File

@@ -639,6 +639,40 @@ class WorkOrderImagesEndpointTests(TestCase):
self.assertNotIn('Liebherr LTM 1090', second_header)
self.assertNotIn('MT150726', second_header)
def test_monthly_work_orders_archive_includes_work_orders_for_user_even_without_assigned_task(self):
other_user = get_user_model().objects.create_user(
username=f'wo-other-{uuid.uuid4().hex[:8]}',
email=f'wo-other-{uuid.uuid4().hex[:8]}@example.test',
password='test1234',
)
linked_work_order = WorkOrder.objects.create(
vehicle=self.vehicle,
creator=self.user,
display_code='MT170726',
purpose='kontrola',
)
Task.objects.create(
title='Zadatak drugog servisera',
assigned_to=other_user,
vehicle=self.vehicle,
work_order=linked_work_order,
scheduled_date=date(2033, 12, 20),
)
WorkOrderInvoice.objects.create(
work_order=linked_work_order,
naziv_racuna='Prosinac račun osoba',
datum='2033-12-12',
image=create_test_pdf('racun-prosinac-osoba.pdf'),
created_by=self.user,
)
response = self.client.get('/api/fleet/reports/monthly-work-orders-archive/?year=2033&month=12')
self.assertEqual(response.status_code, 200, response.content)
archive = zipfile.ZipFile(BytesIO(response.content))
self.assertIn('MT150726.work-order.pdf', archive.namelist())
self.assertIn('MT170726.work-order.pdf', archive.namelist())
def test_monthly_work_orders_archive_contains_work_orders_and_invoices_folder(self):
WorkOrderInvoice.objects.create(
work_order=self.work_order,

View File

@@ -3030,28 +3030,7 @@ def _build_monthly_service_tasks_archive_content(*, user, year, month):
def _build_monthly_work_orders_archive_content(*, user, year, month):
from modules.task_management.models import Task
monthly_tasks = (
Task.objects
.filter(
assigned_to=user,
is_active=True,
scheduled_date__year=year,
scheduled_date__month=month,
work_order__isnull=False,
work_order__is_active=True,
)
.select_related('work_order')
.order_by('scheduled_date', 'created_at')
)
ordered_work_order_ids = []
seen_work_order_ids = set()
for task in monthly_tasks:
if not task.work_order_id or task.work_order_id in seen_work_order_ids:
continue
seen_work_order_ids.add(task.work_order_id)
ordered_work_order_ids.append(task.work_order_id)
ordered_work_order_ids = _user_monthly_work_order_ids(user=user, year=year, month=month)
if not ordered_work_order_ids:
raise DRFValidationError({'detail': 'Nema putnih naloga za odabrani mjesec.'})
@@ -3178,26 +3157,80 @@ def _get_cached_generated_archive(*, user, archive_type, year, month):
)
def _user_monthly_work_order_ids(*, user, year, month):
from modules.task_management.models import Task
task_work_order_ids = set(
Task.objects
.filter(
is_active=True,
scheduled_date__year=year,
scheduled_date__month=month,
work_order__isnull=False,
work_order__is_active=True,
)
.filter(
Q(assigned_to=user)
| Q(work_order__creator=user)
| Q(vehicle__assigned_servicer=user)
)
.values_list('work_order_id', flat=True)
.distinct()
)
work_order_ids = set(
WorkOrder.objects
.filter(
is_active=True,
date__year=year,
date__month=month,
)
.filter(
Q(creator=user)
| Q(vehicle__assigned_servicer=user)
)
.values_list('id', flat=True)
.distinct()
)
return list(dict.fromkeys([*task_work_order_ids, *work_order_ids]))
def _latest_monthly_archive_source_update(*, user, archive_type, year, month):
from modules.task_management.models import Task
task_work_order_ids = _user_monthly_work_order_ids(user=user, year=year, month=month)
base_tasks = Task.objects.filter(
assigned_to=user,
is_active=True,
scheduled_date__year=year,
scheduled_date__month=month,
work_order__isnull=False,
work_order__is_active=True,
).filter(
Q(assigned_to=user)
| Q(work_order__creator=user)
| Q(vehicle__assigned_servicer=user)
)
base_work_orders = WorkOrder.objects.filter(
is_active=True,
date__year=year,
date__month=month,
).filter(
Q(creator=user)
| Q(vehicle__assigned_servicer=user)
)
latest_candidates = [
base_tasks.aggregate(value=Max('updated_at')).get('value'),
base_tasks.aggregate(value=Max('work_order__updated_at')).get('value'),
base_tasks.aggregate(value=Max('work_order__vehicle__updated_at')).get('value'),
base_tasks.aggregate(value=Max('work_hours_table__updated_at')).get('value'),
base_work_orders.aggregate(value=Max('updated_at')).get('value'),
base_work_orders.aggregate(value=Max('vehicle__updated_at')).get('value'),
]
if archive_type == 'work_orders':
latest_candidates.append(
base_tasks.aggregate(value=Max('work_order__invoices__updated_at')).get('value')
WorkOrderInvoice.objects.filter(
work_order_id__in=task_work_order_ids,
is_active=True,
).aggregate(value=Max('updated_at')).get('value')
)
latest_values = [value for value in latest_candidates if value is not None]
if not latest_values: