@bytebrand/export-cars 1.7.0 → 1.8.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/dist/configs/facebook-shop.config.d.ts +5 -0
- package/dist/configs/facebook-shop.config.js +17 -0
- package/dist/configs/facebook-shop.config.js.map +1 -0
- package/dist/configs/index.d.ts +1 -0
- package/dist/configs/index.js +1 -0
- package/dist/configs/index.js.map +1 -1
- package/dist/enums/export-type.enum.d.ts +2 -1
- package/dist/enums/export-type.enum.js +1 -0
- package/dist/enums/export-type.enum.js.map +1 -1
- package/dist/enums/index.d.ts +1 -0
- package/dist/enums/index.js +1 -0
- package/dist/enums/index.js.map +1 -1
- package/dist/export.schema.d.ts +6 -2
- package/dist/export.schema.js +4 -0
- package/dist/export.schema.js.map +1 -1
- package/dist/exporters/facebook-shop.exporter.d.ts +12 -0
- package/dist/exporters/facebook-shop.exporter.js +63 -0
- package/dist/exporters/facebook-shop.exporter.js.map +1 -0
- package/dist/exporters/fb.exporter.js.map +1 -1
- package/dist/exporters/index.d.ts +1 -0
- package/dist/exporters/index.js +1 -0
- package/dist/exporters/index.js.map +1 -1
- package/dist/exporters/modix.exporter.js.map +1 -1
- package/dist/formats/facebook-shop.builder.d.ts +10 -0
- package/dist/formats/facebook-shop.builder.js +62 -0
- package/dist/formats/facebook-shop.builder.js.map +1 -0
- package/dist/formats/index.d.ts +1 -0
- package/dist/formats/index.js +1 -0
- package/dist/formats/index.js.map +1 -1
- package/dist/interfaces/export-item.interface.d.ts +26 -0
- package/dist/interfaces/params.interface.d.ts +1 -2
- package/dist/transformers/autouncle.transformer.d.ts +1 -1
- package/dist/transformers/autouncle.transformer.js +2 -2
- package/dist/transformers/autouncle.transformer.js.map +1 -1
- package/dist/transformers/facebook-shop.transformer.d.ts +18 -0
- package/dist/transformers/facebook-shop.transformer.js +96 -0
- package/dist/transformers/facebook-shop.transformer.js.map +1 -0
- package/dist/transformers/index.d.ts +1 -0
- package/dist/transformers/index.js +1 -0
- package/dist/transformers/index.js.map +1 -1
- package/dist/transformers/meinstadt.transformer.d.ts +1 -1
- package/dist/transformers/meinstadt.transformer.js +3 -4
- package/dist/transformers/meinstadt.transformer.js.map +1 -1
- package/dist/transformers/modix.transformer.d.ts +1 -1
- package/dist/transformers/modix.transformer.js +6 -3
- package/dist/transformers/modix.transformer.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/configs/facebook-shop.config.ts +14 -0
- package/src/configs/index.ts +1 -0
- package/src/enums/export-type.enum.ts +7 -6
- package/src/enums/index.ts +1 -0
- package/src/export.schema.ts +8 -3
- package/src/exporters/facebook-shop.exporter.ts +51 -0
- package/src/exporters/fb.exporter.ts +3 -3
- package/src/exporters/index.ts +1 -0
- package/src/exporters/modix.exporter.ts +6 -5
- package/src/formats/facebook-shop.builder.ts +69 -0
- package/src/formats/index.ts +1 -0
- package/src/interfaces/export-item.interface.ts +26 -0
- package/src/interfaces/params.interface.ts +1 -2
- package/src/transformers/autouncle.transformer.ts +1 -1
- package/src/transformers/facebook-shop.transformer.ts +94 -0
- package/src/transformers/index.ts +1 -0
- package/src/transformers/meinstadt.transformer.ts +2 -3
- package/src/transformers/modix.transformer.ts +20 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bytebrand/export-cars",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "bytebrand",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -66,5 +66,5 @@
|
|
|
66
66
|
"engines": {
|
|
67
67
|
"node": ">=14.0.0"
|
|
68
68
|
},
|
|
69
|
-
"gitHead": "
|
|
69
|
+
"gitHead": "b7be73fdc44db2ae19fef0b970b05b90ff6a0b7a"
|
|
70
70
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Params } from '../interfaces/params.interface';
|
|
2
|
+
import { Config } from './config';
|
|
3
|
+
import { ExportType, FileType } from '../enums';
|
|
4
|
+
|
|
5
|
+
export class FacebookShopConfig extends Config {
|
|
6
|
+
constructor(params: Params) {
|
|
7
|
+
super(params);
|
|
8
|
+
this.pathesConfig.localConvertedDirectory = `resources/${ExportType.FACEBOOK_SHOP}-export`;
|
|
9
|
+
this.imageUrl = this.environmentConfig[params.environment].baseImageUrl;
|
|
10
|
+
this.outputFiles = [
|
|
11
|
+
`${this.pathesConfig.localConvertedDirectory}/api_export_cars_${ExportType.FACEBOOK_SHOP}.${FileType.XML}`,
|
|
12
|
+
];
|
|
13
|
+
}
|
|
14
|
+
}
|
package/src/configs/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export enum ExportType {
|
|
2
2
|
/**
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
* @deprecated
|
|
4
|
+
*/
|
|
5
5
|
YESCAR = 'yescar',
|
|
6
6
|
MARKTDE = 'marktde',
|
|
7
7
|
EAUTO = 'eauto',
|
|
@@ -12,16 +12,17 @@ export enum ExportType {
|
|
|
12
12
|
OOYYO = 'ooyyo',
|
|
13
13
|
MEINSTADT = 'meinstadt',
|
|
14
14
|
/**
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
* @deprecated
|
|
16
|
+
*/
|
|
17
17
|
BY_OWNER = 'by-owner',
|
|
18
18
|
AUTOUNCLE = 'autouncle',
|
|
19
19
|
/**
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
* @deprecated
|
|
21
|
+
*/
|
|
22
22
|
AS24 = 'as24',
|
|
23
23
|
ALLESKRALLE = 'alleskralle',
|
|
24
24
|
DASPARKING = 'dasparking',
|
|
25
25
|
KLEINANZEIGE_FOCUS = 'kleinanzeigefocus',
|
|
26
26
|
CRITEO = 'criteo',
|
|
27
|
+
FACEBOOK_SHOP = 'facebookshop',
|
|
27
28
|
}
|
package/src/enums/index.ts
CHANGED
package/src/export.schema.ts
CHANGED
|
@@ -16,7 +16,8 @@ import {
|
|
|
16
16
|
KleinanzeigeFocusConfig,
|
|
17
17
|
AutoboerseConfig,
|
|
18
18
|
ByOwnerConfig,
|
|
19
|
-
|
|
19
|
+
FacebookShopConfig,
|
|
20
|
+
CriteoConfig,
|
|
20
21
|
} from './configs';
|
|
21
22
|
import {
|
|
22
23
|
As24Exporter,
|
|
@@ -29,10 +30,10 @@ import {
|
|
|
29
30
|
MobileExporter,
|
|
30
31
|
OoyyoExporter,
|
|
31
32
|
ModixExporter,
|
|
32
|
-
RubrikkExporter
|
|
33
|
+
RubrikkExporter,
|
|
34
|
+
FacebookShopExporter,
|
|
33
35
|
} from './exporters';
|
|
34
36
|
|
|
35
|
-
|
|
36
37
|
export const exportSchema = {
|
|
37
38
|
[ExportType.EAUTO]: {
|
|
38
39
|
config: EautoConfig,
|
|
@@ -98,4 +99,8 @@ export const exportSchema = {
|
|
|
98
99
|
config: CriteoConfig,
|
|
99
100
|
exporter: GoogleExporter,
|
|
100
101
|
},
|
|
102
|
+
[ExportType.FACEBOOK_SHOP]: {
|
|
103
|
+
config: FacebookShopConfig,
|
|
104
|
+
exporter: FacebookShopExporter,
|
|
105
|
+
},
|
|
101
106
|
};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { ModuleRef } from '@nestjs/core';
|
|
3
|
+
|
|
4
|
+
import { CronicleUtils } from '@bytebrand/cronicle-helper';
|
|
5
|
+
import { FsChunkInterface } from '@bytebrand/chunkable';
|
|
6
|
+
|
|
7
|
+
import { CarService, ConfigService, LoaderService, RulesService } from '../services';
|
|
8
|
+
import { Exporter } from '../interfaces/exporter.interface';
|
|
9
|
+
import { FacebookShopTransformer } from '../transformers';
|
|
10
|
+
import { FacebookShopXmlBuilder } from '../formats';
|
|
11
|
+
|
|
12
|
+
@Injectable()
|
|
13
|
+
export class FacebookShopExporter implements Exporter {
|
|
14
|
+
constructor(
|
|
15
|
+
private carService: CarService,
|
|
16
|
+
private configService: ConfigService,
|
|
17
|
+
private loaderService: LoaderService,
|
|
18
|
+
private moduleRef: ModuleRef,
|
|
19
|
+
private rulesService: RulesService,
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
async export(): Promise<void> {
|
|
23
|
+
const [fileXml] = this.configService.config.outputFiles;
|
|
24
|
+
await CronicleUtils.ensureDir(this.configService.config.pathesConfig.localConvertedDirectory);
|
|
25
|
+
await CronicleUtils.emptyDir(this.configService.config.pathesConfig.localConvertedDirectory);
|
|
26
|
+
|
|
27
|
+
const facebookShopXmkBuilder = new FacebookShopXmlBuilder(fileXml);
|
|
28
|
+
await facebookShopXmkBuilder.buildStart();
|
|
29
|
+
|
|
30
|
+
const facebookShopTransformer = await this.moduleRef.create(FacebookShopTransformer);
|
|
31
|
+
|
|
32
|
+
await this.loaderService.process(async (chunk: FsChunkInterface) => {
|
|
33
|
+
const chunkData = chunk.data.filter(car => this.carService.filterCar(car, this.rulesService.rules));
|
|
34
|
+
|
|
35
|
+
if (chunk && chunkData) {
|
|
36
|
+
for (let i = 0; i < chunk.data.length; i += 1) {
|
|
37
|
+
const data = chunk.data[i];
|
|
38
|
+
|
|
39
|
+
const transformedCar = await facebookShopTransformer.transform(data);
|
|
40
|
+
|
|
41
|
+
await facebookShopXmkBuilder.addItem(transformedCar);
|
|
42
|
+
this.carService.counter.countCar(data.images);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
await facebookShopXmkBuilder.buildEnd();
|
|
48
|
+
|
|
49
|
+
console.log(this.carService.counter.getCountedCars());
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Injectable } from '@nestjs/common';
|
|
2
|
-
import { CarService, RulesService, LoaderService, ConfigService
|
|
2
|
+
import { CarService, RulesService, LoaderService, ConfigService } from '../services';
|
|
3
3
|
import { FsChunkInterface } from '@bytebrand/chunkable';
|
|
4
4
|
import { Exporter } from '../interfaces/exporter.interface';
|
|
5
5
|
import { CronicleUtils } from '@bytebrand/cronicle-helper';
|
|
@@ -17,7 +17,7 @@ export class FbExporter implements Exporter {
|
|
|
17
17
|
private rulesService: RulesService,
|
|
18
18
|
private loaderService: LoaderService,
|
|
19
19
|
private moduleRef: ModuleRef,
|
|
20
|
-
) {
|
|
20
|
+
) {}
|
|
21
21
|
|
|
22
22
|
async export(): Promise<void> {
|
|
23
23
|
const [fileName] = this.configService.config.outputFiles;
|
|
@@ -36,7 +36,7 @@ export class FbExporter implements Exporter {
|
|
|
36
36
|
const ownerId = get(data.car, 'metaData.ownerId', null);
|
|
37
37
|
const owner = await this.carService.getOwner(ownerId);
|
|
38
38
|
const car = await fbTransformer.transform({ owner, ...data });
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
await fbXmlBuilder.addItem(car as FbXmlItem);
|
|
41
41
|
this.carService.counter.countCar(data.images);
|
|
42
42
|
}
|
package/src/exporters/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
2
|
import { ModuleRef } from '@nestjs/core';
|
|
3
3
|
|
|
4
4
|
import { CronicleUtils, ImportOrigins } from '@bytebrand/cronicle-helper';
|
|
@@ -10,7 +10,6 @@ import { Exporter } from '../interfaces/exporter.interface';
|
|
|
10
10
|
import { ModixTransformer } from '../transformers';
|
|
11
11
|
import { ModixXmlBuilder } from '../formats';
|
|
12
12
|
|
|
13
|
-
|
|
14
13
|
@Injectable()
|
|
15
14
|
export class ModixExporter implements Exporter {
|
|
16
15
|
constructor(
|
|
@@ -38,16 +37,18 @@ export class ModixExporter implements Exporter {
|
|
|
38
37
|
for (let i = 0; i < chunk.data.length; i += 1) {
|
|
39
38
|
const data = chunk.data[i];
|
|
40
39
|
|
|
41
|
-
const transformedCar = await modixTransformer.transform(
|
|
40
|
+
const transformedCar = await modixTransformer.transform(
|
|
41
|
+
data,
|
|
42
|
+
mappingBuilder.getMappingRules({ reversTransforming: true }),
|
|
43
|
+
);
|
|
42
44
|
await modixXmlBuilder.addItem(transformedCar);
|
|
43
45
|
|
|
44
46
|
this.carService.counter.countCar(data.images);
|
|
45
47
|
}
|
|
46
|
-
|
|
47
48
|
}
|
|
48
49
|
});
|
|
49
50
|
|
|
50
51
|
await modixXmlBuilder.buildEnd();
|
|
51
|
-
console.log(this.carService.counter.getCountedCars())
|
|
52
|
+
console.log(this.carService.counter.getCountedCars());
|
|
52
53
|
}
|
|
53
54
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { XMLBuilderBase } from '@bytebrand/cronicle-helper';
|
|
2
|
+
import { FacebookShopItem, FacebookShopTag } from '../interfaces';
|
|
3
|
+
import { Description, DescriptionValue } from '../interfaces/description.interface';
|
|
4
|
+
import { isNotEmptyArray } from '../utils/validator.utils';
|
|
5
|
+
|
|
6
|
+
export class FacebookShopXmlBuilder extends XMLBuilderBase {
|
|
7
|
+
async buildStart(): Promise<void> {
|
|
8
|
+
await this.write(
|
|
9
|
+
'<?xml version="1.0" encoding="utf-8"?>\n<rss version="2.0" xmlns:g="http://base.google.com/ns/1.0" xmlns:atom="http://www.w3.org/2005/Atom">' +
|
|
10
|
+
'\n<channel>\n<title>Produkt für auto.de</title>\n<description>Produkt für auto.de</description> \n<link>https://www.auto.de/</link>\n' +
|
|
11
|
+
'<atom:link href="https://www.mydealsshop.foo/pages/test-feed" rel="self" type="application/rss+xml" />\n',
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async addItem(car: FacebookShopItem): Promise<void> {
|
|
16
|
+
let item = '\n<item>\n';
|
|
17
|
+
|
|
18
|
+
const tags = Object.keys(car);
|
|
19
|
+
|
|
20
|
+
for (const tag of tags) {
|
|
21
|
+
if (tag === 'description') {
|
|
22
|
+
item += this.getDescriptionElement(tag, car[tag].value);
|
|
23
|
+
} else {
|
|
24
|
+
item += this.buildTagElement(tag, car[tag]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
item += '</item>';
|
|
28
|
+
|
|
29
|
+
await this.write(item);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
buildTagElement(tag: string, params: FacebookShopTag) {
|
|
33
|
+
if (params.isGoogle) {
|
|
34
|
+
return this.getElement(`g:${tag}`, params.value);
|
|
35
|
+
}
|
|
36
|
+
return this.getElement(tag, params.value);
|
|
37
|
+
}
|
|
38
|
+
private getDescriptionElement(rootTag: string, descriptionBlocks: Description[]): string {
|
|
39
|
+
const description: string = descriptionBlocks
|
|
40
|
+
.map(({ title, values }: Description) => {
|
|
41
|
+
if (values) {
|
|
42
|
+
return `${title}\n${this.buildDescriptionValues(values)} `;
|
|
43
|
+
}
|
|
44
|
+
return '';
|
|
45
|
+
})
|
|
46
|
+
.join('\n');
|
|
47
|
+
return `<${rootTag}>${description}</${rootTag}>`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
private buildDescriptionValues(values: DescriptionValue[]): string {
|
|
51
|
+
const validValues = [];
|
|
52
|
+
|
|
53
|
+
values.forEach(element => {
|
|
54
|
+
const filteredValues = element.value.filter(el => el);
|
|
55
|
+
if (isNotEmptyArray(filteredValues)) validValues.push(element);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return validValues
|
|
59
|
+
.map(({ title, value }: DescriptionValue) => {
|
|
60
|
+
return `${title}: ${value.join(', ')}`;
|
|
61
|
+
})
|
|
62
|
+
.join(';\n');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async buildEnd(): Promise<void> {
|
|
66
|
+
await this.write('\n</channel>\n</rss>\n');
|
|
67
|
+
await this.end();
|
|
68
|
+
}
|
|
69
|
+
}
|
package/src/formats/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DataSchemes } from '@bytebrand/car-schema';
|
|
2
2
|
|
|
3
3
|
import { IModixWrapItem } from './autoborse.intreface';
|
|
4
|
+
import { Description } from './description.interface';
|
|
4
5
|
|
|
5
6
|
export interface FbXmlItem {
|
|
6
7
|
url: string;
|
|
@@ -279,3 +280,28 @@ export interface dealerItem {
|
|
|
279
280
|
vatid: IModixWrapItem;
|
|
280
281
|
};
|
|
281
282
|
}
|
|
283
|
+
|
|
284
|
+
export interface FacebookShopItem {
|
|
285
|
+
id: FacebookShopTag;
|
|
286
|
+
title: FacebookShopTag;
|
|
287
|
+
description: { value: Description[]; isGoogle: boolean };
|
|
288
|
+
availability: FacebookShopTag;
|
|
289
|
+
condition: FacebookShopTag;
|
|
290
|
+
price: FacebookShopTag;
|
|
291
|
+
link: FacebookShopTag;
|
|
292
|
+
image_link: FacebookShopTag;
|
|
293
|
+
additional_image_link: FacebookShopTag;
|
|
294
|
+
brand: FacebookShopTag;
|
|
295
|
+
|
|
296
|
+
quantity_to_sell_on_facebook: FacebookShopTag;
|
|
297
|
+
google_product_category: FacebookShopTag;
|
|
298
|
+
sale_price: FacebookShopTag;
|
|
299
|
+
status: FacebookShopTag;
|
|
300
|
+
color: FacebookShopTag;
|
|
301
|
+
product_type: FacebookShopTag;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export interface FacebookShopTag {
|
|
305
|
+
isGoogle: boolean;
|
|
306
|
+
value: any;
|
|
307
|
+
}
|
|
@@ -5,7 +5,7 @@ import * as moment from 'moment';
|
|
|
5
5
|
import { DataSchemes } from '@bytebrand/car-schema';
|
|
6
6
|
import { DePostalCodesService } from '@bytebrand/car-basic-data-scope';
|
|
7
7
|
import { DePostalCodesEntryInterface } from '@bytebrand/car-basic-data-scope/dist/interfaces/DePostalCodesInterface';
|
|
8
|
-
import { ConfigService } from '../services
|
|
8
|
+
import { ConfigService } from '../services';
|
|
9
9
|
import { Injectable } from '@nestjs/common';
|
|
10
10
|
import { DEFAULT_ADDR1, DEFAULT_CITY, DEFAULT_ZIP, MIN_MILEAGES } from '../constants/autouncle.contants';
|
|
11
11
|
import { AutouncleJsonItem } from '../interfaces';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
import { escape, get, join, round, toString, trim } from 'lodash';
|
|
4
|
+
|
|
5
|
+
import { de, deVehicleDetailsPage, deVehicleProps } from '@bytebrand/i18n-dictionaries';
|
|
6
|
+
import { TranslatorExtended } from '@bytebrand/schema-tools';
|
|
7
|
+
import { DataSchemes } from '@bytebrand/car-schema';
|
|
8
|
+
|
|
9
|
+
import { FacebookShopItem } from '../interfaces';
|
|
10
|
+
import { ConfigService } from '../services';
|
|
11
|
+
import { Description } from '../interfaces/description.interface';
|
|
12
|
+
import { FbDescription } from './fb-description.transformer';
|
|
13
|
+
import { FbEquipment } from './fb-equipment.transformer';
|
|
14
|
+
|
|
15
|
+
@Injectable()
|
|
16
|
+
export class FacebookShopTransformer {
|
|
17
|
+
private translator: TranslatorExtended;
|
|
18
|
+
|
|
19
|
+
constructor(private readonly configService: ConfigService) {
|
|
20
|
+
const dict = { ...de, ...deVehicleProps, ...deVehicleDetailsPage };
|
|
21
|
+
this.translator = new TranslatorExtended(dict);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async transform({ car }: { car: DataSchemes.Car }): Promise<FacebookShopItem> {
|
|
25
|
+
return {
|
|
26
|
+
id: { value: get(car, 'metaData.vehicleId'), isGoogle: true },
|
|
27
|
+
title: { value: this.getTitle(car), isGoogle: true },
|
|
28
|
+
description: { value: this.getDescription(car), isGoogle: true },
|
|
29
|
+
availability: { value: 'in stock', isGoogle: true },
|
|
30
|
+
condition: { value: this.getCondition(car), isGoogle: true },
|
|
31
|
+
price: { value: this.getPrice(car), isGoogle: true },
|
|
32
|
+
link: { value: this.getCarLink(car), isGoogle: true },
|
|
33
|
+
image_link: { value: this.getImageLink(car), isGoogle: true },
|
|
34
|
+
brand: { value: get(car, 'mainData.make', ''), isGoogle: true },
|
|
35
|
+
additional_image_link: { value: this.getImageLink(car), isGoogle: false },
|
|
36
|
+
quantity_to_sell_on_facebook: { value: 1, isGoogle: true },
|
|
37
|
+
google_product_category: { value: '916', isGoogle: true },
|
|
38
|
+
sale_price: { value: this.getPrice(car), isGoogle: true },
|
|
39
|
+
status: { value: 'active', isGoogle: true },
|
|
40
|
+
color: { value: this.getColor(car), isGoogle: false },
|
|
41
|
+
product_type: {
|
|
42
|
+
value: 'Vehicles & Parts > Vehicles > Motor Vehicles > Cars, Trucks & Vans',
|
|
43
|
+
isGoogle: true,
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private getTitle(car: DataSchemes.Car): string {
|
|
49
|
+
const year = toString(get(car, 'mainData.constructionYear', ''));
|
|
50
|
+
const make = toString(get(car, 'mainData.make', ''));
|
|
51
|
+
const model = toString(get(car, 'mainData.model', ''));
|
|
52
|
+
const subModel = toString(get(car, 'mainData.subModel', ''));
|
|
53
|
+
return trim(escape(join([year, make, model, subModel], ' ')));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private getCondition(car: DataSchemes.Car): string {
|
|
57
|
+
const available = {
|
|
58
|
+
selector_condition_new: 'New',
|
|
59
|
+
selector_condition_used: 'Used',
|
|
60
|
+
selector_unknown: 'New',
|
|
61
|
+
};
|
|
62
|
+
const condition = get(car, 'mainData.condition', 'selector_unknown');
|
|
63
|
+
return get(available, condition);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
private getCarLink(car: DataSchemes.Car): string {
|
|
67
|
+
return `https://${this.configService.config.domain}/search/vehicle/${car._id}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
private getPrice(car: DataSchemes.Car): string {
|
|
71
|
+
const price = get(car, 'price.currentSalesPrice', 0);
|
|
72
|
+
return `${round(price, 2)} EUR`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
private getColor(car: DataSchemes.Car): string {
|
|
76
|
+
let colorSelection = get(car, 'exterior.exteriorColor', 'selector_unknown');
|
|
77
|
+
if (!colorSelection || colorSelection === 'selector_unknown') {
|
|
78
|
+
colorSelection = 'selector_unknown';
|
|
79
|
+
}
|
|
80
|
+
return this.translator.translateVal(colorSelection);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private getDescription(car: DataSchemes.Car): Description[] {
|
|
84
|
+
return FbDescription.create(car, this.translator, new FbEquipment()).getDescriptionArray();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
//todo: move to image service
|
|
88
|
+
private getImageLink(car: DataSchemes.Car): string {
|
|
89
|
+
const mainImageId = get(car, 'metaData.mainImageId', '');
|
|
90
|
+
return mainImageId
|
|
91
|
+
? `${this.configService.config.baseImageUrl}/carimage/${car._id}/${mainImageId}/large-cached.webp`
|
|
92
|
+
: `${this.configService.config.baseImageUrl}/carimage/noimage/7pNvWELuWhZX/large-cached.jpeg`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -3,7 +3,7 @@ import { DataSchemes } from '@bytebrand/car-schema';
|
|
|
3
3
|
|
|
4
4
|
import { de } from '@bytebrand/i18n-dictionaries';
|
|
5
5
|
import { Injectable } from '@nestjs/common';
|
|
6
|
-
import { ConfigService } from '../services
|
|
6
|
+
import { ConfigService } from '../services';
|
|
7
7
|
import { MeinstadtJsonItem } from '../interfaces';
|
|
8
8
|
|
|
9
9
|
@Injectable()
|
|
@@ -73,8 +73,7 @@ export class MeinstadtTransformer {
|
|
|
73
73
|
private getDescription(car: DataSchemes.Car): string {
|
|
74
74
|
const usageType = get(car, 'offer.offerDescription', null);
|
|
75
75
|
if (usageType) {
|
|
76
|
-
|
|
77
|
-
return afterFromatting;
|
|
76
|
+
return usageType.replace(/\\/g, ',').replace(/\\/g, ',').replace(/,,/g, ',');
|
|
78
77
|
} else return null;
|
|
79
78
|
}
|
|
80
79
|
}
|
|
@@ -12,7 +12,7 @@ import { DataSchemes } from '@bytebrand/car-schema';
|
|
|
12
12
|
import { imageItem, IModixWrapItem, ModixXmlItem } from '../interfaces';
|
|
13
13
|
import { isNotEmptyArray, isValidVin } from '../utils/validator.utils';
|
|
14
14
|
import { CategoryList } from '../constants/modix/category.constant';
|
|
15
|
-
import { ConfigService } from '../services
|
|
15
|
+
import { ConfigService } from '../services';
|
|
16
16
|
import {
|
|
17
17
|
BodyColorList,
|
|
18
18
|
VehicleClassList,
|
|
@@ -23,18 +23,17 @@ import {
|
|
|
23
23
|
UsageTypeList,
|
|
24
24
|
} from '../constants';
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
26
|
@Injectable()
|
|
29
27
|
export class ModixTransformer {
|
|
30
|
-
constructor(private readonly configService: ConfigService) {
|
|
31
|
-
|
|
32
|
-
async transform(chunkData: { car: DataSchemes.Car; images: ImboImageResponseInterface[]; }, mappingRules: MappingRulesInterface[]): Promise<ModixXmlItem> {
|
|
28
|
+
constructor(private readonly configService: ConfigService) {}
|
|
33
29
|
|
|
30
|
+
async transform(
|
|
31
|
+
chunkData: { car: DataSchemes.Car; images: ImboImageResponseInterface[] },
|
|
32
|
+
mappingRules: MappingRulesInterface[],
|
|
33
|
+
): Promise<ModixXmlItem> {
|
|
34
34
|
const { car, images } = chunkData;
|
|
35
35
|
// await this.buildOptions(car, mappingRules);
|
|
36
36
|
return {
|
|
37
|
-
|
|
38
37
|
//Main data
|
|
39
38
|
maindata: {
|
|
40
39
|
category: this.getCategoryData(car),
|
|
@@ -121,7 +120,9 @@ export class ModixTransformer {
|
|
|
121
120
|
private getManufactureData(car: DataSchemes.Car): IModixWrapItem {
|
|
122
121
|
const carMake = toString(get(car, 'mainData.make', ''));
|
|
123
122
|
const manufactureData = findLast(ManufactureList, item => toLowercase(item.name) === toLowercase(carMake));
|
|
124
|
-
|
|
123
|
+
// temporary
|
|
124
|
+
if (!manufactureData) { console.log(`missed manufactureData ${carMake}`); }
|
|
125
|
+
return { value: manufactureData?.name || carMake, atributes: { id: manufactureData?.id || null } };
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
private getFuelData(car: DataSchemes.Car): IModixWrapItem {
|
|
@@ -209,8 +210,17 @@ export class ModixTransformer {
|
|
|
209
210
|
return { url, imageList };
|
|
210
211
|
}
|
|
211
212
|
|
|
212
|
-
private async buildOptions(
|
|
213
|
-
|
|
213
|
+
private async buildOptions(
|
|
214
|
+
car: DataSchemes.Car,
|
|
215
|
+
mappingRules: MappingRulesInterface[],
|
|
216
|
+
): Promise<Omit<DataSchemes.Car, 'state'>> {
|
|
217
|
+
const transformer = TransformerFactory.createTransformer(
|
|
218
|
+
ImportOrigins.MODIX,
|
|
219
|
+
car,
|
|
220
|
+
{ importSelectorMappingLog: () => {} } as any,
|
|
221
|
+
[{ make: 'make', model: 'model' }],
|
|
222
|
+
['alt_model'],
|
|
223
|
+
);
|
|
214
224
|
const { car: transformedCar } = await transformer.transform(mappingRules);
|
|
215
225
|
|
|
216
226
|
return omit(transformedCar, ['state']);
|