@b2y/ecommerce-common 1.0.5 → 1.0.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.
- package/README.md +4 -4
- package/constants/AppConstants.js +3 -3
- package/constants/ReportConstants.js +14 -14
- package/constants/StatusMessageConstants.js +17 -17
- package/dbconnection/Connect.js +383 -379
- package/enum/AddressTypeEnum.js +6 -6
- package/enum/BooleanEnum.js +4 -4
- package/enum/EntityTypeEnum.js +11 -11
- package/enum/GenderEnum.js +7 -7
- package/enum/NotificationStatusEnum.js +5 -5
- package/enum/NotificationTypeEnum.js +9 -9
- package/enum/OrderStatusEnum.js +7 -7
- package/enum/PaymentMethodEnum.js +6 -6
- package/enum/PaymentStatusEnum.js +6 -6
- package/enum/PaymentTypeEnum.js +6 -6
- package/enum/PlatformEnum.js +4 -4
- package/enum/RegistrationStatusEnum.js +5 -5
- package/enum/SortByEnum.js +7 -7
- package/index.js +22 -22
- package/model/Address.js +95 -95
- package/model/AttributeType.js +50 -50
- package/model/AttributeValue.js +64 -64
- package/model/Banner.js +78 -78
- package/model/Brand.js +76 -76
- package/model/Cart.js +76 -76
- package/model/Category.js +72 -72
- package/model/CategoryAttributeType.js +62 -62
- package/model/Colour.js +52 -52
- package/model/Customer.js +94 -94
- package/model/DeviceToken.js +51 -51
- package/model/Document.js +70 -70
- package/model/DynamicUIComponent.js +52 -52
- package/model/Feedback.js +79 -79
- package/model/Inventory.js +83 -83
- package/model/NotificationHistory.js +67 -67
- package/model/Order.js +94 -94
- package/model/OrderItem.js +98 -98
- package/model/OrderItemHistory.js +69 -69
- package/model/OrderStatus.js +48 -48
- package/model/Payment.js +101 -101
- package/model/PaymentMethod.js +36 -36
- package/model/PaymentStatus.js +36 -36
- package/model/PaymentType.js +36 -36
- package/model/Permission.js +55 -55
- package/model/Product.js +82 -82
- package/model/ProductGroup.js +48 -48
- package/model/ProductSpecification.js +65 -65
- package/model/ProductVariant.js +75 -75
- package/model/ProductVariantAttribute.js +58 -58
- package/model/Role.js +61 -61
- package/model/RolePermissionMapping.js +63 -63
- package/model/SpecificationType.js +41 -41
- package/model/Store.js +99 -99
- package/model/StoreUserMapping.js +44 -44
- package/model/Tenant.js +91 -91
- package/model/TenantSettings.js +47 -47
- package/model/User.js +132 -132
- package/model/WishList.js +62 -62
- package/package.json +29 -28
- package/utility/AppUtil.js +65 -57
- package/utility/DateUtil.js +55 -55
- package/utility/ExcelUtil.js +125 -125
- package/utility/LocationUtility.js +130 -130
- package/utility/OrderTimeFilterUtil.js +87 -87
- package/utility/PdfUtil.js +64 -0
- package/utility/QueryUtil.js +261 -261
- package/utility/Razorpay.js +65 -65
- package/utility/VariantPriceUtil.js +54 -54
|
@@ -1,131 +1,131 @@
|
|
|
1
|
-
const { getCountries, getStatesOfCountry, getCitiesOfState } = require('@countrystatecity/countries');
|
|
2
|
-
|
|
3
|
-
// Helper to resolve country and state names from codes
|
|
4
|
-
async function resolveCountryAndState(countryCode, stateCode, logger) {
|
|
5
|
-
// eslint-disable-next-line no-useless-catch
|
|
6
|
-
try {
|
|
7
|
-
const trimmedCountry = countryCode ? String(countryCode).trim() : "";
|
|
8
|
-
const trimmedState = stateCode ? String(stateCode).trim() : "";
|
|
9
|
-
|
|
10
|
-
let countryName = trimmedCountry;
|
|
11
|
-
let stateName = trimmedState;
|
|
12
|
-
|
|
13
|
-
if (trimmedCountry) {
|
|
14
|
-
try {
|
|
15
|
-
const countries = await getCountries();
|
|
16
|
-
const country = countries.find(
|
|
17
|
-
(c) =>
|
|
18
|
-
c.iso2 === trimmedCountry || c.iso2 === trimmedCountry.toUpperCase()
|
|
19
|
-
);
|
|
20
|
-
if (country) countryName = country.name;
|
|
21
|
-
} catch (err) {
|
|
22
|
-
logger.error("Error resolving country name:", err);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if (trimmedState) {
|
|
27
|
-
try {
|
|
28
|
-
const states = await getStatesOfCountry(trimmedCountry);
|
|
29
|
-
const state = states.find(
|
|
30
|
-
(s) =>
|
|
31
|
-
s.iso2 === trimmedState ||
|
|
32
|
-
s.state_code === trimmedState ||
|
|
33
|
-
s.state_code === trimmedState.toUpperCase()
|
|
34
|
-
);
|
|
35
|
-
if (state) stateName = state.name;
|
|
36
|
-
} catch (err) {
|
|
37
|
-
logger.error("Error resolving state name:", err);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return { countryName, stateName };
|
|
42
|
-
} catch (err) {
|
|
43
|
-
throw err;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Helper to validate country and state codes
|
|
48
|
-
async function validateCountryAndState(countryCode, stateCode, cityName, countryCallingCode, logger) {
|
|
49
|
-
try {
|
|
50
|
-
const trimmedCountryCode = countryCode ? String(countryCode).trim() : "";
|
|
51
|
-
const trimmedStateCode = stateCode ? String(stateCode).trim() : "";
|
|
52
|
-
const trimmedCityName = cityName ? cityName.trim().toLowerCase() : "";
|
|
53
|
-
const trimmedCountryCallingCode = countryCallingCode ? countryCallingCode.replace('+', '').trim() : "";
|
|
54
|
-
// Validate country code exists
|
|
55
|
-
if (trimmedCountryCode) {
|
|
56
|
-
const countries = await getCountries();
|
|
57
|
-
const validCountry = countries.find(
|
|
58
|
-
(c) =>
|
|
59
|
-
c.iso2 === trimmedCountryCode ||
|
|
60
|
-
c.iso2 === trimmedCountryCode.toUpperCase()
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
if (!validCountry) {
|
|
64
|
-
return {
|
|
65
|
-
isValid: false,
|
|
66
|
-
error: `Invalid country code: ${countryCode}`,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// Validate state code if provided
|
|
71
|
-
if (trimmedStateCode) {
|
|
72
|
-
const states = await getStatesOfCountry(trimmedCountryCode);
|
|
73
|
-
const validState = states.find(
|
|
74
|
-
(s) =>
|
|
75
|
-
s.iso2 === trimmedStateCode ||
|
|
76
|
-
s.state_code === trimmedStateCode ||
|
|
77
|
-
s.state_code === trimmedStateCode.toUpperCase()
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
if (!validState) {
|
|
81
|
-
return {
|
|
82
|
-
isValid: false,
|
|
83
|
-
error: `Invalid state code: ${stateCode} for country: ${countryCode}`,
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
if (trimmedCityName) {
|
|
88
|
-
const cities = await getCitiesOfState(
|
|
89
|
-
trimmedCountryCode,
|
|
90
|
-
trimmedStateCode
|
|
91
|
-
);
|
|
92
|
-
const cityFound = cities.some(
|
|
93
|
-
(city) => city.name.trim().toLowerCase() === trimmedCityName
|
|
94
|
-
);
|
|
95
|
-
if (!cityFound) {
|
|
96
|
-
return {
|
|
97
|
-
isValid: false,
|
|
98
|
-
error: `Invalid city name for state code ${stateCode} and country code ${countryCode}`,
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (trimmedCountryCallingCode) {
|
|
103
|
-
const countries = await getCountries();
|
|
104
|
-
const validCallingCode = countries.find(
|
|
105
|
-
(country) =>
|
|
106
|
-
country.iso2 === trimmedCountryCode &&
|
|
107
|
-
country.phonecode === trimmedCountryCallingCode
|
|
108
|
-
);
|
|
109
|
-
if (!validCallingCode) {
|
|
110
|
-
return {
|
|
111
|
-
isValid: false,
|
|
112
|
-
error: `Invalid country calling code for country code ${trimmedCountryCode}`,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
return { isValid: true };
|
|
119
|
-
} catch (err) {
|
|
120
|
-
logger.error("Error during country/state/city validation:", err);
|
|
121
|
-
return {
|
|
122
|
-
isValid: false,
|
|
123
|
-
error: "Error validating country code, state code and city name",
|
|
124
|
-
};
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
module.exports = {
|
|
129
|
-
resolveCountryAndState,
|
|
130
|
-
validateCountryAndState
|
|
1
|
+
const { getCountries, getStatesOfCountry, getCitiesOfState } = require('@countrystatecity/countries');
|
|
2
|
+
|
|
3
|
+
// Helper to resolve country and state names from codes
|
|
4
|
+
async function resolveCountryAndState(countryCode, stateCode, logger) {
|
|
5
|
+
// eslint-disable-next-line no-useless-catch
|
|
6
|
+
try {
|
|
7
|
+
const trimmedCountry = countryCode ? String(countryCode).trim() : "";
|
|
8
|
+
const trimmedState = stateCode ? String(stateCode).trim() : "";
|
|
9
|
+
|
|
10
|
+
let countryName = trimmedCountry;
|
|
11
|
+
let stateName = trimmedState;
|
|
12
|
+
|
|
13
|
+
if (trimmedCountry) {
|
|
14
|
+
try {
|
|
15
|
+
const countries = await getCountries();
|
|
16
|
+
const country = countries.find(
|
|
17
|
+
(c) =>
|
|
18
|
+
c.iso2 === trimmedCountry || c.iso2 === trimmedCountry.toUpperCase()
|
|
19
|
+
);
|
|
20
|
+
if (country) countryName = country.name;
|
|
21
|
+
} catch (err) {
|
|
22
|
+
logger.error("Error resolving country name:", err);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (trimmedState) {
|
|
27
|
+
try {
|
|
28
|
+
const states = await getStatesOfCountry(trimmedCountry);
|
|
29
|
+
const state = states.find(
|
|
30
|
+
(s) =>
|
|
31
|
+
s.iso2 === trimmedState ||
|
|
32
|
+
s.state_code === trimmedState ||
|
|
33
|
+
s.state_code === trimmedState.toUpperCase()
|
|
34
|
+
);
|
|
35
|
+
if (state) stateName = state.name;
|
|
36
|
+
} catch (err) {
|
|
37
|
+
logger.error("Error resolving state name:", err);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return { countryName, stateName };
|
|
42
|
+
} catch (err) {
|
|
43
|
+
throw err;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Helper to validate country and state codes
|
|
48
|
+
async function validateCountryAndState(countryCode, stateCode, cityName, countryCallingCode, logger) {
|
|
49
|
+
try {
|
|
50
|
+
const trimmedCountryCode = countryCode ? String(countryCode).trim() : "";
|
|
51
|
+
const trimmedStateCode = stateCode ? String(stateCode).trim() : "";
|
|
52
|
+
const trimmedCityName = cityName ? cityName.trim().toLowerCase() : "";
|
|
53
|
+
const trimmedCountryCallingCode = countryCallingCode ? countryCallingCode.replace('+', '').trim() : "";
|
|
54
|
+
// Validate country code exists
|
|
55
|
+
if (trimmedCountryCode) {
|
|
56
|
+
const countries = await getCountries();
|
|
57
|
+
const validCountry = countries.find(
|
|
58
|
+
(c) =>
|
|
59
|
+
c.iso2 === trimmedCountryCode ||
|
|
60
|
+
c.iso2 === trimmedCountryCode.toUpperCase()
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
if (!validCountry) {
|
|
64
|
+
return {
|
|
65
|
+
isValid: false,
|
|
66
|
+
error: `Invalid country code: ${countryCode}`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Validate state code if provided
|
|
71
|
+
if (trimmedStateCode) {
|
|
72
|
+
const states = await getStatesOfCountry(trimmedCountryCode);
|
|
73
|
+
const validState = states.find(
|
|
74
|
+
(s) =>
|
|
75
|
+
s.iso2 === trimmedStateCode ||
|
|
76
|
+
s.state_code === trimmedStateCode ||
|
|
77
|
+
s.state_code === trimmedStateCode.toUpperCase()
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
if (!validState) {
|
|
81
|
+
return {
|
|
82
|
+
isValid: false,
|
|
83
|
+
error: `Invalid state code: ${stateCode} for country: ${countryCode}`,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (trimmedCityName) {
|
|
88
|
+
const cities = await getCitiesOfState(
|
|
89
|
+
trimmedCountryCode,
|
|
90
|
+
trimmedStateCode
|
|
91
|
+
);
|
|
92
|
+
const cityFound = cities.some(
|
|
93
|
+
(city) => city.name.trim().toLowerCase() === trimmedCityName
|
|
94
|
+
);
|
|
95
|
+
if (!cityFound) {
|
|
96
|
+
return {
|
|
97
|
+
isValid: false,
|
|
98
|
+
error: `Invalid city name for state code ${stateCode} and country code ${countryCode}`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (trimmedCountryCallingCode) {
|
|
103
|
+
const countries = await getCountries();
|
|
104
|
+
const validCallingCode = countries.find(
|
|
105
|
+
(country) =>
|
|
106
|
+
country.iso2 === trimmedCountryCode &&
|
|
107
|
+
country.phonecode === trimmedCountryCallingCode
|
|
108
|
+
);
|
|
109
|
+
if (!validCallingCode) {
|
|
110
|
+
return {
|
|
111
|
+
isValid: false,
|
|
112
|
+
error: `Invalid country calling code for country code ${trimmedCountryCode}`,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return { isValid: true };
|
|
119
|
+
} catch (err) {
|
|
120
|
+
logger.error("Error during country/state/city validation:", err);
|
|
121
|
+
return {
|
|
122
|
+
isValid: false,
|
|
123
|
+
error: "Error validating country code, state code and city name",
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
module.exports = {
|
|
129
|
+
resolveCountryAndState,
|
|
130
|
+
validateCountryAndState
|
|
131
131
|
};
|
|
@@ -1,87 +1,87 @@
|
|
|
1
|
-
class OrderTimeFilterUtil {
|
|
2
|
-
static getDateRange(filter) {
|
|
3
|
-
if (!filter) return null;
|
|
4
|
-
|
|
5
|
-
const today = new Date();
|
|
6
|
-
let startDate, endDate;
|
|
7
|
-
|
|
8
|
-
switch (filter.toLowerCase()) {
|
|
9
|
-
case AppConstants.LAST_30DAYS.toLowerCase():
|
|
10
|
-
startDate = new Date(today);
|
|
11
|
-
startDate.setDate(today.getDate() - 30);
|
|
12
|
-
startDate.setHours(0, 0, 0, 0);
|
|
13
|
-
endDate = new Date(today);
|
|
14
|
-
endDate.setHours(23, 59, 59, 999);
|
|
15
|
-
break;
|
|
16
|
-
|
|
17
|
-
case AppConstants.LAST_6MONTHS.toLowerCase():
|
|
18
|
-
startDate = new Date(today);
|
|
19
|
-
startDate.setMonth(today.getMonth() - 6);
|
|
20
|
-
startDate.setHours(0, 0, 0, 0);
|
|
21
|
-
endDate = new Date(today);
|
|
22
|
-
endDate.setHours(23, 59, 59, 999);
|
|
23
|
-
break;
|
|
24
|
-
|
|
25
|
-
case AppConstants.OLDER.toLowerCase():
|
|
26
|
-
startDate = new Date(1970, 0, 1);
|
|
27
|
-
endDate = new Date(today);
|
|
28
|
-
break;
|
|
29
|
-
|
|
30
|
-
default:
|
|
31
|
-
const year = parseInt(filter);
|
|
32
|
-
if (!isNaN(year)) {
|
|
33
|
-
return this.getYearRange(year);
|
|
34
|
-
}
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return { startDate, endDate };
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
static getYearRange(year) {
|
|
42
|
-
const today = new Date();
|
|
43
|
-
const startDate = new Date(year, 0, 1);
|
|
44
|
-
|
|
45
|
-
if (year === today.getFullYear()) {
|
|
46
|
-
const endDate = new Date(today);
|
|
47
|
-
endDate.setHours(23, 59, 59, 999);
|
|
48
|
-
return { startDate, endDate };
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
startDate,
|
|
53
|
-
endDate: new Date(year, 11, 31, 23, 59, 59, 999)
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
static isValidFilter(filter) {
|
|
58
|
-
if (!filter) return false;
|
|
59
|
-
|
|
60
|
-
const validFilters = [
|
|
61
|
-
AppConstants.LAST_30DAYS.toLowerCase(),
|
|
62
|
-
AppConstants.LAST_6MONTHS.toLowerCase(),
|
|
63
|
-
AppConstants.OLDER.toLowerCase()
|
|
64
|
-
];
|
|
65
|
-
|
|
66
|
-
if (validFilters.includes(filter.toLowerCase())) {
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const year = parseInt(filter);
|
|
71
|
-
const currentYear = new Date().getFullYear();
|
|
72
|
-
return !isNaN(year) && year <= currentYear && year;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
static buildWhereCondition(filter, Sequelize) {
|
|
76
|
-
const dateRange = this.getDateRange(filter);
|
|
77
|
-
if (!dateRange) return null;
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
[Sequelize.Op.gte]: dateRange.startDate,
|
|
81
|
-
[Sequelize.Op.lte]: dateRange.endDate
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
module.exports = OrderTimeFilterUtil;
|
|
87
|
-
|
|
1
|
+
class OrderTimeFilterUtil {
|
|
2
|
+
static getDateRange(filter) {
|
|
3
|
+
if (!filter) return null;
|
|
4
|
+
|
|
5
|
+
const today = new Date();
|
|
6
|
+
let startDate, endDate;
|
|
7
|
+
|
|
8
|
+
switch (filter.toLowerCase()) {
|
|
9
|
+
case AppConstants.LAST_30DAYS.toLowerCase():
|
|
10
|
+
startDate = new Date(today);
|
|
11
|
+
startDate.setDate(today.getDate() - 30);
|
|
12
|
+
startDate.setHours(0, 0, 0, 0);
|
|
13
|
+
endDate = new Date(today);
|
|
14
|
+
endDate.setHours(23, 59, 59, 999);
|
|
15
|
+
break;
|
|
16
|
+
|
|
17
|
+
case AppConstants.LAST_6MONTHS.toLowerCase():
|
|
18
|
+
startDate = new Date(today);
|
|
19
|
+
startDate.setMonth(today.getMonth() - 6);
|
|
20
|
+
startDate.setHours(0, 0, 0, 0);
|
|
21
|
+
endDate = new Date(today);
|
|
22
|
+
endDate.setHours(23, 59, 59, 999);
|
|
23
|
+
break;
|
|
24
|
+
|
|
25
|
+
case AppConstants.OLDER.toLowerCase():
|
|
26
|
+
startDate = new Date(1970, 0, 1);
|
|
27
|
+
endDate = new Date(today);
|
|
28
|
+
break;
|
|
29
|
+
|
|
30
|
+
default:
|
|
31
|
+
const year = parseInt(filter);
|
|
32
|
+
if (!isNaN(year)) {
|
|
33
|
+
return this.getYearRange(year);
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return { startDate, endDate };
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static getYearRange(year) {
|
|
42
|
+
const today = new Date();
|
|
43
|
+
const startDate = new Date(year, 0, 1);
|
|
44
|
+
|
|
45
|
+
if (year === today.getFullYear()) {
|
|
46
|
+
const endDate = new Date(today);
|
|
47
|
+
endDate.setHours(23, 59, 59, 999);
|
|
48
|
+
return { startDate, endDate };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
startDate,
|
|
53
|
+
endDate: new Date(year, 11, 31, 23, 59, 59, 999)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
static isValidFilter(filter) {
|
|
58
|
+
if (!filter) return false;
|
|
59
|
+
|
|
60
|
+
const validFilters = [
|
|
61
|
+
AppConstants.LAST_30DAYS.toLowerCase(),
|
|
62
|
+
AppConstants.LAST_6MONTHS.toLowerCase(),
|
|
63
|
+
AppConstants.OLDER.toLowerCase()
|
|
64
|
+
];
|
|
65
|
+
|
|
66
|
+
if (validFilters.includes(filter.toLowerCase())) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const year = parseInt(filter);
|
|
71
|
+
const currentYear = new Date().getFullYear();
|
|
72
|
+
return !isNaN(year) && year <= currentYear && year;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static buildWhereCondition(filter, Sequelize) {
|
|
76
|
+
const dateRange = this.getDateRange(filter);
|
|
77
|
+
if (!dateRange) return null;
|
|
78
|
+
|
|
79
|
+
return {
|
|
80
|
+
[Sequelize.Op.gte]: dateRange.startDate,
|
|
81
|
+
[Sequelize.Op.lte]: dateRange.endDate
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
}
|
|
86
|
+
module.exports = OrderTimeFilterUtil;
|
|
87
|
+
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// utils/PdfUtil.js
|
|
2
|
+
const puppeteer = require('puppeteer');
|
|
3
|
+
|
|
4
|
+
class PdfUtil {
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
this.defaultOptions = {
|
|
7
|
+
format: 'A4',
|
|
8
|
+
printBackground: true,
|
|
9
|
+
margin: {
|
|
10
|
+
top: '20px',
|
|
11
|
+
right: '20px',
|
|
12
|
+
bottom: '20px',
|
|
13
|
+
left: '20px'
|
|
14
|
+
},
|
|
15
|
+
...options
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Generate PDF from HTML content
|
|
21
|
+
* @param {string} htmlContent - Complete HTML content to convert to PDF
|
|
22
|
+
* @param {object} pdfOptions - Optional PDF generation options (overrides defaults)
|
|
23
|
+
* @returns {Buffer} PDF buffer
|
|
24
|
+
*/
|
|
25
|
+
async generatePDFFromHTML(htmlContent, pdfOptions = {}) {
|
|
26
|
+
let browser;
|
|
27
|
+
try {
|
|
28
|
+
// Launch puppeteer
|
|
29
|
+
browser = await puppeteer.launch({
|
|
30
|
+
headless: true,
|
|
31
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox']
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const page = await browser.newPage();
|
|
35
|
+
|
|
36
|
+
// Set content and wait for any resources to load
|
|
37
|
+
await page.setContent(htmlContent, { waitUntil: 'networkidle0' });
|
|
38
|
+
|
|
39
|
+
// Merge default options with provided options
|
|
40
|
+
const finalOptions = { ...this.defaultOptions, ...pdfOptions };
|
|
41
|
+
|
|
42
|
+
// Generate PDF
|
|
43
|
+
const pdfBuffer = await page.pdf(finalOptions);
|
|
44
|
+
|
|
45
|
+
return pdfBuffer;
|
|
46
|
+
|
|
47
|
+
} catch (error) {
|
|
48
|
+
throw error;
|
|
49
|
+
} finally {
|
|
50
|
+
if (browser) {
|
|
51
|
+
await browser.close();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Generate PDF with custom page settings
|
|
58
|
+
*/
|
|
59
|
+
async generatePDFWithCustomSettings(htmlContent, settings) {
|
|
60
|
+
return this.generatePDFFromHTML(htmlContent, settings);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = PdfUtil;
|