307 lines
6.0 KiB
TypeScript
307 lines
6.0 KiB
TypeScript
import { Router } from 'express';
|
|
import { authMiddleware } from '../../auth/middleware/auth.middleware';
|
|
import { branchMiddleware } from '../../branches/middleware/branch.middleware';
|
|
import { validateRequest } from '../../../shared/middleware/validation.middleware';
|
|
import { requirePermissions } from '../../../shared/middleware/permissions.middleware';
|
|
import {
|
|
createPromotionSchema,
|
|
updatePromotionSchema,
|
|
addPromotionProductsSchema,
|
|
listPromotionsQuerySchema,
|
|
createCouponSchema,
|
|
updateCouponSchema,
|
|
generateBulkCouponsSchema,
|
|
redeemCouponSchema,
|
|
validateCouponSchema,
|
|
reverseRedemptionSchema,
|
|
listCouponsQuerySchema,
|
|
calculatePricesSchema,
|
|
} from '../validation/pricing.schema';
|
|
import * as pricingController from '../controllers/pricing.controller';
|
|
|
|
const router = Router();
|
|
|
|
// All routes require authentication
|
|
router.use(authMiddleware);
|
|
|
|
// ==================== PRICE ENGINE ROUTES ====================
|
|
|
|
/**
|
|
* Calculate prices for cart/order items
|
|
* Requires branch context
|
|
*/
|
|
router.post(
|
|
'/calculate',
|
|
branchMiddleware,
|
|
validateRequest(calculatePricesSchema),
|
|
requirePermissions('pricing:calculate'),
|
|
pricingController.calculatePrices
|
|
);
|
|
|
|
/**
|
|
* Validate a coupon code
|
|
* Requires branch context
|
|
*/
|
|
router.post(
|
|
'/validate-coupon',
|
|
branchMiddleware,
|
|
validateRequest(validateCouponSchema),
|
|
requirePermissions('pricing:validate'),
|
|
pricingController.validateCoupon
|
|
);
|
|
|
|
/**
|
|
* Get active promotions for current branch
|
|
* Requires branch context
|
|
*/
|
|
router.get(
|
|
'/active-promotions',
|
|
branchMiddleware,
|
|
requirePermissions('pricing:view'),
|
|
pricingController.getActivePromotions
|
|
);
|
|
|
|
// ==================== PROMOTION ROUTES ====================
|
|
|
|
/**
|
|
* List promotions with filters
|
|
*/
|
|
router.get(
|
|
'/promotions',
|
|
validateRequest(listPromotionsQuerySchema, 'query'),
|
|
requirePermissions('promotions:view'),
|
|
pricingController.listPromotions
|
|
);
|
|
|
|
/**
|
|
* Get promotion by ID
|
|
*/
|
|
router.get(
|
|
'/promotions/:id',
|
|
requirePermissions('promotions:view'),
|
|
pricingController.getPromotion
|
|
);
|
|
|
|
/**
|
|
* Create a new promotion
|
|
*/
|
|
router.post(
|
|
'/promotions',
|
|
validateRequest(createPromotionSchema),
|
|
requirePermissions('promotions:create'),
|
|
pricingController.createPromotion
|
|
);
|
|
|
|
/**
|
|
* Update a promotion
|
|
*/
|
|
router.put(
|
|
'/promotions/:id',
|
|
validateRequest(updatePromotionSchema),
|
|
requirePermissions('promotions:update'),
|
|
pricingController.updatePromotion
|
|
);
|
|
|
|
/**
|
|
* Activate a promotion
|
|
*/
|
|
router.post(
|
|
'/promotions/:id/activate',
|
|
requirePermissions('promotions:activate'),
|
|
pricingController.activatePromotion
|
|
);
|
|
|
|
/**
|
|
* Pause a promotion
|
|
*/
|
|
router.post(
|
|
'/promotions/:id/pause',
|
|
requirePermissions('promotions:update'),
|
|
pricingController.pausePromotion
|
|
);
|
|
|
|
/**
|
|
* End a promotion
|
|
*/
|
|
router.post(
|
|
'/promotions/:id/end',
|
|
requirePermissions('promotions:update'),
|
|
pricingController.endPromotion
|
|
);
|
|
|
|
/**
|
|
* Cancel a promotion
|
|
*/
|
|
router.post(
|
|
'/promotions/:id/cancel',
|
|
requirePermissions('promotions:delete'),
|
|
pricingController.cancelPromotion
|
|
);
|
|
|
|
/**
|
|
* Add products to a promotion
|
|
*/
|
|
router.post(
|
|
'/promotions/:id/products',
|
|
validateRequest(addPromotionProductsSchema),
|
|
requirePermissions('promotions:update'),
|
|
pricingController.addPromotionProducts
|
|
);
|
|
|
|
/**
|
|
* Remove product from a promotion
|
|
*/
|
|
router.delete(
|
|
'/promotions/:id/products/:productId',
|
|
requirePermissions('promotions:update'),
|
|
pricingController.removePromotionProduct
|
|
);
|
|
|
|
/**
|
|
* Delete a promotion (soft delete)
|
|
*/
|
|
router.delete(
|
|
'/promotions/:id',
|
|
requirePermissions('promotions:delete'),
|
|
pricingController.deletePromotion
|
|
);
|
|
|
|
// ==================== COUPON ROUTES ====================
|
|
|
|
/**
|
|
* List coupons with filters
|
|
*/
|
|
router.get(
|
|
'/coupons',
|
|
validateRequest(listCouponsQuerySchema, 'query'),
|
|
requirePermissions('coupons:view'),
|
|
pricingController.listCoupons
|
|
);
|
|
|
|
/**
|
|
* Get coupon by ID
|
|
*/
|
|
router.get(
|
|
'/coupons/:id',
|
|
requirePermissions('coupons:view'),
|
|
pricingController.getCoupon
|
|
);
|
|
|
|
/**
|
|
* Get coupon by code
|
|
*/
|
|
router.get(
|
|
'/coupons/code/:code',
|
|
requirePermissions('coupons:view'),
|
|
pricingController.getCouponByCode
|
|
);
|
|
|
|
/**
|
|
* Create a new coupon
|
|
*/
|
|
router.post(
|
|
'/coupons',
|
|
validateRequest(createCouponSchema),
|
|
requirePermissions('coupons:create'),
|
|
pricingController.createCoupon
|
|
);
|
|
|
|
/**
|
|
* Generate bulk coupons
|
|
*/
|
|
router.post(
|
|
'/coupons/bulk',
|
|
validateRequest(generateBulkCouponsSchema),
|
|
requirePermissions('coupons:create'),
|
|
pricingController.generateBulkCoupons
|
|
);
|
|
|
|
/**
|
|
* Update a coupon
|
|
*/
|
|
router.put(
|
|
'/coupons/:id',
|
|
validateRequest(updateCouponSchema),
|
|
requirePermissions('coupons:update'),
|
|
pricingController.updateCoupon
|
|
);
|
|
|
|
/**
|
|
* Activate a coupon
|
|
*/
|
|
router.post(
|
|
'/coupons/:id/activate',
|
|
requirePermissions('coupons:activate'),
|
|
pricingController.activateCoupon
|
|
);
|
|
|
|
/**
|
|
* Deactivate a coupon
|
|
*/
|
|
router.post(
|
|
'/coupons/:id/deactivate',
|
|
requirePermissions('coupons:update'),
|
|
pricingController.deactivateCoupon
|
|
);
|
|
|
|
/**
|
|
* Redeem a coupon by ID
|
|
*/
|
|
router.post(
|
|
'/coupons/:id/redeem',
|
|
branchMiddleware,
|
|
validateRequest(redeemCouponSchema),
|
|
requirePermissions('coupons:redeem'),
|
|
pricingController.redeemCoupon
|
|
);
|
|
|
|
/**
|
|
* Redeem coupon by code
|
|
*/
|
|
router.post(
|
|
'/coupons/redeem',
|
|
branchMiddleware,
|
|
validateRequest(redeemCouponSchema),
|
|
requirePermissions('coupons:redeem'),
|
|
pricingController.redeemCouponByCode
|
|
);
|
|
|
|
/**
|
|
* Reverse a coupon redemption
|
|
*/
|
|
router.post(
|
|
'/coupons/redemptions/:redemptionId/reverse',
|
|
validateRequest(reverseRedemptionSchema),
|
|
requirePermissions('coupons:reverse'),
|
|
pricingController.reverseRedemption
|
|
);
|
|
|
|
/**
|
|
* Get coupon redemption history
|
|
*/
|
|
router.get(
|
|
'/coupons/:id/redemptions',
|
|
requirePermissions('coupons:view'),
|
|
pricingController.getCouponRedemptions
|
|
);
|
|
|
|
/**
|
|
* Get coupon statistics
|
|
*/
|
|
router.get(
|
|
'/coupons/:id/stats',
|
|
requirePermissions('coupons:view'),
|
|
pricingController.getCouponStats
|
|
);
|
|
|
|
/**
|
|
* Delete a coupon (soft delete)
|
|
*/
|
|
router.delete(
|
|
'/coupons/:id',
|
|
requirePermissions('coupons:delete'),
|
|
pricingController.deleteCoupon
|
|
);
|
|
|
|
export default router;
|