diff --git a/backend/modules/fleet/tests/test_work_order_images_endpoint.py b/backend/modules/fleet/tests/test_work_order_images_endpoint.py index 4f7b652..3a7a563 100644 --- a/backend/modules/fleet/tests/test_work_order_images_endpoint.py +++ b/backend/modules/fleet/tests/test_work_order_images_endpoint.py @@ -561,6 +561,35 @@ class WorkOrderImagesEndpointTests(TestCase): self.assertIsNotNone(generated) self.assertEqual(generated.status, 'pending') + + def test_monthly_service_tasks_archive_request_replaces_stale_pending_archive(self): + stale_pending = GeneratedFleetArchive.objects.create( + requested_by=self.user, + archive_type='service_tasks', + year=2033, + month=12, + status='pending', + filename='pending-archive.zip', + expires_at=timezone.now() + timedelta(days=2), + ) + stale_created_at = timezone.now() - timedelta(minutes=10) + GeneratedFleetArchive.objects.filter(pk=stale_pending.pk).update(created_at=stale_created_at) + + response = self.client.post( + '/api/fleet/reports/monthly-service-tasks-archive-request/', + data={'year': 2033, 'month': 12}, + format='json', + ) + self.assertIn(response.status_code, [200, 202], response.content) + payload = response.json() + self.assertIn('generated_archive_id', payload) + self.assertNotEqual(str(stale_pending.pk), str(payload['generated_archive_id'])) + + stale_pending.refresh_from_db() + self.assertFalse(stale_pending.is_active) + self.assertEqual(stale_pending.status, 'failed') + self.assertIn('pending statusu', stale_pending.error_message) + def test_monthly_work_orders_archive_request_creates_ready_download_with_notification(self): WorkOrderInvoice.objects.create( work_order=self.work_order, diff --git a/backend/modules/fleet/views.py b/backend/modules/fleet/views.py index 2ceb88e..9f8f161 100644 --- a/backend/modules/fleet/views.py +++ b/backend/modules/fleet/views.py @@ -3055,10 +3055,17 @@ def _request_monthly_archive_generation(*, request, archive_type): .first() ) if existing_pending: - return { - 'status': 'processing', - 'generated_archive_id': str(existing_pending.pk), - } + stale_pending_threshold = timezone.now() - timedelta(minutes=3) + if existing_pending.created_at and existing_pending.created_at < stale_pending_threshold: + existing_pending.is_active = False + existing_pending.status = 'failed' + existing_pending.error_message = 'ZIP zahtjev je ostao predugo u pending statusu; pokrece se novi zahtjev.' + existing_pending.save(update_fields=['is_active', 'status', 'error_message', 'updated_at']) + else: + return { + 'status': 'processing', + 'generated_archive_id': str(existing_pending.pk), + } generated_archive = GeneratedFleetArchive.objects.create( requested_by=request.user,