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;