@driveflux/api-functions 1.0.72 → 1.0.74
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/dist/auth/confirm.js +24 -29
- package/dist/auth/emails.js +12 -13
- package/dist/auth/formatter.js +5 -5
- package/dist/auth/otp.js +66 -50
- package/dist/auth/register.js +42 -34
- package/dist/auth/tokens.js +58 -55
- package/dist/auth/verifications.js +53 -52
- package/dist/constants.js +0 -1
- package/dist/create-logger.js +1 -2
- package/dist/mailjet/calls/manage-contacts-in-list.js +5 -6
- package/dist/mailjet/calls/manage-subscription-status.js +4 -5
- package/dist/mailjet/calls/request-service.js +7 -6
- package/dist/mailjet/refresh-email-preferences.js +11 -12
- package/dist/mailjet/set-contact.js +11 -12
- package/dist/mailjet/types.js +1 -2
- package/dist/mailjet/utils/convert-to-array.js +8 -6
- package/dist/mailjet/utils/extract-email-preferences.js +14 -15
- package/dist/mailjet/utils/lists.js +7 -8
- package/dist/mailjet/utils/update-email-references.js +16 -15
- package/dist/notion/client.js +22 -19
- package/dist/notion/helpful.js +6 -9
- package/dist/notion/schemas/block.js +42 -48
- package/dist/notion/schemas/common.js +9 -14
- package/dist/notion/schemas/database.js +62 -60
- package/dist/notion/schemas/emoji.js +1 -2
- package/dist/notion/schemas/file.js +9 -9
- package/dist/notion/schemas/kb.js +5 -6
- package/dist/notion/schemas/page.js +72 -61
- package/dist/notion/schemas/parent.js +4 -5
- package/dist/notion/schemas/user.js +18 -19
- package/dist/reservation/agree.js +6 -7
- package/dist/reservation/checks.js +3 -4
- package/dist/reservation/display-vehicle.js +66 -74
- package/dist/reservation/ensure-user-billing-address.js +9 -11
- package/dist/reservation/fetch-or-create.js +83 -102
- package/dist/reservation/invoice.js +76 -125
- package/dist/reservation/payer.js +5 -6
- package/dist/reservation/payment-intent-sync.js +4 -6
- package/dist/reservation/reserve.js +3 -5
- package/dist/reservation/types.js +1 -2
- package/dist/reservation/vehicle.js +13 -16
- package/dist/slack.js +24 -29
- package/dist/validation.js +77 -79
- package/dist/vehicle/vehicle-pricing/constants.js +22 -19
- package/dist/vehicle/vehicle-pricing/index.js +28 -42
- package/dist/vehicle/vehicle-pricing/types.js +1 -2
- package/package.json +10 -11
|
@@ -1,73 +1,75 @@
|
|
|
1
1
|
import { config } from '@driveflux/config/backend';
|
|
2
|
-
import { prisma
|
|
2
|
+
import { prisma } from '@driveflux/db';
|
|
3
3
|
import { generateId } from '@driveflux/db/id';
|
|
4
4
|
import { createPricingController } from '@driveflux/db/models/vehicle';
|
|
5
|
-
import { getFluxExcessMileage, getFluxPiceMatrix, getHostExcessMileage, getHostsMatrix, getRecommendedMotorcycleDeposit, getStartFeeMatrix
|
|
6
|
-
export const fetchDisplayVehicle = async (displayVehicle)
|
|
7
|
-
return typeof displayVehicle === 'string'
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
import { getFluxExcessMileage, getFluxPiceMatrix, getHostExcessMileage, getHostsMatrix, getRecommendedMotorcycleDeposit, getStartFeeMatrix } from '../vehicle/vehicle-pricing/index.js';
|
|
6
|
+
export const fetchDisplayVehicle = async (displayVehicle)=>{
|
|
7
|
+
return typeof displayVehicle === 'string' ? await prisma.displayVehicle.findFirst({
|
|
8
|
+
where: {
|
|
9
|
+
id: displayVehicle
|
|
10
|
+
}
|
|
11
|
+
}) : displayVehicle;
|
|
10
12
|
};
|
|
11
|
-
export const createVehicleFromDisplayVehicle = async (displayVehicle, selectedColor)
|
|
13
|
+
export const createVehicleFromDisplayVehicle = async (displayVehicle, selectedColor)=>{
|
|
12
14
|
const dv = await fetchDisplayVehicle(displayVehicle);
|
|
13
|
-
if (!dv || typeof dv !== 'object')
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return;
|
|
17
|
-
const mainImage = dv.images.main.find((m) => m.variant === selectedColor)?.url;
|
|
15
|
+
if (!dv || typeof dv !== 'object') return;
|
|
16
|
+
if (!dv.details) return;
|
|
17
|
+
const mainImage = dv.images.main.find((m)=>m.variant === selectedColor)?.url;
|
|
18
18
|
const vehicleData = {
|
|
19
19
|
id: generateId('Vehicle'),
|
|
20
20
|
...transformBasicVehicleData(dv),
|
|
21
21
|
images: [
|
|
22
|
-
...
|
|
23
|
-
|
|
22
|
+
...mainImage ? [
|
|
23
|
+
transfromSingleImage(mainImage)
|
|
24
|
+
] : [],
|
|
25
|
+
...transformImages(dv.images)
|
|
24
26
|
],
|
|
25
27
|
...transformBasePrices(dv.pricing),
|
|
26
28
|
pricing: transformPriceMatrix(dv.type, dv.pricing),
|
|
27
29
|
details: transformDetails(dv.details, selectedColor),
|
|
28
30
|
host: {
|
|
29
31
|
connect: {
|
|
30
|
-
id: dv.defaultHostId
|
|
31
|
-
}
|
|
32
|
+
id: dv.defaultHostId
|
|
33
|
+
}
|
|
32
34
|
},
|
|
33
35
|
displayVehicle: {
|
|
34
36
|
connect: {
|
|
35
|
-
id: dv.id
|
|
36
|
-
}
|
|
37
|
-
}
|
|
37
|
+
id: dv.id
|
|
38
|
+
}
|
|
39
|
+
}
|
|
38
40
|
};
|
|
39
41
|
return await prisma.vehicle.create({
|
|
40
42
|
data: vehicleData,
|
|
41
43
|
include: {
|
|
42
|
-
host: true
|
|
43
|
-
}
|
|
44
|
+
host: true
|
|
45
|
+
}
|
|
44
46
|
});
|
|
45
47
|
};
|
|
46
|
-
export const transfromVehicleDisplayToVehicle = async (displayVehicle, selectedColor)
|
|
48
|
+
export const transfromVehicleDisplayToVehicle = async (displayVehicle, selectedColor)=>{
|
|
47
49
|
const dv = await fetchDisplayVehicle(displayVehicle);
|
|
48
|
-
if (!dv || typeof dv !== 'object')
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return;
|
|
52
|
-
const mainImage = dv.images.main.find((m) => m.variant === selectedColor)?.url;
|
|
50
|
+
if (!dv || typeof dv !== 'object') return;
|
|
51
|
+
if (!dv.details) return;
|
|
52
|
+
const mainImage = dv.images.main.find((m)=>m.variant === selectedColor)?.url;
|
|
53
53
|
return {
|
|
54
54
|
id: dv.id,
|
|
55
55
|
...transformBasicVehicleData(dv),
|
|
56
56
|
images: [
|
|
57
|
-
...
|
|
58
|
-
|
|
57
|
+
...mainImage ? [
|
|
58
|
+
transfromSingleImage(mainImage)
|
|
59
|
+
] : [],
|
|
60
|
+
...transformImages(dv.images)
|
|
59
61
|
],
|
|
60
62
|
...transformBasePrices(dv.pricing),
|
|
61
63
|
pricing: transformPriceMatrix(dv.type, dv.pricing),
|
|
62
64
|
details: transformDetails(dv.details, selectedColor),
|
|
63
65
|
host: {
|
|
64
66
|
address: {
|
|
65
|
-
state: 'Kuala Lumpur'
|
|
66
|
-
}
|
|
67
|
-
}
|
|
67
|
+
state: 'Kuala Lumpur'
|
|
68
|
+
}
|
|
69
|
+
}
|
|
68
70
|
};
|
|
69
71
|
};
|
|
70
|
-
export const transformBasicVehicleData = (dv)
|
|
72
|
+
export const transformBasicVehicleData = (dv)=>{
|
|
71
73
|
return {
|
|
72
74
|
registrationNumber: null,
|
|
73
75
|
featured: false,
|
|
@@ -85,17 +87,17 @@ export const transformBasicVehicleData = (dv) => {
|
|
|
85
87
|
type: dv.type,
|
|
86
88
|
niceName: `${dv.make} ${dv.vehicleModel} ${dv.variant} ${dv.year}`,
|
|
87
89
|
niceNameShort: `${dv.make} ${dv.vehicleModel}`,
|
|
88
|
-
appliedCoupon: dv.appliedCoupon
|
|
90
|
+
appliedCoupon: dv.appliedCoupon
|
|
89
91
|
};
|
|
90
92
|
};
|
|
91
|
-
export const transformImages = (images)
|
|
93
|
+
export const transformImages = (images)=>{
|
|
92
94
|
return [
|
|
93
95
|
transfromSingleImage(images.exterior[0].url, 'exterior'),
|
|
94
96
|
transfromSingleImage(images.interior[0].url, 'interior'),
|
|
95
|
-
...images.gallery.map((i)
|
|
97
|
+
...images.gallery.map((i)=>transfromSingleImage(i.url))
|
|
96
98
|
];
|
|
97
99
|
};
|
|
98
|
-
const transfromSingleImage = (imageUrl, inspectionType)
|
|
100
|
+
const transfromSingleImage = (imageUrl, inspectionType)=>{
|
|
99
101
|
return {
|
|
100
102
|
default: imageUrl,
|
|
101
103
|
blurBase64: null,
|
|
@@ -106,20 +108,20 @@ const transfromSingleImage = (imageUrl, inspectionType) => {
|
|
|
106
108
|
description: null,
|
|
107
109
|
inspection: !!inspectionType,
|
|
108
110
|
inspectionType: inspectionType || null,
|
|
109
|
-
notActualPhoto: true
|
|
111
|
+
notActualPhoto: true
|
|
110
112
|
};
|
|
111
113
|
};
|
|
112
|
-
const transformBasePrices = (pricing)
|
|
114
|
+
const transformBasePrices = (pricing)=>{
|
|
113
115
|
return {
|
|
114
116
|
basePrice: pricing.matrix.plan36.lite,
|
|
115
117
|
basePricePlan1: pricing.matrix.plan1.lite,
|
|
116
118
|
basePricePlan12: pricing.matrix.plan12.lite,
|
|
117
119
|
basePricePlan24: pricing.matrix.plan24.lite,
|
|
118
120
|
basePricePlan36: pricing.matrix.plan36.lite,
|
|
119
|
-
basePricePlan60: pricing.matrix.plan60.lite
|
|
121
|
+
basePricePlan60: pricing.matrix.plan60.lite
|
|
120
122
|
};
|
|
121
123
|
};
|
|
122
|
-
const transformPriceMatrix = (vehicleType, pricing)
|
|
124
|
+
const transformPriceMatrix = (vehicleType, pricing)=>{
|
|
123
125
|
const baseline = pricing?.matrix.plan36.lite;
|
|
124
126
|
const ultraTier = 'tier1';
|
|
125
127
|
const fluxPriceCoefficient = 25;
|
|
@@ -132,18 +134,14 @@ const transformPriceMatrix = (vehicleType, pricing) => {
|
|
|
132
134
|
const { availablePlans, availableMileagePackages } = getNonZeroKeys(priceMatrix);
|
|
133
135
|
const pricingController = createPricingController({
|
|
134
136
|
coefficient: fluxPriceCoefficient,
|
|
135
|
-
vehicleType
|
|
137
|
+
vehicleType
|
|
136
138
|
});
|
|
137
139
|
const startFeeMatrix = excludeServiceFeesFrom(getStartFeeMatrix(pricingController, baseline, flatPricing));
|
|
138
140
|
const hostMatrix = excludeServiceFeesFrom(getHostsMatrix(pricingController, baseline, ultraTier, flatPricing));
|
|
139
141
|
const hostExcessMileage = getHostExcessMileage(pricingController, baseline);
|
|
140
|
-
const fluxPriceMatrix =
|
|
141
|
-
? priceMatrix
|
|
142
|
-
: excludeServiceFeesFrom(getFluxPiceMatrix(pricingController, vehicleType, baseline, hostMatrix, ultraTier, flatPricing));
|
|
142
|
+
const fluxPriceMatrix = excludeServiceFeesFrom(getFluxPiceMatrix(pricingController, vehicleType, baseline, hostMatrix, ultraTier, flatPricing));
|
|
143
143
|
const fluxExcessMileage = getFluxExcessMileage(pricingController, baseline);
|
|
144
|
-
const recommendedDeposit = pricing.refundableDeposit || vehicleType === 'motorcycle'
|
|
145
|
-
? getRecommendedMotorcycleDeposit(baseline)
|
|
146
|
-
: null;
|
|
144
|
+
const recommendedDeposit = pricing.refundableDeposit || vehicleType === 'motorcycle' ? getRecommendedMotorcycleDeposit(baseline) : null;
|
|
147
145
|
return {
|
|
148
146
|
tmv,
|
|
149
147
|
gfv,
|
|
@@ -162,31 +160,31 @@ const transformPriceMatrix = (vehicleType, pricing) => {
|
|
|
162
160
|
excessMileage: fluxExcessMileage,
|
|
163
161
|
originalExcessMileage: fluxExcessMileage,
|
|
164
162
|
matrixComments: null,
|
|
165
|
-
add: null
|
|
163
|
+
add: null
|
|
166
164
|
},
|
|
167
165
|
hostTake: {
|
|
168
166
|
matrix: hostMatrix,
|
|
169
167
|
originalMatrix: hostMatrix,
|
|
170
168
|
excessMileage: hostExcessMileage,
|
|
171
169
|
originalExcessMileage: hostExcessMileage,
|
|
172
|
-
matrixComments: null
|
|
170
|
+
matrixComments: null
|
|
173
171
|
},
|
|
174
172
|
startFee: {
|
|
175
173
|
matrix: startFeeMatrix,
|
|
176
174
|
originalMatrix: startFeeMatrix,
|
|
177
|
-
matrixComments: null
|
|
178
|
-
}
|
|
175
|
+
matrixComments: null
|
|
176
|
+
}
|
|
179
177
|
};
|
|
180
178
|
};
|
|
181
|
-
const getNonZeroKeys = (matrix)
|
|
179
|
+
const getNonZeroKeys = (matrix)=>{
|
|
182
180
|
const planKeys = new Set();
|
|
183
181
|
const mileageKeys = new Set();
|
|
184
|
-
for (const [plan, mileageMap] of Object.entries(matrix))
|
|
182
|
+
for (const [plan, mileageMap] of Object.entries(matrix)){
|
|
185
183
|
const entries = Object.entries(mileageMap ?? {});
|
|
186
|
-
const hasNonZero = entries.some(([_, value])
|
|
184
|
+
const hasNonZero = entries.some(([_, value])=>(value ?? 0) > 0);
|
|
187
185
|
if (hasNonZero) {
|
|
188
186
|
planKeys.add(plan);
|
|
189
|
-
for (const [mileage, value] of entries)
|
|
187
|
+
for (const [mileage, value] of entries){
|
|
190
188
|
if ((value ?? 0) > 0) {
|
|
191
189
|
mileageKeys.add(mileage);
|
|
192
190
|
}
|
|
@@ -195,20 +193,20 @@ const getNonZeroKeys = (matrix) => {
|
|
|
195
193
|
}
|
|
196
194
|
return {
|
|
197
195
|
availablePlans: Array.from(planKeys),
|
|
198
|
-
availableMileagePackages: Array.from(mileageKeys)
|
|
196
|
+
availableMileagePackages: Array.from(mileageKeys)
|
|
199
197
|
};
|
|
200
198
|
};
|
|
201
|
-
const _getInspection = ()
|
|
199
|
+
const _getInspection = ()=>{
|
|
202
200
|
return {
|
|
203
201
|
exterior: 5,
|
|
204
202
|
interior: 5,
|
|
205
203
|
engine: 5,
|
|
206
204
|
frame: 5,
|
|
207
205
|
total: 5,
|
|
208
|
-
comment: 'COMMENT HERE'
|
|
206
|
+
comment: 'COMMENT HERE'
|
|
209
207
|
};
|
|
210
208
|
};
|
|
211
|
-
const transformDetails = (details, selectColor)
|
|
209
|
+
const transformDetails = (details, selectColor)=>{
|
|
212
210
|
const color = selectColor || details.colors[0].name || '';
|
|
213
211
|
return {
|
|
214
212
|
numberOfSeats: details.numberOfSeats,
|
|
@@ -216,31 +214,25 @@ const transformDetails = (details, selectColor) => {
|
|
|
216
214
|
bodyType: details.bodyType,
|
|
217
215
|
transmission: details.transmission,
|
|
218
216
|
engineType: details.fuelType,
|
|
219
|
-
engineCapacity: details.fuelType === 'electric'
|
|
220
|
-
? details.batteryCapacity
|
|
221
|
-
: details.engineCapacity,
|
|
217
|
+
engineCapacity: details.fuelType === 'electric' ? details.batteryCapacity : details.engineCapacity,
|
|
222
218
|
drivetrain: details.drivetrain,
|
|
223
219
|
accelerationTo100km: details.accelerationTo100km,
|
|
224
220
|
fuelConsumptionLitersPer100Km: details.fuelConsumptionLitersPer100Km,
|
|
225
221
|
color,
|
|
226
222
|
features: details.features,
|
|
227
|
-
condition: 'new'
|
|
223
|
+
condition: 'new'
|
|
228
224
|
};
|
|
229
225
|
};
|
|
230
|
-
const excludeServiceFeesFrom = (originalMatrix)
|
|
226
|
+
const excludeServiceFeesFrom = (originalMatrix)=>{
|
|
231
227
|
const matrix = {};
|
|
232
|
-
for (const [planKey, planValue] of Object.entries(originalMatrix))
|
|
233
|
-
if (!planValue)
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
matrix[planKey] = {};
|
|
237
|
-
for (const [mileageKey, price] of Object.entries(planValue)) {
|
|
228
|
+
for (const [planKey, planValue] of Object.entries(originalMatrix)){
|
|
229
|
+
if (!planValue) continue;
|
|
230
|
+
if (!matrix[planKey]) matrix[planKey] = {};
|
|
231
|
+
for (const [mileageKey, price] of Object.entries(planValue)){
|
|
238
232
|
if (typeof price === 'number') {
|
|
239
|
-
matrix[planKey][mileageKey] =
|
|
240
|
-
price / (1 + config.taxRate);
|
|
233
|
+
matrix[planKey][mileageKey] = price / (1 + config.taxRate);
|
|
241
234
|
}
|
|
242
235
|
}
|
|
243
236
|
}
|
|
244
237
|
return matrix;
|
|
245
238
|
};
|
|
246
|
-
//# sourceMappingURL=display-vehicle.js.map
|
|
@@ -3,29 +3,27 @@ import { makeProblem, PROBLEM_INTERNAL } from '@driveflux/problem';
|
|
|
3
3
|
import { Err, Ok } from '@driveflux/result';
|
|
4
4
|
import { createScopedLogger } from '../create-logger.js';
|
|
5
5
|
const log = createScopedLogger('reservation:ensure-user-billing-address');
|
|
6
|
-
export const ensureUserBillingAddress = async (userOrBusiness, deliveryAddresses)
|
|
6
|
+
export const ensureUserBillingAddress = async (userOrBusiness, deliveryAddresses)=>{
|
|
7
7
|
if (userOrBusiness.addresses?.billing) {
|
|
8
8
|
return new Ok(userOrBusiness);
|
|
9
9
|
}
|
|
10
10
|
try {
|
|
11
11
|
const fullQuery = {
|
|
12
|
-
where: {
|
|
12
|
+
where: {
|
|
13
|
+
id: userOrBusiness.id
|
|
14
|
+
},
|
|
13
15
|
data: {
|
|
14
16
|
addresses: {
|
|
15
17
|
home: deliveryAddresses.home,
|
|
16
|
-
billing: deliveryAddresses.billing
|
|
17
|
-
}
|
|
18
|
-
}
|
|
18
|
+
billing: deliveryAddresses.billing
|
|
19
|
+
}
|
|
20
|
+
}
|
|
19
21
|
};
|
|
20
22
|
// Use the delivery addresses
|
|
21
|
-
const updatedUserOrBusiness = userOrBusiness.object === 'user'
|
|
22
|
-
? await prisma.user.update(fullQuery)
|
|
23
|
-
: await prisma.business.update(fullQuery);
|
|
23
|
+
const updatedUserOrBusiness = userOrBusiness.object === 'user' ? await prisma.user.update(fullQuery) : await prisma.business.update(fullQuery);
|
|
24
24
|
return new Ok(updatedUserOrBusiness);
|
|
25
|
-
}
|
|
26
|
-
catch (error) {
|
|
25
|
+
} catch (error) {
|
|
27
26
|
log.error(error, 'Failed to ensure user billing address');
|
|
28
27
|
return new Err(makeProblem(PROBLEM_INTERNAL, 'Failed to ensure user billing address'));
|
|
29
28
|
}
|
|
30
29
|
};
|
|
31
|
-
//# sourceMappingURL=ensure-user-billing-address.js.map
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { prisma
|
|
1
|
+
import { prisma } from '@driveflux/db';
|
|
2
2
|
import { generateId } from '@driveflux/db/id';
|
|
3
|
-
import { makeProblem, PROBLEM_UNKNOWN } from '@driveflux/problem';
|
|
4
3
|
import { reportError } from '@driveflux/reporter';
|
|
5
|
-
import {
|
|
4
|
+
import { Ok } from '@driveflux/result';
|
|
6
5
|
import { slackLater } from '../slack.js';
|
|
7
|
-
import { createReservationInvoice, updateReservationInvoiceIfNeeded
|
|
8
|
-
export const fetchOrCreateReservation = async ({ vehicle, payer, body
|
|
9
|
-
const { subscribingUser, plan, mileagePackage, couponCode, referralCode, asBusiness, source, deliveryAddresses, deliveryDate, analytics, paymentIntentId, freeReservation, freeReservationReason
|
|
6
|
+
import { createReservationInvoice, updateReservationInvoiceIfNeeded } from './invoice.js';
|
|
7
|
+
export const fetchOrCreateReservation = async ({ vehicle, payer, body })=>{
|
|
8
|
+
const { subscribingUser, plan, mileagePackage, couponCode, referralCode, asBusiness, source, deliveryAddresses, deliveryDate, analytics, paymentIntentId, freeReservation, freeReservationReason } = body;
|
|
10
9
|
try {
|
|
11
10
|
const previousReservation = await prisma.subscriptionReservation.findFirst({
|
|
12
11
|
where: {
|
|
@@ -20,17 +19,15 @@ export const fetchOrCreateReservation = async ({ vehicle, payer, body, }) => {
|
|
|
20
19
|
source,
|
|
21
20
|
// If the subscription ID was populated, this means that this reservation was consumed into a subsription,
|
|
22
21
|
// so we shouldn't re-use it
|
|
23
|
-
subscription: null
|
|
22
|
+
subscription: null
|
|
24
23
|
},
|
|
25
24
|
orderBy: {
|
|
26
|
-
updatedAt: 'desc'
|
|
25
|
+
updatedAt: 'desc'
|
|
27
26
|
},
|
|
28
27
|
include: {
|
|
29
|
-
invoice: true
|
|
30
|
-
}
|
|
28
|
+
invoice: true
|
|
29
|
+
}
|
|
31
30
|
});
|
|
32
|
-
console.log('Previous reservation', previousReservation);
|
|
33
|
-
console.log('Previous reservation amount', previousReservation?.invoice.total);
|
|
34
31
|
if (previousReservation) {
|
|
35
32
|
if (previousReservation.invoice.voided) {
|
|
36
33
|
return recreateReservationInvoiceAndUpdateReservation(previousReservation, body, vehicle, payer);
|
|
@@ -42,7 +39,7 @@ export const fetchOrCreateReservation = async ({ vehicle, payer, body, }) => {
|
|
|
42
39
|
'partiallyPaid',
|
|
43
40
|
'partiallyRefunded',
|
|
44
41
|
'refunded',
|
|
45
|
-
'pendingRefund'
|
|
42
|
+
'pendingRefund'
|
|
46
43
|
];
|
|
47
44
|
if (wrongStatuses.includes(previousReservation.invoice.status)) {
|
|
48
45
|
const updatedReservation = await recreateReservationInvoiceAndUpdateReservation(previousReservation, body, vehicle, payer);
|
|
@@ -55,16 +52,16 @@ export const fetchOrCreateReservation = async ({ vehicle, payer, body, }) => {
|
|
|
55
52
|
text: {
|
|
56
53
|
type: 'plain_text',
|
|
57
54
|
text: '‼️ Reservation invoice in wrong status',
|
|
58
|
-
emoji: true
|
|
59
|
-
}
|
|
55
|
+
emoji: true
|
|
56
|
+
}
|
|
60
57
|
},
|
|
61
58
|
{
|
|
62
59
|
type: 'section',
|
|
63
60
|
text: {
|
|
64
61
|
type: 'plain_text',
|
|
65
|
-
text: `The reservation invoice ${previousReservation.invoice.id} was in a wrong status (${previousReservation.invoice.status}), it was discarded and a new invoice (${updatedReservation.val.id}) was created, however, investigate the issue
|
|
66
|
-
}
|
|
67
|
-
}
|
|
62
|
+
text: `The reservation invoice ${previousReservation.invoice.id} was in a wrong status (${previousReservation.invoice.status}), it was discarded and a new invoice (${updatedReservation.val.id}) was created, however, investigate the issue.`
|
|
63
|
+
}
|
|
64
|
+
}
|
|
68
65
|
]);
|
|
69
66
|
return updatedReservation;
|
|
70
67
|
}
|
|
@@ -76,119 +73,104 @@ export const fetchOrCreateReservation = async ({ vehicle, payer, body, }) => {
|
|
|
76
73
|
// Otherwise, we need to create a new reservation
|
|
77
74
|
return new Ok(previousReservation);
|
|
78
75
|
}
|
|
79
|
-
}
|
|
80
|
-
catch (error) {
|
|
76
|
+
} catch (error) {
|
|
81
77
|
// We couldn't fetch the reservation, so we create a new one and just log this
|
|
82
78
|
await reportError(error);
|
|
83
79
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (invoiceResult.err) {
|
|
104
|
-
return invoiceResult;
|
|
105
|
-
}
|
|
106
|
-
const reservation = await createReservation({
|
|
107
|
-
reservationId,
|
|
108
|
-
invoiceId: invoiceResult.val.id,
|
|
109
|
-
subscribingUserId: subscribingUser.id,
|
|
110
|
-
vehicleId: vehicle.id,
|
|
111
|
-
businessId: payer.object === 'business' ? payer.id : undefined,
|
|
112
|
-
plan,
|
|
113
|
-
mileagePackage,
|
|
114
|
-
couponCode,
|
|
115
|
-
referralCode,
|
|
116
|
-
analytics,
|
|
117
|
-
deliveryAddresses,
|
|
118
|
-
deliveryDate,
|
|
119
|
-
asBusiness,
|
|
120
|
-
source,
|
|
121
|
-
});
|
|
122
|
-
return new Ok(reservation);
|
|
123
|
-
}
|
|
124
|
-
catch (e) {
|
|
125
|
-
await reportError(e);
|
|
126
|
-
if (typeof e === 'object' && e && 'message' in e && e.message) {
|
|
127
|
-
return new Err(makeProblem(PROBLEM_UNKNOWN, e.message));
|
|
128
|
-
}
|
|
129
|
-
return new Err(makeProblem(PROBLEM_UNKNOWN, 'Unknown error'));
|
|
80
|
+
const reservationId = generateId('SubscriptionReservation');
|
|
81
|
+
// Create the reservation invoice
|
|
82
|
+
const invoiceResult = await createReservationInvoice({
|
|
83
|
+
invoiceId: generateId('Invoice'),
|
|
84
|
+
couponCode,
|
|
85
|
+
plan,
|
|
86
|
+
mileagePackage,
|
|
87
|
+
referralCode,
|
|
88
|
+
reservationId,
|
|
89
|
+
paymentIntentId,
|
|
90
|
+
freeReservation,
|
|
91
|
+
freeReservationReason,
|
|
92
|
+
analytics,
|
|
93
|
+
vehicle,
|
|
94
|
+
payer,
|
|
95
|
+
subscribingUser
|
|
96
|
+
});
|
|
97
|
+
if (invoiceResult.err) {
|
|
98
|
+
return invoiceResult;
|
|
130
99
|
}
|
|
100
|
+
const reservation = await createReservation({
|
|
101
|
+
reservationId,
|
|
102
|
+
invoiceId: invoiceResult.val.id,
|
|
103
|
+
subscribingUserId: subscribingUser.id,
|
|
104
|
+
vehicleId: vehicle.id,
|
|
105
|
+
businessId: payer.object === 'business' ? payer.id : undefined,
|
|
106
|
+
plan,
|
|
107
|
+
mileagePackage,
|
|
108
|
+
couponCode,
|
|
109
|
+
referralCode,
|
|
110
|
+
analytics,
|
|
111
|
+
deliveryAddresses,
|
|
112
|
+
deliveryDate,
|
|
113
|
+
asBusiness,
|
|
114
|
+
source
|
|
115
|
+
});
|
|
116
|
+
return new Ok(reservation);
|
|
131
117
|
};
|
|
132
|
-
const createReservation = async ({ reservationId, invoiceId, subscribingUserId, vehicleId, businessId, plan, mileagePackage, couponCode, referralCode, analytics, deliveryAddresses, deliveryDate, asBusiness, source
|
|
118
|
+
const createReservation = async ({ reservationId, invoiceId, subscribingUserId, vehicleId, businessId, plan, mileagePackage, couponCode, referralCode, analytics, deliveryAddresses, deliveryDate, asBusiness, source })=>{
|
|
133
119
|
return await prisma.subscriptionReservation.create({
|
|
134
120
|
data: {
|
|
135
121
|
id: reservationId,
|
|
136
122
|
invoice: {
|
|
137
123
|
connect: {
|
|
138
|
-
id: invoiceId
|
|
139
|
-
}
|
|
124
|
+
id: invoiceId
|
|
125
|
+
}
|
|
140
126
|
},
|
|
141
127
|
user: {
|
|
142
128
|
connect: {
|
|
143
|
-
id: subscribingUserId
|
|
144
|
-
}
|
|
129
|
+
id: subscribingUserId
|
|
130
|
+
}
|
|
145
131
|
},
|
|
146
132
|
vehicle: {
|
|
147
133
|
connect: {
|
|
148
|
-
id: vehicleId
|
|
149
|
-
}
|
|
134
|
+
id: vehicleId
|
|
135
|
+
}
|
|
150
136
|
},
|
|
151
|
-
...
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
},
|
|
157
|
-
},
|
|
137
|
+
...businessId ? {
|
|
138
|
+
business: {
|
|
139
|
+
connect: {
|
|
140
|
+
id: businessId
|
|
141
|
+
}
|
|
158
142
|
}
|
|
159
|
-
|
|
143
|
+
} : undefined,
|
|
160
144
|
plan,
|
|
161
145
|
mileagePackage,
|
|
162
146
|
couponCode: couponCode,
|
|
163
147
|
deliveryAddresses: deliveryAddresses,
|
|
164
148
|
deliveryDate: deliveryDate,
|
|
165
|
-
...
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
},
|
|
171
|
-
},
|
|
149
|
+
...referralCode ? {
|
|
150
|
+
referral: {
|
|
151
|
+
connect: {
|
|
152
|
+
id: referralCode
|
|
153
|
+
}
|
|
172
154
|
}
|
|
173
|
-
|
|
155
|
+
} : undefined,
|
|
174
156
|
asBusiness: !!asBusiness,
|
|
175
157
|
source,
|
|
176
158
|
metadata: {
|
|
177
|
-
analytics
|
|
178
|
-
}
|
|
159
|
+
analytics
|
|
160
|
+
}
|
|
179
161
|
},
|
|
180
162
|
include: {
|
|
181
|
-
invoice: true
|
|
182
|
-
}
|
|
163
|
+
invoice: true
|
|
164
|
+
}
|
|
183
165
|
});
|
|
184
166
|
};
|
|
185
|
-
const recreateReservationInvoiceAndUpdateReservation = async (previousReservation, body, vehicle, payer)
|
|
167
|
+
const recreateReservationInvoiceAndUpdateReservation = async (previousReservation, body, vehicle, payer)=>{
|
|
186
168
|
const invoiceResult = await createReservationInvoice({
|
|
187
169
|
...body,
|
|
188
170
|
invoiceId: generateId('Invoice'),
|
|
189
171
|
reservationId: previousReservation.id,
|
|
190
172
|
vehicle,
|
|
191
|
-
payer
|
|
173
|
+
payer
|
|
192
174
|
});
|
|
193
175
|
if (!invoiceResult.ok) {
|
|
194
176
|
return invoiceResult;
|
|
@@ -196,19 +178,18 @@ const recreateReservationInvoiceAndUpdateReservation = async (previousReservatio
|
|
|
196
178
|
const invoice = invoiceResult.val;
|
|
197
179
|
const updatedReservation = await prisma.subscriptionReservation.update({
|
|
198
180
|
where: {
|
|
199
|
-
id: previousReservation.id
|
|
181
|
+
id: previousReservation.id
|
|
200
182
|
},
|
|
201
183
|
data: {
|
|
202
184
|
invoice: {
|
|
203
185
|
connect: {
|
|
204
|
-
id: invoice.id
|
|
205
|
-
}
|
|
206
|
-
}
|
|
186
|
+
id: invoice.id
|
|
187
|
+
}
|
|
188
|
+
}
|
|
207
189
|
},
|
|
208
190
|
include: {
|
|
209
|
-
invoice: true
|
|
210
|
-
}
|
|
191
|
+
invoice: true
|
|
192
|
+
}
|
|
211
193
|
});
|
|
212
194
|
return new Ok(updatedReservation);
|
|
213
195
|
};
|
|
214
|
-
//# sourceMappingURL=fetch-or-create.js.map
|