@bytebrand/export-cars 1.23.1 → 1.23.3
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/transformers/facebook-shop.transformer.d.ts +1 -0
- package/dist/transformers/facebook-shop.transformer.js +30 -27
- package/dist/transformers/facebook-shop.transformer.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/transformers/facebook-shop.transformer.ts +40 -27
- package/dist/tsconfig.tsbuildinfo +0 -1
package/package.json
CHANGED
|
@@ -118,19 +118,25 @@ export class FacebookShopTransformer {
|
|
|
118
118
|
// matching exactly what the CDP displays (per ticket: data.rate.*/data.leasing.*).
|
|
119
119
|
const offersFinancing = get(car, 'rate.offersFinancing') !== false;
|
|
120
120
|
const rawFinancing = {
|
|
121
|
-
monthlyPayment:
|
|
122
|
-
downPayment:
|
|
123
|
-
termLength:
|
|
124
|
-
};
|
|
125
|
-
const rawLeasing = {
|
|
126
|
-
monthlyPayment: get(car, 'leasing.monthlyInstallment', 0),
|
|
127
|
-
downPayment: get(car, 'leasing.firstInstallment', 0),
|
|
128
|
-
termLength: get(car, 'leasing.paybackPeriod', 0),
|
|
121
|
+
monthlyPayment: this.getNum(car, 'rate.monthlyInstallment'),
|
|
122
|
+
downPayment: this.getNum(car, 'rate.firstInstallment'),
|
|
123
|
+
termLength: this.getNum(car, 'rate.paybackPeriod'),
|
|
129
124
|
};
|
|
130
125
|
const leasingIsEligible = this.isLeasingEligible(car);
|
|
131
126
|
|
|
132
127
|
const { financing: computedFinancing, leasing: computedLeasing } = this.computeFinancials(car);
|
|
133
128
|
|
|
129
|
+
// Unlike financing, the CDP never reads a pre-stored leasing.monthlyInstallment — it
|
|
130
|
+
// always computes it live from RWG + price (see fe-main SearchResultsStore/NewMainPage,
|
|
131
|
+
// same isLeasingEligible formula). The raw car.leasing.monthlyInstallment field can be
|
|
132
|
+
// stale/unset even when the CDP shows an active leasing tab, so the computed value is the
|
|
133
|
+
// one that actually matches what the customer sees.
|
|
134
|
+
const computedLeasingValues = {
|
|
135
|
+
monthlyPayment: this.getNum(computedLeasing, 'monthlyInstallment'),
|
|
136
|
+
downPayment: this.getNum(computedLeasing, 'firstInstallment'),
|
|
137
|
+
termLength: this.getNum(computedLeasing, 'paybackPeriod'),
|
|
138
|
+
};
|
|
139
|
+
|
|
134
140
|
if (offersFinancing && rawFinancing.monthlyPayment && computedFinancing) {
|
|
135
141
|
offers.push({
|
|
136
142
|
offerType: OfferType.financing,
|
|
@@ -140,27 +146,27 @@ export class FacebookShopTransformer {
|
|
|
140
146
|
disclaimer: OFFER_DISCLAIMER,
|
|
141
147
|
financials: {
|
|
142
148
|
...rawFinancing,
|
|
143
|
-
apr:
|
|
144
|
-
finalPayment:
|
|
145
|
-
totalAmount:
|
|
146
|
-
netLoanAmount:
|
|
149
|
+
apr: this.getNum(computedFinancing, 'annualPercentageRate'),
|
|
150
|
+
finalPayment: this.getNum(computedFinancing, 'finalInstallment'),
|
|
151
|
+
totalAmount: this.getNum(computedFinancing, 'grossLoanAmount'),
|
|
152
|
+
netLoanAmount: this.getNum(computedFinancing, 'netLoanAmount'),
|
|
147
153
|
},
|
|
148
154
|
});
|
|
149
155
|
}
|
|
150
156
|
|
|
151
|
-
if (leasingIsEligible &&
|
|
157
|
+
if (leasingIsEligible && computedLeasingValues.monthlyPayment && computedLeasing) {
|
|
152
158
|
offers.push({
|
|
153
159
|
offerType: OfferType.leasing,
|
|
154
|
-
title: `${make} ${model} leasen – z. B. ab ${this.formatEUR(
|
|
155
|
-
description: `${make} ${model} leasen – ${
|
|
156
|
-
`${this.formatEUR(
|
|
160
|
+
title: `${make} ${model} leasen – z. B. ab ${this.formatEUR(computedLeasingValues.monthlyPayment)} €/Monat`,
|
|
161
|
+
description: `${make} ${model} leasen – ${computedLeasingValues.termLength} Monate Laufzeit, ` +
|
|
162
|
+
`${this.formatEUR(computedLeasingValues.downPayment)} € Anzahlung`,
|
|
157
163
|
disclaimer: OFFER_DISCLAIMER,
|
|
158
164
|
financials: {
|
|
159
|
-
...
|
|
160
|
-
apr:
|
|
161
|
-
finalPayment:
|
|
162
|
-
totalAmount:
|
|
163
|
-
netLoanAmount:
|
|
165
|
+
...computedLeasingValues,
|
|
166
|
+
apr: this.getNum(computedLeasing, 'annualPercentageRate'),
|
|
167
|
+
finalPayment: this.getNum(computedLeasing, 'finalInstallment'),
|
|
168
|
+
totalAmount: this.getNum(computedLeasing, 'grossLoanAmount'),
|
|
169
|
+
netLoanAmount: this.getNum(computedLeasing, 'netLoanAmount'),
|
|
164
170
|
},
|
|
165
171
|
});
|
|
166
172
|
}
|
|
@@ -194,10 +200,10 @@ export class FacebookShopTransformer {
|
|
|
194
200
|
// Mirrors getLeasing.ts's isLeasingActive: same car ages out of leasing eligibility once
|
|
195
201
|
// it's older than leasing.maxAge months or past leasing.maxMileage km.
|
|
196
202
|
private isLeasingEligible(car: DataSchemes.Car): boolean {
|
|
197
|
-
const firstRegistration =
|
|
198
|
-
const mileage =
|
|
199
|
-
const maxAge =
|
|
200
|
-
const maxMileage =
|
|
203
|
+
const firstRegistration = this.getNum(car, 'mainData.firstRegistration');
|
|
204
|
+
const mileage = this.getNum(car, 'mainData.mileage');
|
|
205
|
+
const maxAge = this.getNum(car, 'leasing.maxAge', 24);
|
|
206
|
+
const maxMileage = this.getNum(car, 'leasing.maxMileage', 1000000);
|
|
201
207
|
|
|
202
208
|
const registrationMs = firstRegistration ? firstRegistration * 1000 : Date.now();
|
|
203
209
|
const maxCarAge = new Date().setMonth(new Date().getMonth() - maxAge);
|
|
@@ -221,6 +227,13 @@ export class FacebookShopTransformer {
|
|
|
221
227
|
return { value, isGoogle };
|
|
222
228
|
}
|
|
223
229
|
|
|
230
|
+
// lodash's get() only falls back to the default for an *undefined* path — an explicit
|
|
231
|
+
// `null` stored on the Car document (a common Mongo pattern for "not set") passes
|
|
232
|
+
// straight through and ends up rendering as an empty XML tag. Coalesce it here instead.
|
|
233
|
+
private getNum(source: any, path: string, fallback = 0): number {
|
|
234
|
+
return get(source, path) ?? fallback;
|
|
235
|
+
}
|
|
236
|
+
|
|
224
237
|
private formatEUR(value: number): string {
|
|
225
238
|
return Math.round(value || 0).toLocaleString(DE_LOCALE);
|
|
226
239
|
}
|
|
@@ -233,7 +246,7 @@ export class FacebookShopTransformer {
|
|
|
233
246
|
}
|
|
234
247
|
|
|
235
248
|
private getYear(car: DataSchemes.Car): string {
|
|
236
|
-
const firstRegistration =
|
|
249
|
+
const firstRegistration = this.getNum(car, 'mainData.firstRegistration');
|
|
237
250
|
return firstRegistration ? moment(firstRegistration * 1000).format('YYYY') : moment().format('YYYY');
|
|
238
251
|
}
|
|
239
252
|
|
|
@@ -252,7 +265,7 @@ export class FacebookShopTransformer {
|
|
|
252
265
|
}
|
|
253
266
|
|
|
254
267
|
private getPriceValue(car: DataSchemes.Car): number {
|
|
255
|
-
return round(
|
|
268
|
+
return round(this.getNum(car, 'price.currentSalesPrice'), 2);
|
|
256
269
|
}
|
|
257
270
|
|
|
258
271
|
private getColor(car: DataSchemes.Car): string {
|