From b78de5378650e98b808dfb7e9a9af6d8083fe6e0 Mon Sep 17 00:00:00 2001 From: sebseb7 Date: Wed, 16 Jul 2025 01:59:43 +0200 Subject: [PATCH] Enhance delivery cost calculation and shipping information display: Implement free shipping threshold for cart value in DeliveryMethodSelector and OrderProcessingService. Update CartDropdown and OrderSummary to reflect shipping costs and free shipping messages based on cart value, improving user clarity on shipping fees. --- src/components/CartDropdown.js | 29 +++++++---- src/components/profile/CheckoutForm.js | 1 + .../profile/DeliveryMethodSelector.js | 52 +++++++++++++++++-- .../profile/OrderProcessingService.js | 13 ++++- src/components/profile/OrderSummary.js | 31 +++++++---- 5 files changed, 98 insertions(+), 28 deletions(-) diff --git a/src/components/CartDropdown.js b/src/components/CartDropdown.js index a4c9c6c..64b5471 100644 --- a/src/components/CartDropdown.js +++ b/src/components/CartDropdown.js @@ -53,8 +53,8 @@ class CartDropdown extends Component { currency: 'EUR' }); - const shippingNetPrice = deliveryCost / (1 + 19 / 100); - const shippingVat = deliveryCost - shippingNetPrice; + const shippingNetPrice = deliveryCost > 0 ? deliveryCost / (1 + 19 / 100) : 0; + const shippingVat = deliveryCost > 0 ? deliveryCost - shippingNetPrice : 0; const totalVat7 = priceCalculations.vat7; const totalVat19 = priceCalculations.vat19 + shippingVat; const totalGross = priceCalculations.totalGross + deliveryCost; @@ -139,14 +139,23 @@ class CartDropdown extends Component { {currencyFormatter.format(priceCalculations.totalGross)} - {deliveryCost > 0 && ( - - Versandkosten: - - {currencyFormatter.format(deliveryCost)} - - - )} + + + Versandkosten: + {deliveryCost === 0 && priceCalculations.totalGross < 100 && ( + + (kostenlos ab 100€) + + )} + + + {deliveryCost === 0 ? ( + kostenlos + ) : ( + currencyFormatter.format(deliveryCost) + )} + + Gesamtsumme: diff --git a/src/components/profile/CheckoutForm.js b/src/components/profile/CheckoutForm.js index 7159b8a..2ee8e78 100644 --- a/src/components/profile/CheckoutForm.js +++ b/src/components/profile/CheckoutForm.js @@ -93,6 +93,7 @@ class CheckoutForm extends Component { deliveryMethod={deliveryMethod} onChange={onDeliveryMethodChange} isPickupOnly={isPickupOnly || hasStecklinge} + cartItems={cartItems} /> {(deliveryMethod === "DHL" || deliveryMethod === "DPD") && ( diff --git a/src/components/profile/DeliveryMethodSelector.js b/src/components/profile/DeliveryMethodSelector.js index 48a6405..c03fa46 100644 --- a/src/components/profile/DeliveryMethodSelector.js +++ b/src/components/profile/DeliveryMethodSelector.js @@ -4,20 +4,27 @@ import Typography from '@mui/material/Typography'; import Radio from '@mui/material/Radio'; import Checkbox from '@mui/material/Checkbox'; -const DeliveryMethodSelector = ({ deliveryMethod, onChange, isPickupOnly }) => { +const DeliveryMethodSelector = ({ deliveryMethod, onChange, isPickupOnly, cartItems = [] }) => { + // Calculate cart value for free shipping threshold + const cartValue = cartItems.reduce((total, item) => total + item.price * item.quantity, 0); + const isFreeShipping = cartValue >= 100; + const remainingForFreeShipping = Math.max(0, 100 - cartValue); + const deliveryOptions = [ { id: 'DHL', name: 'DHL', - description: isPickupOnly ? "nicht auswählbar weil ein oder mehrere Artikel nur abgeholt werden können" : 'Standardversand', - price: '6,99 €', + description: isPickupOnly ? "nicht auswählbar weil ein oder mehrere Artikel nur abgeholt werden können" : + isFreeShipping ? 'Standardversand - KOSTENLOS ab 100€ Warenwert!' : 'Standardversand', + price: isFreeShipping ? 'kostenlos' : '6,99 €', disabled: isPickupOnly }, { id: 'DPD', name: 'DPD', - description: isPickupOnly ? "nicht auswählbar weil ein oder mehrere Artikel nur abgeholt werden können" : 'Standardversand', - price: '4,90 €', + description: isPickupOnly ? "nicht auswählbar weil ein oder mehrere Artikel nur abgeholt werden können" : + isFreeShipping ? 'Standardversand - KOSTENLOS ab 100€ Warenwert!' : 'Standardversand', + price: isFreeShipping ? 'kostenlos' : '4,90 €', disabled: isPickupOnly }, { @@ -114,6 +121,41 @@ const DeliveryMethodSelector = ({ deliveryMethod, onChange, isPickupOnly }) => { ))} + + {/* Free shipping information */} + {!isFreeShipping && remainingForFreeShipping > 0 && ( + + + 💡 Versandkostenfrei ab 100€ Warenwert! + + + Noch {remainingForFreeShipping.toFixed(2).replace('.', ',')}€ für kostenlosen Versand hinzufügen. + + + )} + + {isFreeShipping && ( + + + 🎉 Glückwunsch! Sie erhalten kostenlosen Versand! + + + Ihr Warenkorb von {cartValue.toFixed(2).replace('.', ',')}€ qualifiziert sich für kostenlosen Versand. + + + )} ); diff --git a/src/components/profile/OrderProcessingService.js b/src/components/profile/OrderProcessingService.js index 3ee8e7f..248cc7b 100644 --- a/src/components/profile/OrderProcessingService.js +++ b/src/components/profile/OrderProcessingService.js @@ -347,7 +347,7 @@ class OrderProcessingService { // Calculate delivery cost getDeliveryCost() { - const { deliveryMethod, paymentMethod } = this.getState(); + const { deliveryMethod, paymentMethod, cartItems } = this.getState(); let cost = 0; switch (deliveryMethod) { @@ -367,7 +367,16 @@ class OrderProcessingService { cost = 6.99; } - // Add onDelivery surcharge if selected + // Check for free shipping threshold (>= 100€ cart value) + // Free shipping applies to DHL, DPD, and Sperrgut deliveries when cart value >= 100€ + if (cartItems && Array.isArray(cartItems) && deliveryMethod !== "Abholung") { + const cartValue = cartItems.reduce((total, item) => total + item.price * item.quantity, 0); + if (cartValue >= 100) { + cost = 0; // Free shipping for orders >= 100€ + } + } + + // Add onDelivery surcharge if selected (still applies even with free shipping) if (paymentMethod === "onDelivery") { cost += 8.99; } diff --git a/src/components/profile/OrderSummary.js b/src/components/profile/OrderSummary.js index 3ba49d0..97080e4 100644 --- a/src/components/profile/OrderSummary.js +++ b/src/components/profile/OrderSummary.js @@ -30,9 +30,9 @@ const OrderSummary = ({ deliveryCost, cartItems = [] }) => { return acc; }, { totalGross: 0, totalNet: 0, vat7: 0, vat19: 0 }); - // Calculate shipping VAT (19% VAT for shipping costs) - const shippingNetPrice = deliveryCost / (1 + 19 / 100); - const shippingVat = deliveryCost - shippingNetPrice; + // Calculate shipping VAT (19% VAT for shipping costs) - only if there are shipping costs + const shippingNetPrice = deliveryCost > 0 ? deliveryCost / (1 + 19 / 100) : 0; + const shippingVat = deliveryCost > 0 ? deliveryCost - shippingNetPrice : 0; // Combine totals - add shipping VAT to the 19% VAT total const totalVat7 = cartVatCalculations.vat7; @@ -83,14 +83,23 @@ const OrderSummary = ({ deliveryCost, cartItems = [] }) => { {currencyFormatter.format(cartVatCalculations.totalGross)} - {deliveryCost > 0 && ( - - Versandkosten: - - {currencyFormatter.format(deliveryCost)} - - - )} + + + Versandkosten: + {deliveryCost === 0 && cartVatCalculations.totalGross < 100 && ( + + (kostenlos ab 100€) + + )} + + + {deliveryCost === 0 ? ( + kostenlos + ) : ( + currencyFormatter.format(deliveryCost) + )} + + Gesamtsumme: