@b2y/ecommerce-common 1.3.6 → 1.3.7

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 (96) 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 +15 -15
  6. package/constants/ReportConstants.js +14 -14
  7. package/constants/StatusMessageConstants.js +61 -61
  8. package/controller/LocationController.js +144 -144
  9. package/controller/SubscriptionAbstractController.js +91 -91
  10. package/controller/TenantAbstractController.js +152 -152
  11. package/controller/TenantSettingsAbstractController.js +243 -243
  12. package/dbconnection/Connect.js +498 -498
  13. package/enum/AccessModeEnum.js +8 -8
  14. package/enum/ActionByTypeEnum.js +4 -4
  15. package/enum/AddressTypeEnum.js +6 -6
  16. package/enum/BillingCycleEnum.js +5 -5
  17. package/enum/BooleanEnum.js +4 -4
  18. package/enum/BulkImportStatusEnum.js +6 -6
  19. package/enum/EntityTypeEnum.js +12 -12
  20. package/enum/FeatureTypeEnum.js +6 -6
  21. package/enum/GenderEnum.js +7 -7
  22. package/enum/NotificationStatusEnum.js +5 -5
  23. package/enum/NotificationTypeEnum.js +9 -9
  24. package/enum/OrderActionStatusEnum.js +7 -7
  25. package/enum/OrderStatusEnum.js +7 -7
  26. package/enum/PackageBoxTypeEnum.js +6 -6
  27. package/enum/PaymentMethodEnum.js +6 -6
  28. package/enum/PaymentStatusEnum.js +6 -6
  29. package/enum/PaymentTypeEnum.js +6 -6
  30. package/enum/PlatformEnum.js +4 -4
  31. package/enum/ReasonTypeEnum.js +6 -6
  32. package/enum/RegistrationStatusEnum.js +5 -5
  33. package/enum/SortByEnum.js +7 -7
  34. package/enum/SubscriptionStatusEnum.js +7 -7
  35. package/index.js +28 -28
  36. package/model/Address.js +95 -95
  37. package/model/AttributeType.js +50 -50
  38. package/model/AttributeValue.js +64 -64
  39. package/model/Banner.js +78 -78
  40. package/model/Brand.js +76 -76
  41. package/model/Cart.js +76 -76
  42. package/model/Category.js +72 -72
  43. package/model/CategoryAttributeType.js +62 -62
  44. package/model/Colour.js +52 -52
  45. package/model/Customer.js +94 -94
  46. package/model/DeviceToken.js +51 -51
  47. package/model/Document.js +73 -73
  48. package/model/DynamicUIComponent.js +52 -52
  49. package/model/Feedback.js +79 -79
  50. package/model/Inventory.js +87 -87
  51. package/model/NotificationHistory.js +67 -67
  52. package/model/Order.js +84 -84
  53. package/model/OrderActionReason.js +99 -99
  54. package/model/OrderItem.js +98 -98
  55. package/model/OrderItemHistory.js +69 -69
  56. package/model/OrderStatus.js +48 -48
  57. package/model/PackagingBox.js +78 -78
  58. package/model/Payment.js +101 -101
  59. package/model/PaymentMethod.js +36 -36
  60. package/model/PaymentStatus.js +36 -36
  61. package/model/PaymentType.js +36 -36
  62. package/model/Permission.js +55 -55
  63. package/model/Product.js +97 -97
  64. package/model/ProductGroup.js +48 -48
  65. package/model/ProductImport.js +55 -55
  66. package/model/ProductImportFailureAudits.js +57 -57
  67. package/model/ProductSpecification.js +65 -65
  68. package/model/ProductVariant.js +111 -111
  69. package/model/ProductVariantAttribute.js +58 -58
  70. package/model/ReasonContextMapping.js +70 -70
  71. package/model/ReasonMaster.js +74 -74
  72. package/model/Role.js +61 -61
  73. package/model/RolePermissionMapping.js +63 -63
  74. package/model/SpecificationType.js +41 -41
  75. package/model/Store.js +99 -99
  76. package/model/StoreUserMapping.js +44 -44
  77. package/model/SubscriptionFeature.js +53 -53
  78. package/model/SubscriptionPlan.js +70 -70
  79. package/model/SubscriptionPlanFeature.js +48 -48
  80. package/model/Tenant.js +91 -91
  81. package/model/TenantSettings.js +47 -47
  82. package/model/TenantSubscription.js +73 -73
  83. package/model/User.js +132 -132
  84. package/model/WishList.js +62 -62
  85. package/package.json +30 -30
  86. package/scripts/QueryBuilder.js +162 -162
  87. package/utility/AppUtil.js +65 -65
  88. package/utility/DateUtil.js +55 -55
  89. package/utility/ExcelUtil.js +125 -125
  90. package/utility/LocationUtility.js +130 -130
  91. package/utility/OrderTimeFilterUtil.js +88 -88
  92. package/utility/PdfUtil.js +64 -64
  93. package/utility/QueryUtil.js +261 -261
  94. package/utility/Razorpay.js +65 -65
  95. package/utility/ResolveAccessMode.js +61 -61
  96. package/utility/VariantPriceUtil.js +54 -54
@@ -1,163 +1,163 @@
1
- class QueryBuilder{
2
- static productQueryBuilder(filters) {
3
- const {
4
- DB_SCHEMA,
5
- // Common filters
6
- brandIds,
7
- allCategoryIDs,
8
- searchText,
9
-
10
- // Customer filters
11
- attributeValueIds,
12
- min,
13
- max,
14
- discountPercentage,
15
-
16
- // Admin filters
17
- IsActive,
18
- storeIds,
19
-
20
- // Context
21
- isAdmin = false,
22
- isCustomer = false,
23
- } = filters;
24
-
25
- const schemaPrefix = `"${DB_SCHEMA}"`;
26
-
27
- return `(
28
- WITH filtered_variants AS (
29
- SELECT
30
- pv."ProductVariantID",
31
- pv."ProductID",
32
- pv."GroupByAttributeValue",
33
- inv."SellingPrice",
34
- inv."DiscountPercentage"
35
-
36
- FROM ${schemaPrefix}."ProductVariant" pv
37
-
38
- JOIN ${schemaPrefix}."Inventory" inv
39
- ON pv."ProductVariantID" = inv."ProductVariantID"
40
-
41
- WHERE pv."TenantID" = :tenantID
42
-
43
- ${isCustomer ? `AND pv."IsActive" = true` : ""}
44
-
45
- ${
46
- isAdmin && IsActive !== undefined
47
- ? `AND pv."IsActive" = :IsActive`
48
- : ""
49
- }
50
-
51
- ${
52
- storeIds?.length
53
- ? `AND inv."StoreID" IN (:storeIds)`
54
- : ""
55
- }
56
-
57
- ${
58
- isCustomer && min !== null && min !== undefined
59
- ? `AND inv."SellingPrice" >= :min`
60
- : ""
61
- }
62
-
63
- ${
64
- isCustomer && max !== null && max !== undefined
65
- ? `AND inv."SellingPrice" <= :max`
66
- : ""
67
- }
68
-
69
- ${
70
- isCustomer &&
71
- discountPercentage !== null &&
72
- discountPercentage !== undefined
73
- ? `AND inv."DiscountPercentage" >= :discountPercentage`
74
- : ""
75
- }
76
- ),
77
- filtered_products AS (
78
- SELECT
79
- p."ProductID",
80
- p."GroupBy"
81
-
82
- FROM ${schemaPrefix}."Product" p
83
-
84
- LEFT JOIN ${schemaPrefix}."Brand" b
85
- ON p."BrandID" = b."BrandID"
86
-
87
- LEFT JOIN ${schemaPrefix}."Category" c
88
- ON p."CategoryID" = c."CategoryID"
89
-
90
- WHERE p."TenantID" = :tenantID
91
-
92
- ${isCustomer ? `AND p."IsActive" = true` : ""}
93
-
94
- ${isAdmin && IsActive !== undefined ? `AND p."IsActive" = :IsActive` : ""}
95
-
96
- ${brandIds?.length ? `AND p."BrandID" IN (:brandIds)` : ""}
97
-
98
- ${allCategoryIDs?.length ? `AND p."CategoryID" IN (:allCategoryIDs)` : ""}
99
-
100
- ${
101
- searchText
102
- ? `
103
- AND (
104
- p."ProductName" ILIKE :search OR
105
- p."ProductDescription" ILIKE :search OR
106
- b."BrandName" ILIKE :search OR
107
- c."CategoryName" ILIKE :search
108
- )`
109
- : ""
110
- }
111
- ),
112
-
113
- ranked_variants AS (
114
- SELECT
115
- fv."ProductVariantID",
116
- fv."ProductID",
117
- fv."GroupByAttributeValue",
118
- fv."SellingPrice",
119
- fp."GroupBy",
120
-
121
- CASE
122
- WHEN fp."GroupBy" IS NULL
123
- THEN fv."ProductVariantID"::text
124
- ELSE
125
- fv."ProductID"::text || '_' || fv."GroupByAttributeValue"::text
126
- END AS "groupKey",
127
-
128
- ROW_NUMBER() OVER (
129
- PARTITION BY
130
- CASE
131
- WHEN fp."GroupBy" IS NULL
132
- THEN fv."ProductVariantID"::text
133
- ELSE
134
- fv."ProductID"::text || '_' || fv."GroupByAttributeValue"::text
135
- END
136
- ORDER BY fv."SellingPrice" ASC
137
- ) as rn
138
-
139
- FROM filtered_variants fv
140
-
141
- JOIN filtered_products fp
142
- ON fv."ProductID" = fp."ProductID"
143
-
144
- ${
145
- isCustomer && attributeValueIds?.length
146
- ? `
147
- AND EXISTS (
148
- SELECT 1
149
- FROM ${schemaPrefix}."ProductVariantAttribute" pva
150
- WHERE pva."ProductVariantID" = fv."ProductVariantID"
151
- AND pva."AttributeValueID" IN (:attributeValueIds)
152
- )`
153
- : ""
154
- }
155
- )
156
-
157
- SELECT "ProductVariantID"
158
- FROM ranked_variants
159
- WHERE rn = 1
160
- )`;
161
- }
162
- }
1
+ class QueryBuilder{
2
+ static productQueryBuilder(filters) {
3
+ const {
4
+ DB_SCHEMA,
5
+ // Common filters
6
+ brandIds,
7
+ allCategoryIDs,
8
+ searchText,
9
+
10
+ // Customer filters
11
+ attributeValueIds,
12
+ min,
13
+ max,
14
+ discountPercentage,
15
+
16
+ // Admin filters
17
+ IsActive,
18
+ storeIds,
19
+
20
+ // Context
21
+ isAdmin = false,
22
+ isCustomer = false,
23
+ } = filters;
24
+
25
+ const schemaPrefix = `"${DB_SCHEMA}"`;
26
+
27
+ return `(
28
+ WITH filtered_variants AS (
29
+ SELECT
30
+ pv."ProductVariantID",
31
+ pv."ProductID",
32
+ pv."GroupByAttributeValue",
33
+ inv."SellingPrice",
34
+ inv."DiscountPercentage"
35
+
36
+ FROM ${schemaPrefix}."ProductVariant" pv
37
+
38
+ JOIN ${schemaPrefix}."Inventory" inv
39
+ ON pv."ProductVariantID" = inv."ProductVariantID"
40
+
41
+ WHERE pv."TenantID" = :tenantID
42
+
43
+ ${isCustomer ? `AND pv."IsActive" = true` : ""}
44
+
45
+ ${
46
+ isAdmin && IsActive !== undefined
47
+ ? `AND pv."IsActive" = :IsActive`
48
+ : ""
49
+ }
50
+
51
+ ${
52
+ storeIds?.length
53
+ ? `AND inv."StoreID" IN (:storeIds)`
54
+ : ""
55
+ }
56
+
57
+ ${
58
+ isCustomer && min !== null && min !== undefined
59
+ ? `AND inv."SellingPrice" >= :min`
60
+ : ""
61
+ }
62
+
63
+ ${
64
+ isCustomer && max !== null && max !== undefined
65
+ ? `AND inv."SellingPrice" <= :max`
66
+ : ""
67
+ }
68
+
69
+ ${
70
+ isCustomer &&
71
+ discountPercentage !== null &&
72
+ discountPercentage !== undefined
73
+ ? `AND inv."DiscountPercentage" >= :discountPercentage`
74
+ : ""
75
+ }
76
+ ),
77
+ filtered_products AS (
78
+ SELECT
79
+ p."ProductID",
80
+ p."GroupBy"
81
+
82
+ FROM ${schemaPrefix}."Product" p
83
+
84
+ LEFT JOIN ${schemaPrefix}."Brand" b
85
+ ON p."BrandID" = b."BrandID"
86
+
87
+ LEFT JOIN ${schemaPrefix}."Category" c
88
+ ON p."CategoryID" = c."CategoryID"
89
+
90
+ WHERE p."TenantID" = :tenantID
91
+
92
+ ${isCustomer ? `AND p."IsActive" = true` : ""}
93
+
94
+ ${isAdmin && IsActive !== undefined ? `AND p."IsActive" = :IsActive` : ""}
95
+
96
+ ${brandIds?.length ? `AND p."BrandID" IN (:brandIds)` : ""}
97
+
98
+ ${allCategoryIDs?.length ? `AND p."CategoryID" IN (:allCategoryIDs)` : ""}
99
+
100
+ ${
101
+ searchText
102
+ ? `
103
+ AND (
104
+ p."ProductName" ILIKE :search OR
105
+ p."ProductDescription" ILIKE :search OR
106
+ b."BrandName" ILIKE :search OR
107
+ c."CategoryName" ILIKE :search
108
+ )`
109
+ : ""
110
+ }
111
+ ),
112
+
113
+ ranked_variants AS (
114
+ SELECT
115
+ fv."ProductVariantID",
116
+ fv."ProductID",
117
+ fv."GroupByAttributeValue",
118
+ fv."SellingPrice",
119
+ fp."GroupBy",
120
+
121
+ CASE
122
+ WHEN fp."GroupBy" IS NULL
123
+ THEN fv."ProductVariantID"::text
124
+ ELSE
125
+ fv."ProductID"::text || '_' || fv."GroupByAttributeValue"::text
126
+ END AS "groupKey",
127
+
128
+ ROW_NUMBER() OVER (
129
+ PARTITION BY
130
+ CASE
131
+ WHEN fp."GroupBy" IS NULL
132
+ THEN fv."ProductVariantID"::text
133
+ ELSE
134
+ fv."ProductID"::text || '_' || fv."GroupByAttributeValue"::text
135
+ END
136
+ ORDER BY fv."SellingPrice" ASC
137
+ ) as rn
138
+
139
+ FROM filtered_variants fv
140
+
141
+ JOIN filtered_products fp
142
+ ON fv."ProductID" = fp."ProductID"
143
+
144
+ ${
145
+ isCustomer && attributeValueIds?.length
146
+ ? `
147
+ AND EXISTS (
148
+ SELECT 1
149
+ FROM ${schemaPrefix}."ProductVariantAttribute" pva
150
+ WHERE pva."ProductVariantID" = fv."ProductVariantID"
151
+ AND pva."AttributeValueID" IN (:attributeValueIds)
152
+ )`
153
+ : ""
154
+ }
155
+ )
156
+
157
+ SELECT "ProductVariantID"
158
+ FROM ranked_variants
159
+ WHERE rn = 1
160
+ )`;
161
+ }
162
+ }
163
163
  module.exports = QueryBuilder;
@@ -1,66 +1,66 @@
1
- const BooleanEnum = require('../enum/BooleanEnum');
2
- const AppUtil = {
3
- generateResponse: function (statusCode, status, message, payload, res, customCode = null) {
4
- let response = {
5
- status,
6
- };
7
- if (
8
- payload &&
9
- (Array.isArray(payload) || Object.keys(payload).length > 0)
10
- ) {
11
- if (payload.rows && typeof payload.count !== "undefined") {
12
- const { rows, count, pageNumber, limit } = payload;
13
- const currentPage = Number(pageNumber) || 1;
14
- const pageSize = Number(limit) || count;
15
- const totalPages = Math.ceil(count / pageSize);
16
- response.data = rows;
17
- response.pagination = {
18
- totalRecords: count,
19
- totalPages,
20
- currentPage,
21
- pageSize,
22
- hasNext: currentPage < totalPages,
23
- hasPrev: currentPage > 1,
24
- };
25
- } else {
26
- // Non-paginated response
27
- response.data = payload;
28
- }
29
- }
30
- if (message) {
31
- // No data => return message (POST/PUT/DELETE-like APIs)
32
- response.message = message || "";
33
- }
34
- // if custome code also need to send in reponse body
35
- if (customCode) {
36
- response.customCode = customCode;
37
- }
38
- res.status(statusCode).send(response);
39
- },
40
- parseIsActive: function (isActive) {
41
- if (isActive === true || isActive === "true") return BooleanEnum.TRUE;
42
- if (isActive === false || isActive === "false") return BooleanEnum.FALSE;
43
- return undefined;
44
- },
45
- getPagination: function (page, size) {
46
- if (!size || !page) return {};
47
- const limit = +size;
48
- const offset = (page - 1) * limit;
49
- return { limit, offset };
50
- },
51
- trimDecimal: function (decimal) {
52
- const value = parseFloat(decimal);
53
- return Math.round(value)
54
- },
55
- isValidEmail: function (email) {
56
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
57
- return emailRegex.test(email.trim());
58
- },
59
- isValidPhone: function (phoneNumber) {
60
- const phoneRegex = /^\d{10,20}$/;
61
- return phoneRegex.test(phoneNumber);
62
- }
63
- };
64
-
65
-
1
+ const BooleanEnum = require('../enum/BooleanEnum');
2
+ const AppUtil = {
3
+ generateResponse: function (statusCode, status, message, payload, res, customCode = null) {
4
+ let response = {
5
+ status,
6
+ };
7
+ if (
8
+ payload &&
9
+ (Array.isArray(payload) || Object.keys(payload).length > 0)
10
+ ) {
11
+ if (payload.rows && typeof payload.count !== "undefined") {
12
+ const { rows, count, pageNumber, limit } = payload;
13
+ const currentPage = Number(pageNumber) || 1;
14
+ const pageSize = Number(limit) || count;
15
+ const totalPages = Math.ceil(count / pageSize);
16
+ response.data = rows;
17
+ response.pagination = {
18
+ totalRecords: count,
19
+ totalPages,
20
+ currentPage,
21
+ pageSize,
22
+ hasNext: currentPage < totalPages,
23
+ hasPrev: currentPage > 1,
24
+ };
25
+ } else {
26
+ // Non-paginated response
27
+ response.data = payload;
28
+ }
29
+ }
30
+ if (message) {
31
+ // No data => return message (POST/PUT/DELETE-like APIs)
32
+ response.message = message || "";
33
+ }
34
+ // if custome code also need to send in reponse body
35
+ if (customCode) {
36
+ response.customCode = customCode;
37
+ }
38
+ res.status(statusCode).send(response);
39
+ },
40
+ parseIsActive: function (isActive) {
41
+ if (isActive === true || isActive === "true") return BooleanEnum.TRUE;
42
+ if (isActive === false || isActive === "false") return BooleanEnum.FALSE;
43
+ return undefined;
44
+ },
45
+ getPagination: function (page, size) {
46
+ if (!size || !page) return {};
47
+ const limit = +size;
48
+ const offset = (page - 1) * limit;
49
+ return { limit, offset };
50
+ },
51
+ trimDecimal: function (decimal) {
52
+ const value = parseFloat(decimal);
53
+ return Math.round(value)
54
+ },
55
+ isValidEmail: function (email) {
56
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
57
+ return emailRegex.test(email.trim());
58
+ },
59
+ isValidPhone: function (phoneNumber) {
60
+ const phoneRegex = /^\d{10,20}$/;
61
+ return phoneRegex.test(phoneNumber);
62
+ }
63
+ };
64
+
65
+
66
66
  module.exports = AppUtil;
@@ -1,55 +1,55 @@
1
- const AppConstants = require('../constants/AppConstants');
2
- const {DateTime} = require('luxon');
3
- const StatusMessage = require('../constants/StatusMessageConstants');
4
- const DateUtil = {
5
- isValidDate: function (dateStr) {
6
- const dt = DateTime.fromISO(dateStr);
7
- return dt.isValid;
8
- },
9
- getDateRange: function (startDate, endDate, logger) {
10
- let currentStartDate, currentEndDate, previousStartDate, previousEndDate;
11
- if (startDate && endDate) {
12
- if (!this.isValidDate(startDate) || !this.isValidDate(endDate)) {
13
- logger.warn("invalid date format");
14
- throw new Error(StatusMessage.INVALID_DATE_FORMAT);
15
- }
16
- currentStartDate = DateTime.fromISO(startDate, { zone: "utc" });
17
- currentEndDate = DateTime.fromISO(endDate, { zone: "utc" });
18
- if (currentStartDate > currentEndDate) {
19
- logger.warn("invalid date range");
20
- throw new Error(StatusMessage.INVALID_DATE_RANGE);
21
- }
22
- const duration = currentEndDate.diff(currentStartDate);
23
- previousEndDate = currentStartDate;
24
- previousStartDate = previousEndDate.minus(duration);
25
- } else if (startDate || endDate) {
26
- // Only one provided
27
- logger.warn("start date and date date both required");
28
- throw new Error(StatusMessage.DATE_RANGE_REQUIRED);
29
- } else {
30
- // Default 7 days including today
31
- currentEndDate = DateTime.utc();
32
- currentStartDate = currentEndDate.minus({
33
- days: AppConstants.DASHBOARD_DEFAULT_DAYS - 1,
34
- });
35
-
36
- const duration = currentEndDate.diff(currentStartDate);
37
- previousEndDate = currentStartDate;
38
- previousStartDate = previousEndDate.minus(duration);
39
- }
40
-
41
- return {
42
- currentStartDate: currentStartDate.toISO(),
43
- currentEndDate: currentEndDate.toISO(),
44
- previousStartDate: previousStartDate.toISO(),
45
- previousEndDate: previousEndDate.toISO(),
46
- };
47
- },
48
- formatDate: function (date) {
49
- if (!(date instanceof Date)) return null;
50
- // conver JS date object to luxon date time
51
- const dt = DateTime.fromJSDate(date);
52
- return dt.toFormat('dd/MM/yyyy HH:mm:ss');
53
- }
54
- };
55
- module.exports = DateUtil;
1
+ const AppConstants = require('../constants/AppConstants');
2
+ const {DateTime} = require('luxon');
3
+ const StatusMessage = require('../constants/StatusMessageConstants');
4
+ const DateUtil = {
5
+ isValidDate: function (dateStr) {
6
+ const dt = DateTime.fromISO(dateStr);
7
+ return dt.isValid;
8
+ },
9
+ getDateRange: function (startDate, endDate, logger) {
10
+ let currentStartDate, currentEndDate, previousStartDate, previousEndDate;
11
+ if (startDate && endDate) {
12
+ if (!this.isValidDate(startDate) || !this.isValidDate(endDate)) {
13
+ logger.warn("invalid date format");
14
+ throw new Error(StatusMessage.INVALID_DATE_FORMAT);
15
+ }
16
+ currentStartDate = DateTime.fromISO(startDate, { zone: "utc" });
17
+ currentEndDate = DateTime.fromISO(endDate, { zone: "utc" });
18
+ if (currentStartDate > currentEndDate) {
19
+ logger.warn("invalid date range");
20
+ throw new Error(StatusMessage.INVALID_DATE_RANGE);
21
+ }
22
+ const duration = currentEndDate.diff(currentStartDate);
23
+ previousEndDate = currentStartDate;
24
+ previousStartDate = previousEndDate.minus(duration);
25
+ } else if (startDate || endDate) {
26
+ // Only one provided
27
+ logger.warn("start date and date date both required");
28
+ throw new Error(StatusMessage.DATE_RANGE_REQUIRED);
29
+ } else {
30
+ // Default 7 days including today
31
+ currentEndDate = DateTime.utc();
32
+ currentStartDate = currentEndDate.minus({
33
+ days: AppConstants.DASHBOARD_DEFAULT_DAYS - 1,
34
+ });
35
+
36
+ const duration = currentEndDate.diff(currentStartDate);
37
+ previousEndDate = currentStartDate;
38
+ previousStartDate = previousEndDate.minus(duration);
39
+ }
40
+
41
+ return {
42
+ currentStartDate: currentStartDate.toISO(),
43
+ currentEndDate: currentEndDate.toISO(),
44
+ previousStartDate: previousStartDate.toISO(),
45
+ previousEndDate: previousEndDate.toISO(),
46
+ };
47
+ },
48
+ formatDate: function (date) {
49
+ if (!(date instanceof Date)) return null;
50
+ // conver JS date object to luxon date time
51
+ const dt = DateTime.fromJSDate(date);
52
+ return dt.toFormat('dd/MM/yyyy HH:mm:ss');
53
+ }
54
+ };
55
+ module.exports = DateUtil;