Commit Graph

204 Commits

Author SHA1 Message Date
e7a417bc22 update 2026-05-12 21:37:58 +02:00
522c94a434 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>
2026-05-12 21:37:51 +02:00
0227f2d072 feat(123): receipts export xlsx VAT breakdown
- AccountingController::export(): new headers (Numer | Data wystawienia | Kwota brutto | Kwota netto | Stawka VAT | Kwota VAT), removed Data sprzedazy/Konfiguracja/Nr zamowienia/Nr referencyjny
- buildVatBreakdown() helper groups items_json by vat rate, emits one XLSX row per (receipt x rate); legacy receipts (no `vat` in snapshot) fallback to net=brutto/1.23
- ReceiptService::buildItemsSnapshot(): writes `vat` per item from order_items.tax_rate (fallback 23.0); shipping cost item gets vat=23.0
- RECEIPT-NET-FIX deferred (.paul/codebase/todo.md): ReceiptService::issue() still saves total_net=total_gross

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:06:53 +02:00
a4ed4531dc update 2026-05-12 20:38:56 +02:00
4555548a40 docs(paul): record phase 118 transition + close UNIFY for 121/122
- ROADMAP: Phase 118 marked Complete (1/1)
- STATE: git state updated with 8f14851 + 360eef1; pending parallel work cleared
- STATE: removed Phase 122 transition note (resolved)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-12 20:38:33 +02:00
360eef128d feat(121+122): smsplanet conversation, notifications, default footer
Phase 121 — SMSPLANET Conversation + Notifications:
- migration 20260512_000110 adds smsplanet conversation + notifications tables
- src/Modules/Sms (SmsConversationService, SmsMessageRepository, SmsplanetWebhookController)
- src/Modules/Notifications (Repository, Controller, ApiController)
- order SMS tab, notification center, sender mode, inbound webhook
- public notifications.js + layouts/app.php integration

Phase 122 — SMSPLANET Default SMS Footer:
- migration 20260512_000111 adds smsplanet_integration_settings.default_footer
- footer appended to test SMS and order SMS, validated against 918 char limit
- settings textarea + compact order SMS note when footer configured

Bundled (could not split per-phase without hunk staging):
- routes/web.php (also carries Phase 118 fakturownia redirects)
- DOCS/{ARCHITECTURE,DB_SCHEMA,TECH_CHANGELOG}.md (118 + 121 + 122 entries)
- .paul/codebase/{architecture,db_schema,tech_changelog}.md (118 + 121 + 122)
- .paul/STATE.md, ROADMAP.md, changelog/2026-05-12.md (UNIFY closure)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-12 20:37:41 +02:00
8f14851d85 feat(118): fakturownia single instance
Phase 118 complete:
- migration 20260512_000109 adds single global Fakturownia settings row
- FakturowniaIntegrationRepository simplified to one-instance API
- FakturowniaIntegrationController + edit view collapsed to one settings page
- Integrations hub shows Fakturownia as single instance
- Invoice config delegated flow always uses global integration_id

Note: shared routes/web.php and DOCS/* updates from Phase 118 are bundled
into the follow-up feat(121+122) commit because Phase 121/122 modified the
same files; hunk-level split was not performed.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-12 20:37:19 +02:00
933dfcc67b feat(120): alert component unification
Phase 120 - Plan 01:
- Reusable PHP alert component (resources/views/components/alert.php)
  with inline SVG icon per type, optional dismiss button.
- Missing .alert--info SCSS variant added (#eff6ff/#bfdbfe/#1e3a8a) -
  fixes black-on-white alert after Fakturownia test connection.
- Flash::push(type, message) + Flash::all() with BC for set/get;
  legacy key heuristic (error/.save/warning -> typed entries).
- Central flash renderer in 3 layouts (app/auth/public) iterating
  Flash::all() through component (.alerts-stack wrap).
- Vanilla JS alert-dismiss.js with idempotent guard and delegated
  click handler on [data-alert-dismiss].
- 36 views migrated off inline <div class="alert alert--TYPE">;
  .flash--error/success removed from views (orders/show, shipments/prepare).
- SCSS rebuilt: public/assets/css/{app,login}.css.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 18:47:41 +02:00
3a2c419c25 feat(119): protect total_paid from re-import overwrite
OrderImportRepository::updateOrderDelta() przechodzi na dynamic SET builder.
total_paid jest dolaczane do UPDATE tylko gdy payment_status realnie sie
zmienia; is_canceled_by_buyer analogicznie, ale z override przez
cancelledBySource (cancel ze zrodla nadal propaguje sie do bazy).

Chroni reczne korekty operatora (zwroty czesciowe) przed cichym
nadpisaniem z payloadu zrodla przy kolejnym sync. Incydent #976:
operator zwrocil klientowi 28,00 PLN obnizajac total_paid 119->91,
co bez tej zmiany byloby cofniete przez kolejny re-import shoppro.

Boundaries: identical-payload guard, paymentTransition, statusOverwriteAllowed,
cancel propagation (status_code='anulowane') - bez zmian.

Tests: tests/Unit/OrderImportRepositoryTest.php - 3 scenariusze
(preserve / transition / cancel propagation) via Reflection + sqlite
in-memory. PHPUnit run odroczony (vendor/ gitignored).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 14:57:04 +02:00
bcbb35bc6b feat(117): smsplanet integration settings 2026-05-12 13:19:12 +02:00
09f9ca798d docs(paul): record phase 116 transition 2026-05-12 12:26:18 +02:00
bc2ed2c8e2 feat(116): hostedsms integration settings
Phase 116 complete:
- add HostedSMS settings with encrypted password storage
- add SimpleAPI real test SMS flow and integrations hub row
- document schema, architecture, changelog, and PAUL state

Co-Authored-By: Codex <noreply@openai.com>
2026-05-12 12:25:48 +02:00
adacb65110 update 2026-05-11 20:40:13 +02:00
0578bfc2ae update 2026-05-11 20:22:04 +02:00
2b4d843ae0 Merge branch 'main' of https://git.project-pro.pl/Project-Pro/orderPRO 2026-05-11 00:09:26 +02:00
ee1c5e5cfd update 2026-05-11 00:09:23 +02:00
33ee1a1cf5 feat(115): wystawianie faktury z zamowienia (lokalne + delegowane Fakturownia)
Phase 115 complete (vertical slice "zamowienie z NIP -> faktura PDF"):
- Task 1: InvoiceRepository + InvoiceService (dual-flow orchestrator) +
  InvoiceIssueException + FakturowniaApiClient::createInvoice + buildPdfUrl
- Task 2: InvoiceController + OrdersController::toggleInvoiceRequested +
  OrdersRepository::setInvoiceRequested + auto-import invoice_requested z
  Allegro (invoice.required) i shopPRO (5-key flexible parser) + show.php
  (toggle w zakladce Platnosci + warunkowy przycisk Wystaw fakture)
- Task 3: Lista wystawionych /settings/accounting/invoices/issued z filtrami
  + invoice_preview + invoice_pdf Dompdf template + hub link
- Task 3b (dodany): NIP lookup przez MF Biala Lista (publiczne API, bez
  rejestracji) — MfWhitelistApiClient w src/Core/Http/ + /api/nip/lookup +
  przycisk "Pobierz z GUS" w formularzu

Auto-fixes podczas smoke testu (5):
- GUS endpoint Fakturowni nie istnial (HTML 404 -> "json is not valid");
  switch na MF Biala Liste
- PHP 8.5 curl_close() deprecation wycieka HTML przed JSON; usuniete z
  MfWhitelistApiClient i FakturowniaApiClient (3 miejsca)
- Fakturownia 422 payment_to_kind_days (nieistniejace pole) -> usuniete
- Generic "error" w 422 -> parser plaskuje errors: {pole: [...]} +
  error_log z 1000 znakow raw body
- Fakturownia security odrzuca seller_*/department_id jako "create new
  department"; usuniete z payloadu (Fakturownia uzywa danych konta)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 23:34:50 +02:00
6129042ff6 feat(114): accounting configs refactor + invoice configs CRUD
Phase 114 complete (v3.7 Invoices):
- /settings/accounting jako hub-rozdroze (Paragony / Faktury)
- /settings/accounting/receipts + /invoices osobne podstrony list i edycji
- InvoiceConfigRepository + Controller (CRUD z walidacja delegacji)
- Seed Domyslny VAT (NOT EXISTS idempotent)
- invoice-config-form.js (toggle is_delegated -> integration_id)
- confirm-delete.js (globalny modul OrderProAlerts.confirm)
- Legacy aliasy starych endpointow /settings/accounting/save|toggle|delete

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 22:32:29 +02:00
2382018739 feat(113): fakturownia integration foundation
Phase 113 complete (v3.7 Invoices):
- DB: invoices, invoice_configs, invoice_number_counters, fakturownia_integration_settings + orders.invoice_requested
- FakturowniaIntegrationRepository (multi-account via integrations.type='fakturownia')
- FakturowniaApiClient (testConnection; createInvoice/downloadPdf STUBs)
- IntegrationsRepository::updateTestResult() (reusable test-result writer)
- /settings/integrations/fakturownia (list + edit + test + delete)
- Karta Fakturownia w hubie /settings/integrations

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 22:11:55 +02:00
26a1e67c6d update 2026-05-08 15:28:26 +02:00
322b23b7be update 2026-05-07 23:35:18 +02:00
782a291210 feat(112): re-import data protection — delta-only re-import + project_generated preservation
Phase 112 / Plan 112-01 complete (v3.6):
- OrderImportRepository::upsertOrderAggregate split into create vs re-import paths
- replaceAddresses/Items/Notes/Shipments/StatusHistory invoked only on first import
- new updateOrderDelta() narrows UPDATE to status_code (cond.), payment_status,
  total_paid, is_canceled_by_buyer, source_updated_at, payload_json, fetched_at
- source-side cancellation override (is_canceled_by_buyer=1 OR pull status_code='anulowane')
- identical-payload no-op guard via normalizePayloadJson()
- fixes case #882: order_items.id stable, project_generated (Phase 97) preserved
- Phase 111 payment.status_changed emit retained without regression

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 23:22:37 +02:00
0e457aed38 update 2026-05-07 15:24:05 +02:00
1069ccb85e update 2026-05-06 20:35:26 +02:00
cc07508006 update 2026-05-05 23:35:45 +02:00
5cf531d718 feat(111): payment transition event for Allegro+shopPRO re-import
Re-import zamowienia wykrywa tranzycje payment_status 0/1->2 i emituje
payment.status_changed, dzieki czemu chain reguly automatyzacji #7 zmienia
status na w_realizacji.

- OrderImportRepository: rozdzielenie paymentTransition (event 0/1->2) i
  statusOverwriteAllowed (preservacja status_code z Phase 62)
- AllegroOrderImportService + ShopproOrdersSyncService: emit
  payment.status_changed na re-imporcie (gate !wasCreated && wasPaymentTransition)
- bin/backfill_payment_transition_111.php: jednorazowy CLI dla zamowien
  payment_status=2 && status_code='nieoplacone' (Allegro + shopPRO)
- Naprawa luki znalezionej w analizie zamowienia #864

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 23:35:14 +02:00
0da0241ebf update 2026-05-05 12:59:44 +02:00
3aab40a35e Merge branch 'main' of https://git.project-pro.pl/Project-Pro/orderPRO 2026-05-05 00:00:57 +02:00
a403a715e8 upate 2026-05-05 00:00:40 +02:00
1589cf29fa update 2026-05-05 00:00:31 +02:00
fd63409bd9 update 2026-05-04 23:58:52 +02:00
9ff59f3f0d update 2026-04-30 21:33:48 +02:00
61f10a688d update 2026-04-29 15:14:18 +02:00
0b4ffb7146 feat(110): statistics summary
Phase 110 complete:
- add Statistics -> Podsumowanie page
- add monthly order count and value charts per integration plus total
- use Chart.js with table fallback and 04-2026 default history start
- update PAUL and DOCS technical documentation
2026-04-28 22:48:31 +02:00
1156ce046c upadte 2026-04-28 22:17:25 +02:00
6d3dba89ed feat(109): checkbox multiselect filters
Phase 109 complete:
- Add checkbox dropdown enhancement for statistics multi-select filters
- Preserve GET contract for channels[] and status_groups[]
- Update PAUL plan context to read .paul/codebase docs

Co-Authored-By: Codex <noreply@openai.com>
2026-04-28 22:15:04 +02:00
1009957fff updaate 2026-04-28 15:09:48 +02:00
3f5784d8eb update 2026-04-27 22:10:57 +02:00
0063402897 feat(108): delivery status management
Phase 108 complete (v3.2 milestone):

Plan 108-01 — Delivery Status DB & CRUD:
- Tabela delivery_statuses z seedem 11 statusow systemowych
- DeliveryStatusRepository (CRUD + per-request static cache)
- DeliveryStatus::setRepository() — DB fallback dla static final class
- Panel /settings/delivery-statuses (zakladki Statusy + Mapowanie)
- Sidebar przebudowany: Statusy zamowien + Statusy przesylek

Plan 108-02 — Automation Dropdowns z DB + UI Refactor:
- Dropdowny automatyzacji ladowane z DB (warunek shipment_status + akcja update_shipment_status)
- Walidacja przez DeliveryStatus::getAllStatuses()
- Osobna podstrona formularza CRUD (delivery-status-form.php)
- Lista uproszczona: rename Terminal -> Koncowy, usunieta kolumna Typ
- BREAKING: drop backward compat dla starych grupowych kluczy automatyzacji
- Bug fix: path params w DeliveryStatusesController via \$request->input('id')

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-27 22:10:24 +02:00
d8daf61de6 feat(107-automation-email-send-once): idempotent send-once per order for email automation
Phase 107 complete:
- New table automation_email_once_deliveries with UNIQUE KEY (rule_id, action_id, order_id)
- AutomationEmailOnceRepository: wasSent() / markSent() with ON DUPLICATE KEY guard
- AutomationService: send_once_per_order flag — mark only on successful send
- Checkbox "Wyslij tylko raz dla tego zamowienia" in rule form (edit + new action JS)
- 2 unit tests added; 3/3 passing (49 assertions)

Milestone v3.1 Operational Enhancements: COMPLETE (2/2 phases)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-27 21:19:29 +02:00
5aca41750c update 2026-04-27 15:02:06 +02:00
32d7ae9ceb update 2026-04-27 12:17:21 +02:00
34dac15494 update 2026-04-26 21:55:49 +02:00
f5c5201a2f chore: move TODO to .paul/codebase/todo.md 2026-04-26 21:55:32 +02:00
c3b68d5228 chore: add TODO(DELIVERY-STATUS-MGMT) - manage normalized statuses from panel 2026-04-26 21:54:24 +02:00
69f180a185 feat: add picked_up normalized delivery status (odebrana przez kuriera) 2026-04-26 21:52:58 +02:00
ca7540d374 chore: rename codebase map files to lowercase 2026-04-26 21:41:04 +02:00
b1b2cc5827 chore: generate codebase map in .paul/codebase/
INDEX, STACK, ARCHITECTURE, CONVENTIONS, TESTING, INTEGRATIONS, CONCERNS
2026-04-26 21:39:12 +02:00
4b998ea5be update 2026-04-25 21:31:50 +02:00
4931c55338 update 2026-04-24 18:55:13 +02:00