feat: implement business pricing service and money utilities

- Added `businessPricing.service.js` to handle business customer pricing logic.
- Introduced `money.js` for money parsing, formatting, and calculations.
- Created `pricing.service.js` to manage variant quoting and promotion application.
- Updated validation schemas in `catalogue.schemas.js` and `inventoryMerchandising.schemas.js` for new pricing and inventory features.
- Implemented cron job for inventory reservation expiry in `inventoryReservationExpiry.cron.js`.
- Created database migrations for catalogue and inventory structures.
- Added unit tests for catalogue localization, validation, and inventory merchandising functionalities.
This commit is contained in:
Sathira Sri Sathara
2026-09-03 19:25:13 +05:30
parent fd4e324571
commit 5643d89236
75 changed files with 663 additions and 1 deletions
+1
View File
@@ -0,0 +1 @@
module.exports=(s,D)=>{const M=s.define("Banner",{id:{type:D.STRING,primaryKey:true},placement:{type:D.STRING(80),allowNull:false},status:{type:D.ENUM("DRAFT","ACTIVE","INACTIVE","ARCHIVED"),allowNull:false,defaultValue:"DRAFT"},starts_at:D.DATE,ends_at:D.DATE,image_upload_id:{type:D.INTEGER,allowNull:false},mobile_image_upload_id:D.INTEGER,target_url:D.STRING,audience_type:{type:D.ENUM("ALL","CUSTOMER","BUSINESS_CUSTOMER"),allowNull:false,defaultValue:"ALL"},business_tier_id:D.STRING,sort_order:{type:D.INTEGER,allowNull:false,defaultValue:0},created_by:{type:D.STRING,allowNull:false},updated_by:D.STRING},{tableName:"banners",timestamps:true});M.associate=db=>M.hasMany(db.BannerTranslation,{foreignKey:"banner_id",as:"translations"});return M;};
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("BannerTranslation",{id:{type:D.STRING,primaryKey:true},banner_id:{type:D.STRING,allowNull:false},locale:{type:D.ENUM("en","si","ta"),allowNull:false},headline:D.STRING(250),subheadline:D.STRING(400),cta_text:D.STRING(100),alt_text:D.STRING(250)},{tableName:"banner_translations",timestamps:true,indexes:[{unique:true,fields:["banner_id","locale"]}]});
+1
View File
@@ -0,0 +1 @@
module.exports=(s,D)=>{const M=s.define("Coupon",{id:{type:D.STRING,primaryKey:true},code:{type:D.STRING(50),allowNull:false,unique:true},promotion_id:{type:D.STRING,allowNull:false},status:{type:D.ENUM("ACTIVE","INACTIVE","ARCHIVED"),allowNull:false,defaultValue:"ACTIVE"},starts_at:D.DATE,expires_at:D.DATE,max_uses:D.INTEGER,max_uses_per_user:D.INTEGER},{tableName:"coupons",timestamps:true,hooks:{beforeValidate:x=>{if(x.code)x.code=x.code.trim().toUpperCase();}}});M.associate=db=>M.belongsTo(db.Promotion,{foreignKey:"promotion_id",as:"promotion"});return M;};
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("Promotion",{id:{type:D.STRING,primaryKey:true},name:{type:D.STRING(180),allowNull:false},type:{type:D.ENUM("PERCENTAGE","FIXED_AMOUNT","FIXED_PRICE"),allowNull:false},status:{type:D.ENUM("DRAFT","ACTIVE","INACTIVE","ARCHIVED"),allowNull:false,defaultValue:"DRAFT"},starts_at:D.DATE,ends_at:D.DATE,priority:{type:D.INTEGER,allowNull:false,defaultValue:0},stackable:{type:D.BOOLEAN,allowNull:false,defaultValue:false},discount_percent:D.DECIMAL(5,2),discount_amount:D.DECIMAL(15,2),fixed_price:D.DECIMAL(15,2),minimum_subtotal:D.DECIMAL(15,2),minimum_quantity:D.INTEGER,customer_type:D.STRING(40),created_by:{type:D.STRING,allowNull:false},updated_by:D.STRING},{tableName:"promotions",timestamps:true});
@@ -0,0 +1 @@
module.exports=(s,D)=>s.define("PromotionTarget",{id:{type:D.STRING,primaryKey:true},promotion_id:{type:D.STRING,allowNull:false},target_type:{type:D.ENUM("ALL","PRODUCT","VARIANT","CATEGORY","BRAND","COLLECTION"),allowNull:false},target_id:D.STRING},{tableName:"promotion_targets",timestamps:true,indexes:[{unique:true,fields:["promotion_id","target_type","target_id"]}]});