# Conflicts:
#	.paul/PROJECT.md
#	.paul/ROADMAP.md
#	.paul/STATE.md
#	.paul/codebase/tech_changelog.md
#	resources/lang/pl.php
#	resources/views/shipments/prepare.php
#	routes/web.php
#	src/Modules/Settings/IntegrationsHubController.php
#	src/Modules/Shipments/ShipmentController.php
This commit is contained in:
2026-05-16 01:04:56 +02:00
50 changed files with 8670 additions and 15 deletions

View File

@@ -0,0 +1,29 @@
CREATE TABLE IF NOT EXISTS `polkurier_integration_settings` (
`id` TINYINT UNSIGNED NOT NULL PRIMARY KEY,
`integration_id` INT UNSIGNED NULL,
`login` VARCHAR(190) NULL,
`api_token_encrypted` TEXT NULL,
`default_label_format` VARCHAR(8) NOT NULL DEFAULT 'PDF',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY `polkurier_integration_settings_integration_unique` (`integration_id`),
CONSTRAINT `polkurier_integration_settings_integration_fk`
FOREIGN KEY (`integration_id`) REFERENCES `integrations` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `integrations` (`type`, `name`, `base_url`, `timeout_seconds`, `is_active`, `created_at`, `updated_at`)
VALUES ('polkurier', 'polkurier', 'https://api.polkurier.pl/', 15, 1, NOW(), NOW())
ON DUPLICATE KEY UPDATE
`base_url` = VALUES(`base_url`),
`timeout_seconds` = VALUES(`timeout_seconds`),
`updated_at` = VALUES(`updated_at`);
INSERT INTO `polkurier_integration_settings` (`id`, `integration_id`, `created_at`, `updated_at`)
SELECT 1, `id`, NOW(), NOW()
FROM `integrations`
WHERE `type` = 'polkurier' AND `name` = 'polkurier'
LIMIT 1
ON DUPLICATE KEY UPDATE
`integration_id` = VALUES(`integration_id`),
`updated_at` = VALUES(`updated_at`);

View File

@@ -0,0 +1,27 @@
-- Phase 128-01: seed delivery_status_mappings dla provider='polkurier'.
-- Kody zaczerpniete z oficjalnej dokumentacji API polkurier v1.11 (marzec 2026),
-- tabela "Status zlecenia ORDER_STATUS":
-- O = Oczekuje (zlecenie zapisane, oczekuje na platnosc)
-- P = Potwierdzone (zlecenie zapisane, list przewozowy wygenerowany, oczekuje odbioru)
-- A = Anulowane (przesylka anulowana)
-- WP = W przewozie (odebrana od nadawcy, w drodze do adresata)
-- D = Dostarczona (dotarla do adresata)
-- Z = Zwrot do nadawcy (odmowa odbioru przez odbiorce)
-- W = Wyjatek (problem z doreczeniem)
-- Status PZ (Podjazd zbiorczy) jest filtrem wyszukiwania get_orders, nie wystepuje jako
-- samodzielny status zlecenia -- pomijamy w seedzie.
--
-- Migracja idempotentna: ON DUPLICATE KEY UPDATE nadpisuje normalized_status i description.
INSERT INTO delivery_status_mappings (provider, raw_status, normalized_status, description, created_at, updated_at) VALUES
('polkurier', 'O', 'created', 'Oczekuje (oczekuje na platnosc)', NOW(), NOW()),
('polkurier', 'P', 'confirmed', 'Potwierdzone (list przewozowy wygenerowany)', NOW(), NOW()),
('polkurier', 'A', 'cancelled', 'Anulowane', NOW(), NOW()),
('polkurier', 'WP', 'in_transit','W przewozie', NOW(), NOW()),
('polkurier', 'D', 'delivered', 'Dostarczona', NOW(), NOW()),
('polkurier', 'Z', 'returned', 'Zwrot do nadawcy', NOW(), NOW()),
('polkurier', 'W', 'problem', 'Wyjatek (problem z doreczeniem)', NOW(), NOW())
ON DUPLICATE KEY UPDATE
normalized_status = VALUES(normalized_status),
description = VALUES(description),
updated_at = NOW();

View File

@@ -0,0 +1,57 @@
-- Phase 129-01: extend order_notes o pola dla notatek autorskich (user-authored)
-- Reuse istniejacej tabeli z nowym note_type='user', user_id (FK->users), author_name (snapshot).
-- Idempotentna: guard przez information_schema; no-op po pierwszym uruchomieniu.
-- Pattern z Key Decision 2026-05-10: migracje no-op zawsze jako DDL (ALTER TABLE COMMENT),
-- nigdy SELECT 1 (PDO unbuffered + result set -> SQLSTATE 2014).
-- 1) ADD COLUMN user_id
SET @col_user_id := (
SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order_notes'
AND COLUMN_NAME = 'user_id'
);
SET @sql_user_id := IF(@col_user_id = 0,
'ALTER TABLE order_notes ADD COLUMN user_id INT UNSIGNED NULL AFTER note_type',
'ALTER TABLE order_notes COMMENT = ''phase-129 user_id no-op'''
);
PREPARE s1 FROM @sql_user_id; EXECUTE s1; DEALLOCATE PREPARE s1;
-- 2) ADD COLUMN author_name
SET @col_author_name := (
SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order_notes'
AND COLUMN_NAME = 'author_name'
);
SET @sql_author_name := IF(@col_author_name = 0,
'ALTER TABLE order_notes ADD COLUMN author_name VARCHAR(190) NULL AFTER user_id',
'ALTER TABLE order_notes COMMENT = ''phase-129 author_name no-op'''
);
PREPARE s2 FROM @sql_author_name; EXECUTE s2; DEALLOCATE PREPARE s2;
-- 3) ADD FOREIGN KEY user_id -> users(id) ON DELETE SET NULL
SET @fk_exists := (
SELECT COUNT(*) FROM information_schema.TABLE_CONSTRAINTS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order_notes'
AND CONSTRAINT_NAME = 'order_notes_user_fk'
);
SET @sql_fk := IF(@fk_exists = 0,
'ALTER TABLE order_notes ADD CONSTRAINT order_notes_user_fk FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL ON UPDATE CASCADE',
'ALTER TABLE order_notes COMMENT = ''phase-129 fk no-op'''
);
PREPARE s3 FROM @sql_fk; EXECUTE s3; DEALLOCATE PREPARE s3;
-- 4) ADD INDEX (note_type, order_id) — wspiera subquery user_notes_count i listUserNotes
SET @idx_exists := (
SELECT COUNT(*) FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'order_notes'
AND INDEX_NAME = 'idx_order_notes_type_order'
);
SET @sql_idx := IF(@idx_exists = 0,
'ALTER TABLE order_notes ADD INDEX idx_order_notes_type_order (note_type, order_id)',
'ALTER TABLE order_notes COMMENT = ''phase-129 idx no-op'''
);
PREPARE s4 FROM @sql_idx; EXECUTE s4; DEALLOCATE PREPARE s4;