@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/export-cars",
3
- "version": "1.23.1",
3
+ "version": "1.23.3",
4
4
  "description": "",
5
5
  "author": "bytebrand",
6
6
  "license": "UNLICENSED",
@@ -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: get(car, 'rate.monthlyInstallment', 0),
122
- downPayment: get(car, 'rate.firstInstallment', 0),
123
- termLength: get(car, 'rate.paybackPeriod', 0),
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: get(computedFinancing, 'annualPercentageRate', 0),
144
- finalPayment: get(computedFinancing, 'finalInstallment', 0),
145
- totalAmount: get(computedFinancing, 'grossLoanAmount', 0),
146
- netLoanAmount: get(computedFinancing, 'netLoanAmount', 0),
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 && rawLeasing.monthlyPayment && computedLeasing) {
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(rawLeasing.monthlyPayment)} €/Monat`,
155
- description: `${make} ${model} leasen – ${rawLeasing.termLength} Monate Laufzeit, ` +
156
- `${this.formatEUR(rawLeasing.downPayment)} € Anzahlung`,
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
- ...rawLeasing,
160
- apr: get(computedLeasing, 'annualPercentageRate', 0),
161
- finalPayment: get(computedLeasing, 'finalInstallment', 0),
162
- totalAmount: get(computedLeasing, 'grossLoanAmount', 0),
163
- netLoanAmount: get(computedLeasing, 'netLoanAmount', 0),
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 = get(car, 'mainData.firstRegistration', 0) as number;
198
- const mileage = get(car, 'mainData.mileage', 0) as number;
199
- const maxAge = get(car, 'leasing.maxAge', 24) as number;
200
- const maxMileage = get(car, 'leasing.maxMileage', 1000000) as number;
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 = get(car, 'mainData.firstRegistration', 0) as number;
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(get(car, 'price.currentSalesPrice', 0), 2);
268
+ return round(this.getNum(car, 'price.currentSalesPrice'), 2);
256
269
  }
257
270
 
258
271
  private getColor(car: DataSchemes.Car): string {