I’m gonna try and tinker with the
ww.merx.cart
hook a litte
That’s basically what I did with this shop:
https://www.desinfektionsmittel-gww.de/kasse
The user can add a promo code („Rabatt-Code“). The checkPromoCode()
function checks the code and stores it in the session. The updatePromoCode()
functions calculates the discount. Additionally updatePromoCode()
is called every time the cart is returned to the user (within the returnCart()
function).
// site/config/config.php
function checkPromoCode(string $promoCode): bool
{
$kirby = kirby();
$site = $kirby->site();
$discountPage = $site->discount()->toPage();
$session = $kirby->session();
if ($discountPage
&& $promoCode === $discountPage->content()->code()->toString()) {
$session->set('promo-code', $promoCode);
return true;
} else {
throw new Exception([
'httpCode' => 400,
'key' => 'validation.promoCode',
]);
}
}
function updatePromoCode(Wagnerwagner\Merx\Cart $cart): void
{
$kirby = kirby();
$site = $kirby->site();
$session = $kirby->session();
$promoCode = $session->get('promo-code', false);
$discountPage = $site->discount()->toPage();
// Always remove discount
$cart->remove('discount');
// Check quantity of cart
$quantity = 0.0;
$shippingSum = 0.0;
foreach ($cart->data() as $item) {
$itemPage = page($item['id']);
if ($itemPage && !in_array($itemPage->type()->toString(), ['shipping', 'discount'])) {
$quantity += (float)$item['quantity'];
}
if ($itemPage->type()->toString() === 'shipping') {
$shippingSum += $item['sum'];
}
}
if ($promoCode
&& $quantity > 0.0
&& $discountPage
&& $promoCode === $discountPage->content()->code()->toString()) {
$price = (($cart->getSum() - $shippingSum) / 100 * $discountPage->discount()->toFloat()) * -1;
$cart->add([
'id' => 'discount',
'price' => $price,
]);
}
// remove promo-code if cart is empty
if ($quantity === 0.0) {
$session->remove('promo-code');
}
}
return [
'hooks' => [
'ww.merx.cart' => function ($cart) {
updatePromoCode($cart);
},
],
'routes' => [
[
'method' => 'POST',
'pattern' => 'shop-api/promo-code',
'action' => function()
{
try {
$cart = cart();
$promoCode = Str::trim(get('promocode'));
if (checkPromoCode($promoCode)) {
updatePromoCode($cart);
}
return Response::json(returnCart($cart));
}
],
[
'method' => 'DELETE',
'pattern' => 'shop-api/promo-code',
'action' => function()
{
kirby()->session()->remove('promo-code');
$cart = cart();
return Response::json(returnCart($cart));
},
],
[
'method' => 'GET',
'pattern' => 'shop-api/cart',
'action' => function()
{
$cart = cart();
return Response::json(returnCart($cart));
}
],
],
];