@b2y/ecommerce-common 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/constants/AppConstants.js +4 -0
- package/constants/ReportConstants.js +15 -0
- package/constants/StatusMessageConstants.js +21 -0
- package/dbconnection/Connect.js +417 -0
- package/enum/AddressTypeEnum.js +7 -0
- package/enum/BooleanEnum.js +5 -0
- package/enum/EntityTypeEnum.js +10 -0
- package/enum/GenderEnum.js +7 -0
- package/enum/NotificationStatusEnum.js +6 -0
- package/enum/NotificationTypeEnum.js +10 -0
- package/enum/OrderStatusEnum.js +8 -0
- package/enum/PaymentMethodEnum.js +7 -0
- package/enum/PaymentStatusEnum.js +7 -0
- package/enum/PaymentTypeEnum.js +7 -0
- package/enum/PlatformEnum.js +5 -0
- package/enum/RegistrationStatusEnum.js +6 -0
- package/enum/SortByEnum.js +8 -0
- package/index.js +22 -0
- package/model/Address.js +114 -0
- package/model/AttributeType.js +51 -0
- package/model/AttributeValue.js +65 -0
- package/model/Banner.js +79 -0
- package/model/Brand.js +76 -0
- package/model/Cart.js +77 -0
- package/model/Category.js +73 -0
- package/model/CategoryAttributeType.js +63 -0
- package/model/City.js +49 -0
- package/model/Colour.js +53 -0
- package/model/Country.js +47 -0
- package/model/Customer.js +95 -0
- package/model/DeviceToken.js +52 -0
- package/model/Document.js +71 -0
- package/model/DynamicUIComponent.js +53 -0
- package/model/Feedback.js +80 -0
- package/model/Inventory.js +84 -0
- package/model/NotificationHistory.js +68 -0
- package/model/Order.js +95 -0
- package/model/OrderItem.js +99 -0
- package/model/OrderItemHistory.js +70 -0
- package/model/OrderStatus.js +49 -0
- package/model/Payment.js +101 -0
- package/model/PaymentMethod.js +37 -0
- package/model/PaymentStatus.js +37 -0
- package/model/PaymentType.js +37 -0
- package/model/Permission.js +55 -0
- package/model/Product.js +83 -0
- package/model/ProductGroup.js +48 -0
- package/model/ProductSpecification.js +66 -0
- package/model/ProductVariant.js +76 -0
- package/model/ProductVariantAttribute.js +59 -0
- package/model/Role.js +61 -0
- package/model/RolePermissionMapping.js +63 -0
- package/model/SpecificationType.js +42 -0
- package/model/State.js +56 -0
- package/model/Store.js +117 -0
- package/model/StoreUserMapping.js +44 -0
- package/model/Tenant.js +91 -0
- package/model/User.js +150 -0
- package/model/WishList.js +63 -0
- package/package.json +27 -0
- package/utility/AppUtil.js +58 -0
- package/utility/DateUtil.js +55 -0
- package/utility/ExcelUtil.js +125 -0
- package/utility/OrderTimeFilterUtil.js +86 -0
- package/utility/QueryUtil.js +262 -0
- package/utility/Razorpay.js +67 -0
- package/utility/VariantPriceUtil.js +55 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
|
|
2
|
+
const AppUtil = require('../utility/AppUtil');
|
|
3
|
+
const StatusMessage = require('../constants/StatusMessageConstants');
|
|
4
|
+
const DateUtil = require('../utility/DateUtil');
|
|
5
|
+
const PaymentStatusEnum = require('../enum/PaymentStatusEnum');
|
|
6
|
+
const PaymentTypeEnum = require('../enum/PaymentTypeEnum');
|
|
7
|
+
const PaymentMethodEnum = require('../enum/PaymentMethodEnum');
|
|
8
|
+
class QueryUtil {
|
|
9
|
+
static storeWhereClause(filters, tenantID, Sequelize, logger) {
|
|
10
|
+
const { startDate, endDate, IsActive, searchText } = filters;
|
|
11
|
+
let storeWhereClause = {};
|
|
12
|
+
// Date range filter
|
|
13
|
+
if (startDate && !DateUtil.isValidDate(startDate)) {
|
|
14
|
+
logger.warn("invalid start date");
|
|
15
|
+
throw new Error(StatusMessage.INVALID_START_DATE);
|
|
16
|
+
}
|
|
17
|
+
if (endDate && !DateUtil.isValidDate(endDate)) {
|
|
18
|
+
logger.warn("invalid end date");
|
|
19
|
+
throw new Error(StatusMessage.INVALID_END_DATE);
|
|
20
|
+
}
|
|
21
|
+
if (startDate && endDate) {
|
|
22
|
+
storeWhereClause.CreatedAt = {
|
|
23
|
+
[Sequelize.Op.between]: [new Date(startDate), new Date(endDate)],
|
|
24
|
+
};
|
|
25
|
+
} else if (startDate) {
|
|
26
|
+
storeWhereClause.CreatedAt = { [Sequelize.Op.gte]: new Date(startDate) };
|
|
27
|
+
} else if (endDate) {
|
|
28
|
+
storeWhereClause.CreatedAt = { [Sequelize.Op.lte]: new Date(endDate) };
|
|
29
|
+
}
|
|
30
|
+
if (IsActive) {
|
|
31
|
+
const isActiveValue = AppUtil.parseIsActive(IsActive);
|
|
32
|
+
if (isActiveValue === undefined) {
|
|
33
|
+
logger.warn("invalid IsActive status");
|
|
34
|
+
throw new Error(StatusMessage.INVALID_ISACTIVE_STATUS);
|
|
35
|
+
}
|
|
36
|
+
storeWhereClause.IsActive = isActiveValue;
|
|
37
|
+
}
|
|
38
|
+
// Tenant ID
|
|
39
|
+
if (tenantID) storeWhereClause.TenantID = tenantID;
|
|
40
|
+
if (searchText) {
|
|
41
|
+
storeWhereClause[Sequelize.Op.or] = [
|
|
42
|
+
{ StoreName: { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
43
|
+
{ AddressLine1: { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
44
|
+
{ AddressLine2: { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
45
|
+
{ "$City.CityName$": { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
46
|
+
];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return storeWhereClause;
|
|
50
|
+
}
|
|
51
|
+
static orderWhereClause(filters, tenantID, Sequelize, logger) {
|
|
52
|
+
const { startDate, endDate, searchText, paymentStatus } = filters;
|
|
53
|
+
let orderWhereClause = {};
|
|
54
|
+
let paymentStatusWhere = {};
|
|
55
|
+
if (tenantID) orderWhereClause.TenantID = tenantID;
|
|
56
|
+
if (startDate && !DateUtil.isValidDate(startDate)) {
|
|
57
|
+
logger.warn("invalid start date");
|
|
58
|
+
throw new Error(StatusMessage.INVALID_START_DATE);
|
|
59
|
+
}
|
|
60
|
+
if (endDate && !DateUtil.isValidDate(endDate)) {
|
|
61
|
+
logger.warn("invalid end date");
|
|
62
|
+
throw new Error(StatusMessage.INVALID_END_DATE);
|
|
63
|
+
}
|
|
64
|
+
if (searchText) {
|
|
65
|
+
orderWhereClause[Sequelize.Op.or] = [
|
|
66
|
+
{ OrderRefID: { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
67
|
+
{ "$Customer.FirstName$": { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
if (paymentStatus) {
|
|
71
|
+
const validPaymentStatus = new Set(Object.values(PaymentStatusEnum));
|
|
72
|
+
if (!validPaymentStatus.has(paymentStatus)) {
|
|
73
|
+
logger.warn("invalid payment status")
|
|
74
|
+
throw new Error(StatusMessage.INVALID_PAYMENT_STATUS);
|
|
75
|
+
}
|
|
76
|
+
paymentStatusWhere.PaymentStatusName = paymentStatus;
|
|
77
|
+
}
|
|
78
|
+
if (startDate && endDate) {
|
|
79
|
+
orderWhereClause.OrderDate = {
|
|
80
|
+
[Sequelize.Op.between]: [new Date(startDate), new Date(endDate)],
|
|
81
|
+
};
|
|
82
|
+
} else if (startDate) {
|
|
83
|
+
orderWhereClause.OrderDate = { [Sequelize.Op.gte]: new Date(startDate) };
|
|
84
|
+
} else if (endDate) {
|
|
85
|
+
orderWhereClause.OrderDate = { [Sequelize.Op.lte]: new Date(endDate) };
|
|
86
|
+
}
|
|
87
|
+
return { orderWhereClause, includeWhere: { paymentStatusWhere } };
|
|
88
|
+
}
|
|
89
|
+
static paymentWhereClause(filters, tenantID, Sequelize, logger) {
|
|
90
|
+
const {
|
|
91
|
+
paymentStatus,
|
|
92
|
+
searchText,
|
|
93
|
+
paymentType,
|
|
94
|
+
paymentMethod,
|
|
95
|
+
startDate,
|
|
96
|
+
endDate,
|
|
97
|
+
} = filters;
|
|
98
|
+
let paymentWhereClause = {};
|
|
99
|
+
let paymentStatusWhere = {};
|
|
100
|
+
let paymentTypeWhere = {};
|
|
101
|
+
let paymentMethodWhere = {};
|
|
102
|
+
if (tenantID) paymentWhereClause.TenantID = tenantID;
|
|
103
|
+
if (startDate && !DateUtil.isValidDate(startDate)) {
|
|
104
|
+
logger.warn("invalid start date");
|
|
105
|
+
throw new Error(StatusMessage.INVALID_START_DATE);
|
|
106
|
+
}
|
|
107
|
+
if (endDate && !DateUtil.isValidDate(endDate)) {
|
|
108
|
+
logger.warn("invalid end date");
|
|
109
|
+
throw new Error(StatusMessage.INVALID_END_DATE);
|
|
110
|
+
}
|
|
111
|
+
if (searchText) {
|
|
112
|
+
paymentWhereClause[Sequelize.Op.or] = [
|
|
113
|
+
{ "$Order.OrderRefID$": { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
114
|
+
{ PaymentRefID: { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
115
|
+
];
|
|
116
|
+
}
|
|
117
|
+
if (paymentStatus) {
|
|
118
|
+
const validPaymentStatus = new Set(Object.values(PaymentStatusEnum));
|
|
119
|
+
if (!validPaymentStatus.has(paymentStatus)) {
|
|
120
|
+
logger.warn("invalid payment status");
|
|
121
|
+
throw new Error(StatusMessage.PAYMENT_STATUS_INVALID);
|
|
122
|
+
}
|
|
123
|
+
paymentStatusWhere.PaymentStatusName = paymentStatus;
|
|
124
|
+
}
|
|
125
|
+
if (paymentType) {
|
|
126
|
+
const validPaymentType = new Set(Object.values(PaymentTypeEnum));
|
|
127
|
+
if (!validPaymentType.has(paymentType)) {
|
|
128
|
+
logger.warn("invalid payment type");
|
|
129
|
+
throw new Error(StatusMessage.PAYMENT_TYPE_INVALID);
|
|
130
|
+
}
|
|
131
|
+
paymentTypeWhere.PaymentTypeName = paymentType;
|
|
132
|
+
}
|
|
133
|
+
if (paymentMethod) {
|
|
134
|
+
const validPaymentMethod = new Set(Object.values(PaymentMethodEnum));
|
|
135
|
+
if (!validPaymentMethod.has(paymentMethod)) {
|
|
136
|
+
logger.warn("invalid payment method")
|
|
137
|
+
throw new Error(StatusMessage.PAYMENT_METHOD_INVALID);
|
|
138
|
+
}
|
|
139
|
+
paymentMethodWhere.PaymentMethodName = paymentMethod;
|
|
140
|
+
}
|
|
141
|
+
if (startDate && endDate) {
|
|
142
|
+
paymentWhereClause.PaymentDate = {
|
|
143
|
+
[Sequelize.Op.between]: [new Date(startDate), new Date(endDate)],
|
|
144
|
+
};
|
|
145
|
+
} else if (startDate) {
|
|
146
|
+
paymentWhereClause.PaymentDate = { [Sequelize.Op.gte]: new Date(startDate) };
|
|
147
|
+
} else if (endDate) {
|
|
148
|
+
paymentWhereClause.PaymentDate = { [Sequelize.Op.lte]: new Date(endDate) };
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
paymentWhereClause,
|
|
152
|
+
includeWhere: {
|
|
153
|
+
paymentStatusWhere,
|
|
154
|
+
paymentMethodWhere,
|
|
155
|
+
paymentTypeWhere,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
static customerWhereClause(filters, tenantID, Sequelize, logger) {
|
|
160
|
+
const { searchText, startDate, endDate } = filters;
|
|
161
|
+
let customerWhereClause = {};
|
|
162
|
+
if (startDate && !DateUtil.isValidDate(startDate)) {
|
|
163
|
+
logger.warn("invalid start date")
|
|
164
|
+
throw new Error(StatusMessage.INVALID_START_DATE);
|
|
165
|
+
}
|
|
166
|
+
if (endDate && !DateUtil.isValidDate(endDate)) {
|
|
167
|
+
logger.warn("invalid end date");
|
|
168
|
+
throw new Error(StatusMessage.INVALID_END_DATE);
|
|
169
|
+
}
|
|
170
|
+
if (startDate && endDate) {
|
|
171
|
+
customerWhereClause.CreatedAt = {
|
|
172
|
+
[Sequelize.Op.between]: [new Date(startDate), new Date(endDate)],
|
|
173
|
+
};
|
|
174
|
+
} else if (startDate) {
|
|
175
|
+
customerWhereClause.CreatedAt = { [Sequelize.Op.gte]: new Date(startDate) };
|
|
176
|
+
} else if (endDate) {
|
|
177
|
+
customerWhereClause.CreatedAt = { [Sequelize.Op.lte]: new Date(endDate) };
|
|
178
|
+
}
|
|
179
|
+
if (tenantID) customerWhereClause.TenantID = tenantID;
|
|
180
|
+
if (searchText) {
|
|
181
|
+
customerWhereClause[Sequelize.Op.or] = [
|
|
182
|
+
{ FirstName: { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
183
|
+
{ LastName: { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
184
|
+
];
|
|
185
|
+
}
|
|
186
|
+
return customerWhereClause;
|
|
187
|
+
}
|
|
188
|
+
static productWhereClause(filters, tenantID, Sequelize, logger) {
|
|
189
|
+
const { brandId, categoryId, IsActive, searchText, startDate, endDate } =
|
|
190
|
+
filters;
|
|
191
|
+
const brandWhere = {};
|
|
192
|
+
const categoryWhere = {};
|
|
193
|
+
const productWhereClause = {};
|
|
194
|
+
const parseIds = (idParam) => {
|
|
195
|
+
if (!idParam) return null;
|
|
196
|
+
if (Array.isArray(idParam))
|
|
197
|
+
return idParam.map((id) => id.toString().trim()).filter((id) => id);
|
|
198
|
+
return idParam
|
|
199
|
+
.toString()
|
|
200
|
+
.split(",")
|
|
201
|
+
.map((id) => id.trim())
|
|
202
|
+
.filter((id) => id);
|
|
203
|
+
};
|
|
204
|
+
if (tenantID) {
|
|
205
|
+
productWhereClause.TenantID = tenantID;
|
|
206
|
+
brandWhere.TenantID = tenantID;
|
|
207
|
+
categoryWhere.TenantID = tenantID;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (startDate && !DateUtil.isValidDate(startDate)) {
|
|
211
|
+
logger.warn("invalid start date");
|
|
212
|
+
throw new Error(StatusMessage.INVALID_START_DATE);
|
|
213
|
+
}
|
|
214
|
+
if (endDate && !DateUtil.isValidDate(endDate)) {
|
|
215
|
+
logger.warn("invalid end date");
|
|
216
|
+
throw new Error(StatusMessage.INVALID_END_DATE);
|
|
217
|
+
}
|
|
218
|
+
if (startDate && endDate) {
|
|
219
|
+
productWhereClause.CreatedAt = {
|
|
220
|
+
[Sequelize.Op.between]: [new Date(startDate), new Date(endDate)],
|
|
221
|
+
};
|
|
222
|
+
} else if (startDate) {
|
|
223
|
+
productWhereClause.CreatedAt = { [Sequelize.Op.gte]: new Date(startDate) };
|
|
224
|
+
} else if (endDate) {
|
|
225
|
+
productWhereClause.CreatedAt = { [Sequelize.Op.lte]: new Date(endDate) };
|
|
226
|
+
}
|
|
227
|
+
if (searchText) {
|
|
228
|
+
productWhereClause[Sequelize.Op.or] = [
|
|
229
|
+
{ ProductName: { [Sequelize.Op.iLike]: `%${searchText}%` } },
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
if (IsActive) {
|
|
233
|
+
const isActiveValue = AppUtil.parseIsActive(IsActive);
|
|
234
|
+
if (isActiveValue === undefined) {
|
|
235
|
+
logger.warn("invalid IsActive status");
|
|
236
|
+
throw new Error(StatusMessage.INVALID_ISACTIVE_STATUS);
|
|
237
|
+
}
|
|
238
|
+
productWhereClause.IsActive = isActiveValue;
|
|
239
|
+
}
|
|
240
|
+
if (brandId) {
|
|
241
|
+
const brandIds = parseIds(brandId);
|
|
242
|
+
brandWhere.BrandID = { [Sequelize.Op.in]: brandIds };
|
|
243
|
+
}
|
|
244
|
+
if (categoryId) {
|
|
245
|
+
const categoryIds = parseIds(categoryId);
|
|
246
|
+
categoryWhere.CategoryID = { [Sequelize.Op.in]: categoryIds };
|
|
247
|
+
}
|
|
248
|
+
return {
|
|
249
|
+
productWhereClause,
|
|
250
|
+
includeWhere: { brandWhere, categoryWhere },
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
static getDefaultOptions(whereClause, order = [['CreatedAt', 'DESC']]) {
|
|
255
|
+
return {
|
|
256
|
+
where: whereClause,
|
|
257
|
+
order: order
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
module.exports = QueryUtil;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const Razorpay = require('razorpay');
|
|
2
|
+
const crypto = require('crypto');
|
|
3
|
+
const StatusMessage = require('../constants/StatusMessageConstants');
|
|
4
|
+
class RazorpayUtil {
|
|
5
|
+
constructor(razorpayKeys, logger) {
|
|
6
|
+
this.logger = logger;
|
|
7
|
+
this.instance = new Razorpay({
|
|
8
|
+
key_id: razorpayKeys.keyId,
|
|
9
|
+
key_secret: razorpayKeys.keySecret
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async createOrder(amount, currency, receipt = null) {
|
|
14
|
+
try {
|
|
15
|
+
const options = {
|
|
16
|
+
amount: amount * 100,
|
|
17
|
+
currency,
|
|
18
|
+
receipt: receipt
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const order = await this.instance.orders.create(options);
|
|
22
|
+
return {
|
|
23
|
+
razorpayOrderId: order.id,
|
|
24
|
+
amount: order.amount,
|
|
25
|
+
currency: order.currency,
|
|
26
|
+
created_at:order.created_at,
|
|
27
|
+
status: order.status
|
|
28
|
+
};
|
|
29
|
+
} catch (error) {
|
|
30
|
+
this.logger.error('Razorpay order creation error:', error);
|
|
31
|
+
throw new Error(StatusMessage.ORDER_CREATION_FAILED);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async verifyPayment(paymentId, orderId, signature, razorpaySecret) {
|
|
36
|
+
try {
|
|
37
|
+
const payment = await this.instance.payments.fetch(paymentId);
|
|
38
|
+
|
|
39
|
+
const expectedSignature = crypto
|
|
40
|
+
.createHmac('sha256', razorpaySecret)
|
|
41
|
+
.update(`${orderId}|${paymentId}`)
|
|
42
|
+
.digest('hex');
|
|
43
|
+
if (expectedSignature.trim() !== signature.trim()) {
|
|
44
|
+
throw new Error(StatusMessage.PAYMENT_SIGNATURE_VERIFICATION_FAILED);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
paymentId: payment.id,
|
|
49
|
+
orderId: payment.order_id,
|
|
50
|
+
amount: payment.amount,
|
|
51
|
+
currency: payment.currency,
|
|
52
|
+
status: payment.status,
|
|
53
|
+
method: payment.method,
|
|
54
|
+
cardId: payment.card_id,
|
|
55
|
+
card_last4: payment.card ? payment.card.last4 : null,
|
|
56
|
+
bank: payment.bank,
|
|
57
|
+
email: payment.email,
|
|
58
|
+
created_at: payment.created_at
|
|
59
|
+
};
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.log('Razorpay payment verification error:', error);
|
|
62
|
+
throw new Error(StatusMessage.PAYMENT_VERIFICATION_FAILED);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = RazorpayUtil;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const StatusMessage = require('../constants/StatusMessageConstants');
|
|
2
|
+
const VariantPriceUtil = async function (
|
|
3
|
+
variantData
|
|
4
|
+
) {
|
|
5
|
+
const { MRP, SellingPrice, DiscountPercentage } = variantData;
|
|
6
|
+
|
|
7
|
+
if (!MRP || MRP <= 0) {
|
|
8
|
+
throw new Error(StatusMessage.PRODUCTVARIANT_INVALID_MRP);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (SellingPrice == null && DiscountPercentage == null) {
|
|
12
|
+
throw new Error(StatusMessage.PRODUCTVARIANT_MISSING_PRICE_OR_DISCOUNT);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let calculatedSellingPrice = SellingPrice;
|
|
16
|
+
let calculatedDiscountPercentage = DiscountPercentage;
|
|
17
|
+
|
|
18
|
+
if (SellingPrice != null && DiscountPercentage != null) {
|
|
19
|
+
// Consistency check when both are provided
|
|
20
|
+
const expectedDiscount = ((MRP - SellingPrice) / MRP) * 100;
|
|
21
|
+
if (Math.abs(expectedDiscount - DiscountPercentage) > 0.01) {
|
|
22
|
+
// Tolerance for floating point
|
|
23
|
+
throw new Error(StatusMessage.PRODUCTVARIANT_INCONSISTENT_PRICING);
|
|
24
|
+
}
|
|
25
|
+
// Use provided values since they are consistent
|
|
26
|
+
calculatedDiscountPercentage = DiscountPercentage;
|
|
27
|
+
calculatedSellingPrice = SellingPrice;
|
|
28
|
+
} else if (SellingPrice != null) {
|
|
29
|
+
if (SellingPrice > MRP) {
|
|
30
|
+
throw new Error(StatusMessage.PRODUCTVARIANT_SELLING_PRICE_EXCEEDS_MRP);
|
|
31
|
+
}
|
|
32
|
+
if (SellingPrice < 0) {
|
|
33
|
+
throw new Error(StatusMessage.PRODUCTVARIANT_INVALID_SELLING_PRICE);
|
|
34
|
+
}
|
|
35
|
+
calculatedDiscountPercentage = ((MRP - SellingPrice) / MRP) * 100;
|
|
36
|
+
calculatedDiscountPercentage = parseFloat(
|
|
37
|
+
calculatedDiscountPercentage.toFixed(2)
|
|
38
|
+
);
|
|
39
|
+
} else if (DiscountPercentage != null) {
|
|
40
|
+
if (DiscountPercentage < 0 || DiscountPercentage > 100) {
|
|
41
|
+
throw new Error(
|
|
42
|
+
StatusMessage.PRODUCTVARIANT_INVALID_DISCOUNT_PERCENTAGE
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
calculatedSellingPrice = MRP * (1 - DiscountPercentage / 100);
|
|
46
|
+
calculatedSellingPrice = parseFloat(calculatedSellingPrice.toFixed(2));
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
...variantData,
|
|
51
|
+
SellingPrice: calculatedSellingPrice,
|
|
52
|
+
DiscountPercentage: calculatedDiscountPercentage,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
module.exports = VariantPriceUtil;
|