@bytebrand/export-cars 1.24.1 → 1.25.0

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.24.1",
3
+ "version": "1.25.0",
4
4
  "description": "",
5
5
  "author": "bytebrand",
6
6
  "license": "UNLICENSED",
@@ -17,6 +17,12 @@ export class FacebookShopXmlBuilder extends XMLBuilderBase {
17
17
  const tags = Object.keys(car);
18
18
 
19
19
  for (const tag of tags) {
20
+ if (tag === 'image' && Array.isArray(car[tag])) {
21
+ item += (car[tag] as unknown as string[])
22
+ .map((url: string) => `<image><url>${escape(url)}</url></image>\n`)
23
+ .join('');
24
+ continue;
25
+ }
20
26
  item += this.buildTagElement(tag, car[tag]);
21
27
  }
22
28
  item += '</item>';
@@ -16,8 +16,8 @@ export class FbXmlBuilder extends XMLBuilderBase {
16
16
  if (key === 'description') {
17
17
  return this.getDescriptionElement(key, data);
18
18
  }
19
- if (key === 'additional_image_link' && Array.isArray(data)) {
20
- return data.map((value: string) => this.getElement(key, value, true)).join('');
19
+ if (key === 'image' && Array.isArray(data)) {
20
+ return this.getElementsArray(key, data.map((url: string) => ({ url })));
21
21
  }
22
22
  if (key === 'vehicle_specifications' && Array.isArray(data)) {
23
23
  // getElement() treats falsy values as "missing" — stringify so a legitimate 0
@@ -207,6 +207,7 @@ export interface GoogleXmlItem {
207
207
  identifier_exists: string,
208
208
  ads_redirect?: string;
209
209
  "certified_pre-owned"?: boolean;
210
+ user_id?: string;
210
211
  custom_label_0?: string;
211
212
  custom_label_1?: string,
212
213
  custom_label_2?: string,
@@ -351,11 +352,10 @@ export interface FacebookShopItem {
351
352
  title: FacebookShopTag;
352
353
  description: FacebookShopTag;
353
354
  availability: FacebookShopTag;
354
- condition: FacebookShopTag;
355
+ state_of_vehicle: FacebookShopTag;
355
356
  price: FacebookShopTag;
356
357
  link: FacebookShopTag;
357
- image_link: FacebookShopTag;
358
- additional_image_link: FacebookShopTag;
358
+ image: string[];
359
359
  make: FacebookShopTag;
360
360
  model: FacebookShopTag;
361
361
  year: FacebookShopTag;
@@ -78,13 +78,12 @@ export class FacebookShopTransformer {
78
78
 
79
79
  const base = {
80
80
  vehicle_id: this.tag(vehicleId, true),
81
- availability: this.tag('in stock', true),
82
- condition: this.tag(this.getCondition(car), true),
81
+ availability: this.tag(this.getAvailability(car), false),
82
+ state_of_vehicle: this.tag(this.getCondition(car), false),
83
83
  price: this.tag(`${price} EUR`, true),
84
84
  sale_price: this.tag(`${price} EUR`, true),
85
85
  link: this.tag(this.getCarLink(car), true),
86
- image_link: this.tag(imageLinks[0], true),
87
- additional_image_link: this.tag(imageLinks[0], false),
86
+ image: imageLinks.slice(0, 2), // main + 2nd image, per ticket
88
87
  make: this.tag(make, false),
89
88
  model: this.tag(model, false),
90
89
  year: this.tag(this.getYear(car), false),
@@ -252,14 +251,18 @@ export class FacebookShopTransformer {
252
251
 
253
252
  private getCondition(car: DataSchemes.Car): string {
254
253
  const available = {
255
- selector_condition_new: 'new',
256
- selector_condition_used: 'used',
257
- selector_unknown: 'used',
254
+ selector_condition_new: 'New',
255
+ selector_condition_used: 'Used',
256
+ selector_unknown: 'Used',
258
257
  };
259
258
  const condition = get(car, 'mainData.condition', 'selector_unknown');
260
259
  return get(available, condition);
261
260
  }
262
261
 
262
+ private getAvailability(car: DataSchemes.Car): string {
263
+ return get(car, 'state.isOnline', false) ? 'available' : 'not_available';
264
+ }
265
+
263
266
  private getCarLink(car: DataSchemes.Car): string {
264
267
  return `https://${this.configService.config.domain}/search/vehicle/${car._id}`;
265
268
  }
@@ -106,8 +106,7 @@ export class FbTransformer {
106
106
  make: toString(get(car, 'mainData.make', '')),
107
107
  model: toString(get(car, 'mainData.model', '')),
108
108
  trim: this.getTrim(car),
109
- image_link: image_links[0],
110
- additional_image_link: image_links.slice(1, 21), // Meta allows max 20 additional images
109
+ image: image_links.slice(0, 20), // Meta caps the whole image array at 20 items
111
110
  year: toString(year),
112
111
  mileage: {
113
112
  value: this.getMileage(car),
@@ -121,7 +120,7 @@ export class FbTransformer {
121
120
  price: this.getPrice(car),
122
121
  exterior_color: this.getExteriorColor(car),
123
122
  interior_color: this.getInteriorColor(car),
124
- condition: this.mapCondition(car),
123
+ state_of_vehicle: this.mapCondition(car),
125
124
  energy_efficiency_class_eu: this.getEnergyEfficiencyClass(car),
126
125
  vehicle_specifications: this.getVehicleSpecifications(car),
127
126
  };
@@ -395,16 +394,16 @@ export class FbTransformer {
395
394
 
396
395
  private mapCondition(car: DataSchemes.Car): string {
397
396
  const available = {
398
- selector_condition_new: 'new',
399
- selector_condition_used: 'used',
400
- selector_unknown: 'used',
397
+ selector_condition_new: 'New',
398
+ selector_condition_used: 'Used',
399
+ selector_unknown: 'Used',
401
400
  };
402
401
  const condition = get(car, 'mainData.condition', 'selector_unknown');
403
402
  return get(available, condition);
404
403
  }
405
404
 
406
405
  private mapAvailability(car: DataSchemes.Car): string {
407
- return get(car, 'state.isOnline', false) ? 'in stock' : 'out of stock';
406
+ return get(car, 'state.isOnline', false) ? 'available' : 'not_available';
408
407
  }
409
408
 
410
409
  private getEnergyEfficiencyClass(car: DataSchemes.Car): string {
@@ -1,13 +1,17 @@
1
- import { escape, get, isNumber, join, round, toSafeInteger, toString, trim, truncate } from 'lodash';
1
+ import { escape, get, includes, isNumber, join, round, toSafeInteger, toString, trim, truncate } from 'lodash';
2
2
  import { CarDescriptionFactory, DescriptionTypeEnum } from '@bytebrand/car-description';
3
3
  import { DataSchemes } from '@bytebrand/car-schema';
4
4
  import { TranslatorExtended } from '@bytebrand/schema-tools';
5
5
  import { de, deVehicleDetailsPage, deVehicleProps } from '@bytebrand/i18n-dictionaries';
6
6
  import { ImboImageResponseInterface } from '@bytebrand/chunkable';
7
7
  import { Injectable } from '@nestjs/common';
8
- import { ConfigService, ImagesService, TransformerService, UserService } from '../services';
8
+ import { ConfigService, ImagesService, MappingService, TransformerService, UserService } from '../services';
9
9
  import { GoogleXmlItem } from '../interfaces';
10
10
  import { isValidVin } from '../utils';
11
+ import {
12
+ META_PUSH_PRIORITY_ALLOWED_VALUES,
13
+ META_PUSH_PRIORITY_STANDARD,
14
+ } from '../constants/fb.constants';
11
15
 
12
16
  const GOOGLE_MAX_TRIM_LENGTH = 50;
13
17
  const TIMESTAMP_FIRST_YEAR = 1970;
@@ -21,6 +25,7 @@ export class GoogleTransformer {
21
25
  private configService: ConfigService,
22
26
  private imageService: ImagesService,
23
27
  private readonly transformService: TransformerService,
28
+ private readonly mappingService: MappingService,
24
29
  ) {
25
30
  const dict = { ...de, ...deVehicleProps, ...deVehicleDetailsPage };
26
31
  this.translator = new TranslatorExtended(dict);
@@ -50,6 +55,8 @@ export class GoogleTransformer {
50
55
  ...transformedImages.feat
51
56
  ]
52
57
 
58
+ const ownerId = get(car, 'metaData.ownerId', null);
59
+
53
60
  const item: GoogleXmlItem = {
54
61
  google_product_category: '916',
55
62
  vehicle_fulfillment: {
@@ -92,11 +99,12 @@ export class GoogleTransformer {
92
99
  description: this.processText((await this.getDescription(car))),
93
100
  identifier_exists: 'yes',
94
101
  availability: 'in_stock',
102
+ user_id: ownerId,
103
+ custom_label_4: await this.getMetaPushPriority(ownerId),
95
104
  // custom_label_0: '',
96
105
  // custom_label_1: '',
97
106
  // custom_label_2: '',
98
107
  // custom_label_3: '',
99
- // custom_label_4: '',
100
108
 
101
109
  // availability: this.getAvailability(car),
102
110
  // sale_price: this.getPrice(car),
@@ -131,6 +139,13 @@ export class GoogleTransformer {
131
139
  return item;
132
140
  }
133
141
 
142
+ private async getMetaPushPriority(ownerId: string): Promise<string> {
143
+ const priorities = await this.mappingService.getMetaPushPriorityMapping();
144
+ const entry = priorities.find(priority => priority.dealer_id === ownerId);
145
+ const value = get(entry, 'meta_push_priority', '');
146
+ return includes(META_PUSH_PRIORITY_ALLOWED_VALUES, value) ? value : META_PUSH_PRIORITY_STANDARD;
147
+ }
148
+
134
149
  private checkCarValidity(car: DataSchemes.Car, images: ImboImageResponseInterface[]) {
135
150
  if (images.length === 0)
136
151
  return false