db4bc9bfe1
Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.8 KiB
JavaScript
87 lines
2.8 KiB
JavaScript
const express = require('express');
|
|
const { formatPrice } = require('../db');
|
|
const { getCart, cartCount, cartItems } = require('../cart');
|
|
const { requireCookieConsent } = require('../middleware/cookieConsent');
|
|
const { asyncHandler } = require('../utils/asyncHandler');
|
|
const promoService = require('../services/promo');
|
|
const loyaltyService = require('../services/loyalty');
|
|
const { buildCartPricing } = require('../services/pricing');
|
|
|
|
const router = express.Router();
|
|
|
|
router.use(requireCookieConsent);
|
|
router.use((req, res, next) => {
|
|
res.locals.cartCount = cartCount(getCart(req));
|
|
res.locals.formatPrice = formatPrice;
|
|
next();
|
|
});
|
|
|
|
function cartRedirect(msg, type = 'error') {
|
|
const param = type === 'success' ? 'promo_ok' : 'promo_error';
|
|
return `/cart?${param}=${encodeURIComponent(msg)}`;
|
|
}
|
|
|
|
router.post(
|
|
'/cart/promo',
|
|
asyncHandler(async (req, res) => {
|
|
const cart = getCart(req);
|
|
const items = await cartItems(cart);
|
|
if (!items.length) {
|
|
return res.redirect(cartRedirect('Корзина пуста'));
|
|
}
|
|
|
|
const subtotal = items.reduce((s, i) => s + i.line_total, 0);
|
|
const promo = await promoService.findPromoByCode(req.body.code);
|
|
const check = promoService.validatePromo(promo, subtotal);
|
|
if (!check.ok) {
|
|
delete req.session.appliedPromoCode;
|
|
return res.redirect(cartRedirect(check.error));
|
|
}
|
|
|
|
req.session.appliedPromoCode = promo.code;
|
|
res.redirect(cartRedirect(`Промокод ${promo.code} применён`, 'success'));
|
|
})
|
|
);
|
|
|
|
router.post('/cart/promo/remove', (req, res) => {
|
|
delete req.session.appliedPromoCode;
|
|
res.redirect(cartRedirect('Промокод удалён', 'success'));
|
|
});
|
|
|
|
router.post(
|
|
'/cart/loyalty',
|
|
asyncHandler(async (req, res) => {
|
|
if (!req.session.userId) {
|
|
return res.redirect('/login?next=/cart');
|
|
}
|
|
|
|
const cart = getCart(req);
|
|
const items = await cartItems(cart);
|
|
if (!items.length) {
|
|
return res.redirect(cartRedirect('Корзина пуста'));
|
|
}
|
|
|
|
const pricing = await buildCartPricing(items, req.session, req.session.userId);
|
|
const maxPoints = loyaltyService.pointsForDiscount(
|
|
Math.max(0, pricing.subtotal - pricing.promoDiscount)
|
|
);
|
|
const balance = pricing.loyaltyBalance;
|
|
|
|
if (req.body.use_all === '1') {
|
|
req.session.loyaltyPointsToUse = Math.min(balance, maxPoints);
|
|
} else {
|
|
const pts = Math.max(0, parseInt(req.body.points, 10) || 0);
|
|
req.session.loyaltyPointsToUse = Math.min(pts, balance, maxPoints);
|
|
}
|
|
|
|
res.redirect(cartRedirect('Баллы лояльности применены', 'success'));
|
|
})
|
|
);
|
|
|
|
router.post('/cart/loyalty/remove', (req, res) => {
|
|
delete req.session.loyaltyPointsToUse;
|
|
res.redirect(cartRedirect('Списание баллов отменено', 'success'));
|
|
});
|
|
|
|
module.exports = router;
|