This commit is contained in:
2026-04-08 23:22:48 +02:00
parent c5b2885b44
commit 633da52880
16 changed files with 765 additions and 95 deletions

125
bin/reissue_receipt.php Normal file
View File

@@ -0,0 +1,125 @@
<?php
declare(strict_types=1);
use App\Modules\Accounting\ReceiptRepository;
use App\Modules\Accounting\ReceiptService;
use App\Modules\Orders\OrdersRepository;
use App\Modules\Settings\CompanySettingsRepository;
use App\Modules\Settings\ReceiptConfigRepository;
$basePath = dirname(__DIR__);
// Autoloader
$vendorAutoload = $basePath . '/vendor/autoload.php';
if (is_file($vendorAutoload)) {
require $vendorAutoload;
} else {
spl_autoload_register(static function (string $class) use ($basePath): void {
$prefix = 'App\\';
if (!str_starts_with($class, $prefix)) {
return;
}
$relative = substr($class, strlen($prefix));
$file = $basePath . '/src/' . str_replace('\\', '/', $relative) . '.php';
if (is_file($file)) {
require $file;
}
});
}
// Parse .env manually
$env = [];
$envFile = $basePath . '/.env';
if (is_file($envFile)) {
foreach (file($envFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
$line = trim($line);
if ($line === '' || str_starts_with($line, '#')) continue;
$pos = strpos($line, '=');
if ($pos === false) continue;
$key = trim(substr($line, 0, $pos));
$value = trim(trim(substr($line, $pos + 1)), "\"'");
$env[$key] = $value;
}
}
// Use DB_HOST_REMOTE if available, fallback to DB_HOST
$host = ($env['DB_HOST_REMOTE'] ?? '') !== '' ? $env['DB_HOST_REMOTE'] : ($env['DB_HOST'] ?? '127.0.0.1');
$port = (int) ($env['DB_PORT'] ?? 3306);
$database = $env['DB_DATABASE'] ?? 'orderpro';
$username = $env['DB_USERNAME'] ?? 'root';
$password = $env['DB_PASSWORD'] ?? '';
echo "Connecting to: {$host}:{$port}/{$database}\n";
$dsn = sprintf('mysql:host=%s;port=%d;dbname=%s;charset=utf8mb4', $host, $port, $database);
$pdo = new PDO($dsn, $username, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
]);
echo "Connected OK\n";
$orderId = (int) ($argv[1] ?? 0);
if ($orderId <= 0) {
echo "Usage: php bin/reissue_receipt.php <order_id> [config_id]\n";
exit(1);
}
$configId = (int) ($argv[2] ?? 0);
// Find active config if not specified
if ($configId <= 0) {
$stmt = $pdo->prepare('SELECT id FROM receipt_configs WHERE is_active = 1 LIMIT 1');
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) {
echo "ERROR: No active receipt config found\n";
exit(1);
}
$configId = (int) $row['id'];
echo "Using config_id: {$configId}\n";
}
// Delete existing receipts for this order
$existing = $pdo->prepare('SELECT id, receipt_number FROM receipts WHERE order_id = :order_id');
$existing->execute(['order_id' => $orderId]);
$receipts = $existing->fetchAll(PDO::FETCH_ASSOC);
if ($receipts) {
foreach ($receipts as $r) {
echo "Deleting receipt #{$r['id']} ({$r['receipt_number']})\n";
}
$pdo->prepare('DELETE FROM receipts WHERE order_id = :order_id')->execute(['order_id' => $orderId]);
} else {
echo "No existing receipts for order #{$orderId}\n";
}
// Check delivery_price
$stmt = $pdo->prepare('SELECT delivery_price, total_with_tax FROM orders WHERE id = :id');
$stmt->execute(['id' => $orderId]);
$order = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$order) {
echo "ERROR: Order #{$orderId} not found\n";
exit(1);
}
echo "Order #{$orderId}: total_with_tax={$order['total_with_tax']}, delivery_price={$order['delivery_price']}\n";
// Issue new receipt
$receiptRepo = new ReceiptRepository($pdo);
$configRepo = new ReceiptConfigRepository($pdo);
$companyRepo = new CompanySettingsRepository($pdo);
$ordersRepo = new OrdersRepository($pdo);
$service = new ReceiptService($receiptRepo, $configRepo, $companyRepo, $ordersRepo);
try {
$result = $service->issue([
'order_id' => $orderId,
'config_id' => $configId,
'created_by' => null,
]);
echo "SUCCESS: Receipt issued: {$result['receipt_number']}, total_gross: {$result['total_gross']}\n";
} catch (Throwable $e) {
echo "ERROR: {$e->getMessage()}\n";
exit(1);
}