Browse Source

Order Routes (CREATE, DELETE, UPDATE and GET)

EduLascala 5 months ago
parent
commit
ef3223f88b

+ 10 - 1
bin/setup

@@ -12,12 +12,21 @@ INSERT OR IGNORE INTO company (company_name, company_flag) VALUES ('Ferlin', 'a'
 
 INSERT OR IGNORE INTO role (role_name, role_permission, role_flag, company_id) VALUES ('admin', 'all', 'a', 1);
 
+INSERT OR IGNORE INTO role (role_name, role_permission, role_flag, company_id) VALUES ('waiter', 'waiter', 'a', 1);
+
+INSERT OR IGNORE INTO role (role_name, role_permission, role_flag, company_id) VALUES ('kitchen', 'kitchen', 'a', 1);
+
+INSERT OR IGNORE INTO role (role_name, role_permission, role_flag, company_id) VALUES ('cashier', 'cashier', 'a', 1);
+
 INSERT OR IGNORE INTO status (status_status) VALUES ('Livre');
 
 INSERT OR IGNORE INTO status (status_status) VALUES ('Ocupado');
 
-INSERT OR IGNORE INTO user (user_name, user_email, user_password, user_flag, company_id, role_id) VALUES ('admin', 'admin@example.com', 'admin', 'a', 1, 1);
+INSERT OR IGNORE INTO status (status_status) VALUES ('Aberta');
+
+INSERT OR IGNORE INTO status (status_status) VALUES ('Finalizada');
 
+INSERT OR IGNORE INTO status (status_status) VALUES ('Cancelada');
 
 EOF
 

+ 66 - 0
controllers/OrderCreateController.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Models\OrderModel;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Validator as v;
+use Respect\Validation\Exceptions\ValidationException;
+
+class OrderCreateController
+{
+    private OrderModel $model;
+
+    public function __construct()
+    {
+        $this->model = new OrderModel();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            // Validação dos campos essenciais, esperando 'status_status'
+            v::key('table_id', v::intType()->positive())
+                ->key('user_id', v::intType()->positive())
+                ->key('company_id', v::intType()->positive())
+                ->key('order_name', v::stringType()->notEmpty()->alnum(' '))
+                ->key('order_phone', v::stringType()->notEmpty()->length(8, 20))
+                ->key('status_status', v::stringType()->notEmpty()->in(['Aberta', 'Finalizada', 'Cancelada']))
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail("Validation failed: " . $e->getFullMessage(), [], "E_VALIDATE")->withStatus(400);
+        }
+
+        $tableId = (int) $body['table_id'];
+        $userId = (int) $body['user_id'];
+        $companyId = (int) $body['company_id'];
+        $orderName = $body['order_name'];
+        $orderPhone = $body['order_phone'];
+        $statusStatus = $body['status_status'];
+
+        // Converte o status_status para status_id usando o Model
+        $statusId = $this->model->getStatusIdByName($statusStatus);
+
+        if ($statusId === null) {
+            // Isso pode acontecer se o status_status enviado não for mapeado no banco
+            return ResponseLib::sendFail("Invalid status_status provided: '{$statusStatus}'", [], "E_VALIDATE")->withStatus(400);
+        }
+
+        // AQUI ESTAVA O ERRO: Passando $statusStatus (string) em vez de $statusId (int)
+        $created = $this->model->createOrder(
+            $tableId,
+            $userId,
+            $companyId,
+            $orderName,
+            $orderPhone,
+            $statusId 
+        );
+
+        return $created
+            ? ResponseLib::sendOk(['created' => true, 'order_id' => $created])
+            : ResponseLib::sendFail("Failed to create order", [], "E_DATABASE")->withStatus(500);
+    }
+}

+ 42 - 0
controllers/OrderDeleteController.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Models\OrderModel;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Validator as v;
+use Respect\Validation\Exceptions\ValidationException;
+
+class OrderDeleteController
+{
+    private OrderModel $model;
+
+    public function __construct()
+    {
+        $this->model = new OrderModel();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            // Validação dos campos obrigatórios: order_id e company_id
+            v::key('order_id', v::intType()->positive())
+                ->key('company_id', v::intType()->positive())
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail("Validation failed: " . $e->getFullMessage(), [], "E_VALIDATE")->withStatus(400);
+        }
+
+        $orderId = (int) $body['order_id'];
+        $companyId = (int) $body['company_id'];
+
+        $deleted = $this->model->deleteOrder($orderId, $companyId);
+
+        return $deleted
+            ? ResponseLib::sendOk(['deleted' => true])
+            : ResponseLib::sendFail("Failed to delete order or order not found", [], "E_DATABASE")->withStatus(404);
+    }
+}

+ 79 - 0
controllers/OrderGetController.php

@@ -0,0 +1,79 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Models\OrderModel;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Validator as v;
+use Respect\Validation\Exceptions\ValidationException;
+
+class OrderGetController
+{
+    private OrderModel $model;
+
+    public function __construct()
+    {
+        $this->model = new OrderModel();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            // company_id é obrigatório para qualquer consulta de pedidos
+            v::key('company_id', v::intType()->positive())
+                // order_id, status_status e table_id são opcionais, mas mutuamente exclusivos em alguns cenários
+                ->key('order_id', v::optional(v::intType()->positive()), false)
+                ->key('status_status', v::optional(v::stringType()->notEmpty()->in(['Aberta', 'Finalizada', 'Cancelada'])), false)
+                ->key('table_id', v::optional(v::intType()->positive()), false) // Adicionado table_id como opcional
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail("Validation failed: " . $e->getFullMessage(), [], "E_VALIDATE")->withStatus(400);
+        }
+
+        $companyId = (int) $body['company_id'];
+        $orderId = $body['order_id'] ?? null;
+        $statusStatus = $body['status_status'] ?? null;
+        $tableId = $body['table_id'] ?? null; // Pega o table_id do payload
+
+        $statusId = null;
+
+        // Se status_status for fornecido, converte para status_id
+        if ($statusStatus !== null) {
+            $statusId = $this->model->getStatusIdByName($statusStatus);
+            if ($statusId === null) {
+                return ResponseLib::sendFail("Invalid status_status provided: '{$statusStatus}'", [], "E_VALIDATE")->withStatus(400);
+            }
+        }
+
+        $orders = [];
+        if ($orderId !== null) {
+            // Obter um pedido específico por order_id
+            $order = $this->model->getOrderById($orderId, $companyId);
+            if ($order) {
+                $orders[] = $order;
+            }
+        } elseif ($tableId !== null) { // NOVO: Lógica para obter pedidos por table_id
+            $orders = $this->model->getOrdersByTable($tableId, $companyId, $statusId);
+        } else {
+            // Obter todos os pedidos da empresa, ou filtrados apenas por status
+            $orders = $this->model->getOrders($companyId, $statusId);
+        }
+        
+        // Formata o retorno para incluir o status_status em vez do status_id
+        foreach ($orders as &$order) {
+            if (isset($order['status_id'])) {
+                $order['status_status'] = $this->model->getStatusNameById($order['status_id']);
+                unset($order['status_id']); // Remove o ID se não quiser expô-lo
+            }
+        }
+
+        if (!empty($orders)) {
+            return ResponseLib::sendOk($orders);
+        }
+
+        return ResponseLib::sendFail("No orders found for the given criteria", [], "E_DATABASE")->withStatus(404);
+    }
+}

+ 53 - 0
controllers/OrderUpdateController.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace Controllers;
+
+use Libs\ResponseLib;
+use Models\OrderModel;
+use Psr\Http\Message\ServerRequestInterface;
+use Respect\Validation\Validator as v;
+use Respect\Validation\Exceptions\ValidationException;
+
+class OrderUpdateController
+{
+    private OrderModel $model;
+
+    public function __construct()
+    {
+        $this->model = new OrderModel();
+    }
+
+    public function __invoke(ServerRequestInterface $request)
+    {
+        $body = json_decode((string)$request->getBody(), true) ?? [];
+
+        try {
+            // company_id e order_id são obrigatórios para identificar o pedido
+            // status_status é obrigatório para a atualização
+            v::key('company_id', v::intType()->positive())
+                ->key('order_id', v::intType()->positive())
+                ->key('status_status', v::stringType()->notEmpty()->in(['Aberta', 'Finalizada', 'Cancelada']), true) // Adicione aqui todos os status possíveis para atualização
+                ->assert($body);
+        } catch (ValidationException $e) {
+            return ResponseLib::sendFail("Validation failed: " . $e->getFullMessage(), [], "E_VALIDATE")->withStatus(400);
+        }
+
+        $companyId = (int) $body['company_id'];
+        $orderId = (int) $body['order_id'];
+        $statusStatus = $body['status_status'];
+
+        // Converte o status_status para status_id usando o Model
+        $statusId = $this->model->getStatusIdByName($statusStatus);
+
+        if ($statusId === null) {
+            // Isso pode acontecer se o status_status enviado não for mapeado no banco
+            return ResponseLib::sendFail("Invalid status_status provided: '{$statusStatus}'", [], "E_VALIDATE")->withStatus(400);
+        }
+
+        $updated = $this->model->updateOrderStatus($orderId, $companyId, $statusId);
+
+        return $updated
+            ? ResponseLib::sendOk(['updated' => true])
+            : ResponseLib::sendFail("Failed to update order status or order not found", [], "E_DATABASE")->withStatus(404);
+    }
+}

+ 179 - 0
models/OrderModel.php

@@ -0,0 +1,179 @@
+<?php
+
+namespace Models;
+
+class OrderModel
+{
+    private \PDO $pdo;
+
+    public function __construct()
+    {
+        $dbFile = $_ENV['DB_FILE'];
+        $dbPath = __DIR__ . '/../' . $dbFile;
+        $this->pdo = new \PDO("sqlite:" . $dbPath);
+        $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
+        $this->pdo->exec('PRAGMA journal_mode = WAL;');
+        $this->pdo->exec('PRAGMA busy_timeout = 5000;');
+    }
+
+    public function createOrder(
+        int $tableId,
+        int $userId,
+        int $companyId,
+        string $orderName,
+        string $orderPhone,
+        int $statusId
+    ): int|false {
+        if (!$this->tableExists($tableId, $companyId) || !$this->userExists($userId, $companyId) || !$this->companyExists($companyId) || !$this->statusExists($statusId)) {
+            error_log("Tentativa de criar pedido com IDs inválidos: table_id={$tableId}, user_id={$userId}, company_id={$companyId}, status_id={$statusId}");
+            return false;
+        }
+
+        $stmt = $this->pdo->prepare("
+            INSERT INTO `order` (table_id, user_id, company_id, order_name, order_phone, status_id, order_created_at, order_flag)
+            VALUES (:table_id, :user_id, :company_id, :order_name, :order_phone, :status_id, :order_created_at, 'a')
+        ");
+
+        $currentTime = date('Y-m-d H:i:s');
+
+        try {
+            $executed = $stmt->execute([
+                'table_id' => $tableId,
+                'user_id' => $userId,
+                'company_id' => $companyId,
+                'order_name' => $orderName,
+                'order_phone' => $orderPhone,
+                'status_id' => $statusId,
+                'order_created_at' => $currentTime
+            ]);
+            return $executed ? (int)$this->pdo->lastInsertId() : false;
+        } catch (\PDOException $e) {
+            error_log("PDO Exception during order creation: " . $e->getMessage());
+            return false;
+        }
+    }
+
+    public function updateOrderStatus(int $orderId, int $companyId, int $statusId): bool
+    {
+
+        $stmt = $this->pdo->prepare("
+            UPDATE `order`
+            SET status_id = :status_id
+            WHERE order_id = :order_id AND company_id = :company_id AND order_flag = 'a'
+        ");
+
+        $executed = $stmt->execute([
+            'status_id' => $statusId,
+            'order_id' => $orderId,
+            'company_id' => $companyId
+        ]);
+
+        return $executed && $stmt->rowCount() > 0;
+    }
+
+    public function deleteOrder(int $orderId, int $companyId): bool
+    {
+        $stmt = $this->pdo->prepare("
+            UPDATE `order`
+            SET order_flag = 'd'
+            WHERE order_id = :order_id AND company_id = :company_id AND order_flag = 'a'
+        ");
+
+        $executed = $stmt->execute([
+            'order_id' => $orderId,
+            'company_id' => $companyId
+        ]);
+
+        return $executed && $stmt->rowCount() > 0;
+    }
+
+    public function getOrders(int $companyId, ?int $statusId = null): array
+    {
+        $sql = "SELECT * FROM `order` WHERE company_id = :company_id AND order_flag = 'a'";
+        $params = ['company_id' => $companyId];
+
+        if ($statusId !== null) {
+            $sql .= " AND status_id = :status_id";
+            $params['status_id'] = $statusId;
+        }
+
+        $stmt = $this->pdo->prepare($sql);
+        $stmt->execute($params);
+        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
+    }
+
+    public function getOrdersByTable(int $tableId, int $companyId, ?int $statusId = null): array
+    {
+        if (!$this->tableExists($tableId, $companyId)) {
+            error_log("Tentativa de obter pedidos de mesa inválida: table_id={$tableId}, company_id={$companyId}");
+            return [];
+        }
+
+        $sql = "SELECT * FROM `order` WHERE table_id = :table_id AND company_id = :company_id AND order_flag = 'a'";
+        $params = [
+            'table_id' => $tableId,
+            'company_id' => $companyId
+        ];
+
+        if ($statusId !== null) {
+            $sql .= " AND status_id = :status_id";
+            $params['status_id'] = $statusId;
+        }
+
+        $stmt = $this->pdo->prepare($sql);
+        $stmt->execute($params);
+        return $stmt->fetchAll(\PDO::FETCH_ASSOC);
+    }
+
+    public function getOrderById(int $orderId, int $companyId): ?array
+    {
+        $stmt = $this->pdo->prepare("SELECT * FROM `order` WHERE order_id = :order_id AND company_id = :company_id AND order_flag = 'a'");
+        $stmt->execute(['order_id' => $orderId, 'company_id' => $companyId]);
+        $result = $stmt->fetch(\PDO::FETCH_ASSOC);
+        return $result ?: null;
+    }
+
+    public function getStatusNameById(int $statusId): ?string
+    {
+        $stmt = $this->pdo->prepare("SELECT status_status FROM status WHERE status_id = :status_id");
+        $stmt->execute(['status_id' => $statusId]);
+        $result = $stmt->fetchColumn();
+        return $result ?: null;
+    }
+
+    public function getStatusIdByName(string $statusName): ?int
+    {
+        $stmt = $this->pdo->prepare("SELECT status_id FROM status WHERE status_status = :status_name");
+        $stmt->execute(['status_name' => $statusName]);
+        $result = $stmt->fetch(\PDO::FETCH_ASSOC);
+        return $result ? (int)$result['status_id'] : null;
+    }
+
+    private function companyExists(int $companyId): bool
+    {
+        $stmt = $this->pdo->prepare("SELECT 1 FROM company WHERE company_id = :id AND company_flag = 'a'");
+        $stmt->execute(['id' => $companyId]);
+        return (bool) $stmt->fetch();
+    }
+
+    private function tableExists(int $tableId, int $companyId): bool
+    {
+        $stmt = $this->pdo->prepare("SELECT 1 FROM `table` WHERE table_id = :table_id AND company_id = :company_id AND table_flag = 'a'");
+        $stmt->execute(['table_id' => $tableId, 'company_id' => $companyId]);
+        return (bool) $stmt->fetch();
+    }
+
+    private function userExists(int $userId, int $companyId): bool
+    {
+        $stmt = $this->pdo->prepare("SELECT 1 FROM user WHERE user_id = :user_id AND company_id = :company_id AND user_flag = 'a'");
+        $stmt->execute(['user_id' => $userId, 'company_id' => $companyId]);
+        return (bool) $stmt->fetch();
+    }
+
+    private function statusExists(int $statusId): bool
+    {
+        $stmt = $this->pdo->prepare("SELECT 1 FROM status WHERE status_id = :id");
+        $stmt->execute(['id' => $statusId]);
+        return (bool) $stmt->fetch();
+    }
+}

+ 15 - 0
public/index.php

@@ -20,6 +20,9 @@ error_reporting(E_ALL);
 ini_set('display_errors', 1); // Para depuração
 ini_set('display_startup_errors', 1);
 
+//Definindo o fuso horário para o Brasil
+date_default_timezone_set('America/Sao_Paulo');
+
 use FrameworkX\App;
 use Middlewares\HmacAuthMiddleware;
 use Middlewares\JWTAuthMiddleware;
@@ -66,4 +69,16 @@ $app->post('/table/create', $cors, $authJwt, \Controllers\TableCreateController:
 $app->post('/table/delete', $cors, $authJwt, \Controllers\TableDeleteController::class);
 $app->post('/table/update', $cors, $authJwt, \Controllers\TableUpdateController::class);
 
+// Order
+$app->post('/order/create', $cors, $authJwt, \Controllers\OrderCreateController::class);
+$app->post('/order/delete', $cors, $authJwt, \Controllers\OrderDeleteController::class);
+$app->post('/order/get', $cors, $authJwt, \Controllers\OrderGetController::class);
+$app->post('/order/update', $cors, $authJwt, \Controllers\OrderUpdateController::class);
+
+// Order Item
+$app->post('/order_item/create', $cors, $authJwt, \Controllers\OrderItemCreateController::class);
+$app->post('/order_item/delete', $cors, $authJwt, \Controllers\OrderItemDeleteController::class);
+$app->post('/order_item/get', $cors, $authJwt, \Controllers\OrderItemGetController::class);
+
+
 $app->run();