tripstorekrabi-shared 1.22.3 → 1.22.4

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 (2) hide show
  1. package/package.json +2 -2
  2. package/price.js +47 -24
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tripstorekrabi-shared",
3
- "version": "1.22.3",
3
+ "version": "1.22.4",
4
4
  "description": "Shared library for Trip Store Krabi",
5
5
  "author": "Stefan Sommer <tonprince@gmail.com>",
6
6
  "repository": {
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "dayjs": "^1.11.19",
21
- "libphonenumber-js": "^1.12.29",
21
+ "libphonenumber-js": "^1.12.31",
22
22
  "nanoid": "^5.1.6"
23
23
  },
24
24
  "scripts": {
package/price.js CHANGED
@@ -39,7 +39,7 @@ export function calculateProductOperatorPrice(booking, pricing) {
39
39
  return booking.operatorPaymentStatus === "No Charge" ? 0 : calculateProductPrice(booking, pricing, { mode: OPERATOR_MODE });
40
40
  }
41
41
 
42
- function calculateSellingPrice(commissionRate, price) {
42
+ function calculateSellingPrice(commissionRate = 0, price) {
43
43
  return Math.floor(
44
44
  (price * 100) /
45
45
  (100 -
@@ -47,40 +47,65 @@ function calculateSellingPrice(commissionRate, price) {
47
47
  );
48
48
  }
49
49
 
50
+ function applyPromotionDiscount(price, config) {
51
+ if (!config || !config.inflatedPrices) {
52
+ return price;
53
+ }
54
+
55
+ const discountRate = Number(config.discount) || 0;
56
+
57
+ if (!isFinite(discountRate)) return price;
58
+ const denominator = 100 - discountRate;
59
+
60
+ if (denominator <= 0) {
61
+ console.warn("Invalid discount rate for inflation calculation:", discountRate);
62
+ return price;
63
+ }
64
+
65
+ const finalPrice = (price * 100) / denominator;
66
+ return Math.ceil(finalPrice * 100) / 100;
67
+ }
68
+
50
69
  function calculateProductPrice(booking, pricing, options = { mode: SELLING_MODE }) {
51
70
  if (pricing.promotion) {
52
- let departureDate = booking.departureDate instanceof Date ? dayjs(booking.departureDate) : typeof booking.departureDate?.toDate === 'function' ? dayjs(booking.departureDate.toDate()) : null;
53
- let startDate = pricing.promotion.startDate instanceof Date ? pricing.promotion.startDate : typeof pricing.promotion.startDate.toDate === 'function' ? pricing.promotion.startDate.toDate() : null;
54
- let endDate = pricing.promotion.endDate instanceof Date ? pricing.promotion.endDate : typeof pricing.promotion.endDate.toDate === 'function' ? pricing.promotion.endDate.toDate() : null;
71
+ const departureDate = booking.departureDate instanceof Date ? dayjs(booking.departureDate) : typeof booking.departureDate?.toDate === 'function' ? dayjs(booking.departureDate.toDate()) : null;
72
+ const startDate = pricing.promotion.startDate instanceof Date ? pricing.promotion.startDate : typeof pricing.promotion.startDate.toDate === 'function' ? pricing.promotion.startDate.toDate() : null;
73
+ const endDate = pricing.promotion.endDate instanceof Date ? pricing.promotion.endDate : typeof pricing.promotion.endDate.toDate === 'function' ? pricing.promotion.endDate.toDate() : null;
55
74
 
56
75
  if (departureDate?.isBetween(startDate, endDate, "day", "[]")) {
57
76
  pricing = { ...pricing, volumes: pricing.promotion.volumes };
58
77
  }
59
78
  }
60
79
 
61
- let type = pricing.type;
80
+ const type = pricing.type;
62
81
  let total = 0;
63
82
 
64
83
  switch (type) {
65
84
  case "person": {
66
- let volume = findVolume(booking, pricing);
85
+ const volume = findVolume(booking, pricing);
67
86
  if (!volume) {
68
87
  console.error(`No volume price found for the total amount of ${booking.adults + booking.children} people`);
69
88
  return undefined;
70
89
  } else {
71
- let bookingSourceKey = getBookingSourceKey(booking.otaPartnerRef);
90
+ const bookingSourceKey = getBookingSourceKey(booking.otaPartnerRef);
72
91
 
73
92
  if (volume[bookingSourceKey]) {
74
- let customPricing = volume[bookingSourceKey];
93
+ const customPricing = volume[bookingSourceKey];
75
94
 
76
95
  if (options.mode === SELLING_MODE) {
77
- let commissionRate = pricing.commissionRates?.[bookingSourceKey];
78
-
79
- if (commissionRate && commissionRate > 0) {
80
- total = booking.adults * calculateSellingPrice(commissionRate, customPricing.adult.partnerNetPrice) + (pricing.ageBands.child.active && volume.child && booking.children ? (booking.children * calculateSellingPrice(commissionRate, customPricing.child.partnerNetPrice)) : 0);
81
- } else {
82
- total = booking.adults * customPricing.adult.retailPrice + (pricing.ageBands.child.active && volume.child && booking.children ? booking.children * customPricing.child.retailPrice : 0);
96
+ const commissionRate = pricing.commissionRates?.[bookingSourceKey];
97
+ const baseNetPriceAdult = customPricing.adult.partnerNetPrice;
98
+ const baseRetailPriceAdult = calculateSellingPrice(commissionRate, baseNetPriceAdult);
99
+ const finalPriceAdult = applyPromotionDiscount(baseRetailPriceAdult, customPricing);
100
+
101
+ let finalPriceChild = 0;
102
+ if (pricing.ageBands.child.active && volume.child && booking.children) {
103
+ const baseNetPriceChild = customPricing.child.partnerNetPrice;
104
+ const baseRetailPriceChild = calculateSellingPrice(commissionRate, baseNetPriceChild);
105
+ finalPriceChild = applyPromotionDiscount(baseRetailPriceChild, customPricing);
83
106
  }
107
+
108
+ total = booking.adults * finalPriceAdult + (booking.children ? booking.children * finalPriceChild : 0);
84
109
  } else if (options.mode === PARTNER_MODE) {
85
110
  total = booking.adults * customPricing.adult.partnerNetPrice + (pricing.ageBands.child.active && volume.child && booking.children ? booking.children * customPricing.child.partnerNetPrice : 0);
86
111
  } else if (options.mode === OPERATOR_MODE) {
@@ -97,24 +122,22 @@ function calculateProductPrice(booking, pricing, options = { mode: SELLING_MODE
97
122
  }
98
123
  }
99
124
  case "group": {
100
- let volume = findVolume(booking, pricing);
125
+ const volume = findVolume(booking, pricing);
101
126
  if (!volume) {
102
127
  console.error(`No volume price found for the total amount of ${booking.adults + booking.children} people`);
103
128
  return undefined;
104
129
  } else {
105
- let bookingSourceKey = getBookingSourceKey(booking.otaPartnerRef);
130
+ const bookingSourceKey = getBookingSourceKey(booking.otaPartnerRef);
106
131
 
107
132
  if (volume[bookingSourceKey]) {
108
- let customPricing = volume[bookingSourceKey];
133
+ const customPricing = volume[bookingSourceKey];
109
134
 
110
135
  if (options.mode === SELLING_MODE) {
111
- let commissionRate = pricing.commissionRates?.[bookingSourceKey];
112
-
113
- if (commissionRate && commissionRate > 0) {
114
- total = calculateSellingPrice(commissionRate, customPricing.partnerNetPrice);
115
- } else {
116
- total = customPricing.retailPrice;
117
- }
136
+ const commissionRate = pricing.commissionRates?.[bookingSourceKey];
137
+ const baseNetPrice = customPricing.partnerNetPrice;
138
+ const baseRetailPrice = calculateSellingPrice(commissionRate, baseNetPrice);
139
+ const finalPrice = applyPromotionDiscount(baseRetailPrice, customPricing);
140
+ total = finalPrice;
118
141
  } else if (options.mode === PARTNER_MODE) {
119
142
  total = customPricing.partnerNetPrice
120
143
  } else if (options.mode === OPERATOR_MODE) {