@unchainedshop/core 4.0.0-rc.15 → 4.0.0-rc.16
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/lib/bulk-importer/createBulkImporter.d.ts +61 -0
- package/lib/bulk-importer/createBulkImporter.d.ts.map +1 -0
- package/lib/bulk-importer/createBulkImporter.js +135 -0
- package/lib/bulk-importer/createBulkImporter.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/create.d.ts +15 -0
- package/lib/bulk-importer/handlers/assortment/create.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/create.js +62 -0
- package/lib/bulk-importer/handlers/assortment/create.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/index.d.ts +4 -0
- package/lib/bulk-importer/handlers/assortment/index.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/index.js +4 -0
- package/lib/bulk-importer/handlers/assortment/index.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/remove.d.ts +12 -0
- package/lib/bulk-importer/handlers/assortment/remove.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/remove.js +13 -0
- package/lib/bulk-importer/handlers/assortment/remove.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/update.d.ts +16 -0
- package/lib/bulk-importer/handlers/assortment/update.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/update.js +62 -0
- package/lib/bulk-importer/handlers/assortment/update.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentChildren.d.ts +9 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentChildren.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentChildren.js +37 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentChildren.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentFilters.d.ts +9 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentFilters.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentFilters.js +32 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentFilters.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentProducts.d.ts +9 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentProducts.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentProducts.js +37 -0
- package/lib/bulk-importer/handlers/assortment/upsertAssortmentProducts.js.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertMedia.d.ts +11 -0
- package/lib/bulk-importer/handlers/assortment/upsertMedia.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/assortment/upsertMedia.js +39 -0
- package/lib/bulk-importer/handlers/assortment/upsertMedia.js.map +1 -0
- package/lib/bulk-importer/handlers/filter/create.d.ts +13 -0
- package/lib/bulk-importer/handlers/filter/create.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/filter/create.js +58 -0
- package/lib/bulk-importer/handlers/filter/create.js.map +1 -0
- package/lib/bulk-importer/handlers/filter/index.d.ts +4 -0
- package/lib/bulk-importer/handlers/filter/index.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/filter/index.js +4 -0
- package/lib/bulk-importer/handlers/filter/index.js.map +1 -0
- package/lib/bulk-importer/handlers/filter/remove.d.ts +12 -0
- package/lib/bulk-importer/handlers/filter/remove.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/filter/remove.js +14 -0
- package/lib/bulk-importer/handlers/filter/remove.js.map +1 -0
- package/lib/bulk-importer/handlers/filter/update.d.ts +13 -0
- package/lib/bulk-importer/handlers/filter/update.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/filter/update.js +48 -0
- package/lib/bulk-importer/handlers/filter/update.js.map +1 -0
- package/lib/bulk-importer/handlers/product/create.d.ts +15 -0
- package/lib/bulk-importer/handlers/product/create.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/create.js +53 -0
- package/lib/bulk-importer/handlers/product/create.js.map +1 -0
- package/lib/bulk-importer/handlers/product/index.d.ts +4 -0
- package/lib/bulk-importer/handlers/product/index.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/index.js +4 -0
- package/lib/bulk-importer/handlers/product/index.js.map +1 -0
- package/lib/bulk-importer/handlers/product/remove.d.ts +14 -0
- package/lib/bulk-importer/handlers/product/remove.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/remove.js +13 -0
- package/lib/bulk-importer/handlers/product/remove.js.map +1 -0
- package/lib/bulk-importer/handlers/product/transformSpecificationToProductStructure.d.ts +3 -0
- package/lib/bulk-importer/handlers/product/transformSpecificationToProductStructure.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/transformSpecificationToProductStructure.js +16 -0
- package/lib/bulk-importer/handlers/product/transformSpecificationToProductStructure.js.map +1 -0
- package/lib/bulk-importer/handlers/product/update.d.ts +15 -0
- package/lib/bulk-importer/handlers/product/update.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/update.js +48 -0
- package/lib/bulk-importer/handlers/product/update.js.map +1 -0
- package/lib/bulk-importer/handlers/product/upsertMedia.d.ts +10 -0
- package/lib/bulk-importer/handlers/product/upsertMedia.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/upsertMedia.js +45 -0
- package/lib/bulk-importer/handlers/product/upsertMedia.js.map +1 -0
- package/lib/bulk-importer/handlers/product/upsertVariations.d.ts +8 -0
- package/lib/bulk-importer/handlers/product/upsertVariations.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/product/upsertVariations.js +48 -0
- package/lib/bulk-importer/handlers/product/upsertVariations.js.map +1 -0
- package/lib/bulk-importer/handlers/utils/convertTagsToLowerCase.d.ts +3 -0
- package/lib/bulk-importer/handlers/utils/convertTagsToLowerCase.d.ts.map +1 -0
- package/lib/bulk-importer/handlers/utils/convertTagsToLowerCase.js +6 -0
- package/lib/bulk-importer/handlers/utils/convertTagsToLowerCase.js.map +1 -0
- package/lib/bulk-importer/upsertAsset.d.ts +12 -0
- package/lib/bulk-importer/upsertAsset.d.ts.map +1 -0
- package/lib/bulk-importer/upsertAsset.js +33 -0
- package/lib/bulk-importer/upsertAsset.js.map +1 -0
- package/lib/core-index.d.ts +6 -5
- package/lib/core-index.d.ts.map +1 -1
- package/lib/core-index.js +4 -1
- package/lib/core-index.js.map +1 -1
- package/lib/directors/PaymentDirector.js +2 -2
- package/lib/directors/PaymentDirector.js.map +1 -1
- package/lib/directors/WorkerAdapter.d.ts +3 -2
- package/lib/directors/WorkerAdapter.d.ts.map +1 -1
- package/lib/directors/WorkerAdapter.js.map +1 -1
- package/lib/modules.d.ts.map +1 -1
- package/lib/modules.js +1 -0
- package/lib/modules.js.map +1 -1
- package/lib/services/activateEnrollment.d.ts.map +1 -1
- package/lib/services/activateEnrollment.js +5 -9
- package/lib/services/activateEnrollment.js.map +1 -1
- package/lib/services/addMessage.d.ts +4 -0
- package/lib/services/addMessage.d.ts.map +1 -0
- package/lib/services/addMessage.js +15 -0
- package/lib/services/addMessage.js.map +1 -0
- package/lib/services/index.d.ts +4 -0
- package/lib/services/index.d.ts.map +1 -1
- package/lib/services/index.js +4 -0
- package/lib/services/index.js.map +1 -1
- package/lib/services/initializeEnrollment.d.ts.map +1 -1
- package/lib/services/initializeEnrollment.js +5 -9
- package/lib/services/initializeEnrollment.js.map +1 -1
- package/lib/services/processQuotation.d.ts.map +1 -1
- package/lib/services/processQuotation.js +4 -8
- package/lib/services/processQuotation.js.map +1 -1
- package/lib/services/removeFiles.js +2 -2
- package/lib/services/removeFiles.js.map +1 -1
- package/lib/services/terminateEnrollment.d.ts.map +1 -1
- package/lib/services/terminateEnrollment.js +5 -9
- package/lib/services/terminateEnrollment.js.map +1 -1
- package/package.json +3 -2
- package/src/bulk-importer/createBulkImporter.ts +193 -0
- package/src/bulk-importer/handlers/assortment/create.ts +87 -0
- package/src/bulk-importer/handlers/assortment/index.ts +3 -0
- package/src/bulk-importer/handlers/assortment/remove.ts +15 -0
- package/src/bulk-importer/handlers/assortment/update.ts +89 -0
- package/src/bulk-importer/handlers/assortment/upsertAssortmentChildren.ts +52 -0
- package/src/bulk-importer/handlers/assortment/upsertAssortmentFilters.ts +42 -0
- package/src/bulk-importer/handlers/assortment/upsertAssortmentProducts.ts +50 -0
- package/src/bulk-importer/handlers/assortment/upsertMedia.ts +58 -0
- package/src/bulk-importer/handlers/filter/create.ts +76 -0
- package/src/bulk-importer/handlers/filter/index.ts +3 -0
- package/src/bulk-importer/handlers/filter/remove.ts +20 -0
- package/src/bulk-importer/handlers/filter/update.ts +67 -0
- package/src/bulk-importer/handlers/product/create.ts +70 -0
- package/src/bulk-importer/handlers/product/index.ts +3 -0
- package/src/bulk-importer/handlers/product/remove.ts +21 -0
- package/src/bulk-importer/handlers/product/transformSpecificationToProductStructure.ts +22 -0
- package/src/bulk-importer/handlers/product/update.ts +66 -0
- package/src/bulk-importer/handlers/product/upsertMedia.ts +64 -0
- package/src/bulk-importer/handlers/product/upsertVariations.ts +71 -0
- package/src/bulk-importer/handlers/utils/convertTagsToLowerCase.ts +4 -0
- package/src/bulk-importer/upsertAsset.ts +42 -0
- package/src/core-index.ts +10 -5
- package/src/directors/PaymentDirector.ts +2 -2
- package/src/directors/WorkerAdapter.ts +8 -3
- package/src/modules.ts +1 -0
- package/src/services/activateEnrollment.ts +5 -9
- package/src/services/addMessage.ts +20 -0
- package/src/services/index.ts +4 -0
- package/src/services/initializeEnrollment.ts +5 -9
- package/src/services/processQuotation.ts +4 -8
- package/src/services/removeFiles.ts +2 -2
- package/src/services/terminateEnrollment.ts +5 -9
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
|
|
3
|
+
export default async function createFilter(
|
|
4
|
+
payload: any,
|
|
5
|
+
{ logger, createShouldUpsertIfIDExists },
|
|
6
|
+
unchainedAPI: { modules: Modules },
|
|
7
|
+
) {
|
|
8
|
+
const { modules } = unchainedAPI;
|
|
9
|
+
const { specification, _id } = payload;
|
|
10
|
+
|
|
11
|
+
if (!specification) throw new Error(`Specification is required when creating new filter ${_id}`);
|
|
12
|
+
|
|
13
|
+
const { content, options, ...filterData } = specification;
|
|
14
|
+
|
|
15
|
+
if (!content) throw new Error(`Localizable content is required when creating new filter${_id}`);
|
|
16
|
+
|
|
17
|
+
logger.debug('create filter object', specification);
|
|
18
|
+
try {
|
|
19
|
+
await unchainedAPI.modules.filters.create({
|
|
20
|
+
...filterData,
|
|
21
|
+
_id,
|
|
22
|
+
options: options?.map((option) => option.value) || [],
|
|
23
|
+
});
|
|
24
|
+
} catch (e) {
|
|
25
|
+
if (!createShouldUpsertIfIDExists) throw e;
|
|
26
|
+
|
|
27
|
+
logger.debug('entity already exists, falling back to update', specification);
|
|
28
|
+
await modules.filters.update(_id, {
|
|
29
|
+
...filterData,
|
|
30
|
+
options: options?.map((option) => option.value) || [],
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!(await modules.filters.filterExists({ filterId: _id }))) {
|
|
35
|
+
throw new Error(`Can't upsert filter ${_id}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (content) {
|
|
39
|
+
logger.debug('create localized content for filter', content);
|
|
40
|
+
await modules.filters.texts.updateTexts(
|
|
41
|
+
{ filterId: _id },
|
|
42
|
+
Object.entries(content).map(([locale, localizedData]: [string, any]) => {
|
|
43
|
+
return {
|
|
44
|
+
locale,
|
|
45
|
+
...localizedData,
|
|
46
|
+
};
|
|
47
|
+
}),
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (options) {
|
|
52
|
+
logger.debug('create localized content for filter options', content);
|
|
53
|
+
await Promise.all(
|
|
54
|
+
options.map(async ({ content: optionContent, value: optionValue }) => {
|
|
55
|
+
if (optionContent) {
|
|
56
|
+
await modules.filters.texts.updateTexts(
|
|
57
|
+
{ filterId: _id, filterOptionValue: optionValue },
|
|
58
|
+
Object.entries(optionContent).map(([locale, localizedData]: [string, any]) => {
|
|
59
|
+
return {
|
|
60
|
+
locale,
|
|
61
|
+
...localizedData,
|
|
62
|
+
};
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
entity: 'FILTER',
|
|
72
|
+
operation: 'create',
|
|
73
|
+
_id,
|
|
74
|
+
success: true,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
|
|
3
|
+
export default async function removeFilter(
|
|
4
|
+
payload: any,
|
|
5
|
+
{ logger },
|
|
6
|
+
unchainedAPI: { modules: Modules },
|
|
7
|
+
) {
|
|
8
|
+
const { modules } = unchainedAPI;
|
|
9
|
+
const { _id } = payload;
|
|
10
|
+
logger.debug('remove filter');
|
|
11
|
+
await modules.assortments.filters.deleteMany({ filterId: _id });
|
|
12
|
+
await modules.filters.delete(_id);
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
entity: 'FILTER',
|
|
16
|
+
operation: 'remove',
|
|
17
|
+
_id,
|
|
18
|
+
success: true,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
import createFilter from './create.js';
|
|
3
|
+
|
|
4
|
+
export default async function updateFilter(
|
|
5
|
+
payload: any,
|
|
6
|
+
{ logger, updateShouldUpsertIfIDNotExists }: { logger: any; updateShouldUpsertIfIDNotExists: boolean },
|
|
7
|
+
unchainedAPI: { modules: Modules },
|
|
8
|
+
) {
|
|
9
|
+
const { modules } = unchainedAPI;
|
|
10
|
+
const { specification, _id } = payload;
|
|
11
|
+
|
|
12
|
+
if (!(await modules.filters.filterExists({ filterId: _id }))) {
|
|
13
|
+
if (updateShouldUpsertIfIDNotExists) {
|
|
14
|
+
return createFilter(payload, { logger, createShouldUpsertIfIDExists: false }, unchainedAPI);
|
|
15
|
+
}
|
|
16
|
+
throw new Error(`Can't update non-existing filter ${_id}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const { content, options, ...filterData } = specification;
|
|
20
|
+
|
|
21
|
+
if (specification) {
|
|
22
|
+
logger.debug('update filter object', specification);
|
|
23
|
+
await modules.filters.update(_id, {
|
|
24
|
+
...filterData,
|
|
25
|
+
options: options?.map((option) => option.value) || [],
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (content) {
|
|
30
|
+
logger.debug('replace localized content for filter', content);
|
|
31
|
+
await modules.filters.texts.updateTexts(
|
|
32
|
+
{ filterId: _id },
|
|
33
|
+
Object.entries(content).map(([locale, localizedData]: [string, any]) => {
|
|
34
|
+
return {
|
|
35
|
+
locale,
|
|
36
|
+
...localizedData,
|
|
37
|
+
};
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (options) {
|
|
43
|
+
logger.debug('replace localized content for filter options', content);
|
|
44
|
+
await Promise.all(
|
|
45
|
+
options.map(async ({ content: optionContent, value: optionValue }) => {
|
|
46
|
+
if (optionContent) {
|
|
47
|
+
await modules.filters.texts.updateTexts(
|
|
48
|
+
{ filterId: _id, filterOptionValue: optionValue },
|
|
49
|
+
Object.entries(optionContent).map(([locale, localizedData]: [string, any]) => {
|
|
50
|
+
return {
|
|
51
|
+
locale,
|
|
52
|
+
...localizedData,
|
|
53
|
+
};
|
|
54
|
+
}),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return {
|
|
62
|
+
entity: 'FILTER',
|
|
63
|
+
operation: 'update',
|
|
64
|
+
_id,
|
|
65
|
+
success: true,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
import { Services } from '../../../services/index.js';
|
|
3
|
+
import upsertVariations from './upsertVariations.js';
|
|
4
|
+
import upsertMedia from './upsertMedia.js';
|
|
5
|
+
import transformSpecificationToProductStructure from './transformSpecificationToProductStructure.js';
|
|
6
|
+
|
|
7
|
+
export default async function createProduct(
|
|
8
|
+
payload: any,
|
|
9
|
+
{ logger, createShouldUpsertIfIDExists },
|
|
10
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
11
|
+
) {
|
|
12
|
+
const { modules } = unchainedAPI;
|
|
13
|
+
const { specification, media, variations, _id } = payload;
|
|
14
|
+
|
|
15
|
+
if (!specification) throw new Error(`Specification is required when creating new product ${_id}`);
|
|
16
|
+
|
|
17
|
+
if (!specification.content) throw new Error(`Content is required when creating new product ${_id}`);
|
|
18
|
+
|
|
19
|
+
const productData = transformSpecificationToProductStructure(specification);
|
|
20
|
+
logger.debug('create product object', productData);
|
|
21
|
+
try {
|
|
22
|
+
await modules.products.create({
|
|
23
|
+
...productData,
|
|
24
|
+
_id,
|
|
25
|
+
});
|
|
26
|
+
} catch (e) {
|
|
27
|
+
if (!createShouldUpsertIfIDExists) throw e;
|
|
28
|
+
|
|
29
|
+
logger.debug('entity already exists, falling back to update', specification);
|
|
30
|
+
await modules.products.update(_id, {
|
|
31
|
+
...productData,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (!(await modules.products.productExists({ productId: _id }))) {
|
|
36
|
+
throw new Error(`Can't create product ${_id}, fields missing?`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (specification.content) {
|
|
40
|
+
logger.debug('create localized content for product', specification.content);
|
|
41
|
+
await modules.products.texts.updateTexts(
|
|
42
|
+
_id,
|
|
43
|
+
Object.entries(specification.content).map(([locale, localizedData]: [string, any]) => {
|
|
44
|
+
return {
|
|
45
|
+
locale,
|
|
46
|
+
...localizedData,
|
|
47
|
+
};
|
|
48
|
+
}),
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
logger.debug('create product variations', variations);
|
|
53
|
+
await upsertVariations(
|
|
54
|
+
{
|
|
55
|
+
variations: variations || [],
|
|
56
|
+
productId: _id,
|
|
57
|
+
},
|
|
58
|
+
unchainedAPI,
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
logger.debug('create product media', media);
|
|
62
|
+
await upsertMedia({ media: media || [], productId: _id }, unchainedAPI);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
entity: 'PRODUCT',
|
|
66
|
+
operation: 'create',
|
|
67
|
+
_id,
|
|
68
|
+
success: true,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
import { Services } from '../../../services/index.js';
|
|
3
|
+
|
|
4
|
+
export default async function removeProduct(
|
|
5
|
+
payload: any,
|
|
6
|
+
{ logger },
|
|
7
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
8
|
+
) {
|
|
9
|
+
const { services } = unchainedAPI;
|
|
10
|
+
const { _id } = payload;
|
|
11
|
+
logger.debug(`remove product ${_id}`);
|
|
12
|
+
|
|
13
|
+
await services.products.removeProduct({ productId: _id });
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
entity: 'PRODUCT',
|
|
17
|
+
operation: 'remove',
|
|
18
|
+
_id,
|
|
19
|
+
success: true,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import convertTagsToLowerCase from '../utils/convertTagsToLowerCase.js';
|
|
2
|
+
|
|
3
|
+
export default (specification) => {
|
|
4
|
+
const {
|
|
5
|
+
variationResolvers: assignments,
|
|
6
|
+
content, // eslint-disable-line
|
|
7
|
+
warehousing: warehousingEmbeddedSupply,
|
|
8
|
+
...productData
|
|
9
|
+
} = specification;
|
|
10
|
+
|
|
11
|
+
const { dimensions: supply, ...warehousing } = warehousingEmbeddedSupply || {};
|
|
12
|
+
const tags = convertTagsToLowerCase(productData?.tags);
|
|
13
|
+
const proxy = assignments ? { assignments } : undefined;
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
...productData,
|
|
17
|
+
tags,
|
|
18
|
+
warehousing,
|
|
19
|
+
supply,
|
|
20
|
+
proxy,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Modules } from '../../../modules.js';
|
|
2
|
+
import { Services } from '../../../services/index.js';
|
|
3
|
+
import upsertVariations from './upsertVariations.js';
|
|
4
|
+
import upsertMedia from './upsertMedia.js';
|
|
5
|
+
import transformSpecificationToProductStructure from './transformSpecificationToProductStructure.js';
|
|
6
|
+
import createProduct from './create.js';
|
|
7
|
+
|
|
8
|
+
export default async function updateProduct(
|
|
9
|
+
payload: any,
|
|
10
|
+
{ logger, updateShouldUpsertIfIDNotExists },
|
|
11
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
12
|
+
) {
|
|
13
|
+
const { modules } = unchainedAPI;
|
|
14
|
+
const { specification, media, variations, _id } = payload;
|
|
15
|
+
|
|
16
|
+
if (!(await modules.products.productExists({ productId: _id }))) {
|
|
17
|
+
if (updateShouldUpsertIfIDNotExists) {
|
|
18
|
+
return createProduct(payload, { logger, createShouldUpsertIfIDExists: false }, unchainedAPI);
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Can't update non-existing product ${_id}`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (specification) {
|
|
24
|
+
const productData = transformSpecificationToProductStructure(specification);
|
|
25
|
+
logger.debug('update product object', productData);
|
|
26
|
+
await modules.products.update(_id, {
|
|
27
|
+
...productData,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (specification.content) {
|
|
31
|
+
logger.debug('replace localized content for product', specification.content);
|
|
32
|
+
await modules.products.texts.updateTexts(
|
|
33
|
+
_id,
|
|
34
|
+
Object.entries(specification.content).map(([locale, localizedData]: [string, any]) => {
|
|
35
|
+
return {
|
|
36
|
+
locale,
|
|
37
|
+
...localizedData,
|
|
38
|
+
};
|
|
39
|
+
}),
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (variations) {
|
|
45
|
+
logger.debug('replace variations', variations);
|
|
46
|
+
await upsertVariations(
|
|
47
|
+
{
|
|
48
|
+
variations: variations || [],
|
|
49
|
+
productId: _id,
|
|
50
|
+
},
|
|
51
|
+
unchainedAPI,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (media) {
|
|
56
|
+
logger.debug('replace product media', media);
|
|
57
|
+
await upsertMedia({ media, productId: _id }, unchainedAPI);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
entity: 'PRODUCT',
|
|
62
|
+
operation: 'update',
|
|
63
|
+
_id,
|
|
64
|
+
success: true,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { ProductMedia } from '@unchainedshop/core-products';
|
|
2
|
+
import { Modules } from '../../../modules.js';
|
|
3
|
+
import { Services } from '../../../services/index.js';
|
|
4
|
+
import convertTagsToLowerCase from '../utils/convertTagsToLowerCase.js';
|
|
5
|
+
import upsertAsset from '../../upsertAsset.js';
|
|
6
|
+
|
|
7
|
+
const upsertProductMedia = async (productMedia: ProductMedia, { modules }: { modules: Modules }) => {
|
|
8
|
+
try {
|
|
9
|
+
const productMediaObj = await modules.products.media.create(productMedia);
|
|
10
|
+
return productMediaObj;
|
|
11
|
+
} catch {
|
|
12
|
+
const { _id, ...productMediaData } = productMedia;
|
|
13
|
+
const productMediaId = _id;
|
|
14
|
+
return modules.products.media.update(productMediaId, productMediaData);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export default async function upsertMedia(
|
|
19
|
+
{ media, productId },
|
|
20
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
21
|
+
) {
|
|
22
|
+
const { modules } = unchainedAPI;
|
|
23
|
+
|
|
24
|
+
const productMediaObjects = await Promise.all(
|
|
25
|
+
media.map(async ({ asset, content, ...mediaData }) => {
|
|
26
|
+
const tags = convertTagsToLowerCase(mediaData?.tags);
|
|
27
|
+
const file = await upsertAsset(
|
|
28
|
+
'product-media',
|
|
29
|
+
{ meta: { ...(asset.meta || {}), productId }, ...asset },
|
|
30
|
+
unchainedAPI,
|
|
31
|
+
);
|
|
32
|
+
if (!file) throw new Error(`Unable to create binary ${asset._id}`);
|
|
33
|
+
const fileId = file._id;
|
|
34
|
+
const productMedia = await upsertProductMedia(
|
|
35
|
+
{
|
|
36
|
+
...mediaData,
|
|
37
|
+
tags,
|
|
38
|
+
productId,
|
|
39
|
+
mediaId: file._id,
|
|
40
|
+
} as ProductMedia,
|
|
41
|
+
unchainedAPI,
|
|
42
|
+
);
|
|
43
|
+
if (!productMedia) throw new Error(`Unable to create product media object for file ${fileId}`);
|
|
44
|
+
|
|
45
|
+
if (content) {
|
|
46
|
+
await modules.products.media.texts.updateMediaTexts(
|
|
47
|
+
productMedia._id,
|
|
48
|
+
Object.entries(content).map(([locale, localizedData]: [string, any]) => {
|
|
49
|
+
return {
|
|
50
|
+
locale,
|
|
51
|
+
...localizedData,
|
|
52
|
+
};
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
return productMedia;
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
await modules.products.media.deleteMediaFiles({
|
|
61
|
+
productId,
|
|
62
|
+
excludedProductMediaIds: productMediaObjects.map((obj) => obj._id),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { ProductVariation } from '@unchainedshop/core-products';
|
|
2
|
+
import { Modules } from '../../../modules.js';
|
|
3
|
+
|
|
4
|
+
const upsert = async (productVariation: ProductVariation, unchainedAPI: { modules: Modules }) => {
|
|
5
|
+
const { modules } = unchainedAPI;
|
|
6
|
+
try {
|
|
7
|
+
const newVariation = await modules.products.variations.create(productVariation);
|
|
8
|
+
return newVariation;
|
|
9
|
+
} catch {
|
|
10
|
+
return modules.products.variations.update(productVariation._id, productVariation);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default async function upsertVariations(
|
|
15
|
+
{ variations, productId },
|
|
16
|
+
unchainedAPI: { modules: Modules },
|
|
17
|
+
) {
|
|
18
|
+
const { modules } = unchainedAPI;
|
|
19
|
+
|
|
20
|
+
const upsertedProductVariationIds = await Promise.all(
|
|
21
|
+
variations.map(async ({ content, options, ...variationsRest }) => {
|
|
22
|
+
const variation = await upsert(
|
|
23
|
+
{
|
|
24
|
+
...variationsRest,
|
|
25
|
+
options: options.map((option) => option.value),
|
|
26
|
+
productId,
|
|
27
|
+
},
|
|
28
|
+
unchainedAPI,
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
await Promise.all(
|
|
32
|
+
options.map(async ({ content: optionContent, value: optionValue }) => {
|
|
33
|
+
if (optionContent) {
|
|
34
|
+
await modules.products.variations.texts.updateVariationTexts(
|
|
35
|
+
variation._id,
|
|
36
|
+
Object.entries(optionContent).map(([locale, localizedData]: [string, any]) => {
|
|
37
|
+
return {
|
|
38
|
+
locale,
|
|
39
|
+
...localizedData,
|
|
40
|
+
};
|
|
41
|
+
}),
|
|
42
|
+
optionValue,
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
}),
|
|
46
|
+
);
|
|
47
|
+
if (content) {
|
|
48
|
+
await modules.products.variations.texts.updateVariationTexts(
|
|
49
|
+
variation._id,
|
|
50
|
+
Object.entries(content).map(([locale, localizedData]: [string, any]) => {
|
|
51
|
+
return {
|
|
52
|
+
locale,
|
|
53
|
+
...localizedData,
|
|
54
|
+
};
|
|
55
|
+
}),
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return variation._id;
|
|
59
|
+
}),
|
|
60
|
+
);
|
|
61
|
+
const allVariations = await modules.products.variations.findProductVariations({
|
|
62
|
+
productId,
|
|
63
|
+
});
|
|
64
|
+
await Promise.all(
|
|
65
|
+
allVariations.map(async (variation) => {
|
|
66
|
+
if (!upsertedProductVariationIds.includes(variation._id)) {
|
|
67
|
+
await modules.products.variations.delete(variation._id);
|
|
68
|
+
}
|
|
69
|
+
}),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { File } from '@unchainedshop/core-files';
|
|
2
|
+
import { Modules } from '../modules.js';
|
|
3
|
+
import { Services } from '../services/index.js';
|
|
4
|
+
|
|
5
|
+
const upsertAsset = async (
|
|
6
|
+
directoryName: string,
|
|
7
|
+
asset: File & { fileName: string; headers?: Record<string, unknown> },
|
|
8
|
+
unchainedAPI: { modules: Modules; services: Services },
|
|
9
|
+
) => {
|
|
10
|
+
const { modules, services } = unchainedAPI;
|
|
11
|
+
const { _id: fileId, fileName, url, meta, headers, ...assetData } = asset;
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
const existingFile = fileId && (await modules.files.findFile({ fileId }));
|
|
15
|
+
if (existingFile) {
|
|
16
|
+
if (JSON.stringify(meta) === JSON.stringify(existingFile.meta)) {
|
|
17
|
+
return existingFile;
|
|
18
|
+
}
|
|
19
|
+
await modules.files.update(fileId, { meta, ...assetData });
|
|
20
|
+
const updatedFile = await modules.files.findFile({ fileId });
|
|
21
|
+
return updatedFile;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const assetObject = await services.files.uploadFileFromURL({
|
|
25
|
+
directoryName,
|
|
26
|
+
fileInput: {
|
|
27
|
+
fileLink: url,
|
|
28
|
+
fileName,
|
|
29
|
+
fileId,
|
|
30
|
+
headers,
|
|
31
|
+
},
|
|
32
|
+
meta,
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
if (!assetObject) throw new Error('Media not created');
|
|
36
|
+
return assetObject;
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
export default upsertAsset;
|
package/src/core-index.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { mongodb, MigrationRepository, ModuleInput } from '@unchainedshop/mongodb';
|
|
2
2
|
import initServices, { CustomServices, Services } from './services/index.js';
|
|
3
3
|
import initModules, { Modules, ModuleOptions } from './modules.js';
|
|
4
|
+
import createBulkImporterFactory, {
|
|
5
|
+
BulkImporter,
|
|
6
|
+
BulkImportHandler,
|
|
7
|
+
} from './bulk-importer/createBulkImporter.js';
|
|
4
8
|
|
|
5
9
|
import {
|
|
6
10
|
WorkerDirector,
|
|
@@ -18,17 +22,17 @@ import {
|
|
|
18
22
|
WarehousingDirector,
|
|
19
23
|
} from './directors/index.js';
|
|
20
24
|
|
|
25
|
+
export * from './bulk-importer/createBulkImporter.js';
|
|
21
26
|
export * from './services/index.js';
|
|
22
27
|
export * from './directors/index.js';
|
|
23
28
|
export * from './factory/index.js';
|
|
24
|
-
export interface BulkImporter {
|
|
25
|
-
createBulkImporter: (options: any) => any;
|
|
26
|
-
}
|
|
27
29
|
|
|
28
30
|
export interface UnchainedCoreOptions {
|
|
29
31
|
db: mongodb.Db;
|
|
30
32
|
migrationRepository: MigrationRepository<UnchainedCore>;
|
|
31
|
-
bulkImporter
|
|
33
|
+
bulkImporter?: {
|
|
34
|
+
handlers?: Record<string, BulkImportHandler<UnchainedCore>>;
|
|
35
|
+
};
|
|
32
36
|
modules?: Record<
|
|
33
37
|
string,
|
|
34
38
|
{
|
|
@@ -49,13 +53,14 @@ export interface UnchainedCore {
|
|
|
49
53
|
export const initCore = async ({
|
|
50
54
|
db,
|
|
51
55
|
migrationRepository,
|
|
52
|
-
bulkImporter,
|
|
56
|
+
bulkImporter: bulkImporterOptions = {},
|
|
53
57
|
modules: customModules = {},
|
|
54
58
|
services: customServices = {},
|
|
55
59
|
options = {},
|
|
56
60
|
}: UnchainedCoreOptions): Promise<UnchainedCore> => {
|
|
57
61
|
// Configure custom modules
|
|
58
62
|
|
|
63
|
+
const bulkImporter = createBulkImporterFactory(db, bulkImporterOptions);
|
|
59
64
|
const modules = await initModules({ db, migrationRepository, options }, customModules);
|
|
60
65
|
const services = initServices(modules, customServices);
|
|
61
66
|
|
|
@@ -101,7 +101,7 @@ export const PaymentDirector: IPaymentDirector = {
|
|
|
101
101
|
try {
|
|
102
102
|
return adapter.isActive(paymentContext.transactionContext);
|
|
103
103
|
} catch (error) {
|
|
104
|
-
logger.error(error
|
|
104
|
+
logger.error(error);
|
|
105
105
|
return false;
|
|
106
106
|
}
|
|
107
107
|
},
|
|
@@ -110,7 +110,7 @@ export const PaymentDirector: IPaymentDirector = {
|
|
|
110
110
|
try {
|
|
111
111
|
return adapter.isPayLaterAllowed(paymentContext.transactionContext);
|
|
112
112
|
} catch (error) {
|
|
113
|
-
logger.error(error
|
|
113
|
+
logger.error(error);
|
|
114
114
|
return false;
|
|
115
115
|
}
|
|
116
116
|
},
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { BaseAdapter, IBaseAdapter } from '@unchainedshop/utils';
|
|
2
2
|
import { WorkResult } from '@unchainedshop/core-worker';
|
|
3
|
-
import { Modules } from '../modules.js';
|
|
3
|
+
import { ModuleOptions, Modules } from '../modules.js';
|
|
4
4
|
import { Services } from '../services/index.js';
|
|
5
|
-
import { BulkImporter } from '../
|
|
5
|
+
import { BulkImporter } from '../bulk-importer/createBulkImporter.js';
|
|
6
6
|
|
|
7
7
|
export type IWorkerAdapter<Input, Output> = IBaseAdapter & {
|
|
8
8
|
type: string;
|
|
@@ -11,7 +11,12 @@ export type IWorkerAdapter<Input, Output> = IBaseAdapter & {
|
|
|
11
11
|
|
|
12
12
|
doWork: (
|
|
13
13
|
input: Input,
|
|
14
|
-
unchainedAPI: {
|
|
14
|
+
unchainedAPI: {
|
|
15
|
+
modules: Modules;
|
|
16
|
+
services: Services;
|
|
17
|
+
bulkImporter: BulkImporter;
|
|
18
|
+
options: ModuleOptions;
|
|
19
|
+
},
|
|
15
20
|
workId: string,
|
|
16
21
|
) => Promise<WorkResult<Output>>;
|
|
17
22
|
};
|
package/src/modules.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Enrollment, EnrollmentStatus } from '@unchainedshop/core-enrollments';
|
|
2
2
|
import { Modules } from '../modules.js';
|
|
3
3
|
import { processEnrollmentService } from './processEnrollment.js';
|
|
4
|
+
import { addMessageService } from './addMessage.js';
|
|
4
5
|
|
|
5
6
|
export async function activateEnrollmentService(this: Modules, enrollment: Enrollment) {
|
|
6
7
|
if (enrollment.status === EnrollmentStatus.TERMINATED) return enrollment;
|
|
@@ -15,15 +16,10 @@ export async function activateEnrollmentService(this: Modules, enrollment: Enrol
|
|
|
15
16
|
const user = await this.users.findUserById(enrollment.userId);
|
|
16
17
|
const locale = this.users.userLocale(user);
|
|
17
18
|
|
|
18
|
-
await
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
reason: 'status_change',
|
|
23
|
-
locale: locale.baseName,
|
|
24
|
-
template: 'ENROLLMENT_STATUS',
|
|
25
|
-
enrollmentId: updatedEnrollment._id,
|
|
26
|
-
},
|
|
19
|
+
await addMessageService.bind(this)('ENROLLMENT_STATUS', {
|
|
20
|
+
reason: 'status_change',
|
|
21
|
+
locale: locale.baseName,
|
|
22
|
+
enrollmentId: updatedEnrollment._id,
|
|
27
23
|
});
|
|
28
24
|
|
|
29
25
|
return updatedEnrollment;
|