tripstorekrabi-shared 1.24.4 → 1.24.5
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/booking.js +102 -129
- package/package.json +1 -1
package/booking.js
CHANGED
|
@@ -2,7 +2,6 @@ import dayjs from 'dayjs';
|
|
|
2
2
|
import advancedFormat from 'dayjs/plugin/advancedFormat.js';
|
|
3
3
|
import utc from 'dayjs/plugin/utc.js';
|
|
4
4
|
import timezone from 'dayjs/plugin/timezone.js';
|
|
5
|
-
import { FieldValue, Timestamp } from 'firebase-admin/firestore';
|
|
6
5
|
import { PAY_ON_TOUR, calculateTotalOperatorPrice } from './price.js';
|
|
7
6
|
import { nanoid } from 'nanoid';
|
|
8
7
|
import { CHECK_IN_LATE, IN_HOUSE, isAirportDropOff, isAirportPickup, isHotelPickup, isTrainStation, KEEP_PRIVATE, NO_PICKUP_HOTEL_YET, NO_ROOM, STAY_NEARBY } from './utils.js';
|
|
@@ -28,148 +27,122 @@ export function addBookingFromInvoice(
|
|
|
28
27
|
) {
|
|
29
28
|
let bookingNumberDoc = firestore.collection('meta').doc('BOOKING_NUMBER');
|
|
30
29
|
|
|
31
|
-
return firestore.runTransaction((transaction) => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
let processed = 0;
|
|
35
|
-
|
|
36
|
-
for (let i = 0; i < invoice.items.length; i++) {
|
|
37
|
-
let item = invoice.items[i];
|
|
38
|
-
|
|
39
|
-
// process only product items
|
|
40
|
-
let hasProduct = item.productId?.length > 0;
|
|
41
|
-
let productSnapshot = null;
|
|
42
|
-
let productDescription;
|
|
43
|
-
if (hasProduct) {
|
|
44
|
-
productSnapshot = await firestore
|
|
45
|
-
.collection('products')
|
|
46
|
-
.doc(item.productId)
|
|
47
|
-
.get();
|
|
48
|
-
productDescription = productSnapshot.get('shortName');
|
|
49
|
-
} else {
|
|
50
|
-
productDescription = item.description;
|
|
51
|
-
}
|
|
30
|
+
return firestore.runTransaction(async (transaction) => {
|
|
31
|
+
const snapshot = await transaction.get(bookingNumberDoc);
|
|
32
|
+
const currentLast = snapshot.get('last') ?? 0;
|
|
52
33
|
|
|
53
|
-
|
|
34
|
+
const productSnapshots = {};
|
|
35
|
+
for (const item of invoice.items) {
|
|
36
|
+
if (item.productId?.length > 0 && !productSnapshots[item.productId]) {
|
|
37
|
+
const productRef = firestore.collection('products').doc(item.productId);
|
|
38
|
+
productSnapshots[item.productId] = await transaction.get(productRef);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
54
41
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
description: comment.trim(),
|
|
58
|
-
visibility: [],
|
|
59
|
-
lastModified: dayjs().toDate(),
|
|
60
|
-
lastModifiedBy: 'Trip Store Krabi Next',
|
|
61
|
-
};
|
|
62
|
-
}
|
|
42
|
+
let nextBookingNumber = currentLast + 1;
|
|
43
|
+
let processed = 0;
|
|
63
44
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
};
|
|
71
|
-
}
|
|
45
|
+
for (let i = 0; i < invoice.items.length; i++) {
|
|
46
|
+
let item = invoice.items[i];
|
|
47
|
+
let hasProduct = item.productId?.length > 0;
|
|
48
|
+
|
|
49
|
+
let productSnapshot = hasProduct ? productSnapshots[item.productId] : null;
|
|
50
|
+
let productDescription = hasProduct ? productSnapshot.get('shortName') : item.description;
|
|
72
51
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
: null,
|
|
80
|
-
operator: productSnapshot?.get('operator.default.name') ?? '',
|
|
81
|
-
departureDate: Timestamp.fromDate(
|
|
82
|
-
dayjs(item.departureDate).toDate()
|
|
83
|
-
),
|
|
84
|
-
schedule: item.schedule ?? '',
|
|
85
|
-
pickupTime: '?',
|
|
86
|
-
adults: item.adults ?? 0,
|
|
87
|
-
children: item.children ?? 0,
|
|
88
|
-
infants: item.infants ?? 0,
|
|
89
|
-
leadTraveller: invoice.name,
|
|
90
|
-
email: invoice.email ?? '',
|
|
91
|
-
phoneNumber: invoice.phoneNumber ?? '',
|
|
92
|
-
cc: '',
|
|
93
|
-
customerBookingStatus: 'Pending',
|
|
94
|
-
operatorBookingStatus: 'Pending',
|
|
95
|
-
sentToOperator: false,
|
|
96
|
-
startingPointDescription: item.startingPointDescription ?? "",
|
|
97
|
-
pickupHotel: item.pickupHotel ?? null,
|
|
98
|
-
roomNumber: item.roomNumber ?? '',
|
|
99
|
-
googleMapsLocation: item.googleMapsLocation ?? '',
|
|
100
|
-
dietary: item.dietary ?? "",
|
|
101
|
-
flight: item.flight ?? null,
|
|
102
|
-
train: item.train ?? null,
|
|
103
|
-
customerPaymentStatus: 'Paid',
|
|
104
|
-
operatorPaymentStatus: 'Pending',
|
|
105
|
-
extraPayments: {},
|
|
106
|
-
addOns: item.addOns ?? null,
|
|
107
|
-
labels: ['NEW'],
|
|
108
|
-
paypalInvoiceId: '',
|
|
109
|
-
paypalTransactionId: '',
|
|
110
|
-
omiseChargeId: '',
|
|
111
|
-
invoiceNumber: '',
|
|
112
|
-
date: FieldValue.serverTimestamp(),
|
|
113
|
-
createdBy: 'Trip Store Krabi Next',
|
|
52
|
+
let notes = {};
|
|
53
|
+
|
|
54
|
+
if (comment) {
|
|
55
|
+
notes[nanoid()] = {
|
|
56
|
+
description: comment.trim(),
|
|
57
|
+
visibility: [],
|
|
114
58
|
lastModified: dayjs().toDate(),
|
|
115
59
|
lastModifiedBy: 'Trip Store Krabi Next',
|
|
116
60
|
};
|
|
61
|
+
}
|
|
117
62
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (i > 0) {
|
|
127
|
-
data.partnerNetPrice = 0;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (item.nationalParkFee) {
|
|
131
|
-
data.nationalParkFee = item.nationalParkFee;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (item.tourGuideLanguage) {
|
|
135
|
-
data.tourGuideLanguage = item.tourGuideLanguage;
|
|
136
|
-
}
|
|
63
|
+
if (invoice.comment) {
|
|
64
|
+
notes[nanoid()] = {
|
|
65
|
+
description: invoice.comment.trim(),
|
|
66
|
+
visibility: [],
|
|
67
|
+
lastModified: dayjs().toDate(),
|
|
68
|
+
lastModifiedBy: 'Trip Store Krabi Next',
|
|
69
|
+
};
|
|
70
|
+
}
|
|
137
71
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
72
|
+
let data = {
|
|
73
|
+
date: dayjs().toDate(),
|
|
74
|
+
departureDate: dayjs(item.departureDate).toDate(),
|
|
75
|
+
referenceNumber: 'TSK' + (nextBookingNumber + processed),
|
|
76
|
+
notes,
|
|
77
|
+
productDescription,
|
|
78
|
+
productRef: hasProduct ? firestore.collection('products').doc(item.productId) : null,
|
|
79
|
+
operator: productSnapshot?.get('operator.default.name') ?? '',
|
|
80
|
+
schedule: item.schedule ?? '',
|
|
81
|
+
pickupTime: '?',
|
|
82
|
+
adults: item.adults ?? 0,
|
|
83
|
+
children: item.children ?? 0,
|
|
84
|
+
infants: item.infants ?? 0,
|
|
85
|
+
leadTraveller: invoice.name,
|
|
86
|
+
email: invoice.email ?? '',
|
|
87
|
+
phoneNumber: invoice.phoneNumber ?? '',
|
|
88
|
+
cc: '',
|
|
89
|
+
customerBookingStatus: 'Pending',
|
|
90
|
+
operatorBookingStatus: 'Pending',
|
|
91
|
+
sentToOperator: false,
|
|
92
|
+
startingPointDescription: item.startingPointDescription ?? "",
|
|
93
|
+
pickupHotel: item.pickupHotel ?? null,
|
|
94
|
+
roomNumber: item.roomNumber ?? '',
|
|
95
|
+
googleMapsLocation: item.googleMapsLocation ?? '',
|
|
96
|
+
dietary: item.dietary ?? "",
|
|
97
|
+
flight: item.flight ?? null,
|
|
98
|
+
train: item.train ?? null,
|
|
99
|
+
customerPaymentStatus: 'Paid',
|
|
100
|
+
operatorPaymentStatus: 'Pending',
|
|
101
|
+
extraPayments: {},
|
|
102
|
+
addOns: item.addOns ?? null,
|
|
103
|
+
labels: ['NEW'],
|
|
104
|
+
paypalInvoiceId: '',
|
|
105
|
+
paypalTransactionId: '',
|
|
106
|
+
omiseChargeId: '',
|
|
107
|
+
invoiceNumber: '',
|
|
108
|
+
createdBy: 'Trip Store Krabi Next',
|
|
109
|
+
lastModified: dayjs().toDate(),
|
|
110
|
+
lastModifiedBy: 'Trip Store Krabi Next',
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
if (item.startingPointId) data.startingPointId = item.startingPointId;
|
|
114
|
+
if (item.dropoffHotel && item.dropoffHotel.length > 0) data.dropoffHotel = item.dropoffHotel;
|
|
115
|
+
if (i > 0) data.partnerNetPrice = 0;
|
|
116
|
+
if (item.nationalParkFee) data.nationalParkFee = item.nationalParkFee;
|
|
117
|
+
if (item.tourGuideLanguage) data.tourGuideLanguage = item.tourGuideLanguage;
|
|
118
|
+
|
|
119
|
+
let endPointId = item.endPointId;
|
|
120
|
+
if (!endPointId) {
|
|
121
|
+
let endPoints = productSnapshot?.get('endPoints');
|
|
122
|
+
if (endPoints && endPoints.length === 1) {
|
|
123
|
+
endPointId = endPoints[0].id;
|
|
147
124
|
}
|
|
125
|
+
}
|
|
126
|
+
if (endPointId) data.endPointId = endPointId;
|
|
148
127
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
} else {
|
|
155
|
-
data.operatorNetPrice = 0;
|
|
156
|
-
}
|
|
128
|
+
if (productSnapshot) {
|
|
129
|
+
data.operatorNetPrice = calculateTotalOperatorPrice(data, productSnapshot.data());
|
|
130
|
+
} else {
|
|
131
|
+
data.operatorNetPrice = 0;
|
|
132
|
+
}
|
|
157
133
|
|
|
158
|
-
|
|
134
|
+
data = { ...data, ...paymentData };
|
|
159
135
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
136
|
+
let doc = firestore.collection('bookings').doc();
|
|
137
|
+
transaction.set(doc, data);
|
|
138
|
+
processed++;
|
|
139
|
+
}
|
|
164
140
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
{ merge: true }
|
|
171
|
-
);
|
|
172
|
-
});
|
|
141
|
+
transaction.set(
|
|
142
|
+
bookingNumberDoc,
|
|
143
|
+
{ last: currentLast + processed },
|
|
144
|
+
{ merge: true }
|
|
145
|
+
);
|
|
173
146
|
});
|
|
174
147
|
}
|
|
175
148
|
|