Czego się nauczysz?
- Walidacji danych liczbowych (cena, procent, kwota)
- Wykonywania obliczeń procentowych w PHP
- Pracy z różnymi typami rabatów (procentowy, kwotowy)
- Formatowania walut i procentów
- Tworzenia historii operacji i statystyk
Stworzysz Kalkulator rabatu - aplikację umożliwiającą obliczanie ceny po rabacie procentowym lub kwotowym. System pozwala na zapisywanie historii obliczeń, porównywanie różnych wariantów rabatów i generowanie podsumowań oszczędności.
Czego się nauczysz?
W prawdziwej pracy...
Obliczenia cenowe i rabatowe są podstawą każdego systemu e-commerce, POS (Point of Sale) i CRM. Umiejętność projektowania kalkulatorów z walidacją, różnymi typami obliczeń i historią operacji jest fundamentem dla każdego programisty tworzącego aplikacje sprzedażowe, marketingowe czy finansowe.
Formularz wprowadzania danych Użytkownik podaje cenę bazową i wartość rabatu (procentowo lub kwotowo). System oblicza cenę końcową.
Walidacja danych System sprawdza poprawność wprowadzonych danych - czy cena jest dodatnia, czy rabat nie przekracza 100%, czy wartości są liczbami.
Obliczenie rabatu System oblicza kwotę rabatu i cenę końcową, wyświetlając szczegóły kalkulacji.
Wyświetlenie wyniku Użytkownik widzi cenę przed rabatem, kwotę zniżki i cenę końcową w czytelnej formie.
Przykładowa struktura pliku JSON:
{ "calculations": [ { "id": 1, "original_price": 199.99, "discount_type": "percentage", "discount_value": 20, "discount_amount": 40.00, "final_price": 159.99, "product_name": "Koszulka sportowa", "created_at": "2026-02-10 14:30:00" }, { "id": 2, "original_price": 599.00, "discount_type": "fixed", "discount_value": 100, "discount_amount": 100.00, "final_price": 499.00, "product_name": "Buty do biegania", "created_at": "2026-02-10 15:45:00" }, { "id": 3, "original_price": 1299.00, "discount_type": "percentage", "discount_value": 15, "discount_amount": 194.85, "final_price": 1104.15, "product_name": "", "created_at": "2026-02-11 10:20:00" } ]}Wymagane funkcje:
Przykładowy scenariusz:
Ocena: 3.0Użytkownik wpisuje cenę 199.99 zł i rabat 20%. Po kliknięciu “Oblicz” widzi: “Cena oryginalna: 199,99 zł | Rabat: 40,00 zł (20%) | Cena końcowa: 159,99 zł”.
Wszystko z wariantu A, plus:
Przykładowy scenariusz:
Ocena: 4.0-5.0Użytkownik oblicza rabat dla “Koszulka sportowa” - 199.99 zł z 20% rabatem. Wynik trafia do historii. Na dole strony widzi: “Łączne oszczędności: 334,85 zł (z 5 obliczeń)”.
Wszystko z wariantu B, plus:
Przykładowy scenariusz:
Ocena: 5.0-6.0Użytkownik wybiera typ “kwotowy” i wpisuje rabat 100 zł na produkt za 599 zł. Może też wpisać kod “LATO2026” i system automatycznie zastosuje 25% zniżki. Raport pokazuje: “Średni rabat: 18%, Najwięcej oszczędności: Buty (100 zł)”.
Walidacja danych wejściowych:
$price = filter_var($_POST['price'] ?? '', FILTER_VALIDATE_FLOAT);$discount = filter_var($_POST['discount'] ?? '', FILTER_VALIDATE_FLOAT);
if ($price === false || $price <= 0) { $errors[] = "Cena musi być liczbą dodatnią";}
if ($discount === false || $discount < 0) { $errors[] = "Rabat nie może być ujemny";}
if ($discount > 100) { $errors[] = "Rabat procentowy nie może przekraczać 100%";}
// Dla rabatu kwotowegoif ($discountType === 'fixed' && $discount > $price) { $errors[] = "Rabat kwotowy nie może być większy niż cena";}Obliczanie rabatu:
function calculatePercentageDiscount(float $price, float $percent): array { $discountAmount = round($price * ($percent / 100), 2); $finalPrice = round($price - $discountAmount, 2);
return [ 'discount_amount' => $discountAmount, 'final_price' => $finalPrice, ];}
function calculateFixedDiscount(float $price, float $fixedAmount): array { $discountAmount = min($fixedAmount, $price); // nie więcej niż cena $finalPrice = round($price - $discountAmount, 2);
return [ 'discount_amount' => round($discountAmount, 2), 'final_price' => $finalPrice, ];}
function calculateDiscount(float $price, string $type, float $value): array { if ($type === 'percentage') { return calculatePercentageDiscount($price, $value); } else { return calculateFixedDiscount($price, $value); }}Formatowanie walut:
function formatPrice(float $amount): string { return number_format($amount, 2, ',', ' ') . ' zł';}
function formatPercent(float $percent): string { return number_format($percent, 0) . '%';}
function formatDiscountInfo(float $amount, string $type, float $value): string { if ($type === 'percentage') { return formatPrice($amount) . ' (' . formatPercent($value) . ')'; } return formatPrice($amount);}Suma oszczędności z historii:
function calculateTotalSavings(array $calculations): array { if (empty($calculations)) { return ['total' => 0, 'count' => 0, 'average' => 0]; }
$total = array_sum(array_column($calculations, 'discount_amount')); $count = count($calculations); $average = $total / $count;
return [ 'total' => round($total, 2), 'count' => $count, 'average' => round($average, 2), ];}Kody rabatowe (wariant C):
function getDiscountCodes(): array { return [ 'LATO2026' => ['type' => 'percentage', 'value' => 25], 'NOWY10' => ['type' => 'percentage', 'value' => 10], 'STAŁY50' => ['type' => 'fixed', 'value' => 50], 'VIP20' => ['type' => 'percentage', 'value' => 20], ];}
function applyDiscountCode(string $code): ?array { $codes = getDiscountCodes(); $upperCode = strtoupper(trim($code));
return $codes[$upperCode] ?? null;}
// Użycie$code = $_POST['discount_code'] ?? '';if (!empty($code)) { $codeData = applyDiscountCode($code); if ($codeData) { $discountType = $codeData['type']; $discountValue = $codeData['value']; } else { $errors[] = "Nieprawidłowy kod rabatowy"; }}Porównanie rabatów:
function compareDiscounts(float $price, float $percentDiscount, float $fixedDiscount): array { $percentResult = calculatePercentageDiscount($price, $percentDiscount); $fixedResult = calculateFixedDiscount($price, $fixedDiscount);
$percentBetter = $percentResult['discount_amount'] > $fixedResult['discount_amount'];
return [ 'percentage' => $percentResult, 'fixed' => $fixedResult, 'better' => $percentBetter ? 'percentage' : 'fixed', 'difference' => abs($percentResult['discount_amount'] - $fixedResult['discount_amount']), ];}Wykorzystaj lekcje!
Cotygodniowe spotkania podczas lekcji to idealny moment, by:
Pracuj iteracyjnie - lepiej mieć działający wariant A niż niedokończony C!