Fix PDF locale and missing translations for ru/en

- Set app locale from user preference in PDF route before rendering
- Wrap hardcoded strings (TOTAL, Subtotal, Achitat etc.) with __()
- Translate status values via __() in blade
- Add ru/en translations: statuses, totals, payment lines

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-06 12:14:54 +00:00
parent a556282581
commit 9df834ffa1
4 changed files with 26 additions and 14 deletions
+7 -2
View File
@@ -60,6 +60,7 @@
"Acest email a fost generat automat. Vă rugăm nu răspundeți.": "This email was auto-generated. Please do not reply.", "Acest email a fost generat automat. Vă rugăm nu răspundeți.": "This email was auto-generated. Please do not reply.",
"Achitat": "Paid", "Achitat": "Paid",
"Achitat azi": "Paid today", "Achitat azi": "Paid today",
"Achitat:": "Paid:",
"Achiziție piese": "Parts purchase", "Achiziție piese": "Parts purchase",
"Achiziții": "Purchases", "Achiziții": "Purchases",
"Acord": "Agreed", "Acord": "Agreed",
@@ -225,7 +226,7 @@
"Approved at": "Approved at", "Approved at": "Approved at",
"Aprilie": "April", "Aprilie": "April",
"Aprobare": "Approval", "Aprobare": "Approval",
"Aprobare client": "Client agreement", "Aprobare client": "Awaiting approval",
"Aprobat": "Approved", "Aprobat": "Approved",
"Aprobat de": "Approved by", "Aprobat de": "Approved by",
"Aprobat de client": "Approved by client", "Aprobat de client": "Approved by client",
@@ -705,7 +706,7 @@
"Diagnosis": "Diagnosis", "Diagnosis": "Diagnosis",
"Diagnostic": "Diagnostic", "Diagnostic": "Diagnostic",
"Diagnostic AI bazat pe plângerea clientului": "AI diagnosis based on the client complaint", "Diagnostic AI bazat pe plângerea clientului": "AI diagnosis based on the client complaint",
"Diagnosticare": "Diagnostics", "Diagnosticare": "Diagnosis",
"Diagnoza": "Diagnosis", "Diagnoza": "Diagnosis",
"Diagnoză": "Diagnosis", "Diagnoză": "Diagnosis",
"Diametru R": "Diameter R", "Diametru R": "Diameter R",
@@ -715,6 +716,7 @@
"Disabled": "Disabled", "Disabled": "Disabled",
"Discount": "Discount", "Discount": "Discount",
"Discount %": "Discount %", "Discount %": "Discount %",
"Discount:": "Discount:",
"Distribuie": "Distribute", "Distribuie": "Distribute",
"Distribuție": "Timing", "Distribuție": "Timing",
"Doar active": "Active only", "Doar active": "Active only",
@@ -1754,6 +1756,7 @@
"Respins": "Rejected", "Respins": "Rejected",
"Respins de": "Rejected by", "Respins de": "Rejected by",
"Responsabil": "Assignee", "Responsabil": "Assignee",
"Rest de achitat:": "Balance due:",
"Rest de plată": "Balance due", "Rest de plată": "Balance due",
"Restanță": "Debt", "Restanță": "Debt",
"Restaurează": "Restore", "Restaurează": "Restore",
@@ -1956,6 +1959,7 @@
"Subtotal": "Subtotal", "Subtotal": "Subtotal",
"Subtotal manopere:": "Labor subtotal:", "Subtotal manopere:": "Labor subtotal:",
"Subtotal piese:": "Parts subtotal:", "Subtotal piese:": "Parts subtotal:",
"Subtotal:": "Subtotal:",
"Succes": "Success", "Succes": "Success",
"Sugerează revizie / piese de uzură.": "Suggest service / wear parts.", "Sugerează revizie / piese de uzură.": "Suggest service / wear parts.",
"Sugestii pe pagini:": "In-page hints:", "Sugestii pe pagini:": "In-page hints:",
@@ -1984,6 +1988,7 @@
"Săptămâna curentă": "Current week", "Săptămâna curentă": "Current week",
"Săptămâna trecută": "Last week", "Săptămâna trecută": "Last week",
"Săptămâni": "Weeks", "Săptămâni": "Weeks",
"TOTAL DE PLATĂ:": "TOTAL DUE:",
"TPMS": "TPMS", "TPMS": "TPMS",
"TPMS & foto": "TPMS & photos", "TPMS & foto": "TPMS & photos",
"TVA": "VAT", "TVA": "VAT",
+11 -6
View File
@@ -60,6 +60,7 @@
"Acest email a fost generat automat. Vă rugăm nu răspundeți.": "Это письмо сгенерировано автоматически. Пожалуйста, не отвечайте.", "Acest email a fost generat automat. Vă rugăm nu răspundeți.": "Это письмо сгенерировано автоматически. Пожалуйста, не отвечайте.",
"Achitat": "Оплачено", "Achitat": "Оплачено",
"Achitat azi": "Оплачено сегодня", "Achitat azi": "Оплачено сегодня",
"Achitat:": "Оплачено:",
"Achiziție piese": "Закупка запчастей", "Achiziție piese": "Закупка запчастей",
"Achiziții": "Закупки", "Achiziții": "Закупки",
"Acord": "Согласовано", "Acord": "Согласовано",
@@ -206,7 +207,7 @@
"Anul acesta": "В этом году", "Anul acesta": "В этом году",
"Anul curent": "Текущий год", "Anul curent": "Текущий год",
"Anul trecut": "Прошлый год", "Anul trecut": "Прошлый год",
"Anulat": "Отменён", "Anulat": "Отменено",
"Anulată": "Отменена", "Anulată": "Отменена",
"Anulează": "Отмена", "Anulează": "Отмена",
"Anulează fișa": "Отменить наряд", "Anulează fișa": "Отменить наряд",
@@ -225,8 +226,8 @@
"Approved at": "Утверждено", "Approved at": "Утверждено",
"Aprilie": "Апрель", "Aprilie": "Апрель",
"Aprobare": "Утверждение", "Aprobare": "Утверждение",
"Aprobare client": "Согласование клиента", "Aprobare client": "Ожидает одобрения",
"Aprobat": "Утверждено", "Aprobat": "Одобрено",
"Aprobat de": "Утверждено", "Aprobat de": "Утверждено",
"Aprobat de client": "Одобрено клиентом", "Aprobat de client": "Одобрено клиентом",
"Aprobă": "Утвердить", "Aprobă": "Утвердить",
@@ -282,7 +283,7 @@
"Avg zile": "Ср. дней", "Avg zile": "Ср. дней",
"Azi": "Сегодня", "Azi": "Сегодня",
"Așteaptă client": "Ожидают клиента", "Așteaptă client": "Ожидают клиента",
"Așteaptă piese": "Ждёт запчасти", "Așteaptă piese": "Ожидает запчасти",
"Așteaptă piesele": "Ждёт запчасти", "Așteaptă piesele": "Ждёт запчасти",
"Aștept aprobare client": "Ожидание одобрения клиента", "Aștept aprobare client": "Ожидание одобрения клиента",
"Așteptată": "Ожидается", "Așteptată": "Ожидается",
@@ -715,6 +716,7 @@
"Disabled": "Выключен", "Disabled": "Выключен",
"Discount": "Скидка", "Discount": "Скидка",
"Discount %": "Скидка %", "Discount %": "Скидка %",
"Discount:": "Скидка:",
"Distribuie": "Распределить", "Distribuie": "Распределить",
"Distribuție": "ГРМ", "Distribuție": "ГРМ",
"Doar active": "Только активные", "Doar active": "Только активные",
@@ -930,7 +932,7 @@
"GRANT — adaugă dreptul": "GRANT — добавить право", "GRANT — adaugă dreptul": "GRANT — добавить право",
"Galerie de până la 8 imagini. Prima e afișată în catalog. Max 2 MB / imagine.": "Галерея до 8 изображений. Первое отображается в каталоге. Максимум 2 МБ / изображение.", "Galerie de până la 8 imagini. Prima e afișată în catalog. Max 2 MB / imagine.": "Галерея до 8 изображений. Первое отображается в каталоге. Максимум 2 МБ / изображение.",
"Gata": "Готов", "Gata": "Готов",
"Gata de ridicare": "Готов к выдаче", "Gata de ridicare": "Готово к выдаче",
"Gata estimat (ETA)": "Gata estimat (ETA)", "Gata estimat (ETA)": "Gata estimat (ETA)",
"Gearbox": "КПП", "Gearbox": "КПП",
"Gemini API Key": "Gemini API Key", "Gemini API Key": "Gemini API Key",
@@ -1571,7 +1573,7 @@
"Prag S": "Порог Л", "Prag S": "Порог Л",
"Pre-completat automat la programări noi pe acest pod.": "Pre-completat automat la programări noi pe acest pod.", "Pre-completat automat la programări noi pe acest pod.": "Pre-completat automat la programări noi pe acest pod.",
"Precedent": "Предыдущий", "Precedent": "Предыдущий",
"Predat": "Выдан", "Predat": "Выдано",
"Prefix facturi": "Prefix facturi", "Prefix facturi": "Prefix facturi",
"Pregătită": "Готова", "Pregătită": "Готова",
"Premium": "Премиум", "Premium": "Премиум",
@@ -1754,6 +1756,7 @@
"Respins": "Отклонено", "Respins": "Отклонено",
"Respins de": "Отклонено", "Respins de": "Отклонено",
"Responsabil": "Ответственный", "Responsabil": "Ответственный",
"Rest de achitat:": "Остаток к оплате:",
"Rest de plată": "К оплате", "Rest de plată": "К оплате",
"Restanță": "Задолженность", "Restanță": "Задолженность",
"Restaurează": "Восстановить", "Restaurează": "Восстановить",
@@ -1956,6 +1959,7 @@
"Subtotal": "Промежуточный итог", "Subtotal": "Промежуточный итог",
"Subtotal manopere:": "Итого работы:", "Subtotal manopere:": "Итого работы:",
"Subtotal piese:": "Итого запчасти:", "Subtotal piese:": "Итого запчасти:",
"Subtotal:": "Подытог:",
"Succes": "Успех", "Succes": "Успех",
"Sugerează revizie / piese de uzură.": "Предложите ТО / расходники.", "Sugerează revizie / piese de uzură.": "Предложите ТО / расходники.",
"Sugestii pe pagini:": "Подсказки на страницах:", "Sugestii pe pagini:": "Подсказки на страницах:",
@@ -1984,6 +1988,7 @@
"Săptămâna curentă": "Текущая неделя", "Săptămâna curentă": "Текущая неделя",
"Săptămâna trecută": "Прошлая неделя", "Săptămâna trecută": "Прошлая неделя",
"Săptămâni": "Недели", "Săptămâni": "Недели",
"TOTAL DE PLATĂ:": "ИТОГО К ОПЛАТЕ:",
"TPMS": "TPMS", "TPMS": "TPMS",
"TPMS & foto": "TPMS и фото", "TPMS & foto": "TPMS и фото",
"TVA": "НДС", "TVA": "НДС",
+6 -6
View File
@@ -140,7 +140,7 @@
<div class="doc-meta">{{ __('Data închiderii:') }} <b>{{ $wo->closed_at->format('d.m.Y') }}</b></div> <div class="doc-meta">{{ __('Data închiderii:') }} <b>{{ $wo->closed_at->format('d.m.Y') }}</b></div>
@endif @endif
<div class="doc-meta"> <div class="doc-meta">
{{ __('Status:') }} <b>{{ \App\Models\Tenant\WorkOrder::STATUSES[$wo->status] ?? $wo->status }}</b> {{ __('Status:') }} <b>{{ __(\App\Models\Tenant\WorkOrder::STATUSES[$wo->status] ?? $wo->status) }}</b>
</div> </div>
</div> </div>
</div> </div>
@@ -254,15 +254,15 @@
<div class="total-box"> <div class="total-box">
@if ($wo->discount_pct > 0) @if ($wo->discount_pct > 0)
<div class="total-line">Subtotal: {{ number_format((float) ($worksTotal + $partsTotal), 2, '.', ' ') }} {{ $currency }}</div> <div class="total-line">{{ __('Subtotal:') }} {{ number_format((float) ($worksTotal + $partsTotal), 2, '.', ' ') }} {{ $currency }}</div>
<div class="total-line">Discount: -{{ $wo->discount_pct }}%</div> <div class="total-line">{{ __('Discount:') }} -{{ $wo->discount_pct }}%</div>
@endif @endif
<div class="total-line grand"> <div class="total-line grand">
TOTAL DE PLATĂ: {{ number_format((float) $wo->total, 2, '.', ' ') }} {{ $currency }} {{ __('TOTAL DE PLATĂ:') }} {{ number_format((float) $wo->total, 2, '.', ' ') }} {{ $currency }}
</div> </div>
@if ($paid > 0) @if ($paid > 0)
<div class="total-line">Achitat: {{ number_format($paid, 2, '.', ' ') }} {{ $currency }}</div> <div class="total-line">{{ __('Achitat:') }} {{ number_format($paid, 2, '.', ' ') }} {{ $currency }}</div>
<div class="total-line"><b>Rest de achitat: {{ number_format($balance, 2, '.', ' ') }} {{ $currency }}</b></div> <div class="total-line"><b>{{ __('Rest de achitat:') }} {{ number_format($balance, 2, '.', ' ') }} {{ $currency }}</b></div>
@endif @endif
</div> </div>
+2
View File
@@ -85,6 +85,8 @@ Route::get('/app/appointments/pdf', function (Request $request) {
// so user can print/save); forced download with ?download=1. // so user can print/save); forced download with ?download=1.
Route::get('/app/work-orders/{workOrder}/pdf', function (Request $request, int $workOrder) { Route::get('/app/work-orders/{workOrder}/pdf', function (Request $request, int $workOrder) {
abort_unless(auth('web')->check(), 403); abort_unless(auth('web')->check(), 403);
$locale = auth('web')->user()?->locale ?? config('app.locale');
app()->setLocale($locale);
$wo = \App\Models\Tenant\WorkOrder::findOrFail($workOrder); $wo = \App\Models\Tenant\WorkOrder::findOrFail($workOrder);
$svc = app(\App\Services\WorkOrderPdfService::class); $svc = app(\App\Services\WorkOrderPdfService::class);
$pdf = $svc->generate($wo); $pdf = $svc->generate($wo);