ReportsModel.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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 = 1, int $limit = 10): array
  16. {
  17. $offset = ($page - 1) * $limit;
  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. $sqlTopItems = "
  31. SELECT product_name, COUNT(*) AS sold_quantity
  32. FROM `order`
  33. NATURAL JOIN order_item
  34. NATURAL JOIN product
  35. NATURAL JOIN status
  36. WHERE company_id = :company_id
  37. AND status_status = 'Finalizada'
  38. GROUP BY product_id
  39. ORDER BY sold_quantity DESC
  40. LIMIT 3
  41. ";
  42. $stmtTopItems = $this->pdo->prepare($sqlTopItems);
  43. $stmtTopItems->execute(['company_id' => $companyId]);
  44. $topItems = $stmtTopItems->fetchAll(\PDO::FETCH_ASSOC);
  45. $sqlOrders = "
  46. SELECT order_id,
  47. order_finished_at,
  48. table_id,
  49. order_name,
  50. order_flag
  51. FROM `order`
  52. NATURAL JOIN status
  53. WHERE company_id = :company_id
  54. AND status_status = 'Finalizada'
  55. ORDER BY order_finished_at DESC
  56. LIMIT :limit OFFSET :offset;
  57. ";
  58. $stmtOrders = $this->pdo->prepare($sqlOrders);
  59. $stmtOrders->bindValue(':company_id', $companyId, \PDO::PARAM_INT);
  60. $stmtOrders->bindValue(':limit', $limit, \PDO::PARAM_INT);
  61. $stmtOrders->bindValue(':offset', $offset, \PDO::PARAM_INT);
  62. $stmtOrders->execute();
  63. $ordersData = $stmtOrders->fetchAll(\PDO::FETCH_ASSOC);
  64. if (empty($ordersData)) {
  65. return [
  66. 'total_sales' => (float) $totalSales,
  67. 'top_items' => $topItems,
  68. 'orders' => []
  69. ];
  70. }
  71. $orderIds = array_column($ordersData, 'order_id');
  72. $inQuery = implode(',', array_fill(0, count($orderIds), '?'));
  73. $sqlItems = "
  74. SELECT order_id,
  75. product_name,
  76. product_price
  77. FROM order_item
  78. NATURAL JOIN product
  79. WHERE order_id IN ($inQuery);
  80. ";
  81. $stmtItems = $this->pdo->prepare($sqlItems);
  82. foreach ($orderIds as $k => $id) {
  83. $stmtItems->bindValue($k + 1, $id, \PDO::PARAM_INT);
  84. }
  85. $stmtItems->execute();
  86. $itemsData = $stmtItems->fetchAll(\PDO::FETCH_ASSOC);
  87. $orders = [];
  88. foreach ($ordersData as $order) {
  89. $orders[$order['order_id']] = $order + ['items' => []];
  90. }
  91. foreach ($itemsData as $item) {
  92. $orders[$item['order_id']]['items'][] = [
  93. 'product_name' => $item['product_name'],
  94. 'product_price' => $item['product_price']
  95. ];
  96. }
  97. return [
  98. 'total_sales' => (float) $totalSales,
  99. 'top_items' => $topItems,
  100. 'orders' => array_values($orders),
  101. ];
  102. }
  103. }