Files
autocrm/resources/views/shop/checkout.blade.php
T
Vasyka 954ba8f059 Stage 12 — Online Store: public catalog + cart + orders
Schema:
- online_orders (token-tracked, status workflow, delivery method/fee)
- online_order_items (price snapshot, fulfilled flag)
- part_cross_refs (OEM/equivalent codes for search)
- parts.is_published (shop visibility)

Storefront (ShopController, tenant subdomain, /shop):
- Catalog with search across name/article/brand/cross-refs, category +
  in-stock filters, live stock, white-label themed layout
- Part detail page with cross-ref codes
- VIN search → VinDecoder → guided catalog search
- Session cart (per-tenant key), guest checkout, order confirmation page
- Respects settings.shop.enabled (404 when off); tenant-guarded

Part::searchPublished matches cross-ref articles via whereHas.

Order notifications (ShopOrderNotifier, best-effort):
- Staff: Web Push to active users
- Customer: Telegram if phone matches a linked client

Filament (tenant):
- OnlineOrderResource under "Magazin" nav group, status workflow,
  items relation, "Onorează" action issues stock via WarehouseService (FIFO)
- PartResource: is_published toggle + column + bulk publish/unpublish +
  CrossRefsRelationManager
- Settings: shop section (enable, delivery methods, fee, free-over)
- Landing page: shop button when enabled

Tests (6 new):
- catalog 404 when disabled; lists published only; cross-ref search;
  order placement (token + items + total); fulfill issues stock;
  cross-tenant token isolation

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 05:27:51 +00:00

72 lines
2.8 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', 'Finalizare comandă')
@section('content')
@php
$currency = $tenant->settings['currency'] ?? 'MDL';
$labels = \App\Models\Tenant\OnlineOrder::DELIVERY;
@endphp
<h1 style="font-size:22px;margin-bottom:16px;">Finalizează comanda</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>Nume complet *</label>
<input type="text" name="customer_name" value="{{ old('customer_name') }}" required>
</div>
<div class="field">
<label>Telefon *</label>
<input type="text" name="customer_phone" value="{{ old('customer_phone') }}" required placeholder="+373…">
</div>
<div class="field">
<label>Email</label>
<input type="email" name="customer_email" value="{{ old('customer_email') }}">
</div>
<div class="field">
<label>Livrare *</label>
<select name="delivery_method" required>
@foreach ($deliveryOptions as $opt)
<option value="{{ $opt }}">{{ $labels[$opt] ?? $opt }}</option>
@endforeach
</select>
</div>
<div class="field">
<label>Adresă (pentru curier/poștă)</label>
<input type="text" name="address" value="{{ old('address') }}">
</div>
<div class="field">
<label>Observații</label>
<textarea name="notes" rows="2">{{ old('notes') }}</textarea>
</div>
<button class="btn block" type="submit">Plasează comanda</button>
</form>
<div class="card">
<h3 style="font-size:15px;margin-bottom:10px;">Sumar</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;">Taxa de livrare se calculează în funcție de metoda aleasă.</p>
</div>
</div>
<style>@media (max-width:720px){ .wrap div[style*="grid-template-columns:1fr 320px"]{ grid-template-columns:1fr !important; } }</style>
@endsection