feat(124): sms templates CRUD + order picker

- Nowa tabela sms_templates (name + body + is_active) + minimalny CRUD.
- /settings/sms-templates: lista + formularz z paleta zmiennych (pill chips).
- Wydzielono Sms\SmsVariableResolver ze wspolna logika placeholderow;
  Email\VariableResolver staje sie cienka fasada — EmailSendingService bez zmian.
- Dropdown "Wybierz szablon" w zakladce SMS na /orders/{id} z fetch
  GET /orders/{id}/sms/template + OrderProAlerts.confirm przy nadpisaniu.
- Stopka SMSPLANET dalej doklejana wylacznie przez SmsConversationService
  (Phase 122 contract preserved).
- Sidebar Ustawien: nowy link "Szablony SMS".

Migration: 20260512_000112_create_sms_templates.sql (CREATE TABLE).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-12 21:37:51 +02:00
parent 0227f2d072
commit 522c94a434
25 changed files with 1641 additions and 105 deletions

View File

@@ -1,5 +1,31 @@
# Technical Changelog
## 2026-05-12 - Phase 124 Plan 01: SMS Templates
**Co zrobiono:**
- Nowa tabela `sms_templates(id, name, body, is_active, created_at, updated_at)` + indeks `(is_active, name)` — migracja `20260512_000112_create_sms_templates.sql` (DDL).
- `Sms\SmsTemplateRepository` z minimalnym CRUD (`listAll/listActive/findById/save/delete/toggleStatus`); walidacja name+body w `save()`.
- `Sms\SmsVariableResolver` (wydzielony z `Email\VariableResolver`) — wspolna logika `buildVariableMap` + `resolve` dla Email i SMS (placeholdery `{{zamowienie.*|kupujacy.*|adres.*|firma.*|przesylka.*}}`).
- `Email\VariableResolver` zrefaktorowany na fasade — konstruktor opcjonalnie przyjmuje SmsVariableResolver; metody publiczne deleguja. `EmailSendingService` bez zmian.
- `Settings\SmsTemplateController` + widoki `settings/sms-templates.php` (lista) + `settings/sms-templates-form.php` (CRUD form z paleta zmiennych po prawej, licznikiem znakow, walidacja maxlength 918).
- 7 nowych rout: `GET/POST /settings/sms-templates`, `/create`, `/edit`, `/save`, `/delete`, `/toggle`, `/variables`.
- Dropdown "Wybierz szablon" w zakladce SMS na `/orders/{id}` (renderowany tylko gdy istnieja aktywne szablony) -> JS module `sms-template-picker.js` fetchuje `GET /orders/{id}/sms/template?template_id=N` i wkleja rozwiniete body do textarea. Przy niepustej textarea pyta przez `OrderProAlerts.confirm({...})` (options-object API).
- `OrdersController::smsTemplate()` — nowy endpoint JSON; rozszerzony konstruktor o `?SmsTemplateRepository`, `?SmsVariableResolver`, `?CompanySettingsRepository` (default null = BC).
- Sidebar Ustawien rozszerzony o link "Szablony SMS" (active state na `currentSettings === 'sms-templates'`).
- Nowy SCSS partial `modules/_sms-templates.scss` (paleta zmiennych, licznik znakow). Import w `app.scss`.
- Tlumaczenia `orders.details.sms.template_picker(_placeholder)` w `resources/lang/pl.php`.
**Dlaczego:**
- Operator wysyla powtarzalne SMS-y (numer sledzenia, przypomnienie o platnosci, prosba o opinie). Szablony eliminuja recznie wpisywanie tekstu i tracking number, redukujac wysylke do dropdown + ewentualnej korekty.
- Wspolny VariableResolver bo dokladnie te same placeholdery sa potrzebne w Email i SMS (DRY); zachowanie kontraktu `Email\VariableResolver` jako fasady = zero ryzyka regresji w EmailSendingService.
- Stopka SMSPLANET pozostaje doklejana wylacznie przez `SmsConversationService::buildFinalOutboundBody()` (Phase 122) — nie duplikujemy jej w szablonach, walidacja 918 znakow obowiazuje na finalnej tresci.
**Migracja:**
- `php bin/migrate.php` po wlaczeniu MySQL — utworzy `sms_templates`.
- Operator po wdrozeniu tworzy szablony manualnie z `/settings/sms-templates`.
**BREAKING:** brak. `OrdersController` ctor: nowe params optional. `Email\VariableResolver` ctor: nowy opcjonalny drugi argument (default null = self-construct SmsVariableResolver).
## 2026-05-12 - Phase 123 Plan 01: Receipts Export VAT Breakdown
**Co zrobiono:**