@bytebrand/export-cars 1.21.6 → 1.21.8

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.
Files changed (160) hide show
  1. package/.editorconfig +8 -8
  2. package/.eslintignore +1 -1
  3. package/.eslintrc.js +24 -24
  4. package/.prettierrc.js +7 -7
  5. package/README.md +65 -65
  6. package/dist/configs/index.d.ts +1 -0
  7. package/dist/configs/index.js +1 -0
  8. package/dist/configs/index.js.map +1 -1
  9. package/dist/configs/santander.config.d.ts +5 -0
  10. package/dist/configs/santander.config.js +18 -0
  11. package/dist/configs/santander.config.js.map +1 -0
  12. package/dist/enums/export-type.enum.d.ts +1 -0
  13. package/dist/enums/export-type.enum.js +1 -0
  14. package/dist/enums/export-type.enum.js.map +1 -1
  15. package/dist/export.command.js +1 -1
  16. package/dist/export.command.js.map +1 -1
  17. package/dist/export.schema.d.ts +6 -2
  18. package/dist/export.schema.js +4 -0
  19. package/dist/export.schema.js.map +1 -1
  20. package/dist/exporters/autouncle.exporter.js +5 -1
  21. package/dist/exporters/autouncle.exporter.js.map +1 -1
  22. package/dist/exporters/fb.exporter.js +7 -1
  23. package/dist/exporters/fb.exporter.js.map +1 -1
  24. package/dist/exporters/index.d.ts +1 -0
  25. package/dist/exporters/index.js +1 -0
  26. package/dist/exporters/index.js.map +1 -1
  27. package/dist/exporters/santander.exporter.d.ts +12 -0
  28. package/dist/exporters/santander.exporter.js +63 -0
  29. package/dist/exporters/santander.exporter.js.map +1 -0
  30. package/dist/formats/auto24-xml.builder.js +2 -2
  31. package/dist/formats/google-xml.builder.js +3 -3
  32. package/dist/formats/modix-xml.builder.js +2 -2
  33. package/dist/formats/ooyyo-xml.builder.js +1 -1
  34. package/dist/formats/santander-csv.builder.d.ts +6 -0
  35. package/dist/formats/santander-csv.builder.js +17 -0
  36. package/dist/formats/santander-csv.builder.js.map +1 -0
  37. package/dist/tsconfig.build.tsbuildinfo +1 -1
  38. package/nest-cli.json +5 -5
  39. package/package.json +61 -61
  40. package/src/app.module.ts +38 -38
  41. package/src/configs/alleskralle.config.ts +15 -15
  42. package/src/configs/as24.config.ts +13 -13
  43. package/src/configs/auto24.config.ts +15 -15
  44. package/src/configs/autoboerse.config.ts +16 -16
  45. package/src/configs/autouncle.config.ts +14 -14
  46. package/src/configs/awin.config.ts +15 -15
  47. package/src/configs/by-owner.config.ts +14 -14
  48. package/src/configs/config.ts +83 -83
  49. package/src/configs/criteo.config.ts +17 -17
  50. package/src/configs/dasparking.config.ts +15 -15
  51. package/src/configs/eauto.config.ts +15 -15
  52. package/src/configs/evium.config.ts +18 -18
  53. package/src/configs/facebook-shop.config.ts +16 -16
  54. package/src/configs/fb.config.ts +16 -16
  55. package/src/configs/google.config.ts +14 -14
  56. package/src/configs/index.ts +22 -21
  57. package/src/configs/kleinanzeigeFocus.config.ts +14 -14
  58. package/src/configs/marktde.config.ts +18 -18
  59. package/src/configs/meinstadt.config.ts +15 -15
  60. package/src/configs/mitula.config.ts +14 -14
  61. package/src/configs/ooyyo.config.ts +15 -15
  62. package/src/configs/santander.config.ts +15 -0
  63. package/src/configs/trovit.config.ts +14 -14
  64. package/src/configs/yescar.config.ts +17 -17
  65. package/src/constants/autouncle.contants.ts +4 -4
  66. package/src/constants/fb.constants.ts +7 -7
  67. package/src/constants/index.ts +1 -1
  68. package/src/constants/modix/body-color-name.constant.ts +20 -20
  69. package/src/constants/modix/category.constant.ts +14 -14
  70. package/src/constants/modix/fuel.constant.ts +14 -14
  71. package/src/constants/modix/index.ts +7 -7
  72. package/src/constants/modix/manufacturers.constant.ts +7498 -7498
  73. package/src/constants/modix/transmission.constant.ts +8 -8
  74. package/src/constants/modix/usage-type.constant.ts +13 -13
  75. package/src/constants/modix/vehicle-class.constant.ts +17 -17
  76. package/src/enums/environment.enum.ts +5 -5
  77. package/src/enums/export-type.enum.ts +33 -32
  78. package/src/enums/file-types.enum.ts +8 -8
  79. package/src/enums/image-type.enum.ts +4 -4
  80. package/src/enums/index.ts +4 -4
  81. package/src/export.command.ts +37 -37
  82. package/src/export.schema.ts +134 -128
  83. package/src/exporters/as24.exporter.ts +69 -69
  84. package/src/exporters/auto24.exporter.ts +48 -48
  85. package/src/exporters/autouncle.exporter.ts +60 -58
  86. package/src/exporters/awin.exporter.ts +47 -47
  87. package/src/exporters/by-owner.exporter.ts +44 -44
  88. package/src/exporters/facebook-shop.exporter.ts +51 -51
  89. package/src/exporters/fb.exporter.ts +52 -50
  90. package/src/exporters/google.exporter.ts +45 -45
  91. package/src/exporters/index.ts +15 -14
  92. package/src/exporters/meinstadt.exporter.ts +55 -55
  93. package/src/exporters/mobile.exporter.ts +64 -64
  94. package/src/exporters/modix.exporter.ts +56 -56
  95. package/src/exporters/ooyyo.exporter.ts +48 -48
  96. package/src/exporters/rubrikk.exporter.ts +53 -53
  97. package/src/exporters/santander.exporter.ts +50 -0
  98. package/src/exporters/trovit.exporter.ts +51 -51
  99. package/src/formats/auto24-xml.builder.ts +54 -54
  100. package/src/formats/autouncle-json.builder.ts +20 -20
  101. package/src/formats/awin-csv.builder.ts +16 -16
  102. package/src/formats/facebook-shop.builder.ts +69 -69
  103. package/src/formats/fb-xml.builder.ts +71 -71
  104. package/src/formats/google-xml.builder.ts +35 -35
  105. package/src/formats/index.ts +5 -5
  106. package/src/formats/meinstadt-json.builder.ts +19 -19
  107. package/src/formats/modix-xml.builder.ts +180 -180
  108. package/src/formats/ooyyo-xml.builder.ts +48 -48
  109. package/src/formats/rubrikk-xml.builder.ts +27 -27
  110. package/src/formats/santander-csv.builder.ts +15 -0
  111. package/src/formats/trovit-xml.builder.ts +44 -44
  112. package/src/interfaces/atributes-wrap-item.intreface.ts +6 -6
  113. package/src/interfaces/dealers-mapping.interface.ts +7 -7
  114. package/src/interfaces/description.interface.ts +24 -24
  115. package/src/interfaces/export-item.interface.ts +366 -366
  116. package/src/interfaces/exporter.interface.ts +3 -3
  117. package/src/interfaces/index.ts +3 -3
  118. package/src/interfaces/input.interface.ts +6 -6
  119. package/src/interfaces/mapping-rules.interface.ts +11 -11
  120. package/src/interfaces/modix/index.ts +1 -1
  121. package/src/interfaces/modix/modix-item-list.interface.ts +5 -5
  122. package/src/interfaces/params.interface.ts +13 -13
  123. package/src/interfaces/rule-parser.interface.ts +3 -3
  124. package/src/main.ts +14 -14
  125. package/src/rules/abstract.rule.ts +37 -37
  126. package/src/rules/date.rule.ts +19 -19
  127. package/src/rules/number.rule.ts +15 -15
  128. package/src/rules/string.rule.ts +8 -8
  129. package/src/services/car.service.ts +49 -49
  130. package/src/services/config.service.ts +15 -15
  131. package/src/services/images.service.ts +207 -207
  132. package/src/services/index.ts +9 -9
  133. package/src/services/loader.service.ts +29 -29
  134. package/src/services/mapping.service.ts +91 -91
  135. package/src/services/request.service.ts +44 -44
  136. package/src/services/rules.service.ts +61 -61
  137. package/src/services/transformer.service.ts +129 -129
  138. package/src/services/user.service.ts +57 -57
  139. package/src/transformers/as24.transformer.ts +253 -253
  140. package/src/transformers/auto24.transfomer.ts +155 -155
  141. package/src/transformers/autouncle.transformer.ts +236 -236
  142. package/src/transformers/awin.transformer.ts +193 -193
  143. package/src/transformers/by-owner.transformer.ts +354 -354
  144. package/src/transformers/facebook-shop.transformer.ts +93 -93
  145. package/src/transformers/fb-description.transformer.ts +316 -316
  146. package/src/transformers/fb-equipment.transformer.ts +161 -161
  147. package/src/transformers/fb.transformer.ts +655 -655
  148. package/src/transformers/google.transformer.ts +169 -169
  149. package/src/transformers/index.ts +5 -5
  150. package/src/transformers/meinstadt.transformer.ts +92 -92
  151. package/src/transformers/mobile.transformer.ts +482 -482
  152. package/src/transformers/modix.transformer.ts +227 -227
  153. package/src/transformers/ooyyo.transformer.ts +109 -109
  154. package/src/transformers/rubrikk.transformer.ts +200 -200
  155. package/src/transformers/trovit.transformer.ts +63 -63
  156. package/src/utils/converter.utils.ts +15 -15
  157. package/src/utils/index.ts +2 -2
  158. package/src/utils/validator.utils.ts +7 -7
  159. package/tsconfig.build.json +4 -4
  160. package/tsconfig.json +29 -29
@@ -1,109 +1,109 @@
1
- import { Translator } from '@bytebrand/schema-tools';
2
- import { de } from '@bytebrand/i18n-dictionaries';
3
- import { get, toString, isEmpty, trim, join } from 'lodash';
4
- import * as moment from 'moment';
5
- import { DataSchemes } from '@bytebrand/car-schema';
6
- import { OoyyoXmlItem } from '../interfaces';
7
- import { ImboImageResponseInterface } from '@bytebrand/chunkable';
8
- import { ConfigService, ImagesService } from '../services';
9
- import { Injectable } from '@nestjs/common';
10
-
11
- @Injectable()
12
- export class OoyyoTransformer {
13
- private translator: Translator;
14
-
15
- constructor(private configService: ConfigService, private imageService: ImagesService) {
16
- this.translator = new Translator(de);
17
- }
18
-
19
- async transform(car: DataSchemes.Car, imboImages: ImboImageResponseInterface[]): Promise<OoyyoXmlItem> {
20
- const carId = toString(get(car, '_id', ''));
21
- const creationDate = get(car, 'metaData.creationDate') as number;
22
- const constructionYear = get(car, 'mainData.constructionYear') as number;
23
- const firstRegistration = get(car, 'mainData.firstRegistration') as number;
24
- const isNew = get(car, 'mainData.condition') === 'selector_condition_new';
25
- let year = firstRegistration ? moment(firstRegistration * 1000).format('YYYY') : constructionYear;
26
-
27
- if (!year && isNew) {
28
- year = moment().subtract(2, 'months').format('YYYY');
29
- }
30
-
31
- return {
32
- url: `https://www.${this.configService.config.domain}/search/vehicle/${carId}?source=classifieds&medium=listing&campaign=ooyyo`,
33
- title: this.getTitle(car),
34
- content: trim(toString(get(car, 'offer.offerDescription', ''))),
35
- price: toString(get(car, 'price.currentSalesPrice', '')),
36
- make: toString(get(car, 'mainData.make', '')),
37
- model: toString(get(car, 'mainData.model', '')),
38
- engine_size: toString(get(car, 'engineData.cubicCapacity', '')),
39
- trim: toString(get(car, 'mainData.subModel', '')),
40
- body_type: this.translateSelector(get(car, 'mainData.category', '')),
41
- color: this.translateSelector(get(car, 'exterior.exteriorColor', '')).replace('Außenfarbe ', ''),
42
- year: toString(year),
43
- mileage: toString(get(car, 'mainData.mileage', '')),
44
- fuel_type: this.translateSelector(get(car, 'consumption.fuel', '')),
45
- transmission: this.translateSelector(get(car, 'driveSuspension.gearbox', '')),
46
- euronorm: this.getEmissionClass(car),
47
- power: toString(get(car, 'engineData.powerKW', '')),
48
- doors: toString(get(car, 'mainData.doors', '')),
49
- seats: toString(get(car, 'mainData.seats', '')),
50
- gears: toString(get(car, 'driveSuspension.gears', '')),
51
- pictures: await this.imageService.getImages(car, imboImages, this.configService.config.imageType, false),
52
- location: {
53
- city: toString(get(car, 'location.city', '')),
54
- postcode: toString(get(car, 'location.zipCode', '')),
55
- region: toString(get(car, 'location.countryCode', '')),
56
- },
57
- vin: toString(get(car, 'metaData.vin', '')),
58
- is_new: this.getCondition(car),
59
- date: this.formatTimestamp(creationDate),
60
- time: this.formatTimestamp(creationDate, true),
61
- };
62
- }
63
-
64
- private getTitle(car: DataSchemes.Car): string {
65
- const year = toString(get(car, 'mainData.constructionYear', ''));
66
- const make = toString(get(car, 'mainData.make', ''));
67
- const model = toString(get(car, 'mainData.model', ''));
68
- const subModel = toString(get(car, 'mainData.subModel', ''));
69
- return trim(join([year, make, model, subModel], ' '));
70
- }
71
-
72
- private getCondition(car: DataSchemes.Car): string {
73
- const conditionSelector = get(car, 'mainData.condition', '');
74
- return conditionSelector === 'selector_condition_new' ? '1' : '0';
75
- }
76
-
77
- private translateSelector(selector: string): string {
78
- if (isEmpty(selector) || selector === 'selector_unknown') {
79
- return '';
80
- }
81
- return this.translator.translateVal(selector);
82
- }
83
-
84
- private getEmissionClass(car: DataSchemes.Car): string {
85
- const available = {
86
- selector_emissionClass_euro1: '1',
87
- selector_emissionClass_euro2: '2',
88
- selector_emissionClass_euro3: '3',
89
- selector_emissionClass_euro4: '4',
90
- selector_emissionClass_euro5: '5',
91
- selector_emissionClass_euro6: '6',
92
- selector_emissionClass_euro6b: '6b',
93
- selector_emissionClass_euro6c: '6c',
94
- selector_emissionClass_euro6d: '6d',
95
- selector_emissionClass_euro6d_temp: '6d-TEMP',
96
- selector_unknown: 'default',
97
- };
98
- const emissionClass = get(car, 'environmentEmissions.emissionClass', 'selector_unknown');
99
- return get(available, emissionClass);
100
- }
101
-
102
- private formatTimestamp(timestamp: number, onlyTime = false): string {
103
- if (!timestamp) {
104
- return '';
105
- }
106
- const format = onlyTime ? 'hh:mm:ss' : 'DD/MM/YYYY';
107
- return moment(timestamp * 1000).format(format);
108
- }
109
- }
1
+ import { Translator } from '@bytebrand/schema-tools';
2
+ import { de } from '@bytebrand/i18n-dictionaries';
3
+ import { get, toString, isEmpty, trim, join } from 'lodash';
4
+ import * as moment from 'moment';
5
+ import { DataSchemes } from '@bytebrand/car-schema';
6
+ import { OoyyoXmlItem } from '../interfaces';
7
+ import { ImboImageResponseInterface } from '@bytebrand/chunkable';
8
+ import { ConfigService, ImagesService } from '../services';
9
+ import { Injectable } from '@nestjs/common';
10
+
11
+ @Injectable()
12
+ export class OoyyoTransformer {
13
+ private translator: Translator;
14
+
15
+ constructor(private configService: ConfigService, private imageService: ImagesService) {
16
+ this.translator = new Translator(de);
17
+ }
18
+
19
+ async transform(car: DataSchemes.Car, imboImages: ImboImageResponseInterface[]): Promise<OoyyoXmlItem> {
20
+ const carId = toString(get(car, '_id', ''));
21
+ const creationDate = get(car, 'metaData.creationDate') as number;
22
+ const constructionYear = get(car, 'mainData.constructionYear') as number;
23
+ const firstRegistration = get(car, 'mainData.firstRegistration') as number;
24
+ const isNew = get(car, 'mainData.condition') === 'selector_condition_new';
25
+ let year = firstRegistration ? moment(firstRegistration * 1000).format('YYYY') : constructionYear;
26
+
27
+ if (!year && isNew) {
28
+ year = moment().subtract(2, 'months').format('YYYY');
29
+ }
30
+
31
+ return {
32
+ url: `https://www.${this.configService.config.domain}/search/vehicle/${carId}?source=classifieds&medium=listing&campaign=ooyyo`,
33
+ title: this.getTitle(car),
34
+ content: trim(toString(get(car, 'offer.offerDescription', ''))),
35
+ price: toString(get(car, 'price.currentSalesPrice', '')),
36
+ make: toString(get(car, 'mainData.make', '')),
37
+ model: toString(get(car, 'mainData.model', '')),
38
+ engine_size: toString(get(car, 'engineData.cubicCapacity', '')),
39
+ trim: toString(get(car, 'mainData.subModel', '')),
40
+ body_type: this.translateSelector(get(car, 'mainData.category', '')),
41
+ color: this.translateSelector(get(car, 'exterior.exteriorColor', '')).replace('Außenfarbe ', ''),
42
+ year: toString(year),
43
+ mileage: toString(get(car, 'mainData.mileage', '')),
44
+ fuel_type: this.translateSelector(get(car, 'consumption.fuel', '')),
45
+ transmission: this.translateSelector(get(car, 'driveSuspension.gearbox', '')),
46
+ euronorm: this.getEmissionClass(car),
47
+ power: toString(get(car, 'engineData.powerKW', '')),
48
+ doors: toString(get(car, 'mainData.doors', '')),
49
+ seats: toString(get(car, 'mainData.seats', '')),
50
+ gears: toString(get(car, 'driveSuspension.gears', '')),
51
+ pictures: await this.imageService.getImages(car, imboImages, this.configService.config.imageType, false),
52
+ location: {
53
+ city: toString(get(car, 'location.city', '')),
54
+ postcode: toString(get(car, 'location.zipCode', '')),
55
+ region: toString(get(car, 'location.countryCode', '')),
56
+ },
57
+ vin: toString(get(car, 'metaData.vin', '')),
58
+ is_new: this.getCondition(car),
59
+ date: this.formatTimestamp(creationDate),
60
+ time: this.formatTimestamp(creationDate, true),
61
+ };
62
+ }
63
+
64
+ private getTitle(car: DataSchemes.Car): string {
65
+ const year = toString(get(car, 'mainData.constructionYear', ''));
66
+ const make = toString(get(car, 'mainData.make', ''));
67
+ const model = toString(get(car, 'mainData.model', ''));
68
+ const subModel = toString(get(car, 'mainData.subModel', ''));
69
+ return trim(join([year, make, model, subModel], ' '));
70
+ }
71
+
72
+ private getCondition(car: DataSchemes.Car): string {
73
+ const conditionSelector = get(car, 'mainData.condition', '');
74
+ return conditionSelector === 'selector_condition_new' ? '1' : '0';
75
+ }
76
+
77
+ private translateSelector(selector: string): string {
78
+ if (isEmpty(selector) || selector === 'selector_unknown') {
79
+ return '';
80
+ }
81
+ return this.translator.translateVal(selector);
82
+ }
83
+
84
+ private getEmissionClass(car: DataSchemes.Car): string {
85
+ const available = {
86
+ selector_emissionClass_euro1: '1',
87
+ selector_emissionClass_euro2: '2',
88
+ selector_emissionClass_euro3: '3',
89
+ selector_emissionClass_euro4: '4',
90
+ selector_emissionClass_euro5: '5',
91
+ selector_emissionClass_euro6: '6',
92
+ selector_emissionClass_euro6b: '6b',
93
+ selector_emissionClass_euro6c: '6c',
94
+ selector_emissionClass_euro6d: '6d',
95
+ selector_emissionClass_euro6d_temp: '6d-TEMP',
96
+ selector_unknown: 'default',
97
+ };
98
+ const emissionClass = get(car, 'environmentEmissions.emissionClass', 'selector_unknown');
99
+ return get(available, emissionClass);
100
+ }
101
+
102
+ private formatTimestamp(timestamp: number, onlyTime = false): string {
103
+ if (!timestamp) {
104
+ return '';
105
+ }
106
+ const format = onlyTime ? 'hh:mm:ss' : 'DD/MM/YYYY';
107
+ return moment(timestamp * 1000).format(format);
108
+ }
109
+ }
@@ -1,200 +1,200 @@
1
- import { escape, get, isEmpty, isNumber, join, toNumber, toSafeInteger, toString, trim } from 'lodash';
2
- import { Injectable } from '@nestjs/common';
3
- import * as moment from 'moment/moment';
4
-
5
- import { CarDescriptionFactory, DescriptionTypeEnum } from '@bytebrand/car-description';
6
- import { de, deVehicleDetailsPage, deVehicleProps } from '@bytebrand/i18n-dictionaries';
7
- import { ImboImageResponseInterface } from '@bytebrand/chunkable';
8
- import { TranslatorExtended } from '@bytebrand/schema-tools';
9
- import { DataSchemes } from '@bytebrand/car-schema';
10
-
11
- import { ConfigService, ImagesService, UserService } from '../services';
12
- import { RubrikkXmlItem } from '../interfaces';
13
-
14
- @Injectable()
15
- export class RubrikkTransformer {
16
- private translator: TranslatorExtended;
17
-
18
- constructor(
19
- private readonly configService: ConfigService,
20
- private readonly imageService: ImagesService,
21
- private readonly userService: UserService,
22
- ) {
23
- const dict = { ...de, ...deVehicleProps, ...deVehicleDetailsPage };
24
- this.translator = new TranslatorExtended(dict);
25
- }
26
-
27
- async transform({
28
- car,
29
- images,
30
- }: {
31
- car: DataSchemes.Car;
32
- images: ImboImageResponseInterface[];
33
- }): Promise<RubrikkXmlItem> {
34
- return {
35
- //Common Fields
36
- ad__all_imageurls: await this.imageService.getImages(car, images, this.configService.config.imageType, false),
37
- ad__condition_new_used_etc: this.getCondition(car),
38
- ad__description: await this.getDescription(car),
39
- ad__headline: this.getTitle(car),
40
- ad__imageurl: this.getImageLink(car),
41
- ad__price: toNumber(get(car, 'price.currentSalesPrice', null)),
42
- ad__price_currency: toString(get(car, 'price.currency', 'EUR')),
43
- product__type: this.getCategory(car),
44
- ad__url: this.getCarLink(car),
45
- efficiency_class: this.getEnergyClass(car),
46
- ad__number_ad__number_reference_id: toString(get(car, 'metaData.vehicleId', '')),
47
-
48
- //Categorization
49
- category_original: 'Autos',
50
- maincategory_original: 'Fahrzeuge',
51
-
52
- //Advertiser Info
53
- advertiser__company_homepage_url: 'https://www.auto.de',
54
- advertiser__company_logo_url:
55
- 'https://autode-static.de/wp-content/themes/autode/front/img/header/b_logo_autode.svg',
56
- advertiser__email: 'auto@auto.de',
57
- advertiser__name_company_name: 'Auto.de',
58
- advertiser__phone: '+498004030182',
59
-
60
- // Geography Info
61
- location__country: 'Deutschland',
62
- location__municipality_city: get(car, 'location.city', ''),
63
- location__zip_postal_code: toString(get(car, 'location.zipCode', '')),
64
-
65
- // Motoring Fields
66
- motoring__body_type: this.translateSelector(get(car, 'mainData.category', '')),
67
- motoring__color: this.getColor(car),
68
- motoring__drivetrain: this.getDriveType(car),
69
- motoring__emission_class: this.translateSelector(get(car, 'environmentEmissions.emissionClass', '')),
70
- motoring__emission_co2: get(car, 'environmentEmissions.co2', null),
71
- motoring__emission_co2_unit: 'g/km',
72
- motoring__emission_sticker: this.translateSelector(get(car, 'environmentEmissions.emissionSticker', '')),
73
- motoring__engine_displacement_cubic_centimeters: toNumber(get(car, 'engineData.cubicCapacity', null)),
74
- motoring__fuel_consumption_combined: get(car, 'consumption.consumptionCombined', null),
75
- motoring__fuel_consumption_combined_unit: this.getUrbanUnit(car),
76
- motoring__fuel_consumption_extra_urban: get(car, 'consumption.consumptionOuter', null),
77
- motoring__fuel_consumption_extra_urban_unit: this.getUrbanUnit(car),
78
- motoring__fuel_consumption_urban: get(car, 'consumption.consumptionInner', null),
79
- motoring__fuel_consumption_urban_unit: this.getUrbanUnit(car),
80
- motoring__fuel_type: this.translateSelector(get(car, 'consumption.fuel', '')),
81
- motoring__make: toString(get(car, 'mainData.make', '')),
82
- motoring__mileage_kilometers: get(car, 'mainData.mileage', null),
83
- motoring__model: toString(get(car, 'mainData.model', '')),
84
- motoring__model_year: this.getYear(car),
85
- motoring__number_of_doors: get(car, 'mainData.doors', null),
86
- motoring__number_of_seats: get(car, 'mainData.seats', null),
87
- motoring__power_kw: get(car, 'engineData.powerKW', null),
88
- motoring__power_hp: get(car, 'engineData.powerPS', null),
89
- motoring__transmission: this.getDrivetrain(car),
90
- };
91
- }
92
-
93
- private getUrbanUnit(car: DataSchemes.Car) {
94
- const fuel_type = this.translateSelector(get(car, 'consumption.fuel', ''));
95
- return fuel_type === 'Elektro' ? 'kWt/100km' : 'l/100km';
96
- }
97
-
98
- private translateSelector(selector: string): string {
99
- if (isEmpty(selector) || selector === 'selector_unknown') {
100
- return '';
101
- }
102
- return this.translator.translateVal(selector);
103
- }
104
-
105
- private getTitle(car: DataSchemes.Car): string {
106
- const make = toString(get(car, 'mainData.make', ''));
107
- const model = toString(get(car, 'mainData.model', ''));
108
- const subModel = toString(get(car, 'mainData.subModel', ''));
109
- return trim(escape(join([make, model, subModel], ' ')));
110
- }
111
-
112
- private getCondition(car: DataSchemes.Car): string {
113
- const available = {
114
- selector_condition_new: 'Neu',
115
- selector_condition_used: 'Gebraucht',
116
- selector_unknown: 'Gebraucht',
117
- };
118
- const condition = get(car, 'mainData.condition', 'selector_unknown');
119
- return get(available, condition);
120
- }
121
-
122
- private getCategory(car: DataSchemes.Car): string {
123
- return this.translator.translateVal(get(car, 'mainData.category', ''));
124
- }
125
-
126
- private getCarLink(car: DataSchemes.Car): string {
127
- return `https://${this.configService.config.domain}/search/vehicle/${car._id}?source=classifieds&medium=listing&campaign=focus`;
128
- }
129
-
130
- private getImageLink(car: DataSchemes.Car): string {
131
- const mainImageId = get(car, 'metaData.mainImageId', '');
132
- return mainImageId
133
- ? `${this.configService.config.baseImageUrl}/carimage/${car._id}/${mainImageId}/large-cached.webp`
134
- : `${this.configService.config.baseImageUrl}/carimage/noimage/7pNvWELuWhZX/large-cached.jpeg`;
135
- }
136
-
137
- private getEnergyClass(car: DataSchemes.Car): string {
138
- const available = {
139
- selector_energyEfficiencyClass_a: 'A',
140
- selector_energyEfficiencyClass_ap: 'A+',
141
- selector_energyEfficiencyClass_app: 'A++',
142
- selector_energyEfficiencyClass_appp: 'A+++',
143
- selector_energyEfficiencyClass_b: 'B',
144
- selector_energyEfficiencyClass_c: 'C',
145
- selector_energyEfficiencyClass_d: 'D',
146
- selector_energyEfficiencyClass_e: 'E',
147
- selector_energyEfficiencyClass_f: 'F',
148
- selector_energyEfficiencyClass_g: 'G',
149
- selector_unknown: 'default',
150
- };
151
- const energyClass = get(car, 'environmentEmissions.energyEfficiencyClass', 'selector_unknown');
152
- return get(available, energyClass);
153
- }
154
-
155
- private getColor(car: DataSchemes.Car): string {
156
- let colorSelection = get(car, 'exterior.exteriorColor', 'selector_unknown');
157
- if (!colorSelection || colorSelection === 'selector_unknown') {
158
- colorSelection = 'selector_unknown';
159
- }
160
- return this.translator.translateVal(colorSelection);
161
- }
162
-
163
- private getDrivetrain(car: DataSchemes.Car): string {
164
- const available = {
165
- selector_gearbox_manualShift: 'Manual',
166
- selector_gearbox_semiAutomatic: 'Automatic',
167
- selector_gearbox_automatic: 'Automatic',
168
- selector_unknown: 'N/A',
169
- };
170
- const transmission = get(car, 'driveSuspension.gearbox', 'selector_unknown');
171
- return get(available, transmission);
172
- }
173
-
174
- private getYear(car: DataSchemes.Car): string {
175
- const firstRegistration = get(car, 'mainData.firstRegistration') as number;
176
- if (isNumber(firstRegistration)) {
177
- return moment(firstRegistration * 1000).format('YYYY');
178
- }
179
- return moment().format('YYYY');
180
- }
181
-
182
- private getDriveType(car: DataSchemes.Car): string {
183
- const available = {
184
- selector_unknown: 'N/A',
185
- selector_driveType_frontWheelDrive: 'FWD',
186
- selector_driveType_rearWheelDrive: 'RWD',
187
- selector_driveType_allWheelDrive: 'AWD',
188
- };
189
-
190
- const driveType = get(car, 'driveSuspension.driveType', 'selector_unknown');
191
- return get(available, driveType) || 'N/A';
192
- }
193
-
194
- private async getDescription(car: DataSchemes.Car): Promise<string> {
195
- const dealerId = get(car, 'metaData.ownerId');
196
- const descriptionSchema = await this.userService.getDefaultSummaryByDealerId(dealerId);
197
- const descriptionBuilder = CarDescriptionFactory.create(DescriptionTypeEnum.Mobile, car);
198
- return descriptionBuilder.transform(descriptionSchema);
199
- }
200
- }
1
+ import { escape, get, isEmpty, isNumber, join, toNumber, toSafeInteger, toString, trim } from 'lodash';
2
+ import { Injectable } from '@nestjs/common';
3
+ import * as moment from 'moment/moment';
4
+
5
+ import { CarDescriptionFactory, DescriptionTypeEnum } from '@bytebrand/car-description';
6
+ import { de, deVehicleDetailsPage, deVehicleProps } from '@bytebrand/i18n-dictionaries';
7
+ import { ImboImageResponseInterface } from '@bytebrand/chunkable';
8
+ import { TranslatorExtended } from '@bytebrand/schema-tools';
9
+ import { DataSchemes } from '@bytebrand/car-schema';
10
+
11
+ import { ConfigService, ImagesService, UserService } from '../services';
12
+ import { RubrikkXmlItem } from '../interfaces';
13
+
14
+ @Injectable()
15
+ export class RubrikkTransformer {
16
+ private translator: TranslatorExtended;
17
+
18
+ constructor(
19
+ private readonly configService: ConfigService,
20
+ private readonly imageService: ImagesService,
21
+ private readonly userService: UserService,
22
+ ) {
23
+ const dict = { ...de, ...deVehicleProps, ...deVehicleDetailsPage };
24
+ this.translator = new TranslatorExtended(dict);
25
+ }
26
+
27
+ async transform({
28
+ car,
29
+ images,
30
+ }: {
31
+ car: DataSchemes.Car;
32
+ images: ImboImageResponseInterface[];
33
+ }): Promise<RubrikkXmlItem> {
34
+ return {
35
+ //Common Fields
36
+ ad__all_imageurls: await this.imageService.getImages(car, images, this.configService.config.imageType, false),
37
+ ad__condition_new_used_etc: this.getCondition(car),
38
+ ad__description: await this.getDescription(car),
39
+ ad__headline: this.getTitle(car),
40
+ ad__imageurl: this.getImageLink(car),
41
+ ad__price: toNumber(get(car, 'price.currentSalesPrice', null)),
42
+ ad__price_currency: toString(get(car, 'price.currency', 'EUR')),
43
+ product__type: this.getCategory(car),
44
+ ad__url: this.getCarLink(car),
45
+ efficiency_class: this.getEnergyClass(car),
46
+ ad__number_ad__number_reference_id: toString(get(car, 'metaData.vehicleId', '')),
47
+
48
+ //Categorization
49
+ category_original: 'Autos',
50
+ maincategory_original: 'Fahrzeuge',
51
+
52
+ //Advertiser Info
53
+ advertiser__company_homepage_url: 'https://www.auto.de',
54
+ advertiser__company_logo_url:
55
+ 'https://autode-static.de/wp-content/themes/autode/front/img/header/b_logo_autode.svg',
56
+ advertiser__email: 'auto@auto.de',
57
+ advertiser__name_company_name: 'Auto.de',
58
+ advertiser__phone: '+498004030182',
59
+
60
+ // Geography Info
61
+ location__country: 'Deutschland',
62
+ location__municipality_city: get(car, 'location.city', ''),
63
+ location__zip_postal_code: toString(get(car, 'location.zipCode', '')),
64
+
65
+ // Motoring Fields
66
+ motoring__body_type: this.translateSelector(get(car, 'mainData.category', '')),
67
+ motoring__color: this.getColor(car),
68
+ motoring__drivetrain: this.getDriveType(car),
69
+ motoring__emission_class: this.translateSelector(get(car, 'environmentEmissions.emissionClass', '')),
70
+ motoring__emission_co2: get(car, 'environmentEmissions.co2', null),
71
+ motoring__emission_co2_unit: 'g/km',
72
+ motoring__emission_sticker: this.translateSelector(get(car, 'environmentEmissions.emissionSticker', '')),
73
+ motoring__engine_displacement_cubic_centimeters: toNumber(get(car, 'engineData.cubicCapacity', null)),
74
+ motoring__fuel_consumption_combined: get(car, 'consumption.consumptionCombined', null),
75
+ motoring__fuel_consumption_combined_unit: this.getUrbanUnit(car),
76
+ motoring__fuel_consumption_extra_urban: get(car, 'consumption.consumptionOuter', null),
77
+ motoring__fuel_consumption_extra_urban_unit: this.getUrbanUnit(car),
78
+ motoring__fuel_consumption_urban: get(car, 'consumption.consumptionInner', null),
79
+ motoring__fuel_consumption_urban_unit: this.getUrbanUnit(car),
80
+ motoring__fuel_type: this.translateSelector(get(car, 'consumption.fuel', '')),
81
+ motoring__make: toString(get(car, 'mainData.make', '')),
82
+ motoring__mileage_kilometers: get(car, 'mainData.mileage', null),
83
+ motoring__model: toString(get(car, 'mainData.model', '')),
84
+ motoring__model_year: this.getYear(car),
85
+ motoring__number_of_doors: get(car, 'mainData.doors', null),
86
+ motoring__number_of_seats: get(car, 'mainData.seats', null),
87
+ motoring__power_kw: get(car, 'engineData.powerKW', null),
88
+ motoring__power_hp: get(car, 'engineData.powerPS', null),
89
+ motoring__transmission: this.getDrivetrain(car),
90
+ };
91
+ }
92
+
93
+ private getUrbanUnit(car: DataSchemes.Car) {
94
+ const fuel_type = this.translateSelector(get(car, 'consumption.fuel', ''));
95
+ return fuel_type === 'Elektro' ? 'kWt/100km' : 'l/100km';
96
+ }
97
+
98
+ private translateSelector(selector: string): string {
99
+ if (isEmpty(selector) || selector === 'selector_unknown') {
100
+ return '';
101
+ }
102
+ return this.translator.translateVal(selector);
103
+ }
104
+
105
+ private getTitle(car: DataSchemes.Car): string {
106
+ const make = toString(get(car, 'mainData.make', ''));
107
+ const model = toString(get(car, 'mainData.model', ''));
108
+ const subModel = toString(get(car, 'mainData.subModel', ''));
109
+ return trim(escape(join([make, model, subModel], ' ')));
110
+ }
111
+
112
+ private getCondition(car: DataSchemes.Car): string {
113
+ const available = {
114
+ selector_condition_new: 'Neu',
115
+ selector_condition_used: 'Gebraucht',
116
+ selector_unknown: 'Gebraucht',
117
+ };
118
+ const condition = get(car, 'mainData.condition', 'selector_unknown');
119
+ return get(available, condition);
120
+ }
121
+
122
+ private getCategory(car: DataSchemes.Car): string {
123
+ return this.translator.translateVal(get(car, 'mainData.category', ''));
124
+ }
125
+
126
+ private getCarLink(car: DataSchemes.Car): string {
127
+ return `https://${this.configService.config.domain}/search/vehicle/${car._id}?source=classifieds&medium=listing&campaign=focus`;
128
+ }
129
+
130
+ private getImageLink(car: DataSchemes.Car): string {
131
+ const mainImageId = get(car, 'metaData.mainImageId', '');
132
+ return mainImageId
133
+ ? `${this.configService.config.baseImageUrl}/carimage/${car._id}/${mainImageId}/large-cached.webp`
134
+ : `${this.configService.config.baseImageUrl}/carimage/noimage/7pNvWELuWhZX/large-cached.jpeg`;
135
+ }
136
+
137
+ private getEnergyClass(car: DataSchemes.Car): string {
138
+ const available = {
139
+ selector_energyEfficiencyClass_a: 'A',
140
+ selector_energyEfficiencyClass_ap: 'A+',
141
+ selector_energyEfficiencyClass_app: 'A++',
142
+ selector_energyEfficiencyClass_appp: 'A+++',
143
+ selector_energyEfficiencyClass_b: 'B',
144
+ selector_energyEfficiencyClass_c: 'C',
145
+ selector_energyEfficiencyClass_d: 'D',
146
+ selector_energyEfficiencyClass_e: 'E',
147
+ selector_energyEfficiencyClass_f: 'F',
148
+ selector_energyEfficiencyClass_g: 'G',
149
+ selector_unknown: 'default',
150
+ };
151
+ const energyClass = get(car, 'environmentEmissions.energyEfficiencyClass', 'selector_unknown');
152
+ return get(available, energyClass);
153
+ }
154
+
155
+ private getColor(car: DataSchemes.Car): string {
156
+ let colorSelection = get(car, 'exterior.exteriorColor', 'selector_unknown');
157
+ if (!colorSelection || colorSelection === 'selector_unknown') {
158
+ colorSelection = 'selector_unknown';
159
+ }
160
+ return this.translator.translateVal(colorSelection);
161
+ }
162
+
163
+ private getDrivetrain(car: DataSchemes.Car): string {
164
+ const available = {
165
+ selector_gearbox_manualShift: 'Manual',
166
+ selector_gearbox_semiAutomatic: 'Automatic',
167
+ selector_gearbox_automatic: 'Automatic',
168
+ selector_unknown: 'N/A',
169
+ };
170
+ const transmission = get(car, 'driveSuspension.gearbox', 'selector_unknown');
171
+ return get(available, transmission);
172
+ }
173
+
174
+ private getYear(car: DataSchemes.Car): string {
175
+ const firstRegistration = get(car, 'mainData.firstRegistration') as number;
176
+ if (isNumber(firstRegistration)) {
177
+ return moment(firstRegistration * 1000).format('YYYY');
178
+ }
179
+ return moment().format('YYYY');
180
+ }
181
+
182
+ private getDriveType(car: DataSchemes.Car): string {
183
+ const available = {
184
+ selector_unknown: 'N/A',
185
+ selector_driveType_frontWheelDrive: 'FWD',
186
+ selector_driveType_rearWheelDrive: 'RWD',
187
+ selector_driveType_allWheelDrive: 'AWD',
188
+ };
189
+
190
+ const driveType = get(car, 'driveSuspension.driveType', 'selector_unknown');
191
+ return get(available, driveType) || 'N/A';
192
+ }
193
+
194
+ private async getDescription(car: DataSchemes.Car): Promise<string> {
195
+ const dealerId = get(car, 'metaData.ownerId');
196
+ const descriptionSchema = await this.userService.getDefaultSummaryByDealerId(dealerId);
197
+ const descriptionBuilder = CarDescriptionFactory.create(DescriptionTypeEnum.Mobile, car);
198
+ return descriptionBuilder.transform(descriptionSchema);
199
+ }
200
+ }