@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.
Files changed (68) hide show
  1. package/README.md +4 -0
  2. package/constants/AppConstants.js +4 -0
  3. package/constants/ReportConstants.js +15 -0
  4. package/constants/StatusMessageConstants.js +21 -0
  5. package/dbconnection/Connect.js +417 -0
  6. package/enum/AddressTypeEnum.js +7 -0
  7. package/enum/BooleanEnum.js +5 -0
  8. package/enum/EntityTypeEnum.js +10 -0
  9. package/enum/GenderEnum.js +7 -0
  10. package/enum/NotificationStatusEnum.js +6 -0
  11. package/enum/NotificationTypeEnum.js +10 -0
  12. package/enum/OrderStatusEnum.js +8 -0
  13. package/enum/PaymentMethodEnum.js +7 -0
  14. package/enum/PaymentStatusEnum.js +7 -0
  15. package/enum/PaymentTypeEnum.js +7 -0
  16. package/enum/PlatformEnum.js +5 -0
  17. package/enum/RegistrationStatusEnum.js +6 -0
  18. package/enum/SortByEnum.js +8 -0
  19. package/index.js +22 -0
  20. package/model/Address.js +114 -0
  21. package/model/AttributeType.js +51 -0
  22. package/model/AttributeValue.js +65 -0
  23. package/model/Banner.js +79 -0
  24. package/model/Brand.js +76 -0
  25. package/model/Cart.js +77 -0
  26. package/model/Category.js +73 -0
  27. package/model/CategoryAttributeType.js +63 -0
  28. package/model/City.js +49 -0
  29. package/model/Colour.js +53 -0
  30. package/model/Country.js +47 -0
  31. package/model/Customer.js +95 -0
  32. package/model/DeviceToken.js +52 -0
  33. package/model/Document.js +71 -0
  34. package/model/DynamicUIComponent.js +53 -0
  35. package/model/Feedback.js +80 -0
  36. package/model/Inventory.js +84 -0
  37. package/model/NotificationHistory.js +68 -0
  38. package/model/Order.js +95 -0
  39. package/model/OrderItem.js +99 -0
  40. package/model/OrderItemHistory.js +70 -0
  41. package/model/OrderStatus.js +49 -0
  42. package/model/Payment.js +101 -0
  43. package/model/PaymentMethod.js +37 -0
  44. package/model/PaymentStatus.js +37 -0
  45. package/model/PaymentType.js +37 -0
  46. package/model/Permission.js +55 -0
  47. package/model/Product.js +83 -0
  48. package/model/ProductGroup.js +48 -0
  49. package/model/ProductSpecification.js +66 -0
  50. package/model/ProductVariant.js +76 -0
  51. package/model/ProductVariantAttribute.js +59 -0
  52. package/model/Role.js +61 -0
  53. package/model/RolePermissionMapping.js +63 -0
  54. package/model/SpecificationType.js +42 -0
  55. package/model/State.js +56 -0
  56. package/model/Store.js +117 -0
  57. package/model/StoreUserMapping.js +44 -0
  58. package/model/Tenant.js +91 -0
  59. package/model/User.js +150 -0
  60. package/model/WishList.js +63 -0
  61. package/package.json +27 -0
  62. package/utility/AppUtil.js +58 -0
  63. package/utility/DateUtil.js +55 -0
  64. package/utility/ExcelUtil.js +125 -0
  65. package/utility/OrderTimeFilterUtil.js +86 -0
  66. package/utility/QueryUtil.js +262 -0
  67. package/utility/Razorpay.js +67 -0
  68. 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;