Files
hope-events/backend/src/controllers/couponController.js
T

38 lines
2.4 KiB
JavaScript

// Coupon codes (v1). The logic is in services/deals.ts, shared with /api/v2 (1.51.9).
const deals = require('../services/deals');
const { safeErrorMessage } = require('../utils/errorUtils');
const { listWhere } = require('../utils/campusScope');
const { getClientIp } = require('../utils/requestUtils');
const { scopeFor } = require('../utils/campusScope');
const ctxOf = async (req) => ({ scope: await scopeFor(req), ip: getClientIp(req) });
const fail = (res, error) => res.status(error.statusCode || 400).json({ message: safeErrorMessage(error), ...(error.code && !/^P\d/.test(error.code) ? { code: error.code } : {}) });
const actorOf = (req) => (req.user ? { id: req.user.id, role: req.user.role, email: req.user.email } : null);
const dateOrNull = (v) => { if (!v) return null; const d = new Date(v); return isNaN(d.getTime()) ? null : d; };
// @route GET /api/coupons — with use counts
const listCoupons = async (req, res) => { try { res.json(await deals.listCoupons(await ctxOf(req))); } catch (e) { fail(res, e); } };
// @route GET /api/coupons/:id — with its redemptions
const getCoupon = async (req, res) => { try { res.json(await deals.getCoupon(req.params.id, await ctxOf(req))); } catch (e) { fail(res, e); } };
// @route POST /api/coupons
const createCoupon = async (req, res) => { try { res.status(201).json(await deals.createCoupon(req.body || {}, req.user, await ctxOf(req))); } catch (e) { fail(res, e); } };
// @route PUT /api/coupons/:id
const updateCoupon = async (req, res) => { try { res.json(await deals.updateCoupon(req.params.id, req.body || {}, req.user, await ctxOf(req))); } catch (e) { fail(res, e); } };
// @route POST /api/coupons/validate — a code against a basket ({ valid: false } answers 400, as before)
const validateCode = async (req, res) => {
try {
const result = await deals.checkCode(req.body || {}, actorOf(req));
res.status(result.valid ? 200 : 400).json(result);
} catch (e) { fail(res, e); }
};
// @route GET /api/coupons/redemptions?eventIds=a,b&from=&to= — the Discounts report
const listRedemptions = async (req, res) => {
try {
const eventIds = String(req.query.eventIds || '').split(',').map(s => s.trim()).filter(Boolean);
res.json(await deals.listRedemptions({ eventIds, from: dateOrNull(req.query.from), to: dateOrNull(req.query.to) }, await listWhere(req, 'event')));
} catch (e) { fail(res, e); }
};
module.exports = { listCoupons, getCoupon, createCoupon, updateCoupon, validateCode, listRedemptions };