From 50f38a9e9aa13573c98d11c93b04d1b391afea56 Mon Sep 17 00:00:00 2001 From: Albert Goral Date: Mon, 16 Mar 2026 09:16:23 +0100 Subject: [PATCH] init --- add_order.php | 126 ++++++++ admin.php | 359 +++++++++++++++++++++ ajax_action.php | 66 ++++ ajax_add_row.php | 39 +++ ajax_edit.php | 63 ++++ change_password.php | 72 +++++ edit_order.php | 322 +++++++++++++++++++ export_csv.php | 54 ++++ import_csv.php | 90 ++++++ import_excel.php | 95 ++++++ includes/auth.php | 18 ++ includes/config.php | 14 + includes/db.php | 16 + index.php | 620 ++++++++++++++++++++++++++++++++++++ login.php | 115 +++++++ logout.php | 14 + print.php | 112 +++++++ print_delivery.php | 150 +++++++++ uploads/logo.png | Bin 0 -> 19555 bytes uploads/logo_1773509094.png | Bin 0 -> 4846 bytes uploads/logo_1773574385.png | Bin 0 -> 17130 bytes uploads/logo_1773574724.png | Bin 0 -> 4846 bytes 22 files changed, 2345 insertions(+) create mode 100644 add_order.php create mode 100644 admin.php create mode 100644 ajax_action.php create mode 100644 ajax_add_row.php create mode 100644 ajax_edit.php create mode 100644 change_password.php create mode 100644 edit_order.php create mode 100644 export_csv.php create mode 100644 import_csv.php create mode 100644 import_excel.php create mode 100644 includes/auth.php create mode 100644 includes/config.php create mode 100644 includes/db.php create mode 100644 index.php create mode 100644 login.php create mode 100644 logout.php create mode 100644 print.php create mode 100644 print_delivery.php create mode 100644 uploads/logo.png create mode 100644 uploads/logo_1773509094.png create mode 100644 uploads/logo_1773574385.png create mode 100644 uploads/logo_1773574724.png diff --git a/add_order.php b/add_order.php new file mode 100644 index 0000000..2cab010 --- /dev/null +++ b/add_order.php @@ -0,0 +1,126 @@ + 0) { + try { + $pdo->beginTransaction(); + + $sql = "INSERT INTO " . DB_PREFIX . "orders + (product_name, quantity, purchase_place, price_per_unit, delivery_date, notes, recipient, delivery_address, company, status) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'nowe')"; + $stmt = $pdo->prepare($sql); + $stmt->execute([$product_name, $quantity, $purchase_place, $price, $delivery_date, $notes, $recipient, $delivery_address, $company]); + + $order_id = $pdo->lastInsertId(); + + $hist_sql = "INSERT INTO " . DB_PREFIX . "order_history (order_id, user_id, action) VALUES (?, ?, ?)"; + $hist_stmt = $pdo->prepare($hist_sql); + $hist_stmt->execute([$order_id, $_SESSION['user_id'], 'Utworzono nowe zamówienie.']); + + $pdo->commit(); + + $message = "
Zamówienie dodane pomyślnie!
"; + } catch (PDOException $e) { + $pdo->rollBack(); + $message = "
Błąd: " . $e->getMessage() . "
"; + } + } else { + $message = "
Wypełnij nazwę produktu i ilość.
"; + } +} +?> + + + + + + Dodaj zamówienie - <?php echo APP_NAME; ?> + + + + +
+
+
+
Nowe zamówienie
+
+
+ +
+ +
+ + +
+ +
+ + +
+
+
+ + +
+
+ +
+ + +
+
+
+
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+ + +
+
+ + +
+ +
+ Powrót do listy + +
+
+
+
+
+ + diff --git a/admin.php b/admin.php new file mode 100644 index 0000000..d64f3f0 --- /dev/null +++ b/admin.php @@ -0,0 +1,359 @@ + 'Moje Przedsiębiorstwo IT', + 'company_1_details' => 'ul. Główna 1, 00-000 Warszawa | NIP: 0987654321', + 'company_2_name' => 'Spółka Celowa Sp. z o.o.', + 'company_2_details' => 'ul. Przykładowa 10, 00-000 Warszawa | NIP: 1234567890 | KRS: 0000123456' +]; + +foreach ($default_settings as $key => $val) { + // INSERT IGNORE dodaje wpis tylko wtedy, gdy taki klucz jeszcze nie istnieje w tabeli + $stmt = $pdo->prepare("INSERT IGNORE INTO " . DB_PREFIX . "settings (setting_key, setting_value) VALUES (?, ?)"); + $stmt->execute([$key, $val]); +} + +// --------------------------------------------------------- +// 1. WGRYWANIE LOGO +// --------------------------------------------------------- +if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_FILES['logo'])) { + if ($_FILES['logo']['error'] === 0) { + $upload_dir = 'uploads/'; + if (!is_dir($upload_dir)) mkdir($upload_dir, 0777, true); + + $file_ext = strtolower(pathinfo($_FILES['logo']['name'], PATHINFO_EXTENSION)); + if(in_array($file_ext, ['jpg', 'jpeg', 'png', 'gif', 'svg'])) { + $new_name = 'logo_' . time() . '.' . $file_ext; + $dest_path = $upload_dir . $new_name; + + if (move_uploaded_file($_FILES['logo']['tmp_name'], $dest_path)) { + $stmt = $pdo->prepare("REPLACE INTO " . DB_PREFIX . "settings (setting_key, setting_value) VALUES ('logo_path', ?)"); + $stmt->execute([$dest_path]); + $message = "
Pomyślnie zaktualizowano logo!
"; + } else { + $message = "
Błąd: Nie udało się zapisać pliku. Sprawdź uprawnienia folderu 'uploads'.
"; + } + } else { + $message = "
Błąd: Dozwolone są tylko pliki graficzne (JPG, PNG, GIF, SVG).
"; + } + } +} + +// --------------------------------------------------------- +// 1B. ZAPISYWANIE DANYCH FIRM +// --------------------------------------------------------- +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'update_company_settings') { + $settings_to_update = ['company_1_name', 'company_1_details', 'company_2_name', 'company_2_details']; + + try { + $pdo->beginTransaction(); + $update_stmt = $pdo->prepare("UPDATE " . DB_PREFIX . "settings SET setting_value = ? WHERE setting_key = ?"); + + foreach ($settings_to_update as $key) { + if (isset($_POST[$key])) { + $update_stmt->execute([trim($_POST[$key]), $key]); + } + } + $pdo->commit(); + $message = "
Ustawienia firmowe zostały zapisane!
"; + } catch (PDOException $e) { + $pdo->rollBack(); + $message = "
Błąd zapisu: " . $e->getMessage() . "
"; + } +} + +// --------------------------------------------------------- +// 2. DODAWANIE UŻYTKOWNIKA +// --------------------------------------------------------- +if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['add_user'])) { + $new_user = trim($_POST['new_username']); + $new_pass = $_POST['new_password']; + $new_role = $_POST['new_role']; + + if (!empty($new_user) && !empty($new_pass)) { + try { + $hashed_pass = password_hash($new_pass, PASSWORD_BCRYPT); + $stmt = $pdo->prepare("INSERT INTO " . DB_PREFIX . "users (username, password, role) VALUES (?, ?, ?)"); + $stmt->execute([$new_user, $hashed_pass, $new_role]); + $message = "
Dodano nowego użytkownika: $new_user
"; + } catch (PDOException $e) { + $message = "
Błąd: Użytkownik o takiej nazwie prawdopodobnie już istnieje.
"; + } + } +} + +// --------------------------------------------------------- +// 3. RESET HASŁA UŻYTKOWNIKA +// --------------------------------------------------------- +if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['reset_password'])) { + $user_id = (int)$_POST['user_id']; + $new_pass = $_POST['new_password']; + + if (!empty($new_pass)) { + $hashed_pass = password_hash($new_pass, PASSWORD_BCRYPT); + $stmt = $pdo->prepare("UPDATE " . DB_PREFIX . "users SET password = ? WHERE id = ?"); + $stmt->execute([$hashed_pass, $user_id]); + $message = "
Zmieniono hasło dla wybranego użytkownika.
"; + } +} + +// --------------------------------------------------------- +// 4. USUWANIE UŻYTKOWNIKA +// --------------------------------------------------------- +if (isset($_GET['delete'])) { + $id_to_delete = (int)$_GET['delete']; + if ($id_to_delete != $_SESSION['user_id']) { + $stmt = $pdo->prepare("DELETE FROM " . DB_PREFIX . "users WHERE id = ?"); + $stmt->execute([$id_to_delete]); + $message = "
Użytkownik został pomyślnie usunięty.
"; + } else { + $message = "
Odmowa: Nie możesz usunąć własnego konta administratora!
"; + } +} + +// --------------------------------------------------------- +// POBIERANIE DANYCH DO WIDOKU +// --------------------------------------------------------- +$users = $pdo->query("SELECT id, username, role FROM " . DB_PREFIX . "users")->fetchAll(); + +$settings = []; +try { + $settings = $pdo->query("SELECT setting_key, setting_value FROM " . DB_PREFIX . "settings")->fetchAll(PDO::FETCH_KEY_PAIR); +} catch(PDOException $e) { + // Zabezpieczenie na wypadek awarii tabeli settings +} + +$current_logo = $settings['logo_path'] ?? ''; +?> + + + + + + + Panel Administratora - <?php echo defined('APP_NAME') ? APP_NAME : 'System'; ?> + + + + + + + + +
+
+

Panel Zarządzania Systemem

+
+ + + +
+
+ +
+
+ Ustawienia Wizualne +
+
+
+
+ + + +
Brak wgranego logo
+ +
+
+ + +
+ +
+
+
+ +
+
+ Dane firm (Stopki wydruków) +
+
+
+ + +
+ + +
+
+ + +
+ +
+ + +
+
+ + +
+ + +
+
+
+ +
+
+ Dodaj pracownika +
+
+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ +
+ +
+
+
+ Zarejestrowani pracownicy +
+
+
+ + + + + + + + + + + + + + + + + + + +
IDLoginUprawnieniaZarządzaj
+ + + + + + + + + Usuń + + + + + + +
+
+
+
+
+
+
+ + + + + diff --git a/ajax_action.php b/ajax_action.php new file mode 100644 index 0000000..c402abd --- /dev/null +++ b/ajax_action.php @@ -0,0 +1,66 @@ + false, 'error' => 'Brak danych'])); +} + +$id = (int)$data['id']; +$action = $data['action']; + +try { + if ($action === 'archive') { + $stmt = $pdo->prepare("UPDATE " . DB_PREFIX . "orders SET is_archived = 1 WHERE id = ?"); + $stmt->execute([$id]); + + $hist = $pdo->prepare("INSERT INTO " . DB_PREFIX . "order_history (order_id, user_id, action) VALUES (?, ?, ?)"); + $hist->execute([$id, $_SESSION['user_id'], 'Przeniesiono zamówienie do archiwum.']); + + echo json_encode(['success' => true]); + + } elseif ($action === 'duplicate') { + // Pobierz oryginał + $stmt = $pdo->prepare("SELECT * FROM " . DB_PREFIX . "orders WHERE id = ?"); + $stmt->execute([$id]); + $orig = $stmt->fetch(PDO::FETCH_ASSOC); + + if (!$orig) { + die(json_encode(['success' => false, 'error' => 'Nie znaleziono zamówienia'])); + } + + // Zapisz kopię (zawsze jako nowe, nie zarchiwizowane) + $insert = $pdo->prepare("INSERT INTO " . DB_PREFIX . "orders + (product_name, part_number, quantity, purchase_place, price_per_unit, delivery_date, notes, recipient, delivery_address, company, status, is_archived) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'nowe', 0)"); + + $insert->execute([ + $orig['product_name'] . ' (Kopia)', + $orig['part_number'], + $orig['quantity'], + $orig['purchase_place'], + $orig['price_per_unit'], + $orig['delivery_date'], + $orig['notes'], + $orig['recipient'], + $orig['delivery_address'], + $orig['company'] + ]); + + $new_id = $pdo->lastInsertId(); + + $hist = $pdo->prepare("INSERT INTO " . DB_PREFIX . "order_history (order_id, user_id, action) VALUES (?, ?, ?)"); + $hist->execute([$new_id, $_SESSION['user_id'], "Sklonowano na podstawie archiwalnego/starego zamówienia #$id."]); + + echo json_encode(['success' => true]); + } else { + echo json_encode(['success' => false, 'error' => 'Nieznana akcja']); + } +} catch (PDOException $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); +} +?> diff --git a/ajax_add_row.php b/ajax_add_row.php new file mode 100644 index 0000000..8737f5a --- /dev/null +++ b/ajax_add_row.php @@ -0,0 +1,39 @@ + false, 'error' => 'Nazwa produktu jest wymagana!'])); +} + +try { + $pdo->beginTransaction(); + + $stmt = $pdo->prepare("INSERT INTO " . DB_PREFIX . "orders (product_name, quantity, purchase_place, price_per_unit, status) VALUES (?, ?, ?, ?, 'nowe')"); + + $price = (float)str_replace(',', '.', $data['price_per_unit'] ?? 0); + $qty = (int)($data['quantity'] ?? 1); + + $stmt->execute([ + trim($data['product_name']), + $qty, + trim($data['purchase_place'] ?? ''), + $price + ]); + + $new_id = $pdo->lastInsertId(); + + $hist = $pdo->prepare("INSERT INTO " . DB_PREFIX . "order_history (order_id, user_id, action) VALUES (?, ?, ?)"); + $hist->execute([$new_id, $_SESSION['user_id'], "Utworzono zamówienie (szybkie dodawanie na liście)."]); + + $pdo->commit(); + echo json_encode(['success' => true]); +} catch (PDOException $e) { + $pdo->rollBack(); + echo json_encode(['success' => false, 'error' => $e->getMessage()]); +} +?> diff --git a/ajax_edit.php b/ajax_edit.php new file mode 100644 index 0000000..9acb70f --- /dev/null +++ b/ajax_edit.php @@ -0,0 +1,63 @@ + false, 'error' => 'Brak danych'])); +} + +$id = (int)$data['id']; +$field = $data['field']; +$value = trim($data['value']); + +// TUTAJ JEST MAGIA: dodano 'company' na końcu listy +$allowed_fields = ['product_name', 'quantity', 'purchase_place', 'price_per_unit', 'delivery_date', 'status', 'recipient', 'delivery_address', 'notes', 'company']; + +if (!in_array($field, $allowed_fields)) { + die(json_encode(['success' => false, 'error' => 'Niedozwolona kolumna'])); +} + +$field_labels = [ + 'product_name' => 'Produkt', + 'quantity' => 'Ilość', + 'purchase_place' => 'Miejsce zakupu', + 'price_per_unit' => 'Cena za sztukę', + 'delivery_date' => 'Data dostawy', + 'status' => 'Status', + 'recipient' => 'Odbiorca', + 'delivery_address' => 'Adres dostawy', + 'notes' => 'Notatki', + 'company' => 'Firma kupująca' +]; + +try { + $stmt = $pdo->prepare("SELECT $field FROM " . DB_PREFIX . "orders WHERE id = ?"); + $stmt->execute([$id]); + $old_val = $stmt->fetchColumn(); + + if ((string)$old_val !== (string)$value) { + if ($field === 'price_per_unit') { + $value = (float)str_replace(',', '.', $value); + } + + $update = $pdo->prepare("UPDATE " . DB_PREFIX . "orders SET $field = ? WHERE id = ?"); + $update->execute([$value, $id]); + + $label = $field_labels[$field] ?? $field; + $old_display = $old_val ?: '(brak)'; + $new_display = $value ?: '(brak)'; + $hist_msg = "Szybka edycja: $label zmieniono z [$old_display] ➔ [$new_display]"; + + $hist = $pdo->prepare("INSERT INTO " . DB_PREFIX . "order_history (order_id, user_id, action) VALUES (?, ?, ?)"); + $hist->execute([$id, $_SESSION['user_id'], $hist_msg]); + } + + echo json_encode(['success' => true]); +} catch (PDOException $e) { + echo json_encode(['success' => false, 'error' => $e->getMessage()]); +} +?> diff --git a/change_password.php b/change_password.php new file mode 100644 index 0000000..3304fa4 --- /dev/null +++ b/change_password.php @@ -0,0 +1,72 @@ +Nowe hasła nie są identyczne!'; + } else { + // Pobierz aktualne hasło z bazy + $stmt = $pdo->prepare("SELECT password FROM " . DB_PREFIX . "users WHERE id = ?"); + $stmt->execute([$_SESSION['user_id']]); + $user = $stmt->fetch(); + + if (password_verify($old_pass, $user['password'])) { + // Hasło poprawne - aktualizujemy + $new_hash = password_hash($new_pass, PASSWORD_BCRYPT); + $update = $pdo->prepare("UPDATE " . DB_PREFIX . "users SET password = ? WHERE id = ?"); + $update->execute([$new_hash, $_SESSION['user_id']]); + $message = '
Hasło zostało zmienione pomyślnie!
'; + } else { + $message = '
Obecne hasło jest nieprawidłowe.
'; + } + } +} +?> + + + + + + Zmiana hasła - <?php echo APP_NAME; ?> + + + +
+
+
+
Zmiana hasła
+
+
+ +
+
+ + +
+
+
+ + +
+
+ + +
+
+ Powrót + +
+
+
+
+
+ + diff --git a/edit_order.php b/edit_order.php new file mode 100644 index 0000000..c0d7772 --- /dev/null +++ b/edit_order.php @@ -0,0 +1,322 @@ +prepare("SELECT * FROM " . DB_PREFIX . "orders WHERE id = ?"); +$stmt->execute([$id]); +$order = $stmt->fetch(); + +if (!$order) { + die("Zamówienie nie istnieje."); +} + +// 1. OBSŁUGA ZMIANY STATUSU ARCHIWUM +if (isset($_POST['archive_action'])) { + $new_archive_status = $order['is_archived'] ? 0 : 1; + + $update_arch = $pdo->prepare("UPDATE " . DB_PREFIX . "orders SET is_archived = ? WHERE id = ?"); + $update_arch->execute([$new_archive_status, $id]); + + $action_msg = $new_archive_status ? "Przeniesiono do archiwum." : "Przywrócono z archiwum do aktualnych."; + $hist_arch = $pdo->prepare("INSERT INTO " . DB_PREFIX . "order_history (order_id, user_id, action) VALUES (?, ?, ?)"); + $hist_arch->execute([$id, $_SESSION['user_id'], $action_msg]); + + // Wracamy na listę, uwzględniając czy lądujemy w archiwum czy nie + $redirect_url = $new_archive_status ? "index.php?archive=1" : "index.php"; + header("Location: $redirect_url"); + exit(); +} + +// 2. OBSŁUGA DODAWANIA KOMENTARZA +if ($_SERVER["REQUEST_METHOD"] == "POST" && isset($_POST['add_comment'])) { + $comment_text = trim($_POST['comment_text'] ?? ''); + + if (!empty($comment_text)) { + try { + $ins_comm = $pdo->prepare("INSERT INTO " . DB_PREFIX . "order_comments (order_id, user_id, comment_text) VALUES (?, ?, ?)"); + $ins_comm->execute([$id, $_SESSION['user_id'], $comment_text]); + + // Przeładowanie strony (PRG - Post/Redirect/Get), aby uniknąć ponownego wysłania przy odświeżaniu F5 + header("Location: edit_order.php?id=" . $id); + exit(); + } catch (PDOException $e) { + $message = "
Błąd zapisu komentarza: " . $e->getMessage() . "
"; + } + } +} + +// 3. OBSŁUGA STANDARDOWEJ EDYCJI +if ($_SERVER["REQUEST_METHOD"] == "POST" && !isset($_POST['archive_action']) && !isset($_POST['add_comment'])) { + $product_name = trim($_POST['product_name'] ?? ''); + $part_number = trim($_POST['part_number'] ?? ''); + $quantity = (int)$_POST['quantity']; + $purchase_place = trim($_POST['purchase_place'] ?? ''); + $status = $_POST['status']; + $price = (float)str_replace(',', '.', $_POST['price_per_unit'] ?? '0'); + $delivery_date = $_POST['delivery_date'] ?? null; + $notes = trim($_POST['notes'] ?? ''); + $recipient = trim($_POST['recipient'] ?? ''); + $delivery_address = trim($_POST['delivery_address'] ?? ''); + $company = trim($_POST['company'] ?? ''); + + $changes = []; + if (($order['company'] ?? '') !== $company) $changes[] = "Firma: [{$order['company']}] ➔ [$company]"; + if (($order['product_name'] ?? '') !== $product_name) $changes[] = "Produkt: [{$order['product_name']}] ➔ [$product_name]"; + if (($order['part_number'] ?? '') !== $part_number) $changes[] = "PN: [{$order['part_number']}] ➔ [$part_number]"; + if ((int)$order['quantity'] !== $quantity) $changes[] = "Ilość: [{$order['quantity']}] ➔ [$quantity]"; + if (($order['purchase_place'] ?? '') !== $purchase_place) $changes[] = "Sklep: [{$order['purchase_place']}] ➔ [$purchase_place]"; + if (($order['status'] ?? '') !== $status) $changes[] = "Status: [{$order['status']}] ➔ [$status]"; + if ((float)$order['price_per_unit'] !== $price) $changes[] = "Cena: [{$order['price_per_unit']}] ➔ [$price]"; + if (($order['delivery_date'] ?? '') !== $delivery_date) $changes[] = "Dostawa: [{$order['delivery_date']}] ➔ [$delivery_date]"; + if (($order['recipient'] ?? '') !== $recipient) $changes[] = "Odbiorca: [{$order['recipient']}] ➔ [$recipient]"; + if (($order['delivery_address'] ?? '') !== $delivery_address) $changes[] = "Adres: [{$order['delivery_address']}] ➔ [$delivery_address]"; + if (($order['notes'] ?? '') !== $notes) $changes[] = "Zaktualizowano notatki"; + + if (!empty($changes)) { + try { + $pdo->beginTransaction(); + + $update = $pdo->prepare("UPDATE " . DB_PREFIX . "orders SET + product_name=?, part_number=?, quantity=?, purchase_place=?, status=?, price_per_unit=?, delivery_date=?, notes=?, recipient=?, delivery_address=?, company=? + WHERE id=?"); + $update->execute([$product_name, $part_number, $quantity, $purchase_place, $status, $price, $delivery_date, $notes, $recipient, $delivery_address, $company, $id]); + + $action_text = "Zmieniono: " . implode(', ', $changes); + $hist = $pdo->prepare("INSERT INTO " . DB_PREFIX . "order_history (order_id, user_id, action) VALUES (?, ?, ?)"); + $hist->execute([$id, $_SESSION['user_id'], $action_text]); + + $pdo->commit(); + $message = "
Zmiany zostały zapisane!
"; + + $stmt->execute([$id]); + $order = $stmt->fetch(); + } catch (PDOException $e) { + $pdo->rollBack(); + $message = "
Błąd bazy: " . $e->getMessage() . "
"; + } + } +} + +// POBIERANIE HISTORII +$hist_sql = "SELECT h.action, h.created_at, u.username + FROM " . DB_PREFIX . "order_history h + LEFT JOIN " . DB_PREFIX . "users u ON h.user_id = u.id + WHERE h.order_id = ? + ORDER BY h.created_at DESC"; +$hist_stmt = $pdo->prepare($hist_sql); +$hist_stmt->execute([$id]); +$history = $hist_stmt->fetchAll(); + +// POBIERANIE KOMENTARZY +$comm_sql = "SELECT c.comment_text, c.created_at, u.username + FROM " . DB_PREFIX . "order_comments c + LEFT JOIN " . DB_PREFIX . "users u ON c.user_id = u.id + WHERE c.order_id = ? + ORDER BY c.created_at DESC"; +$comm_stmt = $pdo->prepare($comm_sql); +$comm_stmt->execute([$id]); +$comments = $comm_stmt->fetchAll(); +?> + + + + + + Karta Zamówienia - <?php echo APP_NAME; ?> + + + + + + + +
+
+ +
+
+
+
+ Edycja zamówienia # + + Archiwum + +
+ Powrót +
+
+ +
+ +
+ + +
+ +
+
+ + +
+
+ + +
+
+ +
+
+ + +
+
+ +
+ + +
+
+
+ + +
+
+ +
+
+ + +
+
+ + +
+
+ +
+
+
+ + +
+
+ + +
+
+
+ +
+ + +
+ +
+ + +
+
+
+
+
+ +
+ +
+
+ Komentarze i ustalenia +
+
+
+
+ + +
+
+ +
+ +
Brak komentarzy. Bądź pierwszy!
+ + +
+
+
+ + +
+
+ +
+
+
+ + +
+
+
+ +
+
+ Historia zmian +
+
+
    + +
  • Brak zapisanej historii modyfikacji.
  • + + +
  • +
    + + +
    +
    + +
    +
  • + + +
+
+
+ +
+
+
+ + diff --git a/export_csv.php b/export_csv.php new file mode 100644 index 0000000..33c60b9 --- /dev/null +++ b/export_csv.php @@ -0,0 +1,54 @@ +prepare($sql); + $stmt->execute($ids); + $orders = $stmt->fetchAll(PDO::FETCH_ASSOC); + + // Ustawienia nagłówków dla przeglądarki, by wymusić pobieranie pliku + header('Content-Type: text/csv; charset=utf-8'); + header('Content-Disposition: attachment; filename=zamowienia_' . date('Ymd_Hi') . '.csv'); + + // Wymuszenie BOM (dzięki temu Excel od razu poprawnie przeczyta polskie znaki w UTF-8) + echo "\xEF\xBB\xBF"; + + $output = fopen('php://output', 'w'); + + // Zapisanie nagłówków kolumn (zwróć uwagę na średniki, które lubi polski Excel) + fputcsv($output, ['ID', 'Produkt', 'Part Number', 'Ilosc', 'Miejsce zakupu', 'Cena szt.', 'Data dostawy', 'Odbiorca', 'Adres dostawy', 'Status', 'Notatki'], ';'); + + // Zapisywanie danych + foreach ($orders as $o) { + fputcsv($output, [ + $o['id'], + $o['product_name'], + $o['part_number'], + $o['quantity'], + $o['purchase_place'], + number_format($o['price_per_unit'], 2, ',', ''), // Cena z przecinkiem dla Excela + $o['delivery_date'], + $o['recipient'], + $o['delivery_address'], + $o['status'], + $o['notes'] + ], ';'); + } + + fclose($output); + exit(); +} + +// Jeśli ktoś wszedł tu bezpośrednio lub nic nie zaznaczył, wracamy do indexu +header('Location: index.php'); +exit(); +?> diff --git a/import_csv.php b/import_csv.php new file mode 100644 index 0000000..eb91f22 --- /dev/null +++ b/import_csv.php @@ -0,0 +1,90 @@ +beginTransaction(); + $sql = "INSERT INTO " . DB_PREFIX . "orders + (product_name, quantity, purchase_place, price_per_unit, delivery_date, notes, status) + VALUES (?, ?, ?, ?, ?, ?, ?)"; + $stmt = $pdo->prepare($sql); + + $count = 0; + while (($row = fgetcsv($handle, 1000, ";")) !== FALSE) { + // $row[0] to LP - pomijamy zgodnie z wymaganiem + + // Obsługa polskich znaków (jeśli plik jest w Windows-1250) + foreach($row as $key => $value) { + $row[$key] = mb_convert_encoding($value, "UTF-8", "auto"); + } + + if (empty($row[1])) continue; // Pomiń jeśli brak nazwy produktu + + $stmt->execute([ + $row[1], // Produkt + (int)$row[2], // Ilość + $row[3], // Miejsce zakupu + (float)str_replace(',', '.', $row[4]), // Cena (zamiana przecinka na kropkę) + $row[5], // Data dostawy + $row[6], // Notatki + $row[7] ?? 'nowe' // Status + ]); + $count++; + } + $pdo->commit(); + $message = "
Zaimportowano $count zamówień z pliku CSV!
"; + } catch (Exception $e) { + $pdo->rollBack(); + $message = "
Błąd: " . $e->getMessage() . "
"; + } + fclose($handle); + } +} +?> + + + + + + Import CSV - <?php echo APP_NAME; ?> + + + +
+
+
+

Import z pliku CSV

+
+
+ + +
+ Ważne: W Excelu wybierz Zapisz jako -> CSV (rozdzielany średnikami). +
+ +
+
+ + +
+
+ Powrót + +
+
+
+
+
+ + diff --git a/import_excel.php b/import_excel.php new file mode 100644 index 0000000..1768b20 --- /dev/null +++ b/import_excel.php @@ -0,0 +1,95 @@ +getActiveSheet(); + $rows = $worksheet->toArray(); + + // Pomijamy nagłówek (pierwszy wiersz w Excelu) + unset($rows[0]); + + $pdo->beginTransaction(); + $sql = "INSERT INTO " . DB_PREFIX . "orders + (product_name, quantity, purchase_place, price_per_unit, delivery_date, notes, status) + VALUES (?, ?, ?, ?, ?, ?, ?)"; + $stmt = $pdo->prepare($sql); + + $count = 0; + foreach ($rows as $row) { + // Zgodnie z wymaganiem: pomijamy 1. kolumnę ($row[0]) + // Mapowanie kolumn Excela: + // $row[1] -> Produkt, $row[2] -> Ilość, $row[3] -> Miejsce, + // $row[4] -> Cena, $row[5] -> Data, $row[6] -> Notatki, $row[7] -> Status + + if (empty($row[1])) continue; // Pomiń puste wiersze + + $stmt->execute([ + $row[1], // Produkt + (int)$row[2], // Ilość + $row[3], // Miejsce zakupu + (float)$row[4], // Cena + $row[5], // Data dostawy (format YYYY-MM-DD) + $row[6], // Notatki + $row[7] ?? 'nowe' // Status + ]); + $count++; + } + $pdo->commit(); + $message = "
Pomyślnie zaimportowano $count zamówień!
"; + + } catch (Exception $e) { + if ($pdo->inTransaction()) $pdo->rollBack(); + $message = "
Błąd importu: " . $e->getMessage() . "
"; + } +} +?> + + + + + + Import Zamówień - <?php echo APP_NAME; ?> + + + +
+
+
+

Import z pliku Excel (.xlsx)

+
+
+ + +
+ Instrukcja:
+ 1. System pomija pierwszą kolumnę (LP).
+ 2. Kolejne kolumny to: Produkt, Ilość, Miejsce, Cena, Data (RRRR-MM-DD), Notatki, Status. +
+ +
+
+ + +
+
+ Powrót + +
+
+
+
+
+ + diff --git a/includes/auth.php b/includes/auth.php new file mode 100644 index 0000000..70c41bf --- /dev/null +++ b/includes/auth.php @@ -0,0 +1,18 @@ + diff --git a/includes/config.php b/includes/config.php new file mode 100644 index 0000000..89cffe4 --- /dev/null +++ b/includes/config.php @@ -0,0 +1,14 @@ + diff --git a/includes/db.php b/includes/db.php new file mode 100644 index 0000000..26eb652 --- /dev/null +++ b/includes/db.php @@ -0,0 +1,16 @@ + PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + ]; + + $pdo = new PDO($dsn, DB_USER, DB_PASS, $options); +} catch (\PDOException $e) { + throw new \PDOException($e->getMessage(), (int)$e->getCode()); +} +?> diff --git a/index.php b/index.php new file mode 100644 index 0000000..87d5cdf --- /dev/null +++ b/index.php @@ -0,0 +1,620 @@ + 'id', 'product_name' => 'product_name', 'quantity' => 'quantity', 'purchase_place' => 'purchase_place', 'price_per_unit' => 'price_per_unit', 'delivery_date' => 'delivery_date', 'status' => 'status']; +if (!array_key_exists($sort_col, $allowed_sort_cols)) $sort_col = 'id'; +if ($sort_dir !== 'asc' && $sort_dir !== 'desc') $sort_dir = 'desc'; + +function getSortLink($col_key, $label, $current_sort, $current_dir) { + global $status_filter, $date_from, $date_to, $search_query, $limit, $is_archived; + $new_dir = ($current_sort === $col_key && $current_dir === 'asc') ? 'desc' : 'asc'; + $icon = ($current_sort === $col_key) ? ($current_dir === 'asc' ? '' : '') : ''; + $text_class = ($current_sort === $col_key) ? 'text-warning' : 'text-white'; + + // Dodano parametr 'archive' do linków sortowania + $params = ['archive' => $is_archived, 'status' => $status_filter, 'date_from' => $date_from, 'date_to' => $date_to, 'q' => $search_query, 'limit' => $limit, 'sort' => $col_key, 'dir' => $new_dir]; + $url = '?' . http_build_query($params); + return "$label $icon"; +} + +// BAZOWY WARUNEK ARCHIWUM +$where = ["is_archived = ?"]; +$params = [$is_archived]; + +if ($status_filter) { $where[] = "status = ?"; $params[] = $status_filter; } +if ($date_from) { $where[] = "delivery_date >= ?"; $params[] = $date_from; } +if ($date_to) { $where[] = "delivery_date <= ?"; $params[] = $date_to; } +if ($search_query !== '') { + $where[] = "(product_name LIKE ? OR part_number LIKE ? OR purchase_place LIKE ? OR recipient LIKE ? OR delivery_address LIKE ? OR notes LIKE ? OR company LIKE ?)"; + $like_term = "%" . $search_query . "%"; + for ($i = 0; $i < 7; $i++) { $params[] = $like_term; } +} +$where_sql = implode(" AND ", $where); + +$count_stmt = $pdo->prepare("SELECT COUNT(*) FROM " . DB_PREFIX . "orders WHERE $where_sql"); +$count_stmt->execute($params); +$total_rows = $count_stmt->fetchColumn(); +$total_pages = ceil($total_rows / $limit); + +$sql = "SELECT * FROM " . DB_PREFIX . "orders WHERE $where_sql ORDER BY $sort_col $sort_dir LIMIT $limit OFFSET $offset"; +$stmt = $pdo->prepare($sql); +$stmt->execute($params); +$orders = $stmt->fetchAll(); + +$logo_path = $pdo->query("SELECT setting_value FROM " . DB_PREFIX . "settings WHERE setting_key = 'logo_path'")->fetchColumn() ?: 'assets/default_logo.png'; + +function getStatusClass($status) { + return match($status) { + 'nowe' => 'bg-info text-dark', + 'w trakcie realizacji' => 'bg-warning text-dark', + 'zrealizowane' => 'bg-success', + 'anulowane' => 'bg-danger', + default => 'bg-secondary', + }; +} +?> + + + + + + <?php echo $is_archived ? 'Archiwum' : 'Zamówienia IT'; ?> - <?php echo APP_NAME; ?> + + + + + + + + +
+
+

+ + Archiwum zamówień + + Lista zamówień + +

+ +
+ + Widok Aktualnych + + Widok Archiwum + + + + + + Import + Pełny formularz +
+
+ +
+
+
+ + + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Akcje
Brak wyników w tej sekcji.
# + + +
PN: + +
+ + kliknij...'; ?> + + + + dodaj datę'; ?> + + + + + + + + + +
+
+ + + + +
+
+
+
+ + + + +
+ +
+ + + 1): ?> +
    + +
  • + +
  • + +
+ + + +
+ + + +
+ + + + + diff --git a/login.php b/login.php new file mode 100644 index 0000000..032495b --- /dev/null +++ b/login.php @@ -0,0 +1,115 @@ +query("SELECT setting_value FROM " . DB_PREFIX . "settings WHERE setting_key = 'logo_path'"); + if ($stmt) { + $logo_path = $stmt->fetchColumn(); + } +} catch (PDOException $e) { + // Ignorujemy błąd, jeśli tabela jeszcze nie istnieje itp. +} + +// 4. Obsługa logowania +if ($_SERVER["REQUEST_METHOD"] == "POST") { + $username = trim($_POST['username']); + $password = $_POST['password']; + + if (!empty($username) && !empty($password)) { + try { + // Pobieranie użytkownika z bazy (uwzględniając prefix) + $stmt = $pdo->prepare("SELECT * FROM " . DB_PREFIX . "users WHERE username = ?"); + $stmt->execute([$username]); + $user = $stmt->fetch(); + + if ($user) { + // Weryfikacja hasła + if (password_verify($password, $user['password'])) { + // Logowanie udane - zapis do sesji + $_SESSION['user_id'] = $user['id']; + $_SESSION['username'] = $user['username']; + $_SESSION['role'] = $user['role']; + + // Przekierowanie do index.php + header("Location: index.php"); + exit(); + } else { + $error = "Błędne hasło. Upewnij się, że hasło jest poprawne)."; + } + } else { + $error = "Użytkownik '$username' nie istnieje w bazie."; + } + } catch (PDOException $e) { + $error = "Błąd bazy danych: " . $e->getMessage(); + } + } else { + $error = "Proszę wypełnić oba pola."; + } +} +?> + + + + + + + Logowanie - <?php echo defined('APP_NAME') ? APP_NAME : 'System Zamówień'; ?> + + + + + +
+
+ + + +

💻 Logowanie

+ +

Wpisz dane, aby zarządzać zamówieniami

+
+ + +
+ + +
+
+ + +
+
+ + +
+ +
+ +
+

+ Aplikacja: goral.edu.pl/zeszyt
+ Serwer: OVH PHP 8.x +

+
+
+ + + diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..ba992bd --- /dev/null +++ b/logout.php @@ -0,0 +1,14 @@ + diff --git a/print.php b/print.php new file mode 100644 index 0000000..c8d002f --- /dev/null +++ b/print.php @@ -0,0 +1,112 @@ +prepare($sql); + $stmt->execute($ids); + $orders = $stmt->fetchAll(PDO::FETCH_ASSOC); + + // Obliczamy ile głównych kolumn wydrukować, żeby ustawić odpowiedni colspan dla sub-wiersza + $mainColsCount = 0; + $main_available = ['id', 'product', 'quantity', 'place', 'price', 'status']; + foreach($main_available as $mc) { if($hasCol($mc)) $mainColsCount++; } + if($mainColsCount == 0) $mainColsCount = 1; + +} else { + die("Błąd: Nie wybrano żadnych zamówień do druku."); +} +?> + + + + + Wydruk listy - <?php echo date('Y-m-d'); ?> + + + + +
+ + +
+ +

Zestawienie zamówień IT

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID Produkt (PN) Szt. Sklep Cena jedn. Status
# + +
PN: +
+ +
Odbiorca:
+ + + +
Adres:
+ + + +
Notatki:
+ +
+ + + + diff --git a/print_delivery.php b/print_delivery.php new file mode 100644 index 0000000..e5f8a70 --- /dev/null +++ b/print_delivery.php @@ -0,0 +1,150 @@ +prepare($sql); + $stmt->execute($ids); + $orders = $stmt->fetchAll(PDO::FETCH_ASSOC); + + $logo_db = $pdo->query("SELECT setting_value FROM " . DB_PREFIX . "settings WHERE setting_key = 'logo_path'")->fetchColumn(); + $logo_src = (file_exists('uploads/logo.png')) ? 'uploads/logo.png' : ($logo_db ?: ''); + + // --- KONFIGURACJA STOPEK (pobierana z bazy) --- + $settings_stmt = $pdo->query("SELECT setting_key, setting_value FROM " . DB_PREFIX . "settings WHERE setting_key IN ('company_1_name', 'company_1_details', 'company_2_name', 'company_2_details')"); + $settings = $settings_stmt->fetchAll(PDO::FETCH_KEY_PAIR); + + if ($company_footer === 'Spółka') { + $footer_company_name = $settings['company_2_name'] ?? "Spółka Celowa Sp. z o.o."; + $footer_company_details = $settings['company_2_details'] ?? "-"; + } else { + $footer_company_name = $settings['company_1_name'] ?? "Moje Przedsiębiorstwo IT"; + $footer_company_details = $settings['company_1_details'] ?? "-"; + } + +} else { + die("Błąd: Nie wybrano zamówień."); +} +?> + + + + + <?php echo htmlspecialchars($doc_type); ?> - <?php echo date('Y-m-d'); ?> + + + + +
+ + +
+ +
+
+ + Logo + +
+
+ +
+
Miejsce dostawy / Odbiorca:
+ + (Brak podanego adresu na dokumencie)"; ?> +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
LP ID Wydawany Towar (Produkt / PN) Ilość Notatki
# + +
PN: +
+ +
+
+
Wydający (Podpis i data)
+
+
+
+
Odbierający (Czytelny podpis i data)
+
+
+
+ + + + + diff --git a/uploads/logo.png b/uploads/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..5a0edf28e9f7899f2f016fb9dcdf2377888310aa GIT binary patch literal 19555 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 literal 0 HcmV?d00001 diff --git a/uploads/logo_1773509094.png b/uploads/logo_1773509094.png new file mode 100644 index 0000000000000000000000000000000000000000..f1af883ed5dd405a25100684eaffa0ec944a63e4 GIT binary patch literal 4846 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 MisEH&KYsZ?00xL52><{9 literal 0 HcmV?d00001 diff --git a/uploads/logo_1773574724.png b/uploads/logo_1773574724.png new file mode 100644 index 0000000000000000000000000000000000000000..f1af883ed5dd405a25100684eaffa0ec944a63e4 GIT binary patch literal 4846 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 qor@znFypm_tjvs+^WUuoR-`@kgRY|IM