ReportsModel.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. <?php
  2. namespace Models;
  3. class ReportsModel
  4. {
  5. private \PDO $pdo;
  6. public function __construct()
  7. {
  8. $dbFile = $_ENV['DB_FILE'];
  9. $dbPath = __DIR__ . '/../' . $dbFile;
  10. $this->pdo = new \PDO("sqlite:" . $dbPath);
  11. $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
  12. $this->pdo->exec('PRAGMA journal_mode = WAL;');
  13. $this->pdo->exec('PRAGMA busy_timeout = 5000;');
  14. }
  15. public function getReports(int $companyId, ?int $page = null, ?int $limit = null): array
  16. {
  17. // Total de vendas
  18. $sqlTotalValue = "
  19. SELECT SUM(CAST(product_price AS REAL)) AS total_sales
  20. FROM `order`
  21. NATURAL JOIN order_item
  22. NATURAL JOIN product
  23. NATURAL JOIN status
  24. WHERE company_id = :company_id
  25. AND status_status = 'Finalizada'
  26. ";
  27. $stmtTotal = $this->pdo->prepare($sqlTotalValue);
  28. $stmtTotal->execute(['company_id' => $companyId]);
  29. $totalSales = $stmtTotal->fetchColumn() ?: 0;
  30. // Top 3 itens mais vendidos
  31. $sqlTopItems = "
  32. SELECT product_name, COUNT(*) AS sold_quantity
  33. FROM `order`
  34. NATURAL JOIN order_item
  35. NATURAL JOIN product
  36. NATURAL JOIN status
  37. WHERE company_id = :company_id
  38. AND status_status = 'Finalizada'
  39. GROUP BY product_id
  40. ORDER BY sold_quantity DESC
  41. LIMIT 3
  42. ";
  43. $stmtTopItems = $this->pdo->prepare($sqlTopItems);
  44. $stmtTopItems->execute(['company_id' => $companyId]);
  45. $topItems = $stmtTopItems->fetchAll(\PDO::FETCH_ASSOC);
  46. // Lista de pedidos
  47. $sqlOrders = "
  48. SELECT o.order_id,
  49. o.order_finished_at,
  50. t.table_number,
  51. o.order_name,
  52. o.order_flag
  53. FROM `order` o
  54. NATURAL JOIN status
  55. JOIN `table` t USING(table_id)
  56. WHERE o.company_id = :company_id
  57. AND status_status = 'Finalizada'
  58. ORDER BY o.order_finished_at DESC
  59. ";
  60. $offset = 0;
  61. if ($page !== null && $limit !== null) {
  62. $offset = ($page - 1) * $limit;
  63. $sqlOrders .= " LIMIT :limit OFFSET :offset";
  64. }
  65. $stmtOrders = $this->pdo->prepare($sqlOrders);
  66. $stmtOrders->bindValue(':company_id', $companyId, \PDO::PARAM_INT);
  67. if ($page !== null && $limit !== null) {
  68. $stmtOrders->bindValue(':limit', $limit, \PDO::PARAM_INT);
  69. $stmtOrders->bindValue(':offset', $offset, \PDO::PARAM_INT);
  70. }
  71. $stmtOrders->execute();
  72. $ordersData = $stmtOrders->fetchAll(\PDO::FETCH_ASSOC);
  73. if (empty($ordersData)) {
  74. return [
  75. 'total_sales' => (float) $totalSales,
  76. 'top_items' => $topItems,
  77. 'orders' => []
  78. ];
  79. }
  80. // Pega os IDs dos pedidos encontrados
  81. $orderIds = array_column($ordersData, 'order_id');
  82. $inQuery = implode(',', array_fill(0, count($orderIds), '?'));
  83. // Busca itens dos pedidos
  84. $sqlItems = "
  85. SELECT order_id,
  86. product_name,
  87. product_price
  88. FROM order_item
  89. NATURAL JOIN product
  90. WHERE order_id IN ($inQuery)
  91. ";
  92. $stmtItems = $this->pdo->prepare($sqlItems);
  93. foreach ($orderIds as $k => $id) {
  94. $stmtItems->bindValue($k + 1, $id, \PDO::PARAM_INT);
  95. }
  96. $stmtItems->execute();
  97. $itemsData = $stmtItems->fetchAll(\PDO::FETCH_ASSOC);
  98. // Monta estrutura final de pedidos + itens
  99. $orders = [];
  100. foreach ($ordersData as $order) {
  101. $orders[$order['order_id']] = $order + ['items' => []];
  102. }
  103. foreach ($itemsData as $item) {
  104. $orders[$item['order_id']]['items'][] = [
  105. 'product_name' => $item['product_name'],
  106. 'product_price' => $item['product_price']
  107. ];
  108. }
  109. return [
  110. 'total_sales' => (float) $totalSales,
  111. 'top_items' => $topItems,
  112. 'orders' => array_values($orders),
  113. ];
  114. }
  115. }