feat: dodaj ishodište i PDF račune za putni nalog
Dodano je origin_location polje kroz backend model, serializer, admin i UI modal za kreiranje/uređivanje putnog naloga (default: Zagreb). Računi putnog naloga sada prihvaćaju slike i PDF datoteke, uz backend validaciju formata, podršku za serving PDF-a i prilagodbu preview prikaza. Za greške uploada računa dodan je error toast kako bi poruke validacije bile vidljive korisniku odmah u sučelju. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
from rest_framework import serializers
|
||||
import re
|
||||
from pathlib import Path
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from .models import (
|
||||
@@ -104,7 +105,7 @@ class WorkOrderSerializer(serializers.ModelSerializer):
|
||||
'servicer_vehicle_registration', 'servicer_vehicle_make_model',
|
||||
'servicer_vehicle_start_mileage', 'servicer_vehicle_end_mileage',
|
||||
'servicer_vehicle_fuel_cost',
|
||||
'location', 'travel_start_at', 'travel_end_at',
|
||||
'origin_location', 'location', 'travel_start_at', 'travel_end_at',
|
||||
'purpose', 'notes', 'status'
|
||||
]
|
||||
read_only_fields = ['id', 'date']
|
||||
@@ -119,6 +120,7 @@ class WorkOrderSerializer(serializers.ModelSerializer):
|
||||
'servicer_vehicle_start_mileage': {'required': False, 'allow_null': True},
|
||||
'servicer_vehicle_end_mileage': {'required': False, 'allow_null': True},
|
||||
'servicer_vehicle_fuel_cost': {'required': False, 'allow_null': True},
|
||||
'origin_location': {'required': False, 'allow_blank': True},
|
||||
'location': {'required': False, 'allow_blank': True},
|
||||
'travel_start_at': {'required': False, 'allow_null': True},
|
||||
'travel_end_at': {'required': False, 'allow_null': True},
|
||||
@@ -211,6 +213,7 @@ class WorkOrderSerializer(serializers.ModelSerializer):
|
||||
|
||||
class WorkOrderInvoiceSerializer(serializers.ModelSerializer):
|
||||
image_url = serializers.SerializerMethodField()
|
||||
image_content_type = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = WorkOrderInvoice
|
||||
@@ -223,6 +226,7 @@ class WorkOrderInvoiceSerializer(serializers.ModelSerializer):
|
||||
'opis',
|
||||
'image',
|
||||
'image_url',
|
||||
'image_content_type',
|
||||
'created_by',
|
||||
'created_at',
|
||||
]
|
||||
@@ -238,6 +242,31 @@ class WorkOrderInvoiceSerializer(serializers.ModelSerializer):
|
||||
reverse('work-order-invoice-image', kwargs={'pk': obj.pk})
|
||||
)
|
||||
|
||||
def get_image_content_type(self, obj):
|
||||
if not obj.image:
|
||||
return None
|
||||
suffix = Path(obj.image.name or '').suffix.lower()
|
||||
if suffix == '.pdf':
|
||||
return 'application/pdf'
|
||||
if suffix in {'.jpg', '.jpeg'}:
|
||||
return 'image/jpeg'
|
||||
if suffix == '.png':
|
||||
return 'image/png'
|
||||
if suffix == '.webp':
|
||||
return 'image/webp'
|
||||
if suffix == '.gif':
|
||||
return 'image/gif'
|
||||
return 'application/octet-stream'
|
||||
|
||||
def validate_image(self, value):
|
||||
if not value:
|
||||
return value
|
||||
suffix = Path(getattr(value, 'name', '')).suffix.lower()
|
||||
allowed_suffixes = {'.jpg', '.jpeg', '.png', '.webp', '.gif', '.pdf'}
|
||||
if suffix not in allowed_suffixes:
|
||||
raise serializers.ValidationError('Datoteka računa mora biti slika (.jpg, .jpeg, .png, .webp, .gif) ili PDF (.pdf).')
|
||||
return value
|
||||
|
||||
|
||||
class WorkOrderPhotoSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
|
||||
Reference in New Issue
Block a user