feat(08-10-receipt-module): phases 08-10 complete — receipt issuing from orders

Phase 08 — DB Foundation:
- 3 new tables: receipt_configs, receipts, receipt_number_counters
- company_settings extended with BDO, REGON, KRS, logo fields

Phase 09 — Receipt Config:
- CRUD for receipt configurations (Settings > Accounting)
- ReceiptConfigController + ReceiptConfigRepository

Phase 10 — Receipt Issuing:
- ReceiptRepository with atomic numbering (INSERT ON DUPLICATE KEY UPDATE)
- ReceiptController with snapshot pattern (seller/buyer/items as JSON)
- "Wystaw paragon" button in order view
- Documents tab showing both receipts and marketplace documents
- Activity log entry on receipt creation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-15 19:49:06 +01:00
parent 3bccc7a533
commit ed057fc304
31 changed files with 2539 additions and 39 deletions

View File

@@ -0,0 +1,13 @@
CREATE TABLE IF NOT EXISTS `receipt_configs` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`name` VARCHAR(128) NOT NULL,
`is_active` TINYINT(1) NOT NULL DEFAULT 1,
`number_format` VARCHAR(64) NOT NULL DEFAULT 'PAR/%N/%M/%Y',
`numbering_type` ENUM('monthly','yearly') NOT NULL DEFAULT 'monthly',
`is_named` TINYINT(1) NOT NULL DEFAULT 0,
`sale_date_source` ENUM('order_date','payment_date','issue_date') NOT NULL DEFAULT 'issue_date',
`order_reference` ENUM('none','orderpro','integration') NOT NULL DEFAULT 'none',
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View File

@@ -0,0 +1,23 @@
CREATE TABLE IF NOT EXISTS `receipts` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`order_id` BIGINT UNSIGNED NOT NULL,
`config_id` INT UNSIGNED NOT NULL,
`receipt_number` VARCHAR(64) NOT NULL,
`issue_date` DATE NOT NULL,
`sale_date` DATE NOT NULL,
`seller_data_json` JSON NOT NULL,
`buyer_data_json` JSON DEFAULT NULL,
`items_json` JSON NOT NULL,
`total_net` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
`total_gross` DECIMAL(12,2) NOT NULL DEFAULT 0.00,
`order_reference_value` VARCHAR(128) DEFAULT NULL,
`created_by` INT UNSIGNED DEFAULT NULL,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `receipts_number_unique` (`receipt_number`),
KEY `receipts_order_idx` (`order_id`),
KEY `receipts_config_idx` (`config_id`),
KEY `receipts_issue_date_idx` (`issue_date`),
CONSTRAINT `receipts_order_fk` FOREIGN KEY (`order_id`) REFERENCES `orders` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `receipts_config_fk` FOREIGN KEY (`config_id`) REFERENCES `receipt_configs` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View File

@@ -0,0 +1,10 @@
CREATE TABLE IF NOT EXISTS `receipt_number_counters` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`config_id` INT UNSIGNED NOT NULL,
`year` SMALLINT UNSIGNED NOT NULL,
`month` TINYINT UNSIGNED DEFAULT NULL,
`last_number` INT UNSIGNED NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `receipt_counters_config_period_unique` (`config_id`, `year`, `month`),
CONSTRAINT `receipt_counters_config_fk` FOREIGN KEY (`config_id`) REFERENCES `receipt_configs` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

View File

@@ -0,0 +1,5 @@
ALTER TABLE `company_settings`
ADD COLUMN IF NOT EXISTS `bdo_number` VARCHAR(20) DEFAULT NULL AFTER `bank_owner_name`,
ADD COLUMN IF NOT EXISTS `regon` VARCHAR(14) DEFAULT NULL AFTER `bdo_number`,
ADD COLUMN IF NOT EXISTS `court_register` VARCHAR(128) DEFAULT NULL AFTER `regon`,
ADD COLUMN IF NOT EXISTS `logo_path` VARCHAR(255) DEFAULT NULL AFTER `court_register`;