feat: dodaj display_code polje za putne naloge (MT070626 format)
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

- Dodano polje 'display_code' na WorkOrder model (format: 2 inicijala + ddmmyy)
- Migracije za kreiranje polja i backfill postojećih naloga
- Ažuriran WorkOrderSerializer za validaciju i serijalizaciju display_code
- Backend tasks za auto-generiranje display_code pri kreiranju
- Frontend komponente ažurirane za prikaz display_code umjesto UUID:
  * FleetDashboardShell tablica putnih naloga
  * WorkOrderDetailModal
  * TaskCreateModal
  * Sve PDF stranice
- displayIds.js utility za formatiranjeDisplay ID-eva
- Admin interface prikazuje display_code
This commit is contained in:
mariomitte
2026-07-17 23:53:47 +02:00
parent ef8718a4cf
commit bf8e25efe7
19 changed files with 377 additions and 54 deletions

View File

@@ -11,7 +11,7 @@ import {
sendWorkOrderEmail,
} from '../../stores/fleetDashboardStore';
import { showToast } from '../../stores/toastStore';
import { formatEntityCode } from '../../lib/displayIds';
import { formatWorkOrderDisplayCode } from '../../lib/displayIds';
const PURPOSE_OPTIONS = [
{ value: 'defektaza', label: 'Defektaža' },
@@ -23,6 +23,7 @@ export default function WorkOrderDetailModal({ open, workOrder, onClose, onSubmi
const [isEditing, setIsEditing] = useState(false);
const [form, setForm] = useState({
has_travel_order: false,
display_code: '',
status: 'open',
start_mileage: '',
end_mileage: '',
@@ -92,6 +93,7 @@ export default function WorkOrderDetailModal({ open, workOrder, onClose, onSubmi
setIsEditing(false);
setForm({
has_travel_order: !!(workOrder.travel_start_at || workOrder.travel_end_at || workOrder.location || workOrder.start_mileage != null || workOrder.end_mileage != null),
display_code: workOrder.display_code || '',
status: workOrder.status || 'open',
start_mileage: String(workOrder.start_mileage ?? ''),
end_mileage: workOrder.end_mileage == null ? '' : String(workOrder.end_mileage),
@@ -308,10 +310,20 @@ export default function WorkOrderDetailModal({ open, workOrder, onClose, onSubmi
setError('Svrha naloga je obavezna.');
return;
}
const displayCode = String(form.display_code || '').trim().toUpperCase();
if (!displayCode) {
setError('Prikaz putnog naloga je obavezan.');
return;
}
if (!/^[A-Z]{2}[0-9]{6}$/.test(displayCode)) {
setError('Prikaz putnog naloga mora biti u formatu MT070626.');
return;
}
setSubmitting(true);
try {
await onSubmit(workOrder, {
display_code: displayCode,
status: form.status,
start_mileage: startMileage,
end_mileage: endMileage,
@@ -430,7 +442,7 @@ export default function WorkOrderDetailModal({ open, workOrder, onClose, onSubmi
<div>
<div className="flex items-center justify-between border-b border-border-hairline px-5 py-4">
<div>
<h3 className="text-lg font-semibold text-text-main">Uredi putni nalog {formatEntityCode('PN', workOrder.id)}</h3>
<h3 className="text-lg font-semibold text-text-main">Uredi putni nalog {formatWorkOrderDisplayCode(workOrder)}</h3>
<p className="text-sm text-text-muted">Dizalica: {craneLabel}</p>
</div>
<button
@@ -491,6 +503,20 @@ export default function WorkOrderDetailModal({ open, workOrder, onClose, onSubmi
<div className="rounded-xl border border-border-hairline bg-canvas-base p-3">
<h4 className="mb-2 text-sm font-semibold text-text-main">Status</h4>
<label className="mb-3 flex flex-col gap-1 text-sm">
<span className="font-medium text-text-main">Prikaz putnog naloga *</span>
<input
type="text"
value={form.display_code}
onInput={(event) => setForm({ ...form, display_code: event.currentTarget.value.toUpperCase() })}
className="rounded-lg border border-border-hairline bg-canvas-base px-3 py-2 text-text-main disabled:bg-canvas-deep"
pattern="[A-Za-z]{2}[0-9]{6}"
maxLength={8}
placeholder="MT070626"
disabled={!isEditing}
required
/>
</label>
<label className="flex flex-col gap-1 text-sm">
<span className="font-medium text-text-main">Status *</span>
<select