fix: add editable work order travel expenses
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

Introduce a dedicated travel-expenses table for work orders so Broj sati, Količina dnevnica, and Iznos dnevnice can be reviewed and edited before PDF generation. The PDF now uses the stored travel-expenses values, with default HR rate and cache invalidation on updates.
This commit is contained in:
mariomitte
2026-08-08 03:52:41 +02:00
parent a9ab83c202
commit 8577aaa01b
8 changed files with 697 additions and 35 deletions

View File

@@ -274,6 +274,30 @@ class WorkOrderImagesEndpointTests(TestCase):
self.assertFalse(cached.is_active)
self.assertEqual(cached.status, 'failed')
def test_travel_expenses_update_invalidates_work_order_pdf_cache(self):
cached = GeneratedWorkOrderPdf.objects.create(
work_order=self.work_order,
requested_by=self.user,
pdf_type='work_order',
status='ready',
filename='MT150726.work-order.pdf',
expires_at=timezone.now() + timedelta(hours=1),
)
response = self.client.put(
f"/api/fleet/work-orders/{self.work_order.pk}/travel-expenses-table/",
data={
'broj_sati': '9.5',
'kolicina_dnevnica': '0.5',
'iznos_dnevnica': '30',
'daily_rate_country': 'HR',
},
format='json',
)
self.assertEqual(response.status_code, 200, response.content)
cached.refresh_from_db()
self.assertFalse(cached.is_active)
self.assertEqual(cached.status, 'failed')
def test_service_records_docx_contains_embedded_service_photos(self):
VehicleServicePhoto.objects.create(
service_record=self.service_record,
@@ -491,6 +515,19 @@ class WorkOrderImagesEndpointTests(TestCase):
},
)
save_response = self.client.put(
f'/api/fleet/work-orders/{self.work_order.pk}/travel-expenses-table/',
data={
'broj_sati': '9.5',
'kolicina_dnevnica': '0.5',
'iznos_dnevnica': '80',
'daily_rate_country': 'SI',
},
format='json',
)
self.assertEqual(save_response.status_code, 200, save_response.content)
self.assertEqual(save_response.data['total_for_payout'], '40.00')
response = self.client.get(f'/api/fleet/work-orders/{self.work_order.pk}/pdf/')
self.assertEqual(response.status_code, 200, response.content)
self.assertEqual(response['Content-Type'], 'application/pdf')
@@ -501,6 +538,39 @@ class WorkOrderImagesEndpointTests(TestCase):
self.assertIn('25.12.2033.', text)
self.assertIn('9,5', text)
self.assertIn('0,5', text)
self.assertIn('80.00 €', text)
self.assertIn('40.00 €', text)
def test_work_order_travel_expenses_table_defaults_to_hr_rate_and_calculates_total(self):
TaskWorkHoursTable.objects.create(
task=self.task,
data={
'rows': [
{
'date': '24.12.2033',
'work_time_from': '08:00',
'work_time_to': '16:00',
'travel_hours': '1',
'work_hours': '6',
},
{
'date': '25.12.2033',
'work_time_from': '09:00',
'work_time_to': '15:00',
'travel_hours': '0,5',
'work_hours': '2',
},
]
},
)
response = self.client.get(f'/api/fleet/work-orders/{self.work_order.pk}/travel-expenses-table/')
self.assertEqual(response.status_code, 200, response.content)
self.assertEqual(response.data['broj_sati'], '9.50')
self.assertEqual(response.data['kolicina_dnevnica'], '0.50')
self.assertEqual(response.data['daily_rate_country'], 'HR')
self.assertEqual(response.data['iznos_dnevnica'], '30.00')
self.assertEqual(response.data['total_for_payout'], '15.00')
def test_calculate_daily_quantity_from_hours_follows_business_rules(self):
self.assertEqual(_calculate_daily_quantity_from_hours(0), 0.0)