Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 188 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
| CompletedBuys | |
0.00% |
0 / 188 |
|
0.00% |
0 / 8 |
1260 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| gatherCompletedBuys | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
| gatherCompletedBuysSimple | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
| gatherCompletedBuysFull | |
0.00% |
0 / 93 |
|
0.00% |
0 / 1 |
240 | |||
| gatherLastTen | |
0.00% |
0 / 63 |
|
0.00% |
0 / 1 |
110 | |||
| getCompletedBuysLight | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
12 | |||
| setCompletedBuys | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| getCompletedBuys | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace BuyerKiosk\Core; |
| 4 | |
| 5 | class CompletedBuys extends Store { |
| 6 | |
| 7 | public $completedBuys = array(); |
| 8 | |
| 9 | public function __construct() { |
| 10 | parent::__construct(); |
| 11 | } |
| 12 | |
| 13 | public function gatherCompletedBuys(Store $store, $date = null, $app = null) { |
| 14 | if($store->billingActive == 2) { |
| 15 | error_log("Gathering completed buys"); |
| 16 | $this->gatherCompletedBuysSimple($store, $app); |
| 17 | } else { |
| 18 | $this->gatherCompletedBuysFull($store, $date); |
| 19 | } |
| 20 | } |
| 21 | |
| 22 | public function gatherCompletedBuysSimple($store, $app) { |
| 23 | $queue = new \BuyerKiosk\SimpleQueue\SimpleQueue($store); |
| 24 | $completedItems = $queue->getCompletedQueueItems(); |
| 25 | foreach($completedItems as $item) { |
| 26 | $tempArray = array(); |
| 27 | $tempArray['buyID'] = $item->transID; |
| 28 | $tempArray['customerFullName'] = $item->firstName . " " . $item->lastName; |
| 29 | $tempArray['timeCompleted'] = $item->timeCompleted; |
| 30 | $tempArray['timestampCompleted'] = $item->timeCompleted; |
| 31 | $tempArray['checkedOut'] = 0; |
| 32 | $this->completedBuys[] = $tempArray; |
| 33 | } |
| 34 | } |
| 35 | |
| 36 | /** |
| 37 | * Gather completed buys with buyer and sorter info |
| 38 | * |
| 39 | * Uses unified users table (kiosk_users.users) for employee names |
| 40 | * instead of per-store employees table. |
| 41 | * |
| 42 | * @param Store $store |
| 43 | * @param string|null $date |
| 44 | */ |
| 45 | public function gatherCompletedBuysFull(Store $store, $date = null) { |
| 46 | |
| 47 | $db = \dbConnectByName($store->getDbName()); |
| 48 | $centralDb = \dbConnectByName('kiosk_users'); |
| 49 | $tempArray = array(); |
| 50 | $timeZone = $store->getTimeZone(); |
| 51 | |
| 52 | if($date !== null) { |
| 53 | $dateRange = \getDateRange($date); |
| 54 | } else { |
| 55 | $dateRange = \getCurrentDateRange(); |
| 56 | } |
| 57 | |
| 58 | // Query without employee joins (employees now in central database) |
| 59 | $buys = $db->query("SELECT |
| 60 | buyQueue.*, customers.firstName AS customerFirstName, |
| 61 | customers.lastName AS customerLastName, |
| 62 | customers.phone |
| 63 | FROM `buyQueue` |
| 64 | JOIN customers ON customers.customerID = buyQueue.customerID |
| 65 | WHERE timeCompleted BETWEEN '".$dateRange['dateStart']->format("Y-m-d H:i:s")."' AND '".$dateRange['dateEnd']->format("Y-m-d H:i:s")."' |
| 66 | AND buyQueue.isProcessed = 1 ORDER BY timeCompleted ASC"); |
| 67 | |
| 68 | // Collect all buyer and sorter IDs for batch lookup |
| 69 | $allBuys = []; |
| 70 | $userIds = []; |
| 71 | if($buys) { |
| 72 | while ($data = $buys->fetch(\PDO::FETCH_ASSOC)) { |
| 73 | $allBuys[] = $data; |
| 74 | if (!empty($data['buyerID'])) { |
| 75 | $userIds[] = (int)$data['buyerID']; |
| 76 | } |
| 77 | if (!empty($data['sorterID'])) { |
| 78 | $userIds[] = (int)$data['sorterID']; |
| 79 | } |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | // Batch fetch employee names from unified users table |
| 84 | $userNames = []; |
| 85 | if (!empty($userIds)) { |
| 86 | $userIds = array_unique($userIds); |
| 87 | $placeholders = implode(',', array_fill(0, count($userIds), '?')); |
| 88 | $userStmt = $centralDb->prepare(" |
| 89 | SELECT id, firstName, lastName |
| 90 | FROM users |
| 91 | WHERE id IN ($placeholders) |
| 92 | "); |
| 93 | $userStmt->execute(array_values($userIds)); |
| 94 | $users = $userStmt->fetchAll(\PDO::FETCH_ASSOC); |
| 95 | foreach ($users as $user) { |
| 96 | $userNames[$user['id']] = [ |
| 97 | 'firstName' => $user['firstName'], |
| 98 | 'lastName' => $user['lastName'] |
| 99 | ]; |
| 100 | } |
| 101 | } |
| 102 | |
| 103 | // Process each buy with enriched employee data |
| 104 | foreach ($allBuys as $data) { |
| 105 | // Get buyer name |
| 106 | $buyerId = (int)$data['buyerID']; |
| 107 | $buyerFirstName = isset($userNames[$buyerId]) ? $userNames[$buyerId]['firstName'] : ''; |
| 108 | $buyerLastName = isset($userNames[$buyerId]) ? $userNames[$buyerId]['lastName'] : ''; |
| 109 | |
| 110 | // Get sorter name |
| 111 | $sorterId = (int)$data['sorterID']; |
| 112 | $sorterFirstName = isset($userNames[$sorterId]) ? $userNames[$sorterId]['firstName'] : ''; |
| 113 | $sorterLastName = isset($userNames[$sorterId]) ? $userNames[$sorterId]['lastName'] : ''; |
| 114 | |
| 115 | $timeDroppedOff = new \DateTime($data['timeEntered'], new \DateTimeZone('utc')); |
| 116 | $timeStarted = new \DateTime($data['timeStarted'], new \DateTimeZone('utc')); |
| 117 | $timeCompleted = new \DateTime($data['timeCompleted'], new \DateTimeZone('utc')); |
| 118 | if ($data['sortStarted'] !== "0000-00-00 00:00:00") { |
| 119 | $sortStarted = new \DateTime($data['sortStarted'], new \DateTimeZone('utc')); |
| 120 | $sortCompleted = new \DateTime($data['sortCompleted'], new \DateTimeZone('utc')); |
| 121 | $sortStarted->setTimezone(new \DateTimeZone($timeZone)); |
| 122 | $sortCompleted->setTimezone(new \DateTimeZone($timeZone)); |
| 123 | $textSortStart = $sortStarted->format('g:i A'); |
| 124 | $textSortCompleted = $sortCompleted->format('g:i A'); |
| 125 | $textSorterFullName = $sorterFirstName . ". " . substr($sorterLastName, 0, 1); |
| 126 | $wasSorted = 1; |
| 127 | } else { |
| 128 | $textSortStart = "-"; |
| 129 | $textSortCompleted = "-"; |
| 130 | $textSorterFullName = "-"; |
| 131 | $wasSorted = 0; |
| 132 | } |
| 133 | |
| 134 | $timeDroppedOff->setTimezone(new \DateTimeZone($timeZone)); |
| 135 | $timeStarted->setTimezone(new \DateTimeZone($timeZone)); |
| 136 | $timeCompleted->setTimezone(new \DateTimeZone($timeZone)); |
| 137 | |
| 138 | if($timeDroppedOff->format('U') < $dateRange['dateStart']->format('U')) { |
| 139 | $wasToday = false; |
| 140 | $droppedOff = $timeDroppedOff->format('m/d g:i A'); |
| 141 | } else { |
| 142 | $wasToday = true; |
| 143 | $droppedOff = $timeDroppedOff->format('g:i A'); |
| 144 | } |
| 145 | $phone = $data['phone']; |
| 146 | $phone = "(".substr($phone,0,3).") ".substr($phone,3,3)."-".substr($phone,6,4); |
| 147 | |
| 148 | $tempBuy = array( |
| 149 | 'buyID' => $data['buyID'], |
| 150 | 'buyNumber' => $data['dailyNum'], |
| 151 | 'customerFullName' => $data['customerFirstName'].' '.$data['customerLastName'], |
| 152 | //'phone' => $phone, |
| 153 | 'numContainers' => $data['numContainers'], |
| 154 | 'processedContainers' => $data['processedContainers'], |
| 155 | 'timeDroppedOff' => $droppedOff, |
| 156 | 'timeStarted' => $timeStarted->format('g:i A'), |
| 157 | 'timeCompleted' => $timeCompleted->format('g:i A'), |
| 158 | 'sortStarted' => $textSortStart, |
| 159 | 'sortCompleted' => $textSortCompleted, |
| 160 | 'sorterID' => $data['sorterID'], |
| 161 | 'buyerID' => $data['buyerID'], |
| 162 | 'buyerFullName' => $buyerFirstName . " " . substr($buyerLastName, 0, 1), |
| 163 | 'sorterFullName' => $textSorterFullName, |
| 164 | 'containersRemaining' => $data['remainingContainers'], |
| 165 | 'timestampEntered' => $data['timeEntered'], |
| 166 | 'timestampSortStart' => $data['sortStarted'], |
| 167 | 'timestampSortCompleted' => $data['sortCompleted'], |
| 168 | 'timestampStarted' => $data['timeStarted'], |
| 169 | 'timestampCompleted' => $data['timeCompleted'], |
| 170 | 'wasToday' => $wasToday, |
| 171 | 'wasSorted' => $wasSorted, |
| 172 | 'checkedOut' => (int)$data['checkedOut'] |
| 173 | ); |
| 174 | $tempArray[] = $tempBuy; |
| 175 | } |
| 176 | $this->completedBuys = $tempArray; |
| 177 | } |
| 178 | /** |
| 179 | * Gather last 10 completed buys with buyer info |
| 180 | * |
| 181 | * Uses unified users table (kiosk_users.users) for employee names |
| 182 | * instead of per-store employees table. |
| 183 | * |
| 184 | * @param Store $store |
| 185 | */ |
| 186 | public function gatherLastTen(Store $store) { |
| 187 | $db = \dbConnectByName($store->getDbName()); |
| 188 | $centralDb = \dbConnectByName('kiosk_users'); |
| 189 | $timeZone = $store->getTimeZone(); |
| 190 | |
| 191 | $tempArray = array(); |
| 192 | $dateRange = \getCurrentDateRange(); |
| 193 | |
| 194 | // Query without employee join (employees now in central database) |
| 195 | $buys = $db->query("SELECT buyQueue.*, customers.firstName, customers.lastName |
| 196 | FROM buyQueue, customers |
| 197 | WHERE timeCompleted BETWEEN '".$dateRange['dateStart']->format("Y-m-d H:i:s")."' AND '".$dateRange['dateEnd']->format("Y-m-d H:i:s")."' |
| 198 | AND buyQueue.isProcessed = 1 AND customers.customerID = buyQueue.customerID ORDER BY timeCompleted DESC LIMIT 10"); |
| 199 | |
| 200 | // Collect all buyer IDs for batch lookup |
| 201 | $allBuys = []; |
| 202 | $userIds = []; |
| 203 | if($buys) { |
| 204 | while ($data = $buys->fetch(\PDO::FETCH_ASSOC)) { |
| 205 | $allBuys[] = $data; |
| 206 | if (!empty($data['buyerID'])) { |
| 207 | $userIds[] = (int)$data['buyerID']; |
| 208 | } |
| 209 | } |
| 210 | } |
| 211 | |
| 212 | // Batch fetch employee names from unified users table |
| 213 | $userNames = []; |
| 214 | if (!empty($userIds)) { |
| 215 | $userIds = array_unique($userIds); |
| 216 | $placeholders = implode(',', array_fill(0, count($userIds), '?')); |
| 217 | $userStmt = $centralDb->prepare(" |
| 218 | SELECT id, firstName, lastName |
| 219 | FROM users |
| 220 | WHERE id IN ($placeholders) |
| 221 | "); |
| 222 | $userStmt->execute(array_values($userIds)); |
| 223 | $users = $userStmt->fetchAll(\PDO::FETCH_ASSOC); |
| 224 | foreach ($users as $user) { |
| 225 | $userNames[$user['id']] = [ |
| 226 | 'firstName' => $user['firstName'], |
| 227 | 'lastName' => $user['lastName'] |
| 228 | ]; |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | // Process each buy with enriched employee data |
| 233 | foreach ($allBuys as $data) { |
| 234 | // Get buyer name |
| 235 | $buyerId = (int)$data['buyerID']; |
| 236 | $buyerFirstName = isset($userNames[$buyerId]) ? $userNames[$buyerId]['firstName'] : ''; |
| 237 | $buyerLastName = isset($userNames[$buyerId]) ? $userNames[$buyerId]['lastName'] : ''; |
| 238 | |
| 239 | $timeDroppedOff = new \DateTime($data['timeEntered']); |
| 240 | $timeStarted = new \DateTime($data['timeStarted']); |
| 241 | $timeCompleted = new \DateTime($data['timeCompleted']); |
| 242 | |
| 243 | $timeDroppedOff->setTimezone(new \DateTimeZone($timeZone)); |
| 244 | $timeStarted->setTimezone(new \DateTimeZone($timeZone)); |
| 245 | $timeCompleted->setTimezone(new \DateTimeZone($timeZone)); |
| 246 | |
| 247 | if($timeDroppedOff->format('U') < $dateRange['dateStart']->format('U')) { |
| 248 | $wasToday = false; |
| 249 | $droppedOff = $timeDroppedOff->format('g:i A'); |
| 250 | } else { |
| 251 | $wasToday = true; |
| 252 | $droppedOff = $timeDroppedOff->format('m/d g:i A'); |
| 253 | } |
| 254 | |
| 255 | $tempBuy = array( |
| 256 | 'buyID' => $data['buyID'], |
| 257 | 'buyNumber' => $data['dailyNum'], |
| 258 | 'customerFullName' => $data['firstName'].' '.$data['lastName'], |
| 259 | 'numContainers' => $data['numContainers'], |
| 260 | 'timeDroppedOff' => $droppedOff, |
| 261 | 'timeStarted' => $timeStarted->format('g:i A'), |
| 262 | 'timeCompleted' => $timeCompleted->format('g:i A'), |
| 263 | 'buyerID' => $data['buyerID'], |
| 264 | 'buyerFullName' => substr($buyerFirstName, 0, 1) . ". " . $buyerLastName, |
| 265 | 'containersRemaining' => $data['remainingContainers'], |
| 266 | 'timestampEntered' => $data['timeEntered'], |
| 267 | 'timestampStarted' => $data['timeStarted'], |
| 268 | 'timestampCompleted' => $data['timeCompleted'], |
| 269 | 'wasToday' => $wasToday, |
| 270 | 'checkedOut' => (int)$data['checkedOut'] |
| 271 | ); |
| 272 | $tempArray[] = $tempBuy; |
| 273 | } |
| 274 | $this->completedBuys = $tempArray; |
| 275 | } |
| 276 | public function getCompletedBuysLight(Store $store) { |
| 277 | $db = \dbConnectByName($store->getDbName()); |
| 278 | $timeZone = $store->getTimeZone(); |
| 279 | |
| 280 | $tempArray = array(); |
| 281 | $dateRange = \getCurrentDateRange(); |
| 282 | $buys = $db->prepare("SELECT * FROM buyQueue,customers WHERE isProcessed = 1 AND checkedOut = 0 AND customers.customerID = buyQueue.customerID AND timeCompleted BETWEEN :start AND :end"); |
| 283 | $buys->bindValue(":start", $dateRange['dateStart']->format("Y-m-d H:i:s")); |
| 284 | $buys->bindValue(":end", $dateRange['dateEnd']->format("Y-m-d H:i:s")); |
| 285 | if($buys->execute()) { |
| 286 | while ($data = $buys->fetch(\PDO::FETCH_ASSOC)) { |
| 287 | $tempBuy = array( |
| 288 | 'customerFullName' => $data['firstName'].' '.$data['lastName'], |
| 289 | 'timestampCompleted' => $data['timeCompleted'] |
| 290 | ); |
| 291 | $tempArray[] = $tempBuy; |
| 292 | } |
| 293 | $this->completedBuys = $tempArray; |
| 294 | } |
| 295 | } |
| 296 | public function setCompletedBuys($completedBuys) |
| 297 | { |
| 298 | $this->completedBuys = $completedBuys; |
| 299 | } |
| 300 | |
| 301 | public function getCompletedBuys() |
| 302 | { |
| 303 | return $this->completedBuys; |
| 304 | } |
| 305 | } |