Files
autocrm/resources/views/shop/checkout.blade.php
T
Vasyka 113610ea8f feat: WO apply_margin at fișă level + full RO/RU i18n on client portal
Two changes in one commit:

== 1. Moved apply_margin toggle from line-level to Fișă-level ==

The per-manoperă apply_margin toggle is gone from the Manopere tab.
In its place: a single "Aplică marjă internă" toggle in Fișa's
"Plată & total" section (next to override_margin_pct). One decision
per Fișă instead of per line — cleaner mental model, matches how the
shop actually thinks about at-cost vs. billable work.

Migration: work_orders.apply_margin boolean default true (idempotent).
WorkOrderWork::saving now reads WO.apply_margin from DB directly (not
via belongsTo cache) to determine salary_base:
  - WO.apply_margin=false → every line gets salary_base=total, applied_margin_pct=0
  - WO.apply_margin=true  → resolver chain (WO.override → user margin → tenant default)

Old wo_works.apply_margin column stays untouched (backward-compat with
existing rows), but no longer exposed in UI. Tests updated to new
semantic. All existing tests green.

== 2. Full i18n audit on client-facing portal — RO/RU separated ==

Problem: user selecting Russian saw Romanian mixed into headings,
buttons, labels. Every client-facing Blade file was 100% hardcoded
Romanian — zero __() calls.

Fix: created lang/ro/portal.php + lang/ru/portal.php with 131 keys
across 3 namespaces:
  - portal.common (email, phone, save, total, powered_by, ...)
  - portal.invitation (welcome_name, activate_account, expired_body, ...)
  - portal.tracking (title_fisa, approve, approval_needed_title,
                    ready_estimated, hours, unit_pcs, ...)
  - portal.shop (catalog, cart, checkout_title, order_number, vin_title,
                signin_title, add_to_cart, in_stock, ...)

Converted 15 Blade files to __() calls:
  - resources/views/invitations/{accept,expired,invalid}.blade.php
  - resources/views/tracking/show.blade.php
  - resources/views/shop/{layout,catalog,cart,checkout,order,account,part,vin}.blade.php
  - resources/views/shop/auth/{login,register,forgot,reset}.blade.php

Each view's <html lang="{{ app()->getLocale() }}"> now reflects the
resolved locale (was hardcoded lang="ro").

SetLocale middleware resolves locale in this order:
  1. session locale (user picked via language switcher)
  2. authenticated user.locale
  3. tenant.settings.language
  4. app.locale default (now 'ro')

Config change: config/app.php default locale + fallback both = 'ro'
(was 'en'). English falls back to Romanian for portal.* keys since
we don't ship English portal translations — a Romanian shop that
switches to English shows Romanian text, which is safer than showing
"portal.invitation.activate_account" literals.

phpunit.xml sets APP_LOCALE=ro so test assertSee() calls that look
for Romanian text pass.

Verified via portal.* grep: 131 __() calls across 15 files. Zero
hardcoded Romanian nouns/verbs left in any client-facing view.

Suite: 303 passed (840 assertions). Unchanged count — refactor,
not new tests.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-07-13 04:56:04 +00:00

72 lines
3.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@extends('shop.layout')
@section('title', __('portal.shop.checkout_title'))
@section('content')
@php
$currency = $tenant->settings['currency'] ?? 'MDL';
$labels = \App\Models\Tenant\OnlineOrder::DELIVERY;
@endphp
<h1 style="font-size:22px;margin-bottom:16px;">{{ __('portal.shop.checkout_title') }}</h1>
@if ($errors->any())
<div class="card" style="border-color:#fca5a5;background:#fef2f2;margin-bottom:14px;">
<ul style="margin:0;padding-left:18px;color:#991b1b;font-size:14px;">
@foreach ($errors->all() as $e)<li>{{ $e }}</li>@endforeach
</ul>
</div>
@endif
<div style="display:grid;grid-template-columns:1fr 320px;gap:18px;align-items:start;">
<form method="POST" action="/shop/checkout" class="card">
@csrf
<div class="field">
<label>{{ __('portal.shop.full_name') }}</label>
<input type="text" name="customer_name" value="{{ old('customer_name', ($customer ?? null)?->name) }}" required>
</div>
<div class="field">
<label>{{ __('portal.shop.phone_req') }}</label>
<input type="text" name="customer_phone" value="{{ old('customer_phone', ($customer ?? null)?->phone) }}" required placeholder="+373…">
</div>
<div class="field">
<label>{{ __('portal.common.email') }}</label>
<input type="email" name="customer_email" value="{{ old('customer_email', ($customer ?? null)?->email) }}">
</div>
<div class="field">
<label>{{ __('portal.shop.delivery_req') }}</label>
<select name="delivery_method" required>
@foreach ($deliveryOptions as $opt)
<option value="{{ $opt }}">{{ $labels[$opt] ?? $opt }}</option>
@endforeach
</select>
</div>
<div class="field">
<label>{{ __('portal.shop.address_delivery') }}</label>
<input type="text" name="address" value="{{ old('address') }}">
</div>
<div class="field">
<label>{{ __('portal.shop.notes') }}</label>
<textarea name="notes" rows="2">{{ old('notes') }}</textarea>
</div>
<button class="btn block" type="submit">{{ __('portal.shop.place_order') }}</button>
</form>
<div class="card">
<h3 style="font-size:15px;margin-bottom:10px;">{{ __('portal.shop.summary') }}</h3>
<table class="cart">
@foreach ($cart as $item)
<tr>
<td>{{ $item['name'] }} <span class="muted">×{{ $item['qty'] }}</span></td>
<td class="r">{{ number_format($item['price'] * $item['qty'], 2) }}</td>
</tr>
@endforeach
</table>
<div style="margin-top:12px;font-size:18px;font-weight:700;text-align:right;">
{{ number_format($subtotal, 2) }} {{ $currency }}
</div>
<p class="muted" style="margin-top:6px;">{{ __('portal.shop.delivery_fee_note') }}</p>
</div>
</div>
<style>@media (max-width:720px){ .wrap div[style*="grid-template-columns:1fr 320px"]{ grid-template-columns:1fr !important; } }</style>
@endsection