@b2y/ecommerce-common 1.4.1 → 1.4.3

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 (99) hide show
  1. package/.idea/ecommerce-common.iml +11 -11
  2. package/.idea/modules.xml +7 -7
  3. package/.idea/vcs.xml +5 -5
  4. package/README.md +4 -4
  5. package/constants/AppConstants.js +16 -16
  6. package/constants/AuditConstants.js +16 -0
  7. package/constants/ReportConstants.js +14 -14
  8. package/constants/StatusMessageConstants.js +61 -61
  9. package/controller/LocationController.js +144 -144
  10. package/controller/SubscriptionAbstractController.js +91 -91
  11. package/controller/TenantAbstractController.js +152 -152
  12. package/controller/TenantSettingsAbstractController.js +259 -259
  13. package/dbconnection/Connect.js +498 -498
  14. package/enum/AccessModeEnum.js +8 -8
  15. package/enum/ActionByTypeEnum.js +4 -4
  16. package/enum/AddressTypeEnum.js +6 -6
  17. package/enum/BillingCycleEnum.js +5 -5
  18. package/enum/BooleanEnum.js +4 -4
  19. package/enum/BulkImportStatusEnum.js +6 -6
  20. package/enum/DimensionUnitEnum.js +5 -5
  21. package/enum/EntityTypeEnum.js +12 -12
  22. package/enum/FeatureTypeEnum.js +6 -6
  23. package/enum/GenderEnum.js +7 -7
  24. package/enum/NotificationStatusEnum.js +5 -5
  25. package/enum/NotificationTypeEnum.js +9 -9
  26. package/enum/OrderActionStatusEnum.js +7 -7
  27. package/enum/OrderStatusEnum.js +8 -8
  28. package/enum/PackageBoxTypeEnum.js +6 -6
  29. package/enum/PaymentMethodEnum.js +6 -6
  30. package/enum/PaymentStatusEnum.js +6 -6
  31. package/enum/PaymentTypeEnum.js +6 -6
  32. package/enum/PlatformEnum.js +4 -4
  33. package/enum/ReasonTypeEnum.js +6 -6
  34. package/enum/RegistrationStatusEnum.js +5 -5
  35. package/enum/SortByEnum.js +7 -7
  36. package/enum/SubscriptionStatusEnum.js +7 -7
  37. package/enum/WeightUnitEnum.js +6 -6
  38. package/index.js +29 -28
  39. package/model/Address.js +95 -95
  40. package/model/AttributeType.js +50 -50
  41. package/model/AttributeValue.js +64 -64
  42. package/model/Banner.js +78 -78
  43. package/model/Brand.js +76 -76
  44. package/model/Cart.js +76 -76
  45. package/model/Category.js +72 -72
  46. package/model/CategoryAttributeType.js +62 -62
  47. package/model/Colour.js +52 -52
  48. package/model/Customer.js +98 -94
  49. package/model/DeviceToken.js +51 -51
  50. package/model/Document.js +73 -73
  51. package/model/DynamicUIComponent.js +52 -52
  52. package/model/Feedback.js +79 -79
  53. package/model/Inventory.js +87 -87
  54. package/model/NotificationHistory.js +67 -67
  55. package/model/Order.js +84 -84
  56. package/model/OrderActionReason.js +99 -99
  57. package/model/OrderItem.js +98 -98
  58. package/model/OrderItemHistory.js +69 -69
  59. package/model/OrderStatus.js +48 -48
  60. package/model/PackagingBox.js +78 -78
  61. package/model/Payment.js +101 -101
  62. package/model/PaymentMethod.js +36 -36
  63. package/model/PaymentStatus.js +36 -36
  64. package/model/PaymentType.js +36 -36
  65. package/model/Permission.js +45 -55
  66. package/model/Product.js +97 -97
  67. package/model/ProductGroup.js +48 -48
  68. package/model/ProductImport.js +55 -55
  69. package/model/ProductImportFailureAudits.js +57 -57
  70. package/model/ProductSpecification.js +65 -65
  71. package/model/ProductVariant.js +111 -111
  72. package/model/ProductVariantAttribute.js +58 -58
  73. package/model/ReasonContextMapping.js +70 -70
  74. package/model/ReasonMaster.js +74 -74
  75. package/model/Role.js +61 -61
  76. package/model/RolePermissionMapping.js +63 -63
  77. package/model/SpecificationType.js +41 -41
  78. package/model/Store.js +99 -99
  79. package/model/StoreUserMapping.js +44 -44
  80. package/model/SubscriptionFeature.js +53 -53
  81. package/model/SubscriptionPlan.js +70 -70
  82. package/model/SubscriptionPlanFeature.js +48 -48
  83. package/model/Tenant.js +91 -91
  84. package/model/TenantSettings.js +47 -47
  85. package/model/TenantSubscription.js +73 -73
  86. package/model/User.js +132 -132
  87. package/model/WishList.js +62 -62
  88. package/package.json +30 -30
  89. package/scripts/QueryBuilder.js +162 -162
  90. package/utility/AppUtil.js +69 -69
  91. package/utility/DateUtil.js +55 -55
  92. package/utility/ExcelUtil.js +125 -125
  93. package/utility/LocationUtility.js +130 -130
  94. package/utility/OrderTimeFilterUtil.js +88 -88
  95. package/utility/PdfUtil.js +67 -67
  96. package/utility/QueryUtil.js +261 -261
  97. package/utility/Razorpay.js +65 -65
  98. package/utility/ResolveAccessMode.js +61 -61
  99. package/utility/VariantPriceUtil.js +54 -54
@@ -1,260 +1,260 @@
1
- const EntityTypeEnum = require('../enum/EntityTypeEnum');
2
- const StatusMessage = require('../constants/StatusMessageConstants');
3
- const AppUtil = require('../utility/AppUtil');
4
- const AppConstants = require('../constants/AppConstants')
5
-
6
- const tenantSettingsDocumentValidation = async (
7
- file,
8
- documentMetadata,
9
- FileUploadUtil,
10
- FILE_PATHS,
11
- logger
12
- ) => {
13
- if (documentMetadata !== undefined) {
14
-
15
- // Accept both object and single-element array
16
- if (Array.isArray(documentMetadata)) {
17
- if (documentMetadata.length !== 1) {
18
- logger.warn(
19
- "Validation Failed: Only one logo is allowed."
20
- );
21
- throw new Error(StatusMessage.TENANT_SETTINGS_SINGLE_LOGO_ALLOWED);
22
- }
23
-
24
- // Convert array -> object
25
- documentMetadata = documentMetadata[0];
26
- }
27
-
28
- // Validate the final value
29
- if (typeof documentMetadata !== AppConstants.OBJECT) {
30
- logger.warn(
31
- "Validation Failed: documentMetadata must be a single object."
32
- );
33
- throw new Error(StatusMessage.TENANT_SETTINGS_SINGLE_LOGO_ALLOWED);
34
- }
35
-
36
- logger.info("Uploading new files to storage before transaction");
37
-
38
- const uploadResult = await FileUploadUtil.uploadFilesToStorage(
39
- documentMetadata,
40
- file,
41
- FILE_PATHS.IMAGE_DIR,
42
- );
43
-
44
- return uploadResult;
45
- }
46
-
47
- return [];
48
- };
49
-
50
- const getTenantSettingsById = (TenantSettings, Document, getPublicUrl, logger) => {
51
- return async (req, res) => {
52
- try {
53
- const { id } = req.params;
54
-
55
- const settings = await TenantSettings.findOne({
56
- where: {
57
- TenantID: id
58
- },
59
- attributes: ["TenantSettingID", "TenantID", "ThemeColour"],
60
- });
61
-
62
- if (!settings) {
63
- return AppUtil.generateResponse(
64
- 404,
65
- StatusMessage.FAILURE,
66
- StatusMessage.TENANT_SETTINGS_NOT_FOUND,
67
- null,
68
- res
69
- );
70
- }
71
- let logo = null;
72
- const document = await Document.findOne({
73
- where: {
74
- EntityType: EntityTypeEnum.TENANT_SETTINGS,
75
- EntityID: settings.TenantSettingID
76
- },
77
- order: [["SortOrder", "ASC"]]
78
- });
79
- if(document) {
80
- logo = {
81
- documentId: document.DocumentID,
82
- sortOrder: document.SortOrder,
83
- documentUrl: await getPublicUrl(document, logger)
84
- }
85
- }
86
- const formattedSettings = {
87
- TenantSettingID: settings.TenantSettingID,
88
- TenantID: settings.TenantID,
89
- ThemeColour: settings.ThemeColour,
90
- Logo: logo
91
- };
92
-
93
- return AppUtil.generateResponse(
94
- 200,
95
- StatusMessage.SUCCESS,
96
- null,
97
- formattedSettings,
98
- res
99
- );
100
-
101
- } catch (error) {
102
- logger.error("Error fetching tenant settings:", error);
103
- return AppUtil.generateResponse(
104
- 500,
105
- StatusMessage.FAILURE,
106
- StatusMessage.SERVER_ERROR,
107
- null,
108
- res
109
- );
110
- }
111
- }}
112
-
113
- const updateTenantSettings = (TenantSettings, multer, upload, FileUploadUtil, FILE_PATHS, reqUpdatedBy, sequelize, logger) => {
114
- return async (req, res) => {
115
- upload(req, res, async (err) => {
116
- if (err instanceof multer.MulterError || err) {
117
- logger.error('Upload Error:', err);
118
- return AppUtil.generateResponse(
119
- 400,
120
- StatusMessage.FAILURE,
121
- StatusMessage.TENANT_SETTINGS_IMAGE_UPLOAD_FAILED,
122
- null,
123
- res
124
- );
125
- }
126
-
127
- let transaction;
128
- let uploadedFilePath = [];
129
- try {
130
- let data;
131
- try {
132
- data = req.body.data ? JSON.parse(req.body.data) : req.body;
133
- } catch (error) {
134
- logger.error('Invalid JSON in request body', error);
135
- return AppUtil.generateResponse(
136
- 400,
137
- StatusMessage.FAILURE,
138
- StatusMessage.INVALID_JSON_FORMAT,
139
- null,
140
- res
141
- );
142
- }
143
-
144
- const {
145
- TenantSettingID,
146
- TenantID,
147
- ThemeColour,
148
- documentMetadata
149
- } = data;
150
-
151
- // Validation
152
- if (!TenantSettingID && !TenantID) {
153
- logger.warn('TenantSettingID or TenantID is required for update.');
154
- return AppUtil.generateResponse(
155
- 400,
156
- StatusMessage.FAILURE,
157
- StatusMessage.TENANT_SETTINGS_REQUIRED_FIELD,
158
- null,
159
- res
160
- );
161
- }
162
-
163
- // Find existing settings
164
- const whereClause = TenantSettingID ? { TenantSettingID } : { TenantID };
165
- const existingSettings = await TenantSettings.findOne({ where: whereClause });
166
-
167
- if (!existingSettings) {
168
- logger.warn('Tenant settings not found for update', whereClause);
169
- return AppUtil.generateResponse(
170
- 404,
171
- StatusMessage.FAILURE,
172
- StatusMessage.TENANT_SETTINGS_NOT_FOUND,
173
- null,
174
- res
175
- );
176
- }
177
-
178
- // Upload new file to storage before starting transaction
179
- const uploadResult = await tenantSettingsDocumentValidation(req.files, documentMetadata, FileUploadUtil, FILE_PATHS, logger)
180
- if(uploadResult.length > 0) {
181
- uploadedFilePath = uploadResult.map(result => result.path)
182
- }
183
-
184
- // Start database transaction
185
- transaction = await sequelize.transaction();
186
-
187
- // Update tenant settings
188
- const updatePayload = {};
189
- if (ThemeColour !== undefined) updatePayload.ThemeColour = ThemeColour;
190
- let updatedBy = null
191
- if(reqUpdatedBy) {
192
- updatedBy = reqUpdatedBy;
193
- }
194
- else {
195
- updatedBy = req.user.UserID
196
- }
197
- updatePayload.UpdatedBy = updatedBy
198
- updatePayload.UpdatedAt = new Date();
199
-
200
- await existingSettings.update(updatePayload, { transaction });
201
-
202
- // Save/Update documents (handles both create and replace logic)
203
- if (uploadResult.length > 0) {
204
- logger.info('Saving document records for TenantSettingID:', existingSettings.TenantSettingID);
205
-
206
- await FileUploadUtil.saveDocumentRecords(
207
- uploadResult,
208
- EntityTypeEnum.TENANT_SETTINGS,
209
- existingSettings.TenantSettingID,
210
- existingSettings.TenantID,
211
- updatedBy,
212
- transaction
213
- );
214
- }
215
-
216
- await transaction.commit();
217
- logger.info('Tenant settings updated successfully');
218
-
219
- return AppUtil.generateResponse(
220
- 200,
221
- StatusMessage.SUCCESS,
222
- StatusMessage.TENANT_SETTINGS_UPDATED_SUCCESS,
223
- null,
224
- res
225
- );
226
-
227
- } catch (error) {
228
- if (transaction) await transaction.rollback();
229
-
230
- // Cleanup newly uploaded files if transaction failed
231
- if (uploadedFilePath.length > 0) {
232
- logger.info('Cleaning up uploaded files due to error');
233
- await FileUploadUtil.cleanupFiles(uploadedFilePath);
234
- }
235
- const errorMessages = [
236
- StatusMessage.INVALID_SORT_ORDER,
237
- StatusMessage.FILE_NOT_FOUND,
238
- StatusMessage.INVALID_FILE_UPLOAD_INPUT,
239
- StatusMessage.TENANT_SETTINGS_SINGLE_LOGO_ALLOWED,
240
- ];
241
- // Error handling
242
- if (errorMessages.includes(error.message)) {
243
- return AppUtil.generateResponse(400, StatusMessage.FAILURE, error.message, null, res);
244
- }
245
- if (error.name === 'SequelizeUniqueConstraintError') {
246
- return AppUtil.generateResponse(400, StatusMessage.FAILURE, StatusMessage.TENANT_SETTINGS_ALREADY_EXISTS, null, res);
247
- } else if (error.name === 'SequelizeValidationError') {
248
- const details = error.errors.map((e) => e.message);
249
- logger.warn(`Validation Error detected: ${details.join('; ')}`);
250
- return AppUtil.generateResponse(400, StatusMessage.FAILURE, StatusMessage.INVALID_REQUEST, null, res);
251
- } else {
252
- logger.error("Error in updateTenantSettings:", error);
253
- return AppUtil.generateResponse(500, StatusMessage.FAILURE, StatusMessage.TENANT_SETTINGS_UPDATE_ERROR, null, res);
254
- }
255
- }
256
- });
257
- };
258
- }
259
- module.exports = {getTenantSettingsById, updateTenantSettings, tenantSettingsDocumentValidation};
1
+ const EntityTypeEnum = require('../enum/EntityTypeEnum');
2
+ const StatusMessage = require('../constants/StatusMessageConstants');
3
+ const AppUtil = require('../utility/AppUtil');
4
+ const AppConstants = require('../constants/AppConstants')
5
+
6
+ const tenantSettingsDocumentValidation = async (
7
+ file,
8
+ documentMetadata,
9
+ FileUploadUtil,
10
+ FILE_PATHS,
11
+ logger
12
+ ) => {
13
+ if (documentMetadata !== undefined) {
14
+
15
+ // Accept both object and single-element array
16
+ if (Array.isArray(documentMetadata)) {
17
+ if (documentMetadata.length !== 1) {
18
+ logger.warn(
19
+ "Validation Failed: Only one logo is allowed."
20
+ );
21
+ throw new Error(StatusMessage.TENANT_SETTINGS_SINGLE_LOGO_ALLOWED);
22
+ }
23
+
24
+ // Convert array -> object
25
+ documentMetadata = documentMetadata[0];
26
+ }
27
+
28
+ // Validate the final value
29
+ if (typeof documentMetadata !== AppConstants.OBJECT) {
30
+ logger.warn(
31
+ "Validation Failed: documentMetadata must be a single object."
32
+ );
33
+ throw new Error(StatusMessage.TENANT_SETTINGS_SINGLE_LOGO_ALLOWED);
34
+ }
35
+
36
+ logger.info("Uploading new files to storage before transaction");
37
+
38
+ const uploadResult = await FileUploadUtil.uploadFilesToStorage(
39
+ documentMetadata,
40
+ file,
41
+ FILE_PATHS.IMAGE_DIR,
42
+ );
43
+
44
+ return uploadResult;
45
+ }
46
+
47
+ return [];
48
+ };
49
+
50
+ const getTenantSettingsById = (TenantSettings, Document, getPublicUrl, logger) => {
51
+ return async (req, res) => {
52
+ try {
53
+ const { id } = req.params;
54
+
55
+ const settings = await TenantSettings.findOne({
56
+ where: {
57
+ TenantID: id
58
+ },
59
+ attributes: ["TenantSettingID", "TenantID", "ThemeColour"],
60
+ });
61
+
62
+ if (!settings) {
63
+ return AppUtil.generateResponse(
64
+ 404,
65
+ StatusMessage.FAILURE,
66
+ StatusMessage.TENANT_SETTINGS_NOT_FOUND,
67
+ null,
68
+ res
69
+ );
70
+ }
71
+ let logo = null;
72
+ const document = await Document.findOne({
73
+ where: {
74
+ EntityType: EntityTypeEnum.TENANT_SETTINGS,
75
+ EntityID: settings.TenantSettingID
76
+ },
77
+ order: [["SortOrder", "ASC"]]
78
+ });
79
+ if(document) {
80
+ logo = {
81
+ documentId: document.DocumentID,
82
+ sortOrder: document.SortOrder,
83
+ documentUrl: await getPublicUrl(document, logger)
84
+ }
85
+ }
86
+ const formattedSettings = {
87
+ TenantSettingID: settings.TenantSettingID,
88
+ TenantID: settings.TenantID,
89
+ ThemeColour: settings.ThemeColour,
90
+ Logo: logo
91
+ };
92
+
93
+ return AppUtil.generateResponse(
94
+ 200,
95
+ StatusMessage.SUCCESS,
96
+ null,
97
+ formattedSettings,
98
+ res
99
+ );
100
+
101
+ } catch (error) {
102
+ logger.error("Error fetching tenant settings:", error);
103
+ return AppUtil.generateResponse(
104
+ 500,
105
+ StatusMessage.FAILURE,
106
+ StatusMessage.SERVER_ERROR,
107
+ null,
108
+ res
109
+ );
110
+ }
111
+ }}
112
+
113
+ const updateTenantSettings = (TenantSettings, multer, upload, FileUploadUtil, FILE_PATHS, reqUpdatedBy, sequelize, logger) => {
114
+ return async (req, res) => {
115
+ upload(req, res, async (err) => {
116
+ if (err instanceof multer.MulterError || err) {
117
+ logger.error('Upload Error:', err);
118
+ return AppUtil.generateResponse(
119
+ 400,
120
+ StatusMessage.FAILURE,
121
+ StatusMessage.TENANT_SETTINGS_IMAGE_UPLOAD_FAILED,
122
+ null,
123
+ res
124
+ );
125
+ }
126
+
127
+ let transaction;
128
+ let uploadedFilePath = [];
129
+ try {
130
+ let data;
131
+ try {
132
+ data = req.body.data ? JSON.parse(req.body.data) : req.body;
133
+ } catch (error) {
134
+ logger.error('Invalid JSON in request body', error);
135
+ return AppUtil.generateResponse(
136
+ 400,
137
+ StatusMessage.FAILURE,
138
+ StatusMessage.INVALID_JSON_FORMAT,
139
+ null,
140
+ res
141
+ );
142
+ }
143
+
144
+ const {
145
+ TenantSettingID,
146
+ TenantID,
147
+ ThemeColour,
148
+ documentMetadata
149
+ } = data;
150
+
151
+ // Validation
152
+ if (!TenantSettingID && !TenantID) {
153
+ logger.warn('TenantSettingID or TenantID is required for update.');
154
+ return AppUtil.generateResponse(
155
+ 400,
156
+ StatusMessage.FAILURE,
157
+ StatusMessage.TENANT_SETTINGS_REQUIRED_FIELD,
158
+ null,
159
+ res
160
+ );
161
+ }
162
+
163
+ // Find existing settings
164
+ const whereClause = TenantSettingID ? { TenantSettingID } : { TenantID };
165
+ const existingSettings = await TenantSettings.findOne({ where: whereClause });
166
+
167
+ if (!existingSettings) {
168
+ logger.warn('Tenant settings not found for update', whereClause);
169
+ return AppUtil.generateResponse(
170
+ 404,
171
+ StatusMessage.FAILURE,
172
+ StatusMessage.TENANT_SETTINGS_NOT_FOUND,
173
+ null,
174
+ res
175
+ );
176
+ }
177
+
178
+ // Upload new file to storage before starting transaction
179
+ const uploadResult = await tenantSettingsDocumentValidation(req.files, documentMetadata, FileUploadUtil, FILE_PATHS, logger)
180
+ if(uploadResult.length > 0) {
181
+ uploadedFilePath = uploadResult.map(result => result.path)
182
+ }
183
+
184
+ // Start database transaction
185
+ transaction = await sequelize.transaction();
186
+
187
+ // Update tenant settings
188
+ const updatePayload = {};
189
+ if (ThemeColour !== undefined) updatePayload.ThemeColour = ThemeColour;
190
+ let updatedBy = null
191
+ if(reqUpdatedBy) {
192
+ updatedBy = reqUpdatedBy;
193
+ }
194
+ else {
195
+ updatedBy = req.user.UserID
196
+ }
197
+ updatePayload.UpdatedBy = updatedBy
198
+ updatePayload.UpdatedAt = new Date();
199
+
200
+ await existingSettings.update(updatePayload, { transaction });
201
+
202
+ // Save/Update documents (handles both create and replace logic)
203
+ if (uploadResult.length > 0) {
204
+ logger.info('Saving document records for TenantSettingID:', existingSettings.TenantSettingID);
205
+
206
+ await FileUploadUtil.saveDocumentRecords(
207
+ uploadResult,
208
+ EntityTypeEnum.TENANT_SETTINGS,
209
+ existingSettings.TenantSettingID,
210
+ existingSettings.TenantID,
211
+ updatedBy,
212
+ transaction
213
+ );
214
+ }
215
+
216
+ await transaction.commit();
217
+ logger.info('Tenant settings updated successfully');
218
+
219
+ return AppUtil.generateResponse(
220
+ 200,
221
+ StatusMessage.SUCCESS,
222
+ StatusMessage.TENANT_SETTINGS_UPDATED_SUCCESS,
223
+ null,
224
+ res
225
+ );
226
+
227
+ } catch (error) {
228
+ if (transaction) await transaction.rollback();
229
+
230
+ // Cleanup newly uploaded files if transaction failed
231
+ if (uploadedFilePath.length > 0) {
232
+ logger.info('Cleaning up uploaded files due to error');
233
+ await FileUploadUtil.cleanupFiles(uploadedFilePath);
234
+ }
235
+ const errorMessages = [
236
+ StatusMessage.INVALID_SORT_ORDER,
237
+ StatusMessage.FILE_NOT_FOUND,
238
+ StatusMessage.INVALID_FILE_UPLOAD_INPUT,
239
+ StatusMessage.TENANT_SETTINGS_SINGLE_LOGO_ALLOWED,
240
+ ];
241
+ // Error handling
242
+ if (errorMessages.includes(error.message)) {
243
+ return AppUtil.generateResponse(400, StatusMessage.FAILURE, error.message, null, res);
244
+ }
245
+ if (error.name === 'SequelizeUniqueConstraintError') {
246
+ return AppUtil.generateResponse(400, StatusMessage.FAILURE, StatusMessage.TENANT_SETTINGS_ALREADY_EXISTS, null, res);
247
+ } else if (error.name === 'SequelizeValidationError') {
248
+ const details = error.errors.map((e) => e.message);
249
+ logger.warn(`Validation Error detected: ${details.join('; ')}`);
250
+ return AppUtil.generateResponse(400, StatusMessage.FAILURE, StatusMessage.INVALID_REQUEST, null, res);
251
+ } else {
252
+ logger.error("Error in updateTenantSettings:", error);
253
+ return AppUtil.generateResponse(500, StatusMessage.FAILURE, StatusMessage.TENANT_SETTINGS_UPDATE_ERROR, null, res);
254
+ }
255
+ }
256
+ });
257
+ };
258
+ }
259
+ module.exports = {getTenantSettingsById, updateTenantSettings, tenantSettingsDocumentValidation};
260
260