'success', 'data' => []])); } // 1. & 2. & 3. Pobranie dzisiejszych rachunków ze statusem 0 $tsqlBills = " SELECT r.ID, r.Numer, r.Opis, s.Nazwa as NazwaStolika, o.Imie AS OtwierajacyImie, o.Nazwisko AS OtwierajacyNazwisko, o.Nick AS OtwierajacyNick FROM dbo.NGastroDTRachunek r LEFT JOIN dbo.NGastroStolik s ON s.ID = r.StolikID LEFT JOIN dbo.NGastroUzytkownik u ON u.ID = r.UzytkownikOtwierajacyID LEFT JOIN dbo.NSysOperator o ON o.ID = u.OperatorID WHERE CAST(r.DataOtwarcia as DATE) = CAST(GETDATE() as DATE) AND r.Status = 0 "; $stmtBills = sqlsrv_query($conn, $tsqlBills); if ($stmtBills === false) { die(json_encode(['status' => 'error', 'message' => 'Błąd pobierania rachunków.', 'errors' => sqlsrv_errors()])); } $matchedBillIds = []; $bills = []; // 4. Filtrujemy rachunki po nazwie stolika (tak jak w JS) while ($row = sqlsrv_fetch_array($stmtBills, SQLSRV_FETCH_ASSOC)) { $stolikNazwa = strtolower($row['NazwaStolika'] ?? ''); $opis = strtolower($row['Opis'] ?? ''); // Elastyczne dopasowanie, uwzględnia literówkę 0 zamiast O $normalizedTableParam = str_replace('o', '0', $tableParam); $normalizedStolikNazwa = str_replace('o', '0', $stolikNazwa); $normalizedOpis = str_replace('o', '0', $opis); $isMatched = false; if (!$tableParam) { // Jeśli testujesz w przeglądarce bez parametru ?table=, pokażemy WSZYSTKIE otwarte rachunki $isMatched = true; } else { $pattern = '/\b' . preg_quote($normalizedTableParam, '/') . '\b/i'; if ( $normalizedStolikNazwa === $normalizedTableParam || $normalizedOpis === $normalizedTableParam || preg_match($pattern, $normalizedStolikNazwa) || preg_match($pattern, $normalizedOpis) ) { $isMatched = true; } } if ($isMatched) { $billId = $row['ID']; $matchedBillIds[] = $billId; $imie = trim((string) ($row['OtwierajacyImie'] ?? '')); $nazwisko = trim((string) ($row['OtwierajacyNazwisko'] ?? '')); $nick = trim((string) ($row['OtwierajacyNick'] ?? '')); $pelneImie = trim($imie . ' ' . $nazwisko); $bills[$billId] = [ 'id' => $billId, 'numer' => $row['Numer'], 'opis' => $row['Opis'], 'suma' => 0, 'pozycje' => [], 'otwierajacy' => [ 'imie' => $imie, 'nazwisko' => $nazwisko, 'nick' => $nick, 'nazwa' => $pelneImie !== '' ? $pelneImie : $nick, ], ]; } } if (empty($matchedBillIds)) { die(json_encode(['status' => 'success', 'data' => []])); } // 5. Pobranie pozycji dla dopasowanych rachunków $inClause = implode("','", $matchedBillIds); $tsqlItems = " SELECT rp.DTRachunekID, rp.ID as PozycjaID, ISNULL(NULLIF(t.NazwaNaZamowieniu, ''), t.NazwaTowaru) as NazwaTowaru, ISNULL(NULLIF(tz.NazwaNaZamowieniu, ''), tz.NazwaTowaru) as NazwaZestawu, rp.GrupaZestawuID, rp.ZestawID, rp.Ilosc, rp.Cena, rp._c_Wartosc FROM dbo.NGastroDTRachunekPozycja rp LEFT JOIN dbo.NGastroTowar t ON t.ID = rp.TowarID LEFT JOIN dbo.NGastroTowar tz ON tz.ID = rp.ZestawID WHERE rp.DTRachunekID IN ('$inClause') "; $stmtItems = sqlsrv_query($conn, $tsqlItems); if ($stmtItems === false) { die(json_encode(['status' => 'error', 'message' => 'Błąd pobierania pozycji.', 'errors' => sqlsrv_errors()])); } // 1. Grupujemy najpierw w fizyczne "Dania" (składniki pizzy łączą się w jedną pizzę) $dishes = []; while ($row = sqlsrv_fetch_array($stmtItems, SQLSRV_FETCH_ASSOC)) { $billId = $row['DTRachunekID']; $groupId = !empty($row['GrupaZestawuID']) ? $row['GrupaZestawuID'] : $row['PozycjaID']; if (!isset($dishes[$billId])) { $dishes[$billId] = []; } $ilosc = floatval($row['Ilosc']); $wartosc = floatval($row['_c_Wartosc']); if (!isset($dishes[$billId][$groupId])) { $nazwa = trim(!empty($row['NazwaZestawu']) ? $row['NazwaZestawu'] : $row['NazwaTowaru']); $dishes[$billId][$groupId] = [ 'nazwa' => $nazwa ?: 'Brak nazwy', 'ilosc' => $ilosc, 'wartosc' => 0 ]; } else { // Zabezpieczenie: bierzemy największą ilość ze składników (np. jak ktoś usunął składnik i ma ilość 0) if ($ilosc > $dishes[$billId][$groupId]['ilosc']) { $dishes[$billId][$groupId]['ilosc'] = $ilosc; } } // Zawsze sumujemy wartość składników (ser 53zł + ciasto 0zł = 53zł) $dishes[$billId][$groupId]['wartosc'] += $wartosc; } // 2. Mając pełne dania, redukujemy je (np. dwie takie same pizze "ZADYMIONA BACÓWKA" w jeden wiersz x2) foreach ($dishes as $billId => $billDishes) { $groupedByMenu = []; foreach ($billDishes as $dish) { $nazwa = $dish['nazwa']; $ilosc = $dish['ilosc']; $wartosc = $dish['wartosc']; // Cena jednostkowa uśredniona $cenaJednostkowa = $ilosc > 0 ? ($wartosc / $ilosc) : $wartosc; $key = $nazwa . "_" . number_format($cenaJednostkowa, 2, '.', ''); if (!isset($groupedByMenu[$key])) { $groupedByMenu[$key] = [ 'nazwa' => $nazwa, 'ilosc' => 0, 'cena' => $cenaJednostkowa, 'wartosc' => 0 ]; } $groupedByMenu[$key]['ilosc'] += $ilosc; $groupedByMenu[$key]['wartosc'] += $wartosc; $bills[$billId]['suma'] += $wartosc; } $bills[$billId]['pozycje'] = array_values($groupedByMenu); } $finalData = []; foreach ($bills as $bill) { $finalData[] = $bill; } echo json_encode([ 'status' => 'success', 'tableName' => strtoupper($tableParam), 'data' => $finalData ], JSON_UNESCAPED_UNICODE);