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.
This commit is contained in:
@@ -53,8 +53,8 @@ class CartDropdown extends Component {
|
|||||||
currency: 'EUR'
|
currency: 'EUR'
|
||||||
});
|
});
|
||||||
|
|
||||||
const shippingNetPrice = deliveryCost / (1 + 19 / 100);
|
const shippingNetPrice = deliveryCost > 0 ? deliveryCost / (1 + 19 / 100) : 0;
|
||||||
const shippingVat = deliveryCost - shippingNetPrice;
|
const shippingVat = deliveryCost > 0 ? deliveryCost - shippingNetPrice : 0;
|
||||||
const totalVat7 = priceCalculations.vat7;
|
const totalVat7 = priceCalculations.vat7;
|
||||||
const totalVat19 = priceCalculations.vat19 + shippingVat;
|
const totalVat19 = priceCalculations.vat19 + shippingVat;
|
||||||
const totalGross = priceCalculations.totalGross + deliveryCost;
|
const totalGross = priceCalculations.totalGross + deliveryCost;
|
||||||
@@ -139,14 +139,23 @@ class CartDropdown extends Component {
|
|||||||
{currencyFormatter.format(priceCalculations.totalGross)}
|
{currencyFormatter.format(priceCalculations.totalGross)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
{deliveryCost > 0 && (
|
<TableRow>
|
||||||
<TableRow>
|
<TableCell sx={{ fontWeight: 'bold' }}>
|
||||||
<TableCell sx={{ fontWeight: 'bold' }}>Versandkosten:</TableCell>
|
Versandkosten:
|
||||||
<TableCell align="right" sx={{ fontWeight: 'bold' }}>
|
{deliveryCost === 0 && priceCalculations.totalGross < 100 && (
|
||||||
{currencyFormatter.format(deliveryCost)}
|
<span style={{ color: '#2e7d32', fontSize: '0.8em', marginLeft: '4px' }}>
|
||||||
</TableCell>
|
(kostenlos ab 100€)
|
||||||
</TableRow>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{deliveryCost === 0 ? (
|
||||||
|
<span style={{ color: '#2e7d32' }}>kostenlos</span>
|
||||||
|
) : (
|
||||||
|
currencyFormatter.format(deliveryCost)
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
<TableRow sx={{ borderTop: '1px solid #e0e0e0' }}>
|
<TableRow sx={{ borderTop: '1px solid #e0e0e0' }}>
|
||||||
<TableCell sx={{ fontWeight: 'bold', pt: 2 }}>Gesamtsumme:</TableCell>
|
<TableCell sx={{ fontWeight: 'bold', pt: 2 }}>Gesamtsumme:</TableCell>
|
||||||
<TableCell align="right" sx={{ fontWeight: 'bold', pt: 2 }}>
|
<TableCell align="right" sx={{ fontWeight: 'bold', pt: 2 }}>
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ class CheckoutForm extends Component {
|
|||||||
deliveryMethod={deliveryMethod}
|
deliveryMethod={deliveryMethod}
|
||||||
onChange={onDeliveryMethodChange}
|
onChange={onDeliveryMethodChange}
|
||||||
isPickupOnly={isPickupOnly || hasStecklinge}
|
isPickupOnly={isPickupOnly || hasStecklinge}
|
||||||
|
cartItems={cartItems}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{(deliveryMethod === "DHL" || deliveryMethod === "DPD") && (
|
{(deliveryMethod === "DHL" || deliveryMethod === "DPD") && (
|
||||||
|
|||||||
@@ -4,20 +4,27 @@ import Typography from '@mui/material/Typography';
|
|||||||
import Radio from '@mui/material/Radio';
|
import Radio from '@mui/material/Radio';
|
||||||
import Checkbox from '@mui/material/Checkbox';
|
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 = [
|
const deliveryOptions = [
|
||||||
{
|
{
|
||||||
id: 'DHL',
|
id: 'DHL',
|
||||||
name: 'DHL',
|
name: 'DHL',
|
||||||
description: isPickupOnly ? "nicht auswählbar weil ein oder mehrere Artikel nur abgeholt werden können" : 'Standardversand',
|
description: isPickupOnly ? "nicht auswählbar weil ein oder mehrere Artikel nur abgeholt werden können" :
|
||||||
price: '6,99 €',
|
isFreeShipping ? 'Standardversand - KOSTENLOS ab 100€ Warenwert!' : 'Standardversand',
|
||||||
|
price: isFreeShipping ? 'kostenlos' : '6,99 €',
|
||||||
disabled: isPickupOnly
|
disabled: isPickupOnly
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'DPD',
|
id: 'DPD',
|
||||||
name: 'DPD',
|
name: 'DPD',
|
||||||
description: isPickupOnly ? "nicht auswählbar weil ein oder mehrere Artikel nur abgeholt werden können" : 'Standardversand',
|
description: isPickupOnly ? "nicht auswählbar weil ein oder mehrere Artikel nur abgeholt werden können" :
|
||||||
price: '4,90 €',
|
isFreeShipping ? 'Standardversand - KOSTENLOS ab 100€ Warenwert!' : 'Standardversand',
|
||||||
|
price: isFreeShipping ? 'kostenlos' : '4,90 €',
|
||||||
disabled: isPickupOnly
|
disabled: isPickupOnly
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -114,6 +121,41 @@ const DeliveryMethodSelector = ({ deliveryMethod, onChange, isPickupOnly }) => {
|
|||||||
</Typography>
|
</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
|
{/* Free shipping information */}
|
||||||
|
{!isFreeShipping && remainingForFreeShipping > 0 && (
|
||||||
|
<Box sx={{
|
||||||
|
mt: 2,
|
||||||
|
p: 2,
|
||||||
|
backgroundColor: '#f0f8ff',
|
||||||
|
borderRadius: 1,
|
||||||
|
border: '1px solid #2196f3'
|
||||||
|
}}>
|
||||||
|
<Typography variant="body2" color="primary" sx={{ fontWeight: 'medium' }}>
|
||||||
|
💡 Versandkostenfrei ab 100€ Warenwert!
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary">
|
||||||
|
Noch {remainingForFreeShipping.toFixed(2).replace('.', ',')}€ für kostenlosen Versand hinzufügen.
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isFreeShipping && (
|
||||||
|
<Box sx={{
|
||||||
|
mt: 2,
|
||||||
|
p: 2,
|
||||||
|
backgroundColor: '#e8f5e8',
|
||||||
|
borderRadius: 1,
|
||||||
|
border: '1px solid #2e7d32'
|
||||||
|
}}>
|
||||||
|
<Typography variant="body2" color="success.main" sx={{ fontWeight: 'medium' }}>
|
||||||
|
🎉 Glückwunsch! Sie erhalten kostenlosen Versand!
|
||||||
|
</Typography>
|
||||||
|
<Typography variant="body2" color="text.secondary">
|
||||||
|
Ihr Warenkorb von {cartValue.toFixed(2).replace('.', ',')}€ qualifiziert sich für kostenlosen Versand.
|
||||||
|
</Typography>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -347,7 +347,7 @@ class OrderProcessingService {
|
|||||||
|
|
||||||
// Calculate delivery cost
|
// Calculate delivery cost
|
||||||
getDeliveryCost() {
|
getDeliveryCost() {
|
||||||
const { deliveryMethod, paymentMethod } = this.getState();
|
const { deliveryMethod, paymentMethod, cartItems } = this.getState();
|
||||||
let cost = 0;
|
let cost = 0;
|
||||||
|
|
||||||
switch (deliveryMethod) {
|
switch (deliveryMethod) {
|
||||||
@@ -367,7 +367,16 @@ class OrderProcessingService {
|
|||||||
cost = 6.99;
|
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") {
|
if (paymentMethod === "onDelivery") {
|
||||||
cost += 8.99;
|
cost += 8.99;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ const OrderSummary = ({ deliveryCost, cartItems = [] }) => {
|
|||||||
return acc;
|
return acc;
|
||||||
}, { totalGross: 0, totalNet: 0, vat7: 0, vat19: 0 });
|
}, { totalGross: 0, totalNet: 0, vat7: 0, vat19: 0 });
|
||||||
|
|
||||||
// Calculate shipping VAT (19% VAT for shipping costs)
|
// Calculate shipping VAT (19% VAT for shipping costs) - only if there are shipping costs
|
||||||
const shippingNetPrice = deliveryCost / (1 + 19 / 100);
|
const shippingNetPrice = deliveryCost > 0 ? deliveryCost / (1 + 19 / 100) : 0;
|
||||||
const shippingVat = deliveryCost - shippingNetPrice;
|
const shippingVat = deliveryCost > 0 ? deliveryCost - shippingNetPrice : 0;
|
||||||
|
|
||||||
// Combine totals - add shipping VAT to the 19% VAT total
|
// Combine totals - add shipping VAT to the 19% VAT total
|
||||||
const totalVat7 = cartVatCalculations.vat7;
|
const totalVat7 = cartVatCalculations.vat7;
|
||||||
@@ -83,14 +83,23 @@ const OrderSummary = ({ deliveryCost, cartItems = [] }) => {
|
|||||||
{currencyFormatter.format(cartVatCalculations.totalGross)}
|
{currencyFormatter.format(cartVatCalculations.totalGross)}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
{deliveryCost > 0 && (
|
<TableRow>
|
||||||
<TableRow>
|
<TableCell sx={{ fontWeight: 'bold' }}>
|
||||||
<TableCell sx={{ fontWeight: 'bold' }}>Versandkosten:</TableCell>
|
Versandkosten:
|
||||||
<TableCell align="right" sx={{ fontWeight: 'bold' }}>
|
{deliveryCost === 0 && cartVatCalculations.totalGross < 100 && (
|
||||||
{currencyFormatter.format(deliveryCost)}
|
<span style={{ color: '#2e7d32', fontSize: '0.8em', marginLeft: '4px' }}>
|
||||||
</TableCell>
|
(kostenlos ab 100€)
|
||||||
</TableRow>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
</TableCell>
|
||||||
|
<TableCell align="right" sx={{ fontWeight: 'bold' }}>
|
||||||
|
{deliveryCost === 0 ? (
|
||||||
|
<span style={{ color: '#2e7d32' }}>kostenlos</span>
|
||||||
|
) : (
|
||||||
|
currencyFormatter.format(deliveryCost)
|
||||||
|
)}
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
<TableRow sx={{ borderTop: '1px solid #e0e0e0' }}>
|
<TableRow sx={{ borderTop: '1px solid #e0e0e0' }}>
|
||||||
<TableCell sx={{ fontWeight: 'bold', pt: 2 }}>Gesamtsumme:</TableCell>
|
<TableCell sx={{ fontWeight: 'bold', pt: 2 }}>Gesamtsumme:</TableCell>
|
||||||
<TableCell align="right" sx={{ fontWeight: 'bold', pt: 2 }}>
|
<TableCell align="right" sx={{ fontWeight: 'bold', pt: 2 }}>
|
||||||
|
|||||||
Reference in New Issue
Block a user