feat(125): invoice_requested import fix + drop legacy is_invoice column

- shopPRO: ShopproOrderMapper jako jedyne zrodlo heurystyki detekcji faktury;
  mapOrderAggregate() zwraca top-level invoice_detected (transient).
- ShopproOrdersSyncService: usunieta wlasna shouldRequestInvoice(); propagacja
  aggregate['invoice_detected'] do setInvoiceRequested() tylko przy created=true.
- Allegro: nowa shouldRequestInvoice(payload) z 4 wzorcami (invoice.required,
  naturalPerson=false, address.taxId, companyName/address.company.name).
  Wczesniej tylko invoice.required -> analogiczna luka jak shopPRO.
- Migracja 20260513_000113: idempotentny backfill (UPDATE invoice_requested=1
  WHERE is_invoice=1 AND invoice_requested=0) + DROP COLUMN orders.is_invoice.
  Guard przez information_schema.COLUMNS + PREPARE/EXECUTE z ALTER TABLE COMMENT
  no-op fallbackiem (portable MySQL/MariaDB).
- Cleanup is_invoice z OrderImportRepository (INSERT cols/values/params,
  docstring Phase 112) i OrdersRepository (paginate SELECT, transformOrderRow
  hydrate). AllegroOrderImportService mapping w mapCheckoutFormPayload tez
  usuniety (wymuszone konsekwencja DROP COLUMN).
- Bugfix #1089: zamowienie shopPRO z firm_nip (bez wants_invoice/invoice.required)
  ustawia teraz invoice_requested=1 -> UI w zakladce Platnosci zaznacza checkbox,
  przycisk "Wystaw fakture" widoczny.

Pending operator: php bin/migrate.php (XAMPP MySQL online) -> backfill 7 zamowien.
Smoke test: re-import shopPRO + nowe Allegro z NIP.
This commit is contained in:
2026-05-12 22:11:49 +02:00
parent e7a417bc22
commit 2ab461aaae
15 changed files with 619 additions and 67 deletions

View File

@@ -162,13 +162,13 @@ final class OrderImportRepository
'INSERT INTO orders (
integration_id, source, source_order_id, external_order_id, external_platform_id, external_platform_account_id,
status_code, external_payment_type_id, payment_status, external_carrier_id, external_carrier_account_id,
customer_login, is_invoice, is_encrypted, is_canceled_by_buyer, currency,
customer_login, is_encrypted, is_canceled_by_buyer, currency,
total_without_tax, total_with_tax, total_paid, delivery_price, send_date_min, send_date_max, ordered_at,
source_created_at, source_updated_at, preferences_json, payload_json, fetched_at
) VALUES (
:integration_id, :source, :source_order_id, :external_order_id, :external_platform_id, :external_platform_account_id,
:status_code, :external_payment_type_id, :payment_status, :external_carrier_id, :external_carrier_account_id,
:customer_login, :is_invoice, :is_encrypted, :is_canceled_by_buyer, :currency,
:customer_login, :is_encrypted, :is_canceled_by_buyer, :currency,
:total_without_tax, :total_with_tax, :total_paid, :delivery_price, :send_date_min, :send_date_max, :ordered_at,
:source_created_at, :source_updated_at, :preferences_json, :payload_json, :fetched_at
)'
@@ -187,7 +187,7 @@ final class OrderImportRepository
* Phase 112-01: Delta-only update for re-import. Touches only fields that legitimately
* change at the source between syncs. All other order columns (integration_id, source,
* external_*, customer_login, currency, totals other than total_paid, delivery_price,
* send_date_*, ordered_at, source_created_at, preferences_json, is_invoice, is_encrypted,
* send_date_*, ordered_at, source_created_at, preferences_json, is_encrypted,
* external_carrier_*, external_payment_type_id) are NOT overwritten on re-import.
*
* Phase 119-01: When `payment_status` is unchanged between DB and source payload,
@@ -255,7 +255,6 @@ final class OrderImportRepository
'external_carrier_id' => $orderData['external_carrier_id'] ?? null,
'external_carrier_account_id' => $orderData['external_carrier_account_id'] ?? null,
'customer_login' => $orderData['customer_login'] ?? null,
'is_invoice' => !empty($orderData['is_invoice']) ? 1 : 0,
'is_encrypted' => !empty($orderData['is_encrypted']) ? 1 : 0,
'is_canceled_by_buyer' => !empty($orderData['is_canceled_by_buyer']) ? 1 : 0,
'currency' => (string) ($orderData['currency'] ?? 'PLN'),

View File

@@ -169,7 +169,6 @@ final class OrdersRepository
o.source_updated_at,
o.fetched_at,
' . $effectiveOrderedAtSql . ' AS effective_ordered_at,
o.is_invoice,
o.is_canceled_by_buyer,
a.name AS buyer_name,
a.email AS buyer_email,
@@ -232,7 +231,6 @@ final class OrdersRepository
'source_created_at' => (string) ($row['source_created_at'] ?? ''),
'source_updated_at' => (string) ($row['source_updated_at'] ?? ''),
'fetched_at' => (string) ($row['fetched_at'] ?? ''),
'is_invoice' => (int) ($row['is_invoice'] ?? 0) === 1,
'is_canceled_by_buyer' => (int) ($row['is_canceled_by_buyer'] ?? 0) === 1,
'external_carrier_id' => (string) ($row['external_carrier_id'] ?? ''),
'external_payment_type_id' => (string) ($row['external_payment_type_id'] ?? ''),