@bytebrand/export-cars 1.21.7 → 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 (156) 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/index.d.ts +1 -0
  21. package/dist/exporters/index.js +1 -0
  22. package/dist/exporters/index.js.map +1 -1
  23. package/dist/exporters/santander.exporter.d.ts +12 -0
  24. package/dist/exporters/santander.exporter.js +63 -0
  25. package/dist/exporters/santander.exporter.js.map +1 -0
  26. package/dist/formats/auto24-xml.builder.js +2 -2
  27. package/dist/formats/google-xml.builder.js +3 -3
  28. package/dist/formats/modix-xml.builder.js +2 -2
  29. package/dist/formats/ooyyo-xml.builder.js +1 -1
  30. package/dist/formats/santander-csv.builder.d.ts +6 -0
  31. package/dist/formats/santander-csv.builder.js +17 -0
  32. package/dist/formats/santander-csv.builder.js.map +1 -0
  33. package/dist/tsconfig.build.tsbuildinfo +1 -1
  34. package/nest-cli.json +5 -5
  35. package/package.json +61 -61
  36. package/src/app.module.ts +38 -38
  37. package/src/configs/alleskralle.config.ts +15 -15
  38. package/src/configs/as24.config.ts +13 -13
  39. package/src/configs/auto24.config.ts +15 -15
  40. package/src/configs/autoboerse.config.ts +16 -16
  41. package/src/configs/autouncle.config.ts +14 -14
  42. package/src/configs/awin.config.ts +15 -15
  43. package/src/configs/by-owner.config.ts +14 -14
  44. package/src/configs/config.ts +83 -83
  45. package/src/configs/criteo.config.ts +17 -17
  46. package/src/configs/dasparking.config.ts +15 -15
  47. package/src/configs/eauto.config.ts +15 -15
  48. package/src/configs/evium.config.ts +18 -18
  49. package/src/configs/facebook-shop.config.ts +16 -16
  50. package/src/configs/fb.config.ts +16 -16
  51. package/src/configs/google.config.ts +14 -14
  52. package/src/configs/index.ts +22 -21
  53. package/src/configs/kleinanzeigeFocus.config.ts +14 -14
  54. package/src/configs/marktde.config.ts +18 -18
  55. package/src/configs/meinstadt.config.ts +15 -15
  56. package/src/configs/mitula.config.ts +14 -14
  57. package/src/configs/ooyyo.config.ts +15 -15
  58. package/src/configs/santander.config.ts +15 -0
  59. package/src/configs/trovit.config.ts +14 -14
  60. package/src/configs/yescar.config.ts +17 -17
  61. package/src/constants/autouncle.contants.ts +4 -4
  62. package/src/constants/fb.constants.ts +7 -7
  63. package/src/constants/index.ts +1 -1
  64. package/src/constants/modix/body-color-name.constant.ts +20 -20
  65. package/src/constants/modix/category.constant.ts +14 -14
  66. package/src/constants/modix/fuel.constant.ts +14 -14
  67. package/src/constants/modix/index.ts +7 -7
  68. package/src/constants/modix/manufacturers.constant.ts +7498 -7498
  69. package/src/constants/modix/transmission.constant.ts +8 -8
  70. package/src/constants/modix/usage-type.constant.ts +13 -13
  71. package/src/constants/modix/vehicle-class.constant.ts +17 -17
  72. package/src/enums/environment.enum.ts +5 -5
  73. package/src/enums/export-type.enum.ts +33 -32
  74. package/src/enums/file-types.enum.ts +8 -8
  75. package/src/enums/image-type.enum.ts +4 -4
  76. package/src/enums/index.ts +4 -4
  77. package/src/export.command.ts +37 -37
  78. package/src/export.schema.ts +134 -128
  79. package/src/exporters/as24.exporter.ts +69 -69
  80. package/src/exporters/auto24.exporter.ts +48 -48
  81. package/src/exporters/autouncle.exporter.ts +60 -60
  82. package/src/exporters/awin.exporter.ts +47 -47
  83. package/src/exporters/by-owner.exporter.ts +44 -44
  84. package/src/exporters/facebook-shop.exporter.ts +51 -51
  85. package/src/exporters/fb.exporter.ts +52 -52
  86. package/src/exporters/google.exporter.ts +45 -45
  87. package/src/exporters/index.ts +15 -14
  88. package/src/exporters/meinstadt.exporter.ts +55 -55
  89. package/src/exporters/mobile.exporter.ts +64 -64
  90. package/src/exporters/modix.exporter.ts +56 -56
  91. package/src/exporters/ooyyo.exporter.ts +48 -48
  92. package/src/exporters/rubrikk.exporter.ts +53 -53
  93. package/src/exporters/santander.exporter.ts +50 -0
  94. package/src/exporters/trovit.exporter.ts +51 -51
  95. package/src/formats/auto24-xml.builder.ts +54 -54
  96. package/src/formats/autouncle-json.builder.ts +20 -20
  97. package/src/formats/awin-csv.builder.ts +16 -16
  98. package/src/formats/facebook-shop.builder.ts +69 -69
  99. package/src/formats/fb-xml.builder.ts +71 -71
  100. package/src/formats/google-xml.builder.ts +35 -35
  101. package/src/formats/index.ts +5 -5
  102. package/src/formats/meinstadt-json.builder.ts +19 -19
  103. package/src/formats/modix-xml.builder.ts +180 -180
  104. package/src/formats/ooyyo-xml.builder.ts +48 -48
  105. package/src/formats/rubrikk-xml.builder.ts +27 -27
  106. package/src/formats/santander-csv.builder.ts +15 -0
  107. package/src/formats/trovit-xml.builder.ts +44 -44
  108. package/src/interfaces/atributes-wrap-item.intreface.ts +6 -6
  109. package/src/interfaces/dealers-mapping.interface.ts +7 -7
  110. package/src/interfaces/description.interface.ts +24 -24
  111. package/src/interfaces/export-item.interface.ts +366 -366
  112. package/src/interfaces/exporter.interface.ts +3 -3
  113. package/src/interfaces/index.ts +3 -3
  114. package/src/interfaces/input.interface.ts +6 -6
  115. package/src/interfaces/mapping-rules.interface.ts +11 -11
  116. package/src/interfaces/modix/index.ts +1 -1
  117. package/src/interfaces/modix/modix-item-list.interface.ts +5 -5
  118. package/src/interfaces/params.interface.ts +13 -13
  119. package/src/interfaces/rule-parser.interface.ts +3 -3
  120. package/src/main.ts +14 -14
  121. package/src/rules/abstract.rule.ts +37 -37
  122. package/src/rules/date.rule.ts +19 -19
  123. package/src/rules/number.rule.ts +15 -15
  124. package/src/rules/string.rule.ts +8 -8
  125. package/src/services/car.service.ts +49 -49
  126. package/src/services/config.service.ts +15 -15
  127. package/src/services/images.service.ts +207 -207
  128. package/src/services/index.ts +9 -9
  129. package/src/services/loader.service.ts +29 -29
  130. package/src/services/mapping.service.ts +91 -91
  131. package/src/services/request.service.ts +44 -44
  132. package/src/services/rules.service.ts +61 -61
  133. package/src/services/transformer.service.ts +129 -129
  134. package/src/services/user.service.ts +57 -57
  135. package/src/transformers/as24.transformer.ts +253 -253
  136. package/src/transformers/auto24.transfomer.ts +155 -155
  137. package/src/transformers/autouncle.transformer.ts +236 -236
  138. package/src/transformers/awin.transformer.ts +193 -193
  139. package/src/transformers/by-owner.transformer.ts +354 -354
  140. package/src/transformers/facebook-shop.transformer.ts +93 -93
  141. package/src/transformers/fb-description.transformer.ts +316 -316
  142. package/src/transformers/fb-equipment.transformer.ts +161 -161
  143. package/src/transformers/fb.transformer.ts +655 -655
  144. package/src/transformers/google.transformer.ts +169 -169
  145. package/src/transformers/index.ts +5 -5
  146. package/src/transformers/meinstadt.transformer.ts +92 -92
  147. package/src/transformers/mobile.transformer.ts +482 -482
  148. package/src/transformers/modix.transformer.ts +227 -227
  149. package/src/transformers/ooyyo.transformer.ts +109 -109
  150. package/src/transformers/rubrikk.transformer.ts +200 -200
  151. package/src/transformers/trovit.transformer.ts +63 -63
  152. package/src/utils/converter.utils.ts +15 -15
  153. package/src/utils/index.ts +2 -2
  154. package/src/utils/validator.utils.ts +7 -7
  155. package/tsconfig.build.json +4 -4
  156. package/tsconfig.json +29 -29
@@ -1,57 +1,57 @@
1
- import { CACHE_MANAGER } from '@nestjs/cache-manager';
2
- import { Inject, Injectable } from '@nestjs/common';
3
-
4
- import { MarketingImageConfigInterface, MarketingImageConfigsInterface } from '@bytebrand/autode-request';
5
- import { CronicleUtils } from '@bytebrand/cronicle-helper';
6
-
7
- import { RequestService } from './request.service';
8
- import { Cache } from 'cache-manager';
9
- import { get } from 'lodash';
10
-
11
-
12
- @Injectable()
13
- export class UserService {
14
- constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache, private readonly requestService: RequestService) {}
15
-
16
- async getDefaultSummaryByDealerId(dealerId: string): Promise<any> {
17
- const cacheKey = `${dealerId}_default_summary`;
18
- const cachedResponse = await this.cacheManager.get(cacheKey);
19
-
20
- if (cachedResponse) {
21
- return cachedResponse;
22
- }
23
-
24
- const defaultSummary = await CronicleUtils.retry(() => this.requestService.userActionsRequest.getDefaultSummaryByDealerId(dealerId), 1, 30, true);
25
- const result = get(defaultSummary, 'data.schema', {});
26
- await this.cacheManager.set(cacheKey, result);
27
-
28
- return result;
29
- }
30
-
31
- async getMarketingImageConfig(configId: number): Promise<MarketingImageConfigInterface> {
32
- const key = `marketingImageConfig_${configId}`;
33
- let result = (await this.cacheManager.get(key)) as MarketingImageConfigInterface;
34
- if (result) {
35
- return result;
36
- }
37
-
38
- result = await this.requestService.upaRequest.getMarketingImageConfigById(configId);
39
-
40
- await this.cacheManager.set(key, result);
41
-
42
- return result;
43
- }
44
-
45
- async getMarketingImageConfigs(): Promise<MarketingImageConfigsInterface[]> {
46
- const key = 'marketingImagesConfigs';
47
- let result = (await this.cacheManager.get(key)) as MarketingImageConfigsInterface[];
48
- if (result) {
49
- return result;
50
- }
51
-
52
- result = await this.requestService.upaRequest.getMarketingImageConfigs();
53
- await this.cacheManager.set(key, result);
54
-
55
- return result;
56
- }
57
- }
1
+ import { CACHE_MANAGER } from '@nestjs/cache-manager';
2
+ import { Inject, Injectable } from '@nestjs/common';
3
+
4
+ import { MarketingImageConfigInterface, MarketingImageConfigsInterface } from '@bytebrand/autode-request';
5
+ import { CronicleUtils } from '@bytebrand/cronicle-helper';
6
+
7
+ import { RequestService } from './request.service';
8
+ import { Cache } from 'cache-manager';
9
+ import { get } from 'lodash';
10
+
11
+
12
+ @Injectable()
13
+ export class UserService {
14
+ constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache, private readonly requestService: RequestService) {}
15
+
16
+ async getDefaultSummaryByDealerId(dealerId: string): Promise<any> {
17
+ const cacheKey = `${dealerId}_default_summary`;
18
+ const cachedResponse = await this.cacheManager.get(cacheKey);
19
+
20
+ if (cachedResponse) {
21
+ return cachedResponse;
22
+ }
23
+
24
+ const defaultSummary = await CronicleUtils.retry(() => this.requestService.userActionsRequest.getDefaultSummaryByDealerId(dealerId), 1, 30, true);
25
+ const result = get(defaultSummary, 'data.schema', {});
26
+ await this.cacheManager.set(cacheKey, result);
27
+
28
+ return result;
29
+ }
30
+
31
+ async getMarketingImageConfig(configId: number): Promise<MarketingImageConfigInterface> {
32
+ const key = `marketingImageConfig_${configId}`;
33
+ let result = (await this.cacheManager.get(key)) as MarketingImageConfigInterface;
34
+ if (result) {
35
+ return result;
36
+ }
37
+
38
+ result = await this.requestService.upaRequest.getMarketingImageConfigById(configId);
39
+
40
+ await this.cacheManager.set(key, result);
41
+
42
+ return result;
43
+ }
44
+
45
+ async getMarketingImageConfigs(): Promise<MarketingImageConfigsInterface[]> {
46
+ const key = 'marketingImagesConfigs';
47
+ let result = (await this.cacheManager.get(key)) as MarketingImageConfigsInterface[];
48
+ if (result) {
49
+ return result;
50
+ }
51
+
52
+ result = await this.requestService.upaRequest.getMarketingImageConfigs();
53
+ await this.cacheManager.set(key, result);
54
+
55
+ return result;
56
+ }
57
+ }
@@ -1,253 +1,253 @@
1
- import { get, isEmpty, isNil, set, toNumber, toSafeInteger, upperFirst } from 'lodash';
2
- import { DataSchemes } from '@bytebrand/car-schema';
3
- import { CarDescriptionFactory, DescriptionTypeEnum } from '@bytebrand/car-description';
4
- import { MappingService, UserService } from '../services';
5
- import { MappingRules } from '../interfaces/mapping-rules.interface';
6
- import { Injectable } from '@nestjs/common';
7
- import { LoggerService } from '@bytebrand/cronicle-helper';
8
-
9
- /**
10
- * @deprecated 02.03.2022
11
- */
12
- @Injectable()
13
- export class As24Transformer {
14
- private currentCar: DataSchemes.Car;
15
- constructor(private mappingService: MappingService, private readonly userService: UserService) {}
16
-
17
- async transform(carData: DataSchemes.Car): Promise<unknown> {
18
- this.currentCar = carData;
19
- const transformedCarData = {};
20
- const rules = await this.mappingService.getRules();
21
- for (const rule of rules) {
22
- if (rule.custom === 'yes') {
23
- const transformedField = await this.customTransformers(rule, carData);
24
- if (transformedField) {
25
- set(transformedCarData, `${rule.importField}`, transformedField);
26
- }
27
- } else {
28
- const fieldValue: any = get(carData, `${rule.autodeField}`, null);
29
- if (!isNil(fieldValue)) {
30
- const transformedField = await this.transformField(fieldValue, rule);
31
-
32
- if (!isNil(transformedField)) {
33
- set(transformedCarData, `${rule.importField}`, transformedField);
34
- }
35
- }
36
- }
37
- }
38
-
39
- const ownerId = get(carData, 'metaData.ownerId', '');
40
- const carId = get(carData, '_id', '');
41
- ownerId && set(transformedCarData, 0, ownerId);
42
- carId && set(transformedCarData, 1, carId);
43
-
44
- return transformedCarData;
45
- }
46
-
47
- private async transformField(fieldValue: any, rule: MappingRules): Promise<string | void> {
48
- const transformProcedureName = `${rule.autodeFieldType}To${upperFirst(rule.importFieldType)}`;
49
-
50
- switch (transformProcedureName) {
51
- case 'stringToString': {
52
- if (rule.autodeField === 'offer.offerDescription') {
53
- return await this.offerStringToString();
54
- }
55
- return this.stringToString(fieldValue);
56
- }
57
- case 'integerToString': {
58
- return this.numberToString(fieldValue);
59
- }
60
- case 'numberToString': {
61
- return this.numberToString(fieldValue);
62
- }
63
- case 'booleanToString': {
64
- return this.booleanToString(fieldValue);
65
- }
66
- case 'selectorToSelector': {
67
- return this.selectorToSelector(fieldValue, rule);
68
- }
69
- case 'selectorToString': {
70
- return this.selectorToString(fieldValue, rule);
71
- }
72
- case 'selector[]ToSelector': {
73
- return this.selectorArrayToSelector(fieldValue, rule);
74
- }
75
- case 'selector[]ToString': {
76
- return this.selectorArrayToString(fieldValue, rule);
77
- }
78
- case 'dateToString': {
79
- return this.dateToString(fieldValue, rule);
80
- }
81
- case 'dateToMobile_delivery': {
82
- return this.dateToString(fieldValue, rule);
83
- }
84
- case 'stringToMobile_model': {
85
- return this.stringToMobile_model(fieldValue);
86
- }
87
- case 'numberToMobile_consumption': {
88
- return this.numberToMobile_consumption(fieldValue);
89
- }
90
- case 'booleanToMobile_vatCalc': {
91
- return this.booleanToMobile_vatCalc(fieldValue);
92
- }
93
- case 'selectorToMobile_extColor_selector': {
94
- return this.selectorToSelector(fieldValue, rule);
95
- }
96
- case 'selectorToCategoryOrClass_selector': {
97
- return this.selectorToCategoryOrClass_selector(fieldValue, rule);
98
- }
99
- case 'numberToNumber': {
100
- return this.numberToNumber(fieldValue).toString();
101
- }
102
- case 'numberToInteger': {
103
- return this.numberToInteger(fieldValue).toString();
104
- }
105
- case 'integerToNumber': {
106
- return this.numberToNumber(fieldValue).toString();
107
- }
108
- case 'stringToInteger': {
109
- return this.stringToInteger(fieldValue).toString();
110
- }
111
- default:
112
- LoggerService.log(`missing transform: ${transformProcedureName}`);
113
- break;
114
- }
115
- }
116
-
117
- protected numberToNumber(field: number): number {
118
- const result = isNil(field) ? null : toNumber(field);
119
- return result < 0 || isNaN(result) ? undefined : result;
120
- }
121
-
122
- protected numberToInteger(field: number): number {
123
- const result = isNil(field) ? null : toSafeInteger(field);
124
- return result < 0 ? null : result;
125
- }
126
-
127
- protected stringToInteger(field: string): number {
128
- const result = isEmpty(field) ? null : toSafeInteger(field);
129
- return result < 0 ? null : result;
130
- }
131
-
132
- private async customTransformers(rule: MappingRules, car: DataSchemes.Car): Promise<any> {
133
- switch (rule.autodeField) {
134
- case 'price.vatDeductible': {
135
- return this.getVatDeductible(car);
136
- }
137
- case 'price.originalSalesPrice': {
138
- return this.getOriginalSalesPrice(car);
139
- }
140
- case 'price.vatRate': {
141
- return this.getVatRate(car);
142
- }
143
- default:
144
- return '';
145
- }
146
- }
147
-
148
- private async getVatDeductible(car: DataSchemes.Car): Promise<string> {
149
- return this.booleanToString(!get(car, 'price.vatDeductible', null));
150
- }
151
-
152
- private async getOriginalSalesPrice(car: DataSchemes.Car): Promise<string> {
153
- const vat = !get(car, 'price.vatDeductible', false);
154
- const price = get(car, 'price.originalSalesPrice', null);
155
- if (price && !vat) {
156
- return (price / 1.19).toFixed(2) + '';
157
- }
158
- return price + '';
159
- }
160
-
161
- private async getVatRate(car: DataSchemes.Car): Promise<'19' | '0'> {
162
- const vat = get(car, 'price.vatDeductible', false);
163
- if (vat) {
164
- return '19';
165
- }
166
- return '0';
167
- }
168
-
169
- private async offerStringToString(): Promise<string> {
170
- const dealerID = get(this.currentCar, 'metaData.ownerId');
171
-
172
- const descriptionSchema = await this.userService.getDefaultSummaryByDealerId(dealerID);
173
- const descriptionBuilder = CarDescriptionFactory.create(DescriptionTypeEnum.Mobile, this.currentCar);
174
- return descriptionBuilder.transform(descriptionSchema);
175
- }
176
-
177
- private stringToString(fieldValue: string): string {
178
- return isEmpty(fieldValue) ? null : fieldValue;
179
- }
180
-
181
- private numberToString(fieldValue: number): string {
182
- return String(fieldValue);
183
- }
184
-
185
- private booleanToString(fieldValue: boolean): string {
186
- return String(Number(fieldValue));
187
- }
188
-
189
- private selectorToSelector(fieldValue: string, rule: MappingRules): string | void {
190
- if (fieldValue === 'selector_unknown' && rule.autodeField === 'heatingCooling.climatisation') {
191
- return 'default';
192
- }
193
-
194
- if (fieldValue === 'selector_unknown' || fieldValue === 'selector_interiorColor_rainbow') {
195
- return '';
196
- }
197
- const pairs = rule.selectors.map(p => p.split(':').reverse());
198
- const [match] = pairs.filter(p => p[0] === fieldValue);
199
- // consider adding values not mapped in table
200
- if (match) {
201
- return match[1];
202
- }
203
- }
204
-
205
- private selectorToString(fieldValue: string, rule: MappingRules): string {
206
- return this.booleanToString(fieldValue === rule.autodeFieldSelector);
207
- }
208
-
209
- private selectorArrayToSelector(fieldValue: string[], rule: MappingRules): string | void {
210
- const lastVal = fieldValue[fieldValue.length - 1];
211
- const match = this.selectorToSelector(lastVal, rule);
212
-
213
- if (match && match !== 'default') {
214
- return match;
215
- }
216
- }
217
-
218
- private selectorArrayToString(fieldValue: string[], rule: MappingRules): string {
219
- const match = fieldValue.includes(rule.autodeFieldSelector);
220
- return this.booleanToString(match);
221
- }
222
-
223
- private dateToString(fieldValue: number, rule: MappingRules): string {
224
- const date = new Date(fieldValue * 1000);
225
- if (["['6']", "['7']", "['8']"].includes(rule.importField)) {
226
- return `${date.getMonth() + 1}.${date.getFullYear()}`;
227
- }
228
- return `${date.getDate()}.${date.getMonth() + 1}.${date.getFullYear()}`;
229
- }
230
-
231
- private stringToMobile_model(fieldValue: string): string {
232
- const model = fieldValue;
233
- const subModel = get(this.currentCar, 'mainData.subModel');
234
- return subModel && subModel !== model ? `${model} ${subModel}` : model;
235
- }
236
-
237
- private numberToMobile_consumption(fieldValue: number): string {
238
- const consumption = this.numberToString(fieldValue);
239
- return consumption.replace('.', ',');
240
- }
241
-
242
- private booleanToMobile_vatCalc(fieldValue: boolean): string {
243
- return this.booleanToString(fieldValue);
244
- }
245
-
246
- private selectorToCategoryOrClass_selector(fieldValue: string, rule: MappingRules): string | void {
247
- const pairs = rule.selectors.map(p => p.split(':'));
248
- const found = pairs.find(p => p[1] === fieldValue);
249
- if (found) {
250
- return found[0];
251
- }
252
- }
253
- }
1
+ import { get, isEmpty, isNil, set, toNumber, toSafeInteger, upperFirst } from 'lodash';
2
+ import { DataSchemes } from '@bytebrand/car-schema';
3
+ import { CarDescriptionFactory, DescriptionTypeEnum } from '@bytebrand/car-description';
4
+ import { MappingService, UserService } from '../services';
5
+ import { MappingRules } from '../interfaces/mapping-rules.interface';
6
+ import { Injectable } from '@nestjs/common';
7
+ import { LoggerService } from '@bytebrand/cronicle-helper';
8
+
9
+ /**
10
+ * @deprecated 02.03.2022
11
+ */
12
+ @Injectable()
13
+ export class As24Transformer {
14
+ private currentCar: DataSchemes.Car;
15
+ constructor(private mappingService: MappingService, private readonly userService: UserService) {}
16
+
17
+ async transform(carData: DataSchemes.Car): Promise<unknown> {
18
+ this.currentCar = carData;
19
+ const transformedCarData = {};
20
+ const rules = await this.mappingService.getRules();
21
+ for (const rule of rules) {
22
+ if (rule.custom === 'yes') {
23
+ const transformedField = await this.customTransformers(rule, carData);
24
+ if (transformedField) {
25
+ set(transformedCarData, `${rule.importField}`, transformedField);
26
+ }
27
+ } else {
28
+ const fieldValue: any = get(carData, `${rule.autodeField}`, null);
29
+ if (!isNil(fieldValue)) {
30
+ const transformedField = await this.transformField(fieldValue, rule);
31
+
32
+ if (!isNil(transformedField)) {
33
+ set(transformedCarData, `${rule.importField}`, transformedField);
34
+ }
35
+ }
36
+ }
37
+ }
38
+
39
+ const ownerId = get(carData, 'metaData.ownerId', '');
40
+ const carId = get(carData, '_id', '');
41
+ ownerId && set(transformedCarData, 0, ownerId);
42
+ carId && set(transformedCarData, 1, carId);
43
+
44
+ return transformedCarData;
45
+ }
46
+
47
+ private async transformField(fieldValue: any, rule: MappingRules): Promise<string | void> {
48
+ const transformProcedureName = `${rule.autodeFieldType}To${upperFirst(rule.importFieldType)}`;
49
+
50
+ switch (transformProcedureName) {
51
+ case 'stringToString': {
52
+ if (rule.autodeField === 'offer.offerDescription') {
53
+ return await this.offerStringToString();
54
+ }
55
+ return this.stringToString(fieldValue);
56
+ }
57
+ case 'integerToString': {
58
+ return this.numberToString(fieldValue);
59
+ }
60
+ case 'numberToString': {
61
+ return this.numberToString(fieldValue);
62
+ }
63
+ case 'booleanToString': {
64
+ return this.booleanToString(fieldValue);
65
+ }
66
+ case 'selectorToSelector': {
67
+ return this.selectorToSelector(fieldValue, rule);
68
+ }
69
+ case 'selectorToString': {
70
+ return this.selectorToString(fieldValue, rule);
71
+ }
72
+ case 'selector[]ToSelector': {
73
+ return this.selectorArrayToSelector(fieldValue, rule);
74
+ }
75
+ case 'selector[]ToString': {
76
+ return this.selectorArrayToString(fieldValue, rule);
77
+ }
78
+ case 'dateToString': {
79
+ return this.dateToString(fieldValue, rule);
80
+ }
81
+ case 'dateToMobile_delivery': {
82
+ return this.dateToString(fieldValue, rule);
83
+ }
84
+ case 'stringToMobile_model': {
85
+ return this.stringToMobile_model(fieldValue);
86
+ }
87
+ case 'numberToMobile_consumption': {
88
+ return this.numberToMobile_consumption(fieldValue);
89
+ }
90
+ case 'booleanToMobile_vatCalc': {
91
+ return this.booleanToMobile_vatCalc(fieldValue);
92
+ }
93
+ case 'selectorToMobile_extColor_selector': {
94
+ return this.selectorToSelector(fieldValue, rule);
95
+ }
96
+ case 'selectorToCategoryOrClass_selector': {
97
+ return this.selectorToCategoryOrClass_selector(fieldValue, rule);
98
+ }
99
+ case 'numberToNumber': {
100
+ return this.numberToNumber(fieldValue).toString();
101
+ }
102
+ case 'numberToInteger': {
103
+ return this.numberToInteger(fieldValue).toString();
104
+ }
105
+ case 'integerToNumber': {
106
+ return this.numberToNumber(fieldValue).toString();
107
+ }
108
+ case 'stringToInteger': {
109
+ return this.stringToInteger(fieldValue).toString();
110
+ }
111
+ default:
112
+ LoggerService.log(`missing transform: ${transformProcedureName}`);
113
+ break;
114
+ }
115
+ }
116
+
117
+ protected numberToNumber(field: number): number {
118
+ const result = isNil(field) ? null : toNumber(field);
119
+ return result < 0 || isNaN(result) ? undefined : result;
120
+ }
121
+
122
+ protected numberToInteger(field: number): number {
123
+ const result = isNil(field) ? null : toSafeInteger(field);
124
+ return result < 0 ? null : result;
125
+ }
126
+
127
+ protected stringToInteger(field: string): number {
128
+ const result = isEmpty(field) ? null : toSafeInteger(field);
129
+ return result < 0 ? null : result;
130
+ }
131
+
132
+ private async customTransformers(rule: MappingRules, car: DataSchemes.Car): Promise<any> {
133
+ switch (rule.autodeField) {
134
+ case 'price.vatDeductible': {
135
+ return this.getVatDeductible(car);
136
+ }
137
+ case 'price.originalSalesPrice': {
138
+ return this.getOriginalSalesPrice(car);
139
+ }
140
+ case 'price.vatRate': {
141
+ return this.getVatRate(car);
142
+ }
143
+ default:
144
+ return '';
145
+ }
146
+ }
147
+
148
+ private async getVatDeductible(car: DataSchemes.Car): Promise<string> {
149
+ return this.booleanToString(!get(car, 'price.vatDeductible', null));
150
+ }
151
+
152
+ private async getOriginalSalesPrice(car: DataSchemes.Car): Promise<string> {
153
+ const vat = !get(car, 'price.vatDeductible', false);
154
+ const price = get(car, 'price.originalSalesPrice', null);
155
+ if (price && !vat) {
156
+ return (price / 1.19).toFixed(2) + '';
157
+ }
158
+ return price + '';
159
+ }
160
+
161
+ private async getVatRate(car: DataSchemes.Car): Promise<'19' | '0'> {
162
+ const vat = get(car, 'price.vatDeductible', false);
163
+ if (vat) {
164
+ return '19';
165
+ }
166
+ return '0';
167
+ }
168
+
169
+ private async offerStringToString(): Promise<string> {
170
+ const dealerID = get(this.currentCar, 'metaData.ownerId');
171
+
172
+ const descriptionSchema = await this.userService.getDefaultSummaryByDealerId(dealerID);
173
+ const descriptionBuilder = CarDescriptionFactory.create(DescriptionTypeEnum.Mobile, this.currentCar);
174
+ return descriptionBuilder.transform(descriptionSchema);
175
+ }
176
+
177
+ private stringToString(fieldValue: string): string {
178
+ return isEmpty(fieldValue) ? null : fieldValue;
179
+ }
180
+
181
+ private numberToString(fieldValue: number): string {
182
+ return String(fieldValue);
183
+ }
184
+
185
+ private booleanToString(fieldValue: boolean): string {
186
+ return String(Number(fieldValue));
187
+ }
188
+
189
+ private selectorToSelector(fieldValue: string, rule: MappingRules): string | void {
190
+ if (fieldValue === 'selector_unknown' && rule.autodeField === 'heatingCooling.climatisation') {
191
+ return 'default';
192
+ }
193
+
194
+ if (fieldValue === 'selector_unknown' || fieldValue === 'selector_interiorColor_rainbow') {
195
+ return '';
196
+ }
197
+ const pairs = rule.selectors.map(p => p.split(':').reverse());
198
+ const [match] = pairs.filter(p => p[0] === fieldValue);
199
+ // consider adding values not mapped in table
200
+ if (match) {
201
+ return match[1];
202
+ }
203
+ }
204
+
205
+ private selectorToString(fieldValue: string, rule: MappingRules): string {
206
+ return this.booleanToString(fieldValue === rule.autodeFieldSelector);
207
+ }
208
+
209
+ private selectorArrayToSelector(fieldValue: string[], rule: MappingRules): string | void {
210
+ const lastVal = fieldValue[fieldValue.length - 1];
211
+ const match = this.selectorToSelector(lastVal, rule);
212
+
213
+ if (match && match !== 'default') {
214
+ return match;
215
+ }
216
+ }
217
+
218
+ private selectorArrayToString(fieldValue: string[], rule: MappingRules): string {
219
+ const match = fieldValue.includes(rule.autodeFieldSelector);
220
+ return this.booleanToString(match);
221
+ }
222
+
223
+ private dateToString(fieldValue: number, rule: MappingRules): string {
224
+ const date = new Date(fieldValue * 1000);
225
+ if (["['6']", "['7']", "['8']"].includes(rule.importField)) {
226
+ return `${date.getMonth() + 1}.${date.getFullYear()}`;
227
+ }
228
+ return `${date.getDate()}.${date.getMonth() + 1}.${date.getFullYear()}`;
229
+ }
230
+
231
+ private stringToMobile_model(fieldValue: string): string {
232
+ const model = fieldValue;
233
+ const subModel = get(this.currentCar, 'mainData.subModel');
234
+ return subModel && subModel !== model ? `${model} ${subModel}` : model;
235
+ }
236
+
237
+ private numberToMobile_consumption(fieldValue: number): string {
238
+ const consumption = this.numberToString(fieldValue);
239
+ return consumption.replace('.', ',');
240
+ }
241
+
242
+ private booleanToMobile_vatCalc(fieldValue: boolean): string {
243
+ return this.booleanToString(fieldValue);
244
+ }
245
+
246
+ private selectorToCategoryOrClass_selector(fieldValue: string, rule: MappingRules): string | void {
247
+ const pairs = rule.selectors.map(p => p.split(':'));
248
+ const found = pairs.find(p => p[1] === fieldValue);
249
+ if (found) {
250
+ return found[0];
251
+ }
252
+ }
253
+ }