UNPKG

@tomei/product

Version:

NestJS package for product module

692 lines 27.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ProductVariant = void 0; const sequelize_1 = require("sequelize"); const product_variant_enum_1 = require("../../enum/product-variant.enum"); const yn_enum_1 = require("../../enum/yn.enum"); const variant_product_repository_1 = require("./variant-product.repository"); const general_1 = require("@tomei/general"); const config_1 = require("@tomei/config"); const product_variant_with_inventory_entity_1 = require("../../entities/product-variant-with-inventory.entity"); const product_entity_1 = require("../../entities/product.entity"); const cuid_1 = require("../../helpers/cuid"); const activity_history_1 = require("@tomei/activity-history"); const privilege_checking_1 = require("../../helpers/privilege-checking"); class ProductVariant extends general_1.ObjectBase { get VariantId() { return this.ObjectId; } set VariantId(VariantId) { this.ObjectId = VariantId; } get Name() { return this._Name; } set Name(Name) { this._Name = Name; } get Description() { return this._Description; } set Description(Description) { this._Description = Description; } get Type() { return this._Type; } set Type(Type) { this._Type = Type; } get ProductId() { return this._ProductId; } set ProductId(ProductId) { this._ProductId = ProductId; } get Level() { return this._Level; } set Level(Level) { this._Level = Level; } get CreatedAt() { return this._CreatedAt; } get UpdatedAt() { return this._UpdatedAt; } get CreatedById() { return this._CreatedById; } get UpdatedById() { return this._UpdatedById; } get UpdatedSSYN() { return this._UpdatedSSYN; } get SKU() { return this._SKU; } get Size() { return this._Size; } get Colour() { return this._Colour; } get MinWeight() { return this._MinWeight; } get MaxWeight() { return this._MaxWeight; } get MinWidth() { return this._MinWidth; } get MaxWidth() { return this._MaxWidth; } get MinHeight() { return this._MinHeight; } get MaxHeight() { return this._MaxHeight; } get MinLength() { return this._MinLength; } get MaxLength() { return this._MaxLength; } get ParentId() { return this._ParentId; } get Status() { return this._Status; } set Status(Status) { this._Status = Status; } async setSKU(SKU) { try { const where = { SKU: SKU, }; if (this.VariantId) { where['VariantId'] = { [sequelize_1.Op.ne]: this.VariantId, }; } const variant = await ProductVariant._Repo.findOne({ where: where, }); if (variant) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg03', 'SKU must be unique.'); } this._SKU = SKU; } catch (error) { throw error; } } async setParentId(ParentId) { try { if (this.Level === 0) { this._ParentId = null; } if (this.Level >= 1) { const variant = await ProductVariant._Repo.findOne({ where: { VariantId: ParentId, }, }); if (!variant) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg04', 'ParentId must be existing Product Variant Id.'); } this._ParentId = ParentId; } } catch (error) { throw error; } } isProductIdMissing() { if (!this.ProductId) { return true; } return false; } async setSize(Size) { try { if (this.isProductIdMissing()) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg02', 'ProductId is missing.'); } const where = { ProductId: this.ProductId, Level: this.Level, ParentId: this.ParentId, }; if (this.VariantId) { where['VariantId'] = { [sequelize_1.Op.ne]: this.VariantId, }; } const variants = await ProductVariant._Repo.findAll({ where, }); variants.forEach((variant) => { if (variant.Size === Size) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg11', 'Duplicate Size found on other variant of the same product.'); } }); this._Size = Size; } catch (error) { throw error; } } async setColour(Colour) { try { if (this.isProductIdMissing()) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg02', 'ProductId is missing.'); } const where = { ProductId: this.ProductId, Level: this.Level, ParentId: this.ParentId, }; if (this.VariantId) { where['VariantId'] = { [sequelize_1.Op.ne]: this.VariantId, }; } const variants = await ProductVariant._Repo.findAll({ where, }); variants.forEach((variant) => { if (variant.Colour === Colour) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg12', 'Duplicate Colour found on other variant of the same product.'); } }); this._Colour = Colour; } catch (error) { throw error; } } async setMinMax(type, min, max) { try { if (this.isProductIdMissing()) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg02', 'ProductId is missing.'); } const where = { ProductId: this.ProductId, Level: this.Level, ParentId: this.ParentId, [sequelize_1.Op.or]: [ { ['Min' + type]: { [sequelize_1.Op.between]: [min[0], max[1]] } }, { ['Max' + type]: { [sequelize_1.Op.between]: [min[0], max[1]] } }, ], }; if (this.VariantId) { where['VariantId'] = { [sequelize_1.Op.ne]: this.VariantId, }; } const variants = await ProductVariant._Repo.findAll({ where, }); if (variants) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg13', 'Min Max fields values cannot overlap.'); } switch (this.Type) { case product_variant_enum_1.ProductVariantType.WEIGHT: this._MinWeight = min; this._MaxWeight = max; break; case product_variant_enum_1.ProductVariantType.WIDTH: this._MinWidth = min; this._MaxWidth = max; break; case product_variant_enum_1.ProductVariantType.HEIGHT: this._MinHeight = min; this._MaxHeight = max; break; case product_variant_enum_1.ProductVariantType.LENGTH: this._MinLength = min; this._MaxLength = max; break; default: break; } } catch (error) { throw error; } } validateType() { switch (this.Type) { case product_variant_enum_1.ProductVariantType.SIZE: if (this.Size === null) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg05', 'Size is compulsory.'); } break; case product_variant_enum_1.ProductVariantType.COLOUR: if (this.Colour === null) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg06', 'Colour is compulsory.'); } break; case product_variant_enum_1.ProductVariantType.WEIGHT: if (this.MinWeight === null || this.MaxWeight === null) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg07', 'MinWeight and MaxWeight fields must be compulsory.'); } break; case product_variant_enum_1.ProductVariantType.WIDTH: if (this.MinWidth === null || this.MaxWidth === null) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg08', 'MinWidth and MaxWidth fields must be compulsory.'); } break; case product_variant_enum_1.ProductVariantType.HEIGHT: if (this.MinHeight === null || this.MaxHeight === null) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg09', 'MinHeight and MaxHeight fields must be compulsory.'); } break; case product_variant_enum_1.ProductVariantType.LENGTH: if (this.MinLength === null || this.MaxLength === null) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg10', 'MinLength and MaxLength fields must be compulsory.'); } break; default: break; } } constructor(variantAttr) { super(); this.ObjectType = 'ProductVariant'; this._Level = 0; this._ParentId = null; this._Status = product_variant_enum_1.ProductVariantStatus.ACTIVE; this._UpdatedSSYN = yn_enum_1.YN.N; if (variantAttr) { this.VariantId = variantAttr.VariantId; this.ProductId = variantAttr.ProductId; this.Name = variantAttr.Name; this.Description = variantAttr.Description; this._SKU = variantAttr.SKU; this._Size = variantAttr.Size; this._Colour = variantAttr.Colour; this.Type = variantAttr.Type; this.Level = variantAttr.Level; this._ParentId = variantAttr.ParentId; this._MinWeight = variantAttr.MinWeight; this._MaxWeight = variantAttr.MaxWeight; this._MinWidth = variantAttr.MinWidth; this._MaxWidth = variantAttr.MaxWidth; this._MinHeight = variantAttr.MinHeight; this._MaxHeight = variantAttr.MaxHeight; this._MinLength = variantAttr.MinLength; this._MaxLength = variantAttr.MaxLength; this._Status = variantAttr.Status; this._UpdatedSSYN = variantAttr.UpdatedSSYN; this._CreatedAt = variantAttr.CreatedAt; this._UpdatedAt = variantAttr.UpdatedAt; this._CreatedById = variantAttr.CreatedById; this._UpdatedById = variantAttr.UpdatedById; } } static async init(variantId, dbTransaction) { try { if (variantId) { const variant = await ProductVariant._Repo.findOne({ where: { VariantId: variantId, }, transaction: dbTransaction, }); if (!variant) { throw new Error(`Variant not found.`); } const data = { VariantId: variant.VariantId, ProductId: variant.ProductId, Name: variant.Name, Description: variant.Description, SKU: variant.SKU, Size: variant.Size, Colour: variant.Colour, Type: variant.Type, Level: variant.Level, ParentId: variant.ParentId, MinWeight: variant.MinWeight, MaxWeight: variant.MaxWeight, MinWidth: variant.MinWidth, MaxWidth: variant.MaxWidth, MinHeight: variant.MinHeight, MaxHeight: variant.MaxHeight, MinLength: variant.MinLength, MaxLength: variant.MaxLength, Status: variant.Status, CreatedById: variant.CreatedById, CreatedAt: variant.CreatedAt, UpdatedById: variant.UpdatedById, UpdatedAt: variant.UpdatedAt, UpdatedSSYN: variant.UpdatedSSYN, }; return new ProductVariant(data); } else { return new ProductVariant(); } } catch (error) { throw error; } } static async findAll(productId, loginUser, page, row, dbTransaction) { try { const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges(systemCode, 'ProductVariant - List'); if (!isPrivileged) { throw new Error('You do not have permission to list product variant.'); } let options = { where: { ProductId: productId, }, include: [ { model: product_variant_with_inventory_entity_1.ProductVariantWithInventoryModel, }, { model: product_entity_1.ProductModel, }, ], transaction: dbTransaction, }; if (page && row) { options = Object.assign(Object.assign({}, options), { offset: (page - 1) * row, limit: row, order: [['CreatedAt', 'DESC']] }); } const productBrand = await this._Repo.findAndCountAll(options); const data = productBrand.rows.map((variant) => { return { VariantId: variant.VariantId, ProductId: variant.ProductId, Name: variant.Name, Description: variant.Description, SKU: variant.SKU, Size: variant.Size, Colour: variant.Colour, Type: variant.Type, Level: variant.Level, ParentId: variant.ParentId, MinWeight: variant.MinWeight, MaxWeight: variant.MaxWeight, MinWidth: variant.MinWidth, MaxWidth: variant.MaxWidth, MinHeight: variant.MinHeight, MaxHeight: variant.MaxHeight, MinLength: variant.MinLength, MaxLength: variant.MaxLength, Status: variant.Status, CreatedById: variant.CreatedById, CreatedAt: variant.CreatedAt, UpdatedById: variant.UpdatedById, UpdatedAt: variant.UpdatedAt, UpdatedSSYN: variant.UpdatedSSYN, TotalUnitsAvailable: variant.ProductVariantWithInventory.TotalUnitsAvailable, TotalUnitsInCurrentOrder: variant.ProductVariantWithInventory.TotalUnitsInCurrentOrder, TotalUnitsSold: variant.ProductVariantWithInventory.TotalUnitsSold, TotalUnitsReserved: variant.ProductVariantWithInventory.TotalUnitsReserved, TotalUnitsInTransit: variant.ProductVariantWithInventory.TotalUnitsInTransit, TotalUnitsOnConsignment: variant.ProductVariantWithInventory.TotalUnitsOnConsignment, TotalUnitsBackOrdered: variant.ProductVariantWithInventory.TotalUnitsBackOrdered, TotalUnitsPreOrdered: variant.ProductVariantWithInventory.TotalUnitsPreOrdered, StockLowAlertLevel: variant.ProductVariantWithInventory.StockLowAlertLevel, StockReorderLevel: variant.ProductVariantWithInventory.StockReorderLevel, BufferStockLevel: variant.ProductVariantWithInventory.BufferStockLevel, Products: Object.assign({}, variant.Product), }; }); return { count: productBrand.count, rows: data, }; } catch (error) { throw error; } } async create(loginUser, dbTransaction) { try { const systemCode = config_1.ApplicationConfig.getComponentConfigValue('system-code'); const isPrivileged = await loginUser.checkPrivileges(systemCode, 'ProductVariant - Create'); if (!isPrivileged) { throw new Error('You do not have permission to create product variant.'); } if (!this.ProductId) { throw new general_1.ClassError('ProductVariant', 'ProductVariantErrMsg02', 'ProductId is missing.'); } this.validateType(); this.VariantId = (0, cuid_1.default)(); this._CreatedAt = new Date(); this._UpdatedAt = new Date(); this._CreatedById = loginUser.ObjectId; this._UpdatedById = loginUser.ObjectId; const data = { VariantId: this.VariantId, ProductId: this.ProductId, Name: this.Name, Description: this.Description, SKU: this.SKU, Size: this.Size, Colour: this.Colour, Type: this.Type, Level: this.Level, ParentId: this.ParentId, MinWeight: this.MinWeight, MaxWeight: this.MaxWeight, MinWidth: this.MinWidth, MaxWidth: this.MaxWidth, MinHeight: this.MinHeight, MaxHeight: this.MaxHeight, MinLength: this.MinLength, MaxLength: this.MaxLength, Status: this.Status, CreatedById: this.CreatedById, CreatedAt: this.CreatedAt, UpdatedById: this.UpdatedById, UpdatedAt: this.UpdatedAt, UpdatedSSYN: this.UpdatedSSYN, }; await ProductVariant._Repo.create(data, { transaction: dbTransaction, }); const activity = new activity_history_1.Activity(); activity.ActivityId = (0, cuid_1.default)(); activity.Action = activity_history_1.ActionEnum.CREATE; activity.Description = 'Add new product variant'; activity.EntityType = 'ProductVariant'; activity.EntityId = data.VariantId; activity.EntityValueBefore = JSON.stringify({}); activity.EntityValueAfter = JSON.stringify(data); await activity.create(loginUser.ObjectId, dbTransaction); return this; } catch (error) { throw error; } } async update(payload, loginUser, dbTransaction) { try { await (0, privilege_checking_1.default)(loginUser, 'ProductVariant - Update', 'You do not have permission to update product variant.'); const entityValueBefore = { VariantId: this.VariantId, ProductId: this.ProductId, Name: this.Name, Description: this.Description, SKU: this.SKU, Size: this.Size, Colour: this.Colour, Type: this.Type, Level: this.Level, ParentId: this.ParentId, MinWeight: this.MinWeight, MaxWeight: this.MaxWeight, MinWidth: this.MinWidth, MaxWidth: this.MaxWidth, MinHeight: this.MinHeight, MaxHeight: this.MaxHeight, MinLength: this.MinLength, MaxLength: this.MaxLength, UpdatedSSYN: this.UpdatedSSYN, Status: this.Status, CreatedById: this.CreatedById, CreatedAt: this.CreatedAt, UpdatedById: this.UpdatedById, UpdatedAt: this.UpdatedAt, }; this.Name = payload.Name; this.Description = payload.Description; if (this.SKU !== payload.SKU) { await this.setSKU(payload.SKU); } this.Level = payload.Level; if (this.ParentId !== payload.ParentId) { await this.setParentId(payload.ParentId); } const isTypeChanged = this.Type !== payload.Type; this.Type = payload.Type; if (isTypeChanged) { this._Size = null; this._Colour = null; this._MinWeight = null; this._MaxWeight = null; this._MinWidth = null; this._MaxWidth = null; this._MinHeight = null; this._MaxHeight = null; this._MinLength = null; this._MaxLength = null; } switch (this.Type) { case product_variant_enum_1.ProductVariantType.COLOUR: await this.setColour(payload.Colour); break; case product_variant_enum_1.ProductVariantType.SIZE: await this.setSize(payload.Size); break; case product_variant_enum_1.ProductVariantType.HEIGHT: await this.setMinMax(this.Type, payload.MinWeight, payload.MaxHeight); break; case product_variant_enum_1.ProductVariantType.LENGTH: await this.setMinMax(this.Type, payload.MinHeight, payload.MaxHeight); break; case product_variant_enum_1.ProductVariantType.WIDTH: await this.setMinMax(this.Type, payload.MinHeight, payload.MaxHeight); break; case product_variant_enum_1.ProductVariantType.WEIGHT: await this.setMinMax(this.Type, payload.MinHeight, payload.MaxHeight); break; default: break; } this._UpdatedAt = new Date(); this._CreatedById = loginUser.ObjectId; const data = { Name: this.Name, Description: this.Description, SKU: this.SKU, Size: this.Size, Colour: this.Colour, Type: this.Type, Level: this.Level, ParentId: this.ParentId, MinWeight: this.MinWeight, MaxWeight: this.MaxWeight, MinWidth: this.MinWidth, MaxWidth: this.MaxWidth, MinHeight: this.MinHeight, MaxHeight: this.MaxHeight, MinLength: this.MinLength, MaxLength: this.MaxLength, UpdatedSSYN: this.UpdatedSSYN, Status: this.Status, CreatedById: this.CreatedById, CreatedAt: this.CreatedAt, UpdatedById: this.UpdatedById, UpdatedAt: this.UpdatedAt, }; await ProductVariant._Repo.update(data, { where: { VariantId: this.VariantId, }, transaction: dbTransaction, }); data.VariantId = this.VariantId; data.ProductId = this.ProductId; const activity = new activity_history_1.Activity(); activity.ActivityId = (0, cuid_1.default)(); activity.Action = activity_history_1.ActionEnum.UPDATE; activity.Description = 'Update product variant'; activity.EntityType = 'ProductVariant'; activity.EntityId = data.VariantId; activity.EntityValueBefore = JSON.stringify(entityValueBefore); activity.EntityValueAfter = JSON.stringify(data); await activity.create(loginUser.ObjectId, dbTransaction); return this; } catch (error) { throw error; } } async delete(loginUser, dbTransaction) { try { await (0, privilege_checking_1.default)(loginUser, 'ProductVariant - Delete', 'You do not have permission to delete product variant.'); const entityValueBefore = { VariantId: this.VariantId, ProductId: this.ProductId, Name: this.Name, Description: this.Description, SKU: this.SKU, Size: this.Size, Colour: this.Colour, Type: this.Type, Level: this.Level, ParentId: this.ParentId, MinWeight: this.MinWeight, MaxWeight: this.MaxWeight, MinWidth: this.MinWidth, MaxWidth: this.MaxWidth, MinHeight: this.MinHeight, MaxHeight: this.MaxHeight, MinLength: this.MinLength, MaxLength: this.MaxLength, UpdatedSSYN: this.UpdatedSSYN, Status: this.Status, CreatedById: this.CreatedById, CreatedAt: this.CreatedAt, UpdatedById: this.UpdatedById, UpdatedAt: this.UpdatedAt, }; await ProductVariant._Repo.delete(this.VariantId, dbTransaction); const activity = new activity_history_1.Activity(); activity.ActivityId = (0, cuid_1.default)(); activity.Action = activity_history_1.ActionEnum.DELETE; activity.Description = 'Delete product variant'; activity.EntityType = 'ProductVariant'; activity.EntityId = this.VariantId; activity.EntityValueBefore = JSON.stringify(entityValueBefore); activity.EntityValueAfter = JSON.stringify({}); await activity.create(loginUser.ObjectId, dbTransaction); return { MessageCode: 'ProductVariantDeleted', Message: 'Product Variant is deleted.', }; } catch (error) { throw error; } } } exports.ProductVariant = ProductVariant; ProductVariant._Repo = new variant_product_repository_1.ProductVariantRepository(); //# sourceMappingURL=variant-product.js.map