Vasyka
|
75386c354a
|
feat: shop customer accounts (register/login + order history)
Schema:
- shop_customers (company_id, name, phone unique-per-tenant, email, password,
client_id auto-linked, last_login_at)
- online_orders.shop_customer_id nullable FK
Auth:
- New 'shop' guard (session driver, shop_customers provider) in config/auth.php
- ShopCustomer Authenticatable with hashed password cast and BelongsToTenant
global scope — login attempts naturally scoped to current tenant subdomain
Flow:
- ShopAuthController: register / login / logout / account
- Register auto-links to existing Client by phone match
- /shop/account: order history (only the logged customer's orders) + profile
- Checkout prefills name/phone/email from logged customer + sets
shop_customer_id (and client_id from auto-link) on the placed order
- Layout nav switches between Login/Register and "👤 Name + Ieșire"
Tests (8 new):
- register creates customer + auto-login
- register auto-links existing Client by phone
- duplicate phone rejected
- login validates credentials
- /account requires auth (redirects to /shop/login)
- /account lists only the logged customer's orders
- checkout attaches shop_customer_id
- customers tenant-isolated
Full suite: 117 passed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-06-02 19:43:39 +00:00 |
|
Vasyka
|
8fdfc9ef85
|
feat: Part product images + seasonal tire-swap reminders
Part (HasMedia):
- Spatie media `image` single-file collection + imageUrl() helper
- PartResource form: image upload section (image editor, 2 MB max)
- Parts list: circular thumbnail column
- Shop catalog cards: square thumbnail + 📦 placeholder
- Shop part detail: 260px image alongside info, single column when no image
Seasonal tire-swap reminders:
- NotificationDispatcher::tireSeasonalSwap(TireSet) — Telegram first, email
fallback (when set has a vehicle, via ServiceReminderMail with 'tire_swap'
type and a size-aware note)
- tires:remind-seasonal artisan command, self-gating to Feb 15-Mar 15
(notify winter sets stored) and Sep 15-Oct 15 (notify summer sets stored).
60-day cooldown per client via service_reminders_sent. --force / --dry-run.
- Schedule: weekly Mon 09:30
Tests (6 new):
- outside window no-ops; spring window notifies winter; spring ignores summer;
autumn notifies summer; cooldown blocks doubles; --force overrides window
Full suite: 106 passed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
2026-06-02 19:31:24 +00:00 |
|
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 |
|