input('id', 0)); $details = $this->orders->findDetails($orderId); if ($details === null) { return Response::html('Not found', 404); } $configs = array_filter($this->receiptConfigs->listAll(), static fn(array $c): bool => (int) ($c['is_active'] ?? 0) === 1); if ($configs === []) { Flash::set('order.error', $this->translator->get('receipts.create.no_configs')); return Response::redirect('/orders/' . $orderId); } $existingReceipts = $this->receipts->findByOrderId($orderId); $order = is_array($details['order'] ?? null) ? $details['order'] : []; $items = is_array($details['items'] ?? null) ? $details['items'] : []; $deliveryPrice = (float) ($order['delivery_price'] ?? 0); $totalGross = $this->receiptService->calculateTotalGross($items, $deliveryPrice); $html = $this->template->render('orders/receipt-create', [ 'title' => $this->translator->get('receipts.create.title'), 'activeMenu' => 'orders', 'activeOrders' => 'list', 'user' => $this->auth->user(), 'csrfToken' => Csrf::token(), 'orderId' => $orderId, 'order' => $order, 'items' => $items, 'configs' => array_values($configs), 'seller' => $this->companySettings->getSettings(), 'totalGross' => $totalGross, 'deliveryPrice' => $deliveryPrice, 'existingReceipts' => $existingReceipts, ], 'layouts/app'); return Response::html($html); } public function store(Request $request): Response { $orderId = max(0, (int) $request->input('id', 0)); if (!Csrf::validate((string) $request->input('_token', ''))) { Flash::set('order.error', 'Nieprawidlowy token CSRF'); return Response::redirect('/orders/' . $orderId); } $configId = (int) $request->input('config_id', '0'); if ($configId <= 0) { Flash::set('order.error', $this->translator->get('receipts.create.no_config_selected')); return Response::redirect('/orders/' . $orderId . '/receipt/create'); } $user = $this->auth->user(); try { $result = $this->receiptService->issue([ 'order_id' => $orderId, 'config_id' => $configId, 'issue_date_override' => (string) $request->input('issue_date', ''), 'created_by' => is_array($user) ? ($user['id'] ?? null) : null, ]); $userName = is_array($user) ? trim((string) ($user['name'] ?? $user['email'] ?? '')) : ''; $this->orders->recordActivity( $orderId, 'receipt_issued', 'Wystawiono paragon: ' . $result['receipt_number'], ['receipt_number' => $result['receipt_number'], 'config_id' => $configId, 'total_gross' => $result['total_gross']], 'user', $userName !== '' ? $userName : null ); Flash::set('order.success', 'Paragon wystawiony: ' . $result['receipt_number']); try { $this->automation->trigger('receipt.created', $orderId); } catch (Throwable) { } } catch (ReceiptIssueException $e) { Flash::set('order.error', $e->getMessage()); } catch (Throwable) { Flash::set('order.error', 'Blad wystawiania paragonu'); } return Response::redirect('/orders/' . $orderId); } public function show(Request $request): Response { $orderId = max(0, (int) $request->input('id', 0)); $receiptId = max(0, (int) $request->input('receiptId', 0)); $receipt = $this->receipts->findById($receiptId); if ($receipt === null || (int) ($receipt['order_id'] ?? 0) !== $orderId) { return Response::html('Not found', 404); } $data = $this->buildReceiptViewData($receipt, $orderId); $html = $this->template->render('receipts/show', $data, 'layouts/app'); return Response::html($html); } public function printView(Request $request): Response { $orderId = max(0, (int) $request->input('id', 0)); $receiptId = max(0, (int) $request->input('receiptId', 0)); $receipt = $this->receipts->findById($receiptId); if ($receipt === null || (int) ($receipt['order_id'] ?? 0) !== $orderId) { return Response::html('Not found', 404); } $data = $this->buildReceiptViewData($receipt, $orderId); $html = $this->template->render('receipts/print', $data); return Response::html($html); } public function pdf(Request $request): Response { $orderId = max(0, (int) $request->input('id', 0)); $receiptId = max(0, (int) $request->input('receiptId', 0)); $receipt = $this->receipts->findById($receiptId); if ($receipt === null || (int) ($receipt['order_id'] ?? 0) !== $orderId) { return Response::html('Not found', 404); } $data = $this->buildReceiptViewData($receipt, $orderId); $html = $this->template->render('receipts/print', $data); $dompdf = new \Dompdf\Dompdf(); $dompdf->loadHtml($html); $dompdf->setPaper('A4'); $dompdf->render(); $filename = str_replace(['/', '\\'], '_', (string) ($receipt['receipt_number'] ?? 'receipt')) . '.pdf'; return new Response($dompdf->output() ?: '', 200, [ 'Content-Type' => 'application/pdf', 'Content-Disposition' => 'attachment; filename="' . $filename . '"', ]); } /** * @param array $receipt * @return array */ private function buildReceiptViewData(array $receipt, int $orderId): array { $seller = json_decode((string) ($receipt['seller_data_json'] ?? '{}'), true); $buyer = ($receipt['buyer_data_json'] ?? null) !== null ? json_decode((string) $receipt['buyer_data_json'], true) : null; $items = json_decode((string) ($receipt['items_json'] ?? '[]'), true); $configName = ''; $config = $this->receiptConfigs->findById((int) ($receipt['config_id'] ?? 0)); if ($config !== null) { $configName = (string) ($config['name'] ?? ''); } return [ 'title' => $this->translator->get('receipts.show.title') . ' ' . ($receipt['receipt_number'] ?? ''), 'activeMenu' => 'orders', 'activeOrders' => 'list', 'user' => $this->auth->user(), 'orderId' => $orderId, 'receipt' => $receipt, 'seller' => is_array($seller) ? $seller : [], 'buyer' => is_array($buyer) ? $buyer : null, 'items' => is_array($items) ? $items : [], 'configName' => $configName, ]; } }