Skip to content

Commit 11974f5

Browse files
committed
Adicionando fluxo de pedidos e carrinho com chekout e impressão
1 parent f2316d1 commit 11974f5

File tree

7 files changed

+303
-95
lines changed

7 files changed

+303
-95
lines changed

app/Controllers/CartController.php

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ public function checkout(Request $request, Response $response, array $args): Res
263263
/**
264264
* Processa o pedido e envia para WhatsApp
265265
*/
266-
public function processOrder(Request $request, Response $response, array $args): Response
266+
public function processOrder(Request $request, Response $response, array $args): Response
267267
{
268268
$storeSlug = $args['store'] ?? '';
269269
$store = $this->userModel->getStoreBySlug($storeSlug);
@@ -273,7 +273,6 @@ public function processOrder(Request $request, Response $response, array $args):
273273
}
274274

275275
$cart = $_SESSION['cart_' . $store['id']] ?? [];
276-
// Se o carrinho estiver vazio, redireciona para o checkout (não para o menu)
277276
if (empty($cart)) {
278277
return $response->withHeader('Location', '/' . $storeSlug . '/checkout')->withStatus(302);
279278
}
@@ -284,7 +283,6 @@ public function processOrder(Request $request, Response $response, array $args):
284283
$customerAddress = trim($data['customer_address'] ?? '');
285284
$notes = trim($data['notes'] ?? '');
286285

287-
// Validações
288286
if (empty($customerName) || empty($customerPhone) || empty($customerAddress)) {
289287
$_SESSION['error'] = 'Todos os campos são obrigatórios';
290288
return $response->withHeader('Location', '/' . $storeSlug . '/checkout')->withStatus(302);
@@ -309,67 +307,74 @@ public function processOrder(Request $request, Response $response, array $args):
309307
}
310308

311309
try {
312-
// Salvar pedido na tabela 'pedidos'
313-
$stmt = $this->pdo->prepare("INSERT INTO pedidos (store_id, customer_name, customer_phone, customer_address, notes, cart, total_amount) VALUES (?, ?, ?, ?, ?, ?, ?)");
314-
$stmt->execute([
315-
$store['id'],
316-
$customerName,
317-
$customerPhone,
318-
$customerAddress,
319-
$notes,
320-
json_encode($cart),
321-
$total
310+
// Salvar pedido na tabela orders
311+
$orderId = $this->orderModel->create([
312+
'user_id' => $store['id'],
313+
'customer_name' => $customerName,
314+
'customer_phone' => $customerPhone,
315+
'customer_address' => $customerAddress,
316+
'notes' => $notes,
317+
'total_amount' => $total,
318+
'created_at' => date('Y-m-d H:i:s')
322319
]);
323-
$pedidoId = $this->pdo->lastInsertId();
320+
321+
// Salvar itens do pedido
322+
foreach ($cart as $item) {
323+
$orderItemId = $this->orderItemModel->create([
324+
'order_id' => $orderId,
325+
'product_id' => $item['product_id'],
326+
'quantity' => $item['quantity'],
327+
'unit_price' => $item['price'],
328+
'size' => $item['size'] ?? '',
329+
'notes' => $item['notes'] ?? '',
330+
'created_at' => date('Y-m-d H:i:s')
331+
]);
332+
333+
// Salvar ingredientes/adicionais do item
334+
if (!empty($item['ingredients'])) {
335+
foreach ($item['ingredients'] as $ingredientId => $quantity) {
336+
$ingredient = $this->ingredientModel->getById($ingredientId);
337+
$price = $ingredient ? $ingredient['additional_price'] : 0;
338+
$this->orderItemModel->addIngredient($orderItemId, $ingredientId, $quantity, $price);
339+
}
340+
}
341+
}
324342

325343
// Montar mensagem WhatsApp simples
326-
$whatsappMessage = "Olá, novo pedido recebido!\nCliente: $customerName\nTelefone: $customerPhone\nEndereço: $customerAddress\nTotal: R$ " . number_format($total, 2, ',', '.') . "\nPedido #$pedidoId";
344+
$whatsappMessage = "Olá, novo pedido recebido!\nCliente: $customerName\nTelefone: $customerPhone\nEndereço: $customerAddress\nTotal: R$ " . number_format($total, 2, ',', '.') . "\nPedido #$orderId";
327345
$whatsappUrl = "https://wa.me/{$store['whatsapp']}?text=" . urlencode($whatsappMessage);
328346

329347
// Limpar carrinho
330348
unset($_SESSION['cart_' . $store['id']]);
331349

332-
// Monta os itens do pedido para o template de sucesso
333-
$orderItems = [];
334-
foreach ($cart as $item) {
335-
$product = $this->productModel->getById($item['product_id']);
336-
$ingredients = [];
337-
$itemTotal = $item['price'] * $item['quantity'];
338-
if (!empty($item['ingredients'])) {
339-
foreach ($item['ingredients'] as $ingredientId => $quantity) {
340-
$ingredient = $this->ingredientModel->getById($ingredientId);
341-
if ($ingredient) {
342-
$ingredients[] = [
343-
'name' => $ingredient['name'],
344-
'quantity' => $quantity,
345-
'price' => $ingredient['additional_price']
346-
];
347-
$itemTotal += $ingredient['additional_price'] * $quantity * $item['quantity'];
350+
// Buscar pedido completo para template de sucesso
351+
$order = $this->orderModel->getOrderWithItems($orderId);
352+
353+
// Enriquecer ingredientes/adicionais dos itens do pedido com o campo 'name'
354+
if (!empty($order['items'])) {
355+
foreach ($order['items'] as &$item) {
356+
if (!empty($item['ingredients'])) {
357+
foreach ($item['ingredients'] as &$ingredient) {
358+
if (empty($ingredient['name']) && !empty($ingredient['ingredient_id'])) {
359+
$ingredientData = $this->ingredientModel->getById($ingredient['ingredient_id']);
360+
if ($ingredientData && !empty($ingredientData['name'])) {
361+
$ingredient['name'] = $ingredientData['name'];
362+
} else {
363+
$ingredient['name'] = 'Adicional';
364+
}
365+
}
348366
}
367+
unset($ingredient);
349368
}
350369
}
351-
$orderItems[] = [
352-
'product_name' => $product ? $product['name'] : 'Produto removido',
353-
'unit_price' => $item['price'],
354-
'quantity' => $item['quantity'],
355-
'size' => $item['size'] ?? '',
356-
'ingredients' => $ingredients,
357-
'notes' => $item['notes'] ?? '',
358-
'total' => $itemTotal
359-
];
370+
unset($item);
360371
}
361372

362373
$data = [
363374
'title' => 'Pedido Enviado - ' . $store['store_name'],
364375
'store' => $store,
365376
'store_slug' => $storeSlug,
366-
'order' => [
367-
'id' => $pedidoId,
368-
'customer_name' => $customerName,
369-
'total_amount' => $total,
370-
'created_at' => date('Y-m-d H:i:s'),
371-
'items' => $orderItems
372-
],
377+
'order' => $order,
373378
'whatsapp_url' => $whatsappUrl
374379
];
375380

@@ -380,4 +385,5 @@ public function processOrder(Request $request, Response $response, array $args):
380385
return $response->withHeader('Location', '/' . $storeSlug . '/checkout')->withStatus(302);
381386
}
382387
}
388+
383389
}

app/Controllers/PrintController.php

Lines changed: 66 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,61 +8,83 @@ class PrintController
88
{
99
private \PDO $pdo;
1010
private $userModel;
11+
private $logger;
1112

12-
public function __construct(\PDO $pdo, $userModel)
13+
public function __construct(\PDO $pdo, $userModel, $logger)
1314
{
1415
$this->pdo = $pdo;
1516
$this->userModel = $userModel;
17+
$this->logger = $logger;
1618
}
1719

18-
public function printOrder(Request $request, Response $response, array $args): Response
19-
{
20-
$pedidoId = $args['id'] ?? null;
21-
if (!$pedidoId) {
22-
$response->getBody()->write(json_encode(['error' => 'Pedido não encontrado']));
23-
return $response->withHeader('Content-Type', 'application/json')->withStatus(404);
24-
}
20+
public function printOrder(Request $request, Response $response, array $args): Response
21+
{
22+
23+
$orderId = $args['id'] ?? null;
24+
if (!$orderId) {
25+
$response->getBody()->write(json_encode(['error' => 'Pedido não encontrado']));
26+
$this->logger->error('Erro ao imprimir', ['order_id' => $orderId]);
27+
return $response->withHeader('Content-Type', 'application/json')->withStatus(404);
28+
}
2529

26-
// Busca pedido no banco
27-
$stmt = $this->pdo->prepare("SELECT * FROM pedidos WHERE id = ?");
28-
$stmt->execute([$pedidoId]);
29-
$pedido = $stmt->fetch(\PDO::FETCH_ASSOC);
30+
// Busca pedido na tabela orders
31+
$stmt = $this->pdo->prepare("SELECT * FROM orders WHERE id = ?");
32+
$stmt->execute([$orderId]);
33+
$order = $stmt->fetch(\PDO::FETCH_ASSOC);
3034

31-
if (!$pedido) {
32-
$response->getBody()->write(json_encode(['error' => 'Pedido não encontrado']));
33-
return $response->withHeader('Content-Type', 'application/json')->withStatus(404);
34-
}
35+
if (!$order) {
36+
$response->getBody()->write(json_encode(['error' => 'Pedido não encontrado']));
37+
$this->logger->error('Erro ao imprimir *Pedido não encontrado*', ['order_id' => $orderId]);
38+
return $response->withHeader('Content-Type', 'application/json')->withStatus(404);
39+
}
40+
41+
$store = $this->userModel->getById($order['user_id']);
3542

36-
$store = $this->userModel->getStoreById($pedido['store_id']);
37-
$cart = json_decode($pedido['cart'], true);
38-
39-
// Monta array para impressão
40-
$printData = [
41-
["type"=>0,"content"=>strtoupper($store['store_name']),"bold"=>1,"align"=>1,"format"=>2],
42-
["type"=>0,"content"=>"PEDIDO #".$pedido['id'],"bold"=>1,"align"=>1],
43-
["type"=>0,"content"=>"Cliente: ".$pedido['customer_name'],"bold"=>0,"align"=>0],
44-
["type"=>0,"content"=>"Endereço: ".$pedido['customer_address'],"bold"=>0,"align"=>0],
45-
["type"=>0,"content"=>"------------------------------","bold"=>0,"align"=>1]
46-
];
47-
48-
foreach ($cart as $item) {
49-
$linha = $item['quantity']."x ".$item['product_name']." - R$ ".number_format($item['unit_price'],2,',','.');
50-
$printData[] = ["type"=>0,"content"=>$linha,"bold"=>0,"align"=>0];
51-
if (!empty($item['ingredients'])) {
52-
foreach ($item['ingredients'] as $ing) {
53-
$printData[] = ["type"=>0,"content"=>" + ".$ing['name']." (".$ing['quantity']."x)","bold"=>0,"align"=>0];
54-
}
43+
// Busca itens do pedido
44+
$stmt = $this->pdo->prepare("SELECT * FROM order_items WHERE order_id = ?");
45+
$stmt->execute([$orderId]);
46+
$items = $stmt->fetchAll(\PDO::FETCH_ASSOC);
47+
48+
// Monta array para impressão
49+
$printData = [
50+
["type"=>0,"content"=>strtoupper($store['store_name']),"bold"=>1,"align"=>1,"format"=>2],
51+
["type"=>0,"content"=>"PEDIDO #".$order['id'],"bold"=>1,"align"=>1],
52+
["type"=>0,"content"=>"Cliente: ".$order['customer_name'],"bold"=>0,"align"=>0],
53+
["type"=>0,"content"=>"Endereço: ".$order['customer_address'],"bold"=>0,"align"=>0],
54+
["type"=>0,"content"=>"------------------------------","bold"=>0,"align"=>1]
55+
];
56+
57+
foreach ($items as $item) {
58+
// Busca nome do produto
59+
$stmtProd = $this->pdo->prepare("SELECT name FROM products WHERE id = ?");
60+
$stmtProd->execute([$item['product_id']]);
61+
$product = $stmtProd->fetch(\PDO::FETCH_ASSOC);
62+
63+
$linha = $item['quantity']."x ".$product['name']." - R$ ".number_format($item['unit_price'],2,',','.');
64+
$printData[] = ["type"=>0,"content"=>$linha,"bold"=>0,"align"=>0];
65+
66+
// Busca ingredientes/adicionais do item
67+
$stmtIng = $this->pdo->prepare("SELECT oi.*, i.name FROM order_item_ingredients oi JOIN ingredients i ON oi.ingredient_id = i.id WHERE oi.order_item_id = ?");
68+
$stmtIng->execute([$item['id']]);
69+
$ingredients = $stmtIng->fetchAll(\PDO::FETCH_ASSOC);
70+
71+
if (!empty($ingredients)) {
72+
foreach ($ingredients as $ing) {
73+
$printData[] = ["type"=>0,"content"=>" + ".$ing['name']." (".$ing['quantity']."x)","bold"=>0,"align"=>0];
5574
}
5675
}
76+
}
5777

58-
$printData[] = ["type"=>0,"content"=>"------------------------------","bold"=>0,"align"=>1];
59-
$printData[] = ["type"=>0,"content"=>"TOTAL: R$ ".number_format($pedido['total_amount'],2,',','.'),"bold"=>1,"align"=>2];
60-
$printData[] = ["type"=>0,"content"=>" ","bold"=>0,"align"=>0];
61-
// Adiciona QR Code PIX no final
62-
$pixQrCode = '00020126460014br.gov.bcb.pix0124fortalecai2025@gmail.com5204000053039865802BR5925Alefe Augusto Lima Da Sil6014RIO DE JANEIRO622805242bf17e522526e2838a7b30ac6304993A';
63-
$printData[] = ["type"=>3,"value"=>$pixQrCode,"size"=>30,"align"=>1];
78+
$printData[] = ["type"=>0,"content"=>"------------------------------","bold"=>0,"align"=>1];
79+
$printData[] = ["type"=>0,"content"=>"TOTAL: R$ ".number_format($order['total_amount'],2,',','.'),"bold"=>1,"align"=>2];
80+
$printData[] = ["type"=>0,"content"=>" ","bold"=>0,"align"=>0];
81+
// Adiciona QR Code PIX no final
82+
$pixQrCode = '00020126460014br.gov.bcb.pix0124fortalecai2025@gmail.com5204000053039865802BR5925Alefe Augusto Lima Da Sil6014RIO DE JANEIRO622805242bf17e522526e2838a7b30ac6304993A';
83+
$printData[] = ["type"=>3,"value"=>$pixQrCode,"size"=>30,"align"=>1];
6484

65-
$response->getBody()->write(json_encode($printData, JSON_UNESCAPED_UNICODE));
66-
return $response->withHeader('Content-Type', 'application/json')->withStatus(200);
67-
}
85+
$response->getBody()->write(json_encode($printData, JSON_UNESCAPED_UNICODE));
86+
87+
$this->logger->info('Pedido enviado para impressão', ['order_id' => $orderId]);
88+
return $response->withHeader('Content-Type', 'application/json')->withStatus(200);
89+
}
6890
}

app/Services/LoggerService.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
namespace App\Services;
3+
4+
use Monolog\Logger;
5+
use Monolog\Handler\StreamHandler;
6+
7+
class LoggerService
8+
{
9+
private Logger $logger;
10+
11+
public function __construct()
12+
{
13+
$this->logger = new Logger('menu.linksbio.me');
14+
$this->logger->pushHandler(new StreamHandler(__DIR__ . '/../../storage/logs/app.log', Logger::INFO));
15+
}
16+
17+
public function getLogger(): Logger
18+
{
19+
return $this->logger;
20+
}
21+
}

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"slim/slim": "^4.12",
77
"slim/psr7": "^1.6",
88
"php-di/php-di": "^7.0",
9-
"doctrine/dbal": "^3.7"
9+
"doctrine/dbal": "^3.7",
10+
"monolog/monolog": "^3.9"
1011
},
1112
"require-dev": {
1213
"phpunit/phpunit": "^9.0"

0 commit comments

Comments
 (0)