@tomei/product
Version:
NestJS package for product module
692 lines • 27.5 kB
JavaScript
"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