Wersja przed ENG
This commit is contained in:
parent
09395ccf2c
commit
044ab71d5f
@ -8,28 +8,36 @@ $pdo = db();
|
|||||||
|
|
||||||
$message = '';
|
$message = '';
|
||||||
// Handle form submission
|
// Handle form submission
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['client_id'], $_POST['product_id'], $_POST['price'])) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['client_id'], $_POST['product_id'])) {
|
||||||
$clientId = $_POST['client_id'];
|
$clientId = $_POST['client_id'];
|
||||||
$productId = $_POST['product_id'];
|
$productId = $_POST['product_id'];
|
||||||
$price = $_POST['price'];
|
$priceNet = isset($_POST['price_net']) && is_numeric($_POST['price_net']) ? (float)$_POST['price_net'] : null;
|
||||||
|
$priceGross = isset($_POST['price_gross']) && is_numeric($_POST['price_gross']) ? (float)$_POST['price_gross'] : null;
|
||||||
|
|
||||||
if (!empty($clientId) && !empty($productId) && is_numeric($price)) {
|
// Server-side validation and calculation
|
||||||
|
if ($priceGross !== null) {
|
||||||
|
$priceNet = round($priceGross / 1.23, 2);
|
||||||
|
} elseif ($priceNet !== null) {
|
||||||
|
$priceGross = round($priceNet * 1.23, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($clientId) && !empty($productId) && $priceNet !== null && $priceGross !== null) {
|
||||||
// Upsert logic
|
// Upsert logic
|
||||||
$stmt = $pdo->prepare("SELECT COUNT(*) FROM client_prices WHERE client_id = :client_id AND product_id = :product_id");
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM client_prices WHERE client_id = :client_id AND product_id = :product_id");
|
||||||
$stmt->execute(['client_id' => $clientId, 'product_id' => $productId]);
|
$stmt->execute(['client_id' => $clientId, 'product_id' => $productId]);
|
||||||
$exists = $stmt->fetchColumn() > 0;
|
$exists = $stmt->fetchColumn() > 0;
|
||||||
|
|
||||||
if ($exists) {
|
if ($exists) {
|
||||||
$stmt = $pdo->prepare("UPDATE client_prices SET price = :price WHERE client_id = :client_id AND product_id = :product_id");
|
$stmt = $pdo->prepare("UPDATE client_prices SET price_net = :price_net, price_gross = :price_gross WHERE client_id = :client_id AND product_id = :product_id");
|
||||||
$stmt->execute(['price' => $price, 'client_id' => $clientId, 'product_id' => $productId]);
|
$stmt->execute(['price_net' => $priceNet, 'price_gross' => $priceGross, 'client_id' => $clientId, 'product_id' => $productId]);
|
||||||
$message = '<div class="alert alert-success">Cena została zaktualizowana.</div>';
|
$message = '<div class="alert alert-success">Cena została zaktualizowana.</div>';
|
||||||
} else {
|
} else {
|
||||||
$stmt = $pdo->prepare("INSERT INTO client_prices (client_id, product_id, price) VALUES (:client_id, :product_id, :price)");
|
$stmt = $pdo->prepare("INSERT INTO client_prices (client_id, product_id, price_net, price_gross) VALUES (:client_id, :product_id, :price_net, :price_gross)");
|
||||||
$stmt->execute(['client_id' => $clientId, 'product_id' => $productId, 'price' => $price]);
|
$stmt->execute(['client_id' => $clientId, 'product_id' => $productId, 'price_net' => $priceNet, 'price_gross' => $priceGross]);
|
||||||
$message = '<div class="alert alert-success">Nowa cena została dodana.</div>';
|
$message = '<div class="alert alert-success">Nowa cena została dodana.</div>';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$message = '<div class="alert alert-danger">Wszystkie pola są wymagane.</div>';
|
$message = '<div class="alert alert-danger">Wszystkie pola są wymagane, a ceny muszą być prawidłowymi liczbami.</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +50,8 @@ $pricesStmt = $pdo->query("
|
|||||||
SELECT
|
SELECT
|
||||||
cp.client_id,
|
cp.client_id,
|
||||||
cp.product_id,
|
cp.product_id,
|
||||||
cp.price,
|
cp.price_net,
|
||||||
|
cp.price_gross,
|
||||||
c.name as client_name,
|
c.name as client_name,
|
||||||
p.name as product_name
|
p.name as product_name
|
||||||
FROM client_prices cp
|
FROM client_prices cp
|
||||||
@ -80,7 +89,7 @@ $existingPrices = $pricesStmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="POST" action="client_prices.php">
|
<form method="POST" action="client_prices.php">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 mb-3">
|
<div class="col-md-3 mb-3">
|
||||||
<label for="client_id" class="form-label">Klient:</label>
|
<label for="client_id" class="form-label">Klient:</label>
|
||||||
<select name="client_id" id="client_id" class="form-select" required>
|
<select name="client_id" id="client_id" class="form-select" required>
|
||||||
<option value="">Wybierz klienta</option>
|
<option value="">Wybierz klienta</option>
|
||||||
@ -89,7 +98,7 @@ $existingPrices = $pricesStmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4 mb-3">
|
<div class="col-md-3 mb-3">
|
||||||
<label for="product_id" class="form-label">Produkt:</label>
|
<label for="product_id" class="form-label">Produkt:</label>
|
||||||
<select name="product_id" id="product_id" class="form-select" required>
|
<select name="product_id" id="product_id" class="form-select" required>
|
||||||
<option value="">Wybierz produkt</option>
|
<option value="">Wybierz produkt</option>
|
||||||
@ -99,8 +108,12 @@ $existingPrices = $pricesStmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2 mb-3">
|
<div class="col-md-2 mb-3">
|
||||||
<label for="price" class="form-label">Cena:</label>
|
<label for="price_net" class="form-label">Cena netto (PLN):</label>
|
||||||
<input type="number" step="0.01" name="price" id="price" class="form-control" required>
|
<input type="number" step="0.01" name="price_net" id="price_net" class="form-control">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-2 mb-3">
|
||||||
|
<label for="price_gross" class="form-label">Cena brutto (PLN):</label>
|
||||||
|
<input type="number" step="0.01" name="price_gross" id="price_gross" class="form-control">
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-2 d-flex align-items-end">
|
<div class="col-md-2 d-flex align-items-end">
|
||||||
<button type="submit" class="btn btn-primary w-100">Zapisz</button>
|
<button type="submit" class="btn btn-primary w-100">Zapisz</button>
|
||||||
@ -117,20 +130,22 @@ $existingPrices = $pricesStmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Klient</th>
|
<th>Klient</th>
|
||||||
<th>Produkt</th>
|
<th>Produkt</th>
|
||||||
<th>Cena (PLN)</th>
|
<th>Cena netto (PLN)</th>
|
||||||
|
<th>Cena brutto (PLN)</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php if (empty($existingPrices)): ?>
|
<?php if (empty($existingPrices)): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3" class="text-center">Brak zdefiniowanych cen indywidualnych.</td>
|
<td colspan="4" class="text-center">Brak zdefiniowanych cen indywidualnych.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
<?php foreach ($existingPrices as $price): ?>
|
<?php foreach ($existingPrices as $price): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?php echo htmlspecialchars($price['client_name']); ?></td>
|
<td><?php echo htmlspecialchars($price['client_name']); ?></td>
|
||||||
<td><?php echo htmlspecialchars($price['product_name']); ?></td>
|
<td><?php echo htmlspecialchars($price['product_name']); ?></td>
|
||||||
<td><?php echo number_format($price['price'], 2, ',', ' '); ?></td>
|
<td><?php echo number_format($price['price_net'], 2, ',', ' '); ?></td>
|
||||||
|
<td><?php echo number_format($price['price_gross'], 2, ',', ' '); ?></td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
@ -141,4 +156,30 @@ $existingPrices = $pricesStmt->fetchAll(PDO::FETCH_ASSOC);
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
const priceNetInput = document.getElementById('price_net');
|
||||||
|
const priceGrossInput = document.getElementById('price_gross');
|
||||||
|
const vatRate = 1.23;
|
||||||
|
|
||||||
|
priceNetInput.addEventListener('input', function () {
|
||||||
|
const netValue = parseFloat(this.value);
|
||||||
|
if (!isNaN(netValue)) {
|
||||||
|
priceGrossInput.value = (netValue * vatRate).toFixed(2);
|
||||||
|
} else {
|
||||||
|
priceGrossInput.value = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
priceGrossInput.addEventListener('input', function () {
|
||||||
|
const grossValue = parseFloat(this.value);
|
||||||
|
if (!isNaN(grossValue)) {
|
||||||
|
priceNetInput.value = (grossValue / vatRate).toFixed(2);
|
||||||
|
} else {
|
||||||
|
priceNetInput.value = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
<?php include __DIR__ . '/../includes/footer.php'; ?>
|
<?php include __DIR__ . '/../includes/footer.php'; ?>
|
||||||
@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
session_start();
|
||||||
require_once __DIR__ . '/../includes/auth.php';
|
require_once __DIR__ . '/../includes/auth.php';
|
||||||
require_role('admin');
|
require_role('admin');
|
||||||
require_once __DIR__ . '/../includes/helpers.php';
|
require_once __DIR__ . '/../includes/helpers.php';
|
||||||
require_once __DIR__ . '/menu.php';
|
|
||||||
|
|
||||||
$db = db();
|
$db = db();
|
||||||
|
|
||||||
@ -92,6 +92,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
|||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<?php require_once __DIR__ . '/menu.php'; ?>
|
||||||
<div class="container mt-4">
|
<div class="container mt-4">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
|
|||||||
@ -99,16 +99,23 @@ $pageTitle = 'Szczegóły zamówienia #' . htmlspecialchars($order['id']);
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Produkt</th>
|
<th>Produkt</th>
|
||||||
<th>Ilość</th>
|
<th>Ilość</th>
|
||||||
<th>Cena jednostkowa</th>
|
<th>Cena jedn. netto</th>
|
||||||
<th>Suma</th>
|
<th>Cena jedn. brutto</th>
|
||||||
|
<th>Suma (brutto)</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($order_items as $item): ?>
|
<?php
|
||||||
|
$vatRate = 1.23;
|
||||||
|
foreach ($order_items as $item):
|
||||||
|
$unit_price_gross = (float)$item['unit_price'];
|
||||||
|
$unit_price_net = $unit_price_gross / $vatRate;
|
||||||
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?php echo htmlspecialchars($item['product_name']); ?></td>
|
<td><?php echo htmlspecialchars($item['product_name']); ?></td>
|
||||||
<td><?php echo htmlspecialchars($item['quantity']); ?></td>
|
<td><?php echo htmlspecialchars($item['quantity']); ?></td>
|
||||||
<td><?php echo number_format($item['unit_price'], 2, ',', ' '); ?> zł</td>
|
<td><?php echo number_format($unit_price_net, 2, ',', ' '); ?> zł</td>
|
||||||
|
<td><?php echo number_format($unit_price_gross, 2, ',', ' '); ?> zł</td>
|
||||||
<td><?php echo number_format($item['line_total'], 2, ',', ' '); ?> zł</td>
|
<td><?php echo number_format($item['line_total'], 2, ',', ' '); ?> zł</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
@ -125,7 +132,7 @@ $pageTitle = 'Szczegóły zamówienia #' . htmlspecialchars($order['id']);
|
|||||||
<p><strong>Klient:</strong> <?php echo htmlspecialchars($order['client_company_name'] ?? 'Brak'); ?></p>
|
<p><strong>Klient:</strong> <?php echo htmlspecialchars($order['client_company_name'] ?? 'Brak'); ?></p>
|
||||||
<p><strong>Data:</strong> <?php echo date('d.m.Y H:i', strtotime($order['created_at'])); ?></p>
|
<p><strong>Data:</strong> <?php echo date('d.m.Y H:i', strtotime($order['created_at'])); ?></p>
|
||||||
<p><strong>Metoda płatności:</strong> <span class="badge bg-secondary"><?php echo htmlspecialchars(get_payment_method_translation_local($order['payment_method'], $i18n)); ?></span></p>
|
<p><strong>Metoda płatności:</strong> <span class="badge bg-secondary"><?php echo htmlspecialchars(get_payment_method_translation_local($order['payment_method'], $i18n)); ?></span></p>
|
||||||
<p><strong>Suma:</strong> <strong class="fs-5"><?php echo number_format($order['total_amount'], 2, ',', ' '); ?> zł</strong></p>
|
<p><strong>Suma (brutto):</strong> <strong class="fs-5"><?php echo number_format($order['total_amount'], 2, ',', ' '); ?> zł</strong></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|||||||
@ -125,7 +125,7 @@ $pageTitle = "Zarządzanie zamówieniami";
|
|||||||
<th>Data</th>
|
<th>Data</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>Źródło</th>
|
<th>Źródło</th>
|
||||||
<th>Suma</th>
|
<th>Suma (brutto)</th>
|
||||||
<th>Akcje</th>
|
<th>Akcje</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
44
cart.php
44
cart.php
@ -18,38 +18,32 @@ if (!empty($cart)) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
|
|
||||||
$client_id = $_SESSION['client_id'] ?? null;
|
$client_id = $_SESSION['client_id'] ?? null;
|
||||||
$params = [];
|
|
||||||
|
|
||||||
$sql = 'SELECT p.*, ';
|
$stmt = $pdo->prepare("SELECT * FROM products WHERE id IN ($placeholders)");
|
||||||
if ($client_id) {
|
$stmt->execute($product_ids);
|
||||||
$sql .= 'COALESCE(cp.price, p.price) as final_price FROM products p';
|
|
||||||
$sql .= ' LEFT JOIN client_prices cp ON p.id = cp.product_id AND cp.client_id = ?';
|
|
||||||
$params[] = $client_id;
|
|
||||||
} else {
|
|
||||||
$sql .= 'p.price as final_price FROM products p';
|
|
||||||
}
|
|
||||||
|
|
||||||
$sql .= " WHERE p.id IN ($placeholders)";
|
|
||||||
|
|
||||||
$params = array_merge($params, $product_ids);
|
|
||||||
|
|
||||||
$stmt = $pdo->prepare($sql);
|
|
||||||
$stmt->execute($params);
|
|
||||||
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
foreach ($products as $product) {
|
foreach ($products as $product) {
|
||||||
$quantity = $cart[$product['id']];
|
$quantity = $cart[$product['id']];
|
||||||
$line_total = $product['final_price'] * $quantity;
|
|
||||||
|
// Use the new centralized price function
|
||||||
|
$price_info = getEffectivePrice($pdo, $product['id'], $client_id);
|
||||||
|
$price_net = $price_info['net'];
|
||||||
|
$price_gross = $price_info['gross'];
|
||||||
|
|
||||||
|
$line_total_gross = $price_gross * $quantity;
|
||||||
|
|
||||||
$cart_products[] = [
|
$cart_products[] = [
|
||||||
'id' => $product['id'],
|
'id' => $product['id'],
|
||||||
'name' => $product['name'],
|
'name' => $product['name'],
|
||||||
'price' => $product['final_price'],
|
'price_net' => $price_net,
|
||||||
|
'price_gross' => $price_gross,
|
||||||
'quantity' => $quantity,
|
'quantity' => $quantity,
|
||||||
'line_total' => $line_total,
|
'line_total' => $line_total_gross, // Use gross for calculations
|
||||||
];
|
];
|
||||||
$total_price += $line_total;
|
|
||||||
|
$total_price += $line_total_gross; // Sum up the gross total
|
||||||
}
|
}
|
||||||
} catch (PDOException $e) {
|
} catch (PDOException $e) {
|
||||||
die("Błąd połączenia z bazą danych: " . $e->getMessage());
|
die("Błąd połączenia z bazą danych: " . $e->getMessage());
|
||||||
@ -126,7 +120,8 @@ $user_role = get_user_role();
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Produkt</th>
|
<th>Produkt</th>
|
||||||
<th>Cena</th>
|
<th>Cena netto</th>
|
||||||
|
<th>Cena brutto</th>
|
||||||
<th>Ilość</th>
|
<th>Ilość</th>
|
||||||
<th>Razem</th>
|
<th>Razem</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
@ -136,7 +131,8 @@ $user_role = get_user_role();
|
|||||||
<?php foreach ($cart_products as $item): ?>
|
<?php foreach ($cart_products as $item): ?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><?php echo htmlspecialchars($item['name']); ?></td>
|
<td><?php echo htmlspecialchars($item['name']); ?></td>
|
||||||
<td><?php echo number_format($item['price'], 2, ',', ' '); ?> zł</td>
|
<td><?php echo number_format($item['price_net'], 2, ',', ' '); ?> zł</td>
|
||||||
|
<td><?php echo number_format($item['price_gross'], 2, ',', ' '); ?> zł</td>
|
||||||
<td>
|
<td>
|
||||||
<form action="cart_actions.php" method="POST" class="d-inline-flex align-items-center">
|
<form action="cart_actions.php" method="POST" class="d-inline-flex align-items-center">
|
||||||
<input type="hidden" name="action" value="update">
|
<input type="hidden" name="action" value="update">
|
||||||
@ -161,7 +157,7 @@ $user_role = get_user_role();
|
|||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3" class="text-end"><strong>Razem:</strong></td>
|
<td colspan="4" class="text-end"><strong>Razem (brutto):</strong></td>
|
||||||
<td colspan="2"><strong><?php echo number_format($total_price, 2, ',', ' '); ?> zł</strong></td>
|
<td colspan="2"><strong><?php echo number_format($total_price, 2, ',', ' '); ?> zł</strong></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
|
|||||||
25
checkout.php
25
checkout.php
@ -30,20 +30,25 @@ if (!empty($cart)) {
|
|||||||
$credit_info = $stmt->fetch(PDO::FETCH_ASSOC);
|
$credit_info = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sql = "SELECT p.id, p.name, p.units_per_pallet, COALESCE(cp.price, p.price_gross) as price FROM products p LEFT JOIN client_prices cp ON p.id = cp.product_id AND cp.client_id = ? WHERE p.id IN ($placeholders)";
|
$sql = "SELECT p.id, p.name, p.units_per_pallet FROM products p WHERE p.id IN ($placeholders)";
|
||||||
$stmt = $pdo->prepare($sql);
|
$stmt = $pdo->prepare($sql);
|
||||||
$params = array_merge([$client_id], $product_ids);
|
$stmt->execute($product_ids);
|
||||||
$stmt->execute($params);
|
|
||||||
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
$is_supplier_delivery = false;
|
$is_supplier_delivery = false;
|
||||||
foreach ($products as $product) {
|
foreach ($products as $product) {
|
||||||
$quantity = $cart[$product['id']];
|
$quantity = $cart[$product['id']];
|
||||||
$line_total = $product['price'] * $quantity;
|
|
||||||
|
$price_info = getEffectivePrice($pdo, $product['id'], $client_id);
|
||||||
|
$price_net = $price_info['net'];
|
||||||
|
$price_gross = $price_info['gross'];
|
||||||
|
|
||||||
|
$line_total = $price_gross * $quantity;
|
||||||
$cart_products[] = [
|
$cart_products[] = [
|
||||||
'id' => $product['id'],
|
'id' => $product['id'],
|
||||||
'name' => $product['name'],
|
'name' => $product['name'],
|
||||||
'price' => $product['price'],
|
'price_net' => $price_net,
|
||||||
|
'price_gross' => $price_gross,
|
||||||
'quantity' => $quantity,
|
'quantity' => $quantity,
|
||||||
'line_total' => $line_total,
|
'line_total' => $line_total,
|
||||||
];
|
];
|
||||||
@ -134,8 +139,9 @@ $user_role = get_user_role();
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Produkt</th>
|
<th>Produkt</th>
|
||||||
<th>Ilość</th>
|
<th>Ilość</th>
|
||||||
<th>Cena jedn.</th>
|
<th>Cena netto</th>
|
||||||
<th>Suma</th>
|
<th>Cena brutto</th>
|
||||||
|
<th>Suma (brutto)</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -143,14 +149,15 @@ $user_role = get_user_role();
|
|||||||
<tr>
|
<tr>
|
||||||
<td><?php echo htmlspecialchars($item['name']); ?></td>
|
<td><?php echo htmlspecialchars($item['name']); ?></td>
|
||||||
<td><?php echo $item['quantity']; ?></td>
|
<td><?php echo $item['quantity']; ?></td>
|
||||||
<td><?php echo number_format($item['price'], 2, ',', ' '); ?> zł</td>
|
<td><?php echo number_format($item['price_net'], 2, ',', ' '); ?> zł</td>
|
||||||
|
<td><?php echo number_format($item['price_gross'], 2, ',', ' '); ?> zł</td>
|
||||||
<td><?php echo number_format($item['line_total'], 2, ',', ' '); ?> zł</td>
|
<td><?php echo number_format($item['line_total'], 2, ',', ' '); ?> zł</td>
|
||||||
</tr>
|
</tr>
|
||||||
<?php endforeach; ?>
|
<?php endforeach; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tfoot>
|
<tfoot>
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3" class="text-end"><strong>Suma:</strong></td>
|
<td colspan="4" class="text-end"><strong>Suma (brutto):</strong></td>
|
||||||
<td><strong><?php echo number_format($total_price, 2, ',', ' '); ?> zł</strong></td>
|
<td><strong><?php echo number_format($total_price, 2, ',', ' '); ?> zł</strong></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tfoot>
|
</tfoot>
|
||||||
|
|||||||
10
db/migrations/026_add_net_gross_to_client_prices.sql
Normal file
10
db/migrations/026_add_net_gross_to_client_prices.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
-- Add net and gross price columns to client_prices
|
||||||
|
ALTER TABLE client_prices
|
||||||
|
ADD COLUMN price_net DECIMAL(10, 2) NULL,
|
||||||
|
ADD COLUMN price_gross DECIMAL(10, 2) NULL;
|
||||||
|
|
||||||
|
-- Migrate existing price to price_gross (assuming it was gross)
|
||||||
|
UPDATE client_prices SET price_gross = price WHERE price IS NOT NULL;
|
||||||
|
|
||||||
|
-- Calculate price_net from price_gross
|
||||||
|
UPDATE client_prices SET price_net = ROUND(price_gross / 1.23, 2) WHERE price_gross IS NOT NULL;
|
||||||
@ -75,3 +75,58 @@ function upload_error_message($error_code) {
|
|||||||
return 'Unknown upload error';
|
return 'Unknown upload error';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEffectivePrice(PDO $db, int $productId, ?int $clientId): array {
|
||||||
|
$vatRate = 1.23;
|
||||||
|
$net = null;
|
||||||
|
$gross = null;
|
||||||
|
$priceFound = false;
|
||||||
|
|
||||||
|
// Priority A: Try to fetch from client_prices
|
||||||
|
if ($clientId) {
|
||||||
|
$stmt = $db->prepare("SELECT price_net, price_gross FROM client_prices WHERE client_id = :client_id AND product_id = :product_id LIMIT 1");
|
||||||
|
$stmt->execute(['client_id' => $clientId, 'product_id' => $productId]);
|
||||||
|
$priceRow = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($priceRow) {
|
||||||
|
$net = $priceRow['price_net'] !== null ? (float)$priceRow['price_net'] : null;
|
||||||
|
$gross = $priceRow['price_gross'] !== null ? (float)$priceRow['price_gross'] : null;
|
||||||
|
|
||||||
|
if ($net !== null || $gross !== null) {
|
||||||
|
$priceFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Priority B: Fallback to product base prices if no client-specific price was found
|
||||||
|
if (!$priceFound) {
|
||||||
|
$stmt = $db->prepare("SELECT price_net, price_gross FROM products WHERE id = :product_id");
|
||||||
|
$stmt->execute(['product_id' => $productId]);
|
||||||
|
$priceRow = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($priceRow) {
|
||||||
|
$net = $priceRow['price_net'] !== null ? (float)$priceRow['price_net'] : null;
|
||||||
|
$gross = $priceRow['price_gross'] !== null ? (float)$priceRow['price_gross'] : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have one price, calculate the other
|
||||||
|
if ($gross !== null && $net === null) {
|
||||||
|
$net = round($gross / $vatRate, 2);
|
||||||
|
} elseif ($net !== null && $gross === null) {
|
||||||
|
$gross = round($net * $vatRate, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sanity check: gross must not be less than net. If so, log it and fix it.
|
||||||
|
if ($gross !== null && $net !== null && $gross < $net) {
|
||||||
|
error_log("Price inconsistency for product ID $productId: gross ($gross) is less than net ($net). Recalculating net from gross.");
|
||||||
|
$net = round($gross / $vatRate, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final check for nulls before returning
|
||||||
|
if ($net === null || $gross === null) {
|
||||||
|
return ['net' => 0.0, 'gross' => 0.0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['net' => $net, 'gross' => $gross];
|
||||||
|
}
|
||||||
|
|||||||
24
index.php
24
index.php
@ -11,9 +11,7 @@ try {
|
|||||||
|
|
||||||
// Fetch products and their primary images
|
// Fetch products and their primary images
|
||||||
$sql = "SELECT
|
$sql = "SELECT
|
||||||
p.*,
|
p.*,
|
||||||
COALESCE(cp.price, p.price_gross) as final_price,
|
|
||||||
p.price_net as final_price_net,
|
|
||||||
(SELECT file_path
|
(SELECT file_path
|
||||||
FROM product_images
|
FROM product_images
|
||||||
WHERE product_id = p.id
|
WHERE product_id = p.id
|
||||||
@ -21,17 +19,13 @@ try {
|
|||||||
LIMIT 1) AS image_path
|
LIMIT 1) AS image_path
|
||||||
FROM
|
FROM
|
||||||
products p
|
products p
|
||||||
LEFT JOIN
|
|
||||||
users u ON u.id = :user_id
|
|
||||||
LEFT JOIN
|
|
||||||
client_prices cp ON cp.product_id = p.id AND cp.client_id = u.client_id
|
|
||||||
WHERE
|
WHERE
|
||||||
p.is_active = 1
|
p.is_active = 1
|
||||||
ORDER BY
|
ORDER BY
|
||||||
CASE p.product_role WHEN 'membrana' THEN 1 WHEN 'akcesoria' THEN 2 ELSE 3 END, p.name ASC";
|
CASE p.product_role WHEN 'membrana' THEN 1 WHEN 'akcesoria' THEN 2 ELSE 3 END, p.name ASC";
|
||||||
|
|
||||||
$stmt = $pdo->prepare($sql);
|
$stmt = $pdo->prepare($sql);
|
||||||
$stmt->execute(['user_id' => $_SESSION['user_id']]);
|
$stmt->execute();
|
||||||
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
// Separate products into main and accessories
|
// Separate products into main and accessories
|
||||||
@ -132,7 +126,8 @@ $page_title = 'Katalog';
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-4">
|
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-3 row-cols-lg-4 g-4">
|
||||||
<?php foreach ($main_products as $product):
|
<?php foreach ($main_products as $product):
|
||||||
|
$prices = getEffectivePrice($pdo, $product['id'], $_SESSION['client_id']);
|
||||||
$image_url = !empty($product['image_path'])
|
$image_url = !empty($product['image_path'])
|
||||||
? 'uploads/products/' . htmlspecialchars($product['image_path'])
|
? 'uploads/products/' . htmlspecialchars($product['image_path'])
|
||||||
: 'https://placehold.co/600x400/EEE/31343C?text=Brak+zdj%C4%99cia';
|
: 'https://placehold.co/600x400/EEE/31343C?text=Brak+zdj%C4%99cia';
|
||||||
@ -152,7 +147,10 @@ $page_title = 'Katalog';
|
|||||||
$desc = $product['description'];
|
$desc = $product['description'];
|
||||||
echo htmlspecialchars(strlen($desc) > 100 ? substr($desc, 0, 100) . '...' : $desc);
|
echo htmlspecialchars(strlen($desc) > 100 ? substr($desc, 0, 100) . '...' : $desc);
|
||||||
?></p>
|
?></p>
|
||||||
<p class="card-text fw-bold fs-5 mt-auto"><?= htmlspecialchars(number_format($product['final_price'], 2, ',', ' ')) ?> PLN / <?= htmlspecialchars($product['unit']) ?></p>
|
<div class="mt-auto">
|
||||||
|
<p class="card-text text-muted small mb-0"><?= htmlspecialchars(number_format($prices['net'], 2, ',', ' ')) ?> zł netto</p>
|
||||||
|
<p class="card-text fw-bold fs-5"><?= htmlspecialchars(number_format($prices['gross'], 2, ',', ' ')) ?> zł brutto</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer bg-white border-top-0 pb-3">
|
<div class="card-footer bg-white border-top-0 pb-3">
|
||||||
<form action="cart_actions.php" method="POST" class="d-grid">
|
<form action="cart_actions.php" method="POST" class="d-grid">
|
||||||
@ -177,6 +175,7 @@ $page_title = 'Katalog';
|
|||||||
<h2 class="mb-4">Akcesoria i produkty uzupełniające</h2>
|
<h2 class="mb-4">Akcesoria i produkty uzupełniające</h2>
|
||||||
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-4 row-cols-lg-5 g-4">
|
<div class="row row-cols-1 row-cols-sm-2 row-cols-md-4 row-cols-lg-5 g-4">
|
||||||
<?php foreach ($accessories as $product):
|
<?php foreach ($accessories as $product):
|
||||||
|
$prices = getEffectivePrice($pdo, $product['id'], $_SESSION['client_id']);
|
||||||
$image_url = !empty($product['image_path'])
|
$image_url = !empty($product['image_path'])
|
||||||
? 'uploads/products/' . htmlspecialchars($product['image_path'])
|
? 'uploads/products/' . htmlspecialchars($product['image_path'])
|
||||||
: 'https://placehold.co/600x400/EEE/31343C?text=Brak+zdj%C4%99cia';
|
: 'https://placehold.co/600x400/EEE/31343C?text=Brak+zdj%C4%99cia';
|
||||||
@ -192,7 +191,10 @@ $page_title = 'Katalog';
|
|||||||
<?= htmlspecialchars($product['name']) ?>
|
<?= htmlspecialchars($product['name']) ?>
|
||||||
</a>
|
</a>
|
||||||
</h6>
|
</h6>
|
||||||
<p class="card-text fw-bold mt-auto"><?= htmlspecialchars(number_format($product['final_price'], 2, ',', ' ')) ?> PLN / <?= htmlspecialchars($product['unit']) ?></p>
|
<div class="mt-auto">
|
||||||
|
<p class="card-text text-muted small mb-0"><?= htmlspecialchars(number_format($prices['net'], 2, ',', ' ')) ?> zł netto</p>
|
||||||
|
<p class="card-text fw-bold"><?= htmlspecialchars(number_format($prices['gross'], 2, ',', ' ')) ?> zł brutto</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer bg-white border-top-0 pb-3">
|
<div class="card-footer bg-white border-top-0 pb-3">
|
||||||
<form action="cart_actions.php" method="POST" class="d-grid">
|
<form action="cart_actions.php" method="POST" class="d-grid">
|
||||||
|
|||||||
@ -161,7 +161,7 @@ $lang = 'pl';
|
|||||||
<p><strong>Data zamówienia:</strong> <?php echo date('d.m.Y H:i', strtotime($order['created_at'])); ?></p>
|
<p><strong>Data zamówienia:</strong> <?php echo date('d.m.Y H:i', strtotime($order['created_at'])); ?></p>
|
||||||
<p><strong>Status:</strong> <span class="badge bg-info"><?php echo htmlspecialchars(get_polish_status_translation($order['status'])); ?></span></p>
|
<p><strong>Status:</strong> <span class="badge bg-info"><?php echo htmlspecialchars(get_polish_status_translation($order['status'])); ?></span></p>
|
||||||
<p><strong>Metoda płatności:</strong> <?php echo htmlspecialchars(get_polish_status_translation($order['payment_method'])); ?></p>
|
<p><strong>Metoda płatności:</strong> <?php echo htmlspecialchars(get_polish_status_translation($order['payment_method'])); ?></p>
|
||||||
<p><strong>Suma:</strong> <?php echo number_format($order['total_amount'], 2, ',', ' '); ?> zł</p>
|
<p><strong>Suma (brutto):</strong> <?php echo number_format($order['total_amount'], 2, ',', ' '); ?> zł</p>
|
||||||
<p><strong>Uwagi:</strong> <?php echo nl2br(htmlspecialchars($order['notes'])); ?></p>
|
<p><strong>Uwagi:</strong> <?php echo nl2br(htmlspecialchars($order['notes'])); ?></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -174,19 +174,25 @@ $lang = 'pl';
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Zdjęcie</th>
|
<th>Zdjęcie</th>
|
||||||
<th>Produkt</th>
|
<th>Produkt</th>
|
||||||
<th>Cena jednostkowa</th>
|
<th>Cena jedn. netto</th>
|
||||||
|
<th>Cena jedn. brutto</th>
|
||||||
<th>Ilość</th>
|
<th>Ilość</th>
|
||||||
<th>Suma częściowa</th>
|
<th>Suma (brutto)</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<?php foreach ($order_items as $item):
|
<?php
|
||||||
|
$vatRate = 1.23;
|
||||||
|
foreach ($order_items as $item):
|
||||||
$image_url = $product_images[$item['product_id']] ?? 'https://placehold.co/100x100/EEE/31343C?text=' . urlencode('Brak zdjęcia');
|
$image_url = $product_images[$item['product_id']] ?? 'https://placehold.co/100x100/EEE/31343C?text=' . urlencode('Brak zdjęcia');
|
||||||
|
$unit_price_gross = (float)$item['unit_price'];
|
||||||
|
$unit_price_net = $unit_price_gross / $vatRate;
|
||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td><img src="<?php echo htmlspecialchars($image_url); ?>" alt="<?php echo htmlspecialchars($item['product_name']); ?>" style="width: 50px; height: 50px; object-fit: cover;"></td>
|
<td><img src="<?php echo htmlspecialchars($image_url); ?>" alt="<?php echo htmlspecialchars($item['product_name']); ?>" style="width: 50px; height: 50px; object-fit: cover;"></td>
|
||||||
<td><?php echo htmlspecialchars($item['product_name']); ?></td>
|
<td><?php echo htmlspecialchars($item['product_name']); ?></td>
|
||||||
<td><?php echo number_format($item['unit_price'], 2, ',', ' '); ?> zł</td>
|
<td><?php echo number_format($unit_price_net, 2, ',', ' '); ?> zł</td>
|
||||||
|
<td><?php echo number_format($unit_price_gross, 2, ',', ' '); ?> zł</td>
|
||||||
<td><?php echo $item['quantity']; ?></td>
|
<td><?php echo $item['quantity']; ?></td>
|
||||||
<td><?php echo number_format($item['line_total'], 2, ',', ' '); ?> zł</td>
|
<td><?php echo number_format($item['line_total'], 2, ',', ' '); ?> zł</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@ -31,27 +31,28 @@ try {
|
|||||||
$products_by_id = $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
|
$products_by_id = $stmt->fetchAll(PDO::FETCH_GROUP|PDO::FETCH_UNIQUE|PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
|
||||||
// 2. Calculate total amount & total pallets
|
// 2. Calculate total amount
|
||||||
$total_amount = 0;
|
$total_amount_gross = 0;
|
||||||
$is_supplier_delivery = false;
|
|
||||||
$client_id = $_SESSION['client_id'] ?? null;
|
$client_id = $_SESSION['client_id'] ?? null;
|
||||||
|
|
||||||
$product_prices = [];
|
$order_items_data = [];
|
||||||
if ($client_id) {
|
|
||||||
$price_placeholders = implode(',', array_fill(0, count($product_ids), '?'));
|
|
||||||
$sql = "SELECT p.id, COALESCE(cp.price, p.price) as price FROM products p LEFT JOIN client_prices cp ON p.id = cp.product_id AND cp.client_id = ? WHERE p.id IN ($price_placeholders)";
|
|
||||||
$stmt = $pdo->prepare($sql);
|
|
||||||
$params = array_merge([$client_id], $product_ids);
|
|
||||||
$stmt->execute($params);
|
|
||||||
$product_prices = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
$is_supplier_delivery = false;
|
$is_supplier_delivery = false;
|
||||||
foreach ($cart as $product_id => $quantity) {
|
foreach ($cart as $product_id => $quantity) {
|
||||||
if (isset($products_by_id[$product_id])) {
|
if (isset($products_by_id[$product_id])) {
|
||||||
$product = $products_by_id[$product_id];
|
$product = $products_by_id[$product_id];
|
||||||
$price = $product_prices[$product_id] ?? $product['price'];
|
|
||||||
$total_amount += $price * $quantity;
|
$price_info = getEffectivePrice($pdo, $product_id, $client_id);
|
||||||
|
$price_gross = $price_info['gross'];
|
||||||
|
|
||||||
|
$total_amount_gross += $price_gross * $quantity;
|
||||||
|
|
||||||
|
$order_items_data[] = [
|
||||||
|
'product_id' => $product_id,
|
||||||
|
'quantity' => $quantity,
|
||||||
|
'unit_price' => $price_gross, // Save gross price
|
||||||
|
'line_total' => $price_gross * $quantity,
|
||||||
|
];
|
||||||
|
|
||||||
$units_per_pallet = $product['units_per_pallet'];
|
$units_per_pallet = $product['units_per_pallet'];
|
||||||
if (isset($units_per_pallet) && $units_per_pallet > 0) {
|
if (isset($units_per_pallet) && $units_per_pallet > 0) {
|
||||||
@ -69,11 +70,11 @@ try {
|
|||||||
$stmt->execute([$client_id]);
|
$stmt->execute([$client_id]);
|
||||||
$credit_info = $stmt->fetch();
|
$credit_info = $stmt->fetch();
|
||||||
|
|
||||||
if (!$credit_info || !$credit_info['credit_enabled'] || $credit_info['credit_balance'] < $total_amount) {
|
if (!$credit_info || !$credit_info['credit_enabled'] || $credit_info['credit_balance'] < $total_amount_gross) {
|
||||||
throw new Exception('Invalid payment method or insufficient credit.');
|
throw new Exception('Invalid payment method or insufficient credit.');
|
||||||
}
|
}
|
||||||
|
|
||||||
$new_balance = $credit_info['credit_balance'] - $total_amount;
|
$new_balance = $credit_info['credit_balance'] - $total_amount_gross;
|
||||||
$stmt = $pdo->prepare('UPDATE clients SET credit_balance = ? WHERE id = ?');
|
$stmt = $pdo->prepare('UPDATE clients SET credit_balance = ? WHERE id = ?');
|
||||||
$stmt->execute([$new_balance, $client_id]);
|
$stmt->execute([$new_balance, $client_id]);
|
||||||
}
|
}
|
||||||
@ -84,7 +85,7 @@ try {
|
|||||||
);
|
);
|
||||||
$stmt->execute([
|
$stmt->execute([
|
||||||
$client_id,
|
$client_id,
|
||||||
$total_amount,
|
$total_amount_gross,
|
||||||
$_POST['payment_method'],
|
$_POST['payment_method'],
|
||||||
$delivery_source,
|
$delivery_source,
|
||||||
$_POST['notes'],
|
$_POST['notes'],
|
||||||
@ -96,18 +97,14 @@ try {
|
|||||||
$stmt = $pdo->prepare(
|
$stmt = $pdo->prepare(
|
||||||
'INSERT INTO order_items (order_id, product_id, quantity, unit_price, line_total) VALUES (?, ?, ?, ?, ?)'
|
'INSERT INTO order_items (order_id, product_id, quantity, unit_price, line_total) VALUES (?, ?, ?, ?, ?)'
|
||||||
);
|
);
|
||||||
foreach ($cart as $product_id => $quantity) {
|
foreach ($order_items_data as $item) {
|
||||||
if (isset($products_by_id[$product_id])) {
|
$stmt->execute([
|
||||||
$product = $products_by_id[$product_id];
|
$order_id,
|
||||||
$price = $product_prices[$product_id] ?? $product['price'];
|
$item['product_id'],
|
||||||
$stmt->execute([
|
$item['quantity'],
|
||||||
$order_id,
|
$item['unit_price'],
|
||||||
$product_id,
|
$item['line_total'],
|
||||||
$quantity,
|
]);
|
||||||
$price,
|
|
||||||
$price * $quantity
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Commit the transaction
|
// 5. Commit the transaction
|
||||||
|
|||||||
@ -126,7 +126,7 @@ $lang = 'pl';
|
|||||||
<th>Numer zamówienia</th>
|
<th>Numer zamówienia</th>
|
||||||
<th>Data zamówienia</th>
|
<th>Data zamówienia</th>
|
||||||
<th>Status</th>
|
<th>Status</th>
|
||||||
<th>Suma</th>
|
<th>Suma (brutto)</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|||||||
25
product.php
25
product.php
@ -15,25 +15,17 @@ if (!$product_id) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$pdo = db();
|
$pdo = db();
|
||||||
$stmt = $pdo->prepare("SELECT p.*,
|
$stmt = $pdo->prepare("SELECT p.* FROM products p WHERE p.id = :product_id");
|
||||||
COALESCE(cp.price, p.price_gross) as final_price,
|
$stmt->execute(['product_id' => $product_id]);
|
||||||
p.price_net as final_price_net
|
|
||||||
FROM products p
|
|
||||||
LEFT JOIN users u ON u.id = :user_id
|
|
||||||
LEFT JOIN client_prices cp ON cp.product_id = p.id AND cp.client_id = u.client_id
|
|
||||||
WHERE p.id = :product_id");
|
|
||||||
$stmt->execute(['user_id' => $_SESSION['user_id'], 'product_id' => $product_id]);
|
|
||||||
$product = $stmt->fetch(PDO::FETCH_ASSOC);
|
$product = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if (!$product) {
|
if (!$product) {
|
||||||
header('Location: index.php');
|
header('Location: index.php');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If client-specific price is used, re-calculate net price from it
|
// Get the correct price pair using the centralized function
|
||||||
if (!empty($product['final_price']) && empty($product['final_price_net'])) {
|
$prices = getEffectivePrice($pdo, $product['id'], $_SESSION['client_id']);
|
||||||
$product['final_price_net'] = round($product['final_price'] / 1.23, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Fetch product images
|
// Fetch product images
|
||||||
@ -139,9 +131,10 @@ $user_role = get_user_role();
|
|||||||
<h1 class="mb-3"><?= htmlspecialchars($product['name']) ?></h1>
|
<h1 class="mb-3"><?= htmlspecialchars($product['name']) ?></h1>
|
||||||
|
|
||||||
<div class="bg-light p-4 rounded mb-4">
|
<div class="bg-light p-4 rounded mb-4">
|
||||||
<h2 class="h4 fw-bold"><?= htmlspecialchars(number_format($product['final_price'], 2, ',', ' ')) ?> PLN / <?= htmlspecialchars($product['unit']) ?></h2>
|
<p class="h4 fw-bold mb-1"><?= htmlspecialchars(number_format($prices['gross'], 2, ',', ' ')) ?> zł <span class="fs-6 fw-normal">brutto</span></p>
|
||||||
<small class="text-muted">Cena brutto</small>
|
<p class="text-muted mb-0"><?= htmlspecialchars(number_format($prices['net'], 2, ',', ' ')) ?> zł <span class="fs-6 fw-normal">netto</span></p>
|
||||||
<p class="mb-0"><?= htmlspecialchars(number_format($product['final_price_net'], 2, ',', ' ')) ?> PLN netto</p>
|
<hr class="my-2">
|
||||||
|
<small class="text-muted">Cena za: <?= htmlspecialchars($product['unit']) ?></small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="cart_actions.php" method="post" class="d-flex align-items-center">
|
<form action="cart_actions.php" method="post" class="d-flex align-items-center">
|
||||||
|
|||||||
@ -27,15 +27,13 @@ $stmt = $db->prepare("
|
|||||||
p.name,
|
p.name,
|
||||||
p.unit,
|
p.unit,
|
||||||
p.price_net,
|
p.price_net,
|
||||||
COALESCE(cp.price, p.price_gross) as final_price,
|
p.price_gross,
|
||||||
pi.file_path AS primary_image
|
pi.file_path AS primary_image
|
||||||
FROM products p
|
FROM products p
|
||||||
LEFT JOIN users u ON u.id = :user_id
|
|
||||||
LEFT JOIN client_prices cp ON cp.product_id = p.id AND cp.client_id = u.client_id
|
|
||||||
LEFT JOIN product_images pi ON pi.product_id = p.id AND pi.is_primary = 1
|
LEFT JOIN product_images pi ON pi.product_id = p.id AND pi.is_primary = 1
|
||||||
WHERE p.id = :product_id
|
WHERE p.id = :product_id
|
||||||
");
|
");
|
||||||
$stmt->execute(['user_id' => $user_id, 'product_id' => $product_id]);
|
$stmt->execute(['product_id' => $product_id]);
|
||||||
$added_product = $stmt->fetch(PDO::FETCH_ASSOC);
|
$added_product = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
// If product somehow doesn't exist, redirect away
|
// If product somehow doesn't exist, redirect away
|
||||||
@ -43,6 +41,8 @@ if (!$added_product) {
|
|||||||
header('Location: cart.php');
|
header('Location: cart.php');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
$added_product_price = getEffectivePrice($db, $added_product['id'], $_SESSION['client_id'] ?? null);
|
||||||
|
|
||||||
|
|
||||||
// If image is not found, use a placeholder
|
// If image is not found, use a placeholder
|
||||||
if (empty($added_product['primary_image'])) {
|
if (empty($added_product['primary_image'])) {
|
||||||
@ -57,16 +57,14 @@ $related_products_stmt = $db->prepare("
|
|||||||
p.name,
|
p.name,
|
||||||
p.unit,
|
p.unit,
|
||||||
p.price_net,
|
p.price_net,
|
||||||
COALESCE(cp.price, p.price_gross) as final_price,
|
p.price_gross,
|
||||||
pi.file_path as primary_image
|
pi.file_path as primary_image
|
||||||
FROM products p
|
FROM products p
|
||||||
JOIN product_relations pr ON p.id = pr.related_product_id
|
JOIN product_relations pr ON p.id = pr.related_product_id
|
||||||
LEFT JOIN users u ON u.id = :user_id
|
|
||||||
LEFT JOIN client_prices cp ON cp.product_id = p.id AND cp.client_id = u.client_id
|
|
||||||
LEFT JOIN product_images pi ON p.id = pi.product_id AND pi.is_primary = 1
|
LEFT JOIN product_images pi ON p.id = pi.product_id AND pi.is_primary = 1
|
||||||
WHERE pr.product_id = :product_id AND p.product_role = 'akcesoria'
|
WHERE pr.product_id = :product_id AND p.product_role = 'akcesoria'
|
||||||
");
|
");
|
||||||
$related_products_stmt->execute(['user_id' => $user_id, 'product_id' => $product_id]);
|
$related_products_stmt->execute(['product_id' => $product_id]);
|
||||||
$related_products = $related_products_stmt->fetchAll(PDO::FETCH_ASSOC);
|
$related_products = $related_products_stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
$user_role = get_user_role();
|
$user_role = get_user_role();
|
||||||
@ -165,8 +163,8 @@ $page_title = 'Dodano do koszyka';
|
|||||||
<div class="col-md-5">
|
<div class="col-md-5">
|
||||||
<div class="d-flex justify-content-end align-items-center">
|
<div class="d-flex justify-content-end align-items-center">
|
||||||
<div class="text-end">
|
<div class="text-end">
|
||||||
<p class="mb-0 h5"><strong><?= number_format($added_product['final_price'], 2, ',', ' '); ?> zł</strong> <small>brutto</small></p>
|
<p class="mb-0 h5"><strong><?= number_format($added_product_price['gross'], 2, ',', ' '); ?> zł</strong> <small>brutto</small></p>
|
||||||
<p class="mb-0 text-muted"><?= number_format($added_product['price_net'], 2, ',', ' '); ?> zł <small>netto</small></p>
|
<p class="mb-0 text-muted"><?= number_format($added_product_price['net'], 2, ',', ' '); ?> zł <small>netto</small></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -178,7 +176,9 @@ $page_title = 'Dodano do koszyka';
|
|||||||
<?php if (!empty($related_products)): ?>
|
<?php if (!empty($related_products)): ?>
|
||||||
<h3 class="mt-5 mb-4">Polecamy także produkty powiązane:</h3>
|
<h3 class="mt-5 mb-4">Polecamy także produkty powiązane:</h3>
|
||||||
<div class="list-group">
|
<div class="list-group">
|
||||||
<?php foreach ($related_products as $product): ?>
|
<?php foreach ($related_products as $product):
|
||||||
|
$effective_price = getEffectivePrice($db, $product['id'], $_SESSION['client_id'] ?? null);
|
||||||
|
?>
|
||||||
<div class="list-group-item list-group-item-action">
|
<div class="list-group-item list-group-item-action">
|
||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col-md-2 text-center">
|
<div class="col-md-2 text-center">
|
||||||
@ -198,8 +198,8 @@ $page_title = 'Dodano do koszyka';
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<div class="text-end">
|
<div class="text-end">
|
||||||
<p class="mb-0 h5"><strong><?= number_format($product['final_price'], 2, ',', ' '); ?> zł</strong> <small>brutto</small></p>
|
<p class="mb-0 h5"><strong><?= number_format($effective_price['gross'], 2, ',', ' '); ?> zł</strong> <small>brutto</small></p>
|
||||||
<p class="mb-0 text-muted"><?= number_format($product['price_net'], 2, ',', ' '); ?> zł <small>netto</small></p>
|
<p class="mb-0 text-muted"><?= number_format($effective_price['net'], 2, ',', ' '); ?> zł <small>netto</small></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user