From dd8e8739f518a9a86d5ec914a9b75479e8dbe0ed Mon Sep 17 00:00:00 2001 From: Pascal Kaufmann Date: Fri, 21 May 2021 10:26:37 +0200 Subject: [PATCH 1/2] Optimize handling of products that are flagged DELETED --- examples/minimal/.meteor/versions | 4 +- packages/core-products/.versions | 16 +++--- packages/core-products/db/products/helpers.js | 8 +++ packages/core-products/package.js | 2 +- packages/platform/.versions | 4 +- .../bulk-importer/handlers/product/remove.js | 12 +---- packages/platform/package.js | 2 +- tests/bulk-importer.test.js | 51 +++++++++++++++++-- 8 files changed, 72 insertions(+), 27 deletions(-) diff --git a/examples/minimal/.meteor/versions b/examples/minimal/.meteor/versions index 3bed35d657..d083bbbcd8 100644 --- a/examples/minimal/.meteor/versions +++ b/examples/minimal/.meteor/versions @@ -72,14 +72,14 @@ unchained:core-messaging@0.61.1 unchained:core-orders@0.61.0 unchained:core-payment@0.61.2 unchained:core-pricing@0.61.3 -unchained:core-products@0.61.4 +unchained:core-products@0.61.5 unchained:core-quotations@0.61.0 unchained:core-settings@0.61.0 unchained:core-subscriptions@0.61.0 unchained:core-users@0.61.4 unchained:core-warehousing@0.61.0 unchained:core-worker@0.61.4 -unchained:platform@0.61.7 +unchained:platform@0.61.9 unchained:roles@0.61.0 unchained:utils@0.61.0 underscore@1.0.10 diff --git a/packages/core-products/.versions b/packages/core-products/.versions index db9540e855..0569aa7c22 100644 --- a/packages/core-products/.versions +++ b/packages/core-products/.versions @@ -1,6 +1,6 @@ aldeed:collection2@3.2.1 allow-deny@1.1.0 -babel-compiler@7.6.0 +babel-compiler@7.6.1 babel-runtime@1.5.0 base64@1.0.12 binary-heap@1.0.11 @@ -14,7 +14,7 @@ ddp-common@1.4.0 ddp-server@2.3.2 diff-sequence@1.1.1 dynamic-import@0.6.0 -ecmascript@0.15.0 +ecmascript@0.15.1 ecmascript-runtime@0.7.0 ecmascript-runtime-client@0.11.0 ecmascript-runtime-server@0.10.0 @@ -24,18 +24,18 @@ geojson-utils@1.0.10 http@1.4.2 id-map@1.1.0 inter-process-messaging@0.1.1 -local-test:unchained:core-products@0.61.4 +local-test:unchained:core-products@0.61.5 logging@1.2.0 meteor@1.9.3 -minimongo@1.6.1 +minimongo@1.6.2 modern-browsers@0.1.5 modules@0.16.0 modules-runtime@0.12.0 -mongo@1.10.1 +mongo@1.11.0 mongo-decimal@0.1.2 mongo-dev-server@1.1.0 mongo-id@1.0.7 -npm-mongo@3.8.1 +npm-mongo@3.9.0 ordered-dict@1.1.0 ostrio:cookies@2.6.0 ostrio:files@1.14.2 @@ -58,12 +58,12 @@ unchained:core-files@0.61.0 unchained:core-languages@0.61.0 unchained:core-logger@0.61.0 unchained:core-pricing@0.61.0 -unchained:core-products@0.61.4 +unchained:core-products@0.61.5 unchained:core-settings@0.61.0 unchained:core-users@0.61.0 unchained:core-warehousing@0.61.0 unchained:utils@0.61.0 underscore@1.0.10 url@1.3.1 -webapp@1.10.0 +webapp@1.10.1 webapp-hashing@1.1.0 diff --git a/packages/core-products/db/products/helpers.js b/packages/core-products/db/products/helpers.js index 4f61fb687c..09acf58aa3 100644 --- a/packages/core-products/db/products/helpers.js +++ b/packages/core-products/db/products/helpers.js @@ -62,6 +62,10 @@ Products.createProduct = ( { locale, title, type, sequence, authorId, ...productData }, { autopublish = false } = {} ) => { + if (productData._id) { + // Remove deleted product by _id before creating a new one. + Products.permanentlyRemoveDeletedProduct({ productId: productData._id }); + } const productId = Products.insert({ created: new Date(), type: ProductTypes[type], @@ -165,6 +169,10 @@ Products.removeBundleItem = ({ productId, index }) => { ); }; +Products.permanentlyRemoveDeletedProduct = ({ productId }) => { + Products.remove({ status: ProductStatus.DELETED, _id: productId }); +}; + Products.removeProduct = ({ productId }) => { const product = Products.findOne({ _id: productId }); switch (product.status) { diff --git a/packages/core-products/package.js b/packages/core-products/package.js index d0ec076a87..7ecbff3744 100644 --- a/packages/core-products/package.js +++ b/packages/core-products/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'unchained:core-products', - version: '0.61.4', + version: '0.61.5', summary: 'Unchained Engine Core: Products', git: 'https://github.com/unchainedshop/unchained', documentation: 'README.md', diff --git a/packages/platform/.versions b/packages/platform/.versions index b346dc5c8b..7fbf4d5bd4 100644 --- a/packages/platform/.versions +++ b/packages/platform/.versions @@ -26,7 +26,7 @@ http@1.4.2 id-map@1.1.0 inter-process-messaging@0.1.1 littledata:synced-cron@1.5.1 -local-test:unchained:platform@0.61.8 +local-test:unchained:platform@0.61.9 logging@1.2.0 meteor@1.9.3 minimongo@1.6.2 @@ -79,7 +79,7 @@ unchained:core-subscriptions@0.61.0 unchained:core-users@0.61.0 unchained:core-warehousing@0.61.0 unchained:core-worker@0.61.0 -unchained:platform@0.61.8 +unchained:platform@0.61.9 unchained:roles@0.61.0 unchained:utils@0.61.0 underscore@1.0.10 diff --git a/packages/platform/bulk-importer/handlers/product/remove.js b/packages/platform/bulk-importer/handlers/product/remove.js index 52cb873128..6ef91c0c4b 100644 --- a/packages/platform/bulk-importer/handlers/product/remove.js +++ b/packages/platform/bulk-importer/handlers/product/remove.js @@ -1,15 +1,7 @@ -import { ProductStatus, Products } from 'meteor/unchained:core-products'; +import { Products } from 'meteor/unchained:core-products'; export default async function removeProduct(payload, { logger }) { const { _id } = payload; logger.debug('remove product'); - Products.update( - { _id }, - { - $set: { - status: ProductStatus.DELETED, - updated: new Date(), - }, - } - ); + Products.removeProduct({ productId: _id }); } diff --git a/packages/platform/package.js b/packages/platform/package.js index 92b4140f75..70d4f93a05 100644 --- a/packages/platform/package.js +++ b/packages/platform/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'unchained:platform', - version: '0.61.8', + version: '0.61.9', summary: 'Unchained Engine', git: 'https://github.com/unchainedshop/unchained', documentation: 'README.md', diff --git a/tests/bulk-importer.test.js b/tests/bulk-importer.test.js index a1d658c073..88cc552406 100644 --- a/tests/bulk-importer.test.js +++ b/tests/bulk-importer.test.js @@ -17,7 +17,7 @@ describe('Bulk Importer', () => { }); describe('Import Products', () => { - it('adds 1 Product CREATE event and 1 UPDATE event', async () => { + it('adds 1 Product CREATE event and 1 UPDATE event, followed by DELETE & CREATE again', async () => { const { data: { addWork } = {} } = await graphqlFetch({ query: /* GraphQL */ ` mutation addWork($input: JSON) { @@ -181,6 +181,51 @@ describe('Bulk Importer', () => { ], }, }, + { + entity: 'PRODUCT', + operation: 'REMOVE', + payload: { + _id: 'A', + }, + }, + { + entity: 'PRODUCT', + operation: 'CREATE', + payload: { + _id: 'A', + specification: { + tags: ['awesome2'], + type: 'SimpleProduct', + published: '2020-01-01T00:00Z', + commerce: { + salesUnit: 'ST', + salesQuantityPerUnit: '1', + defaultOrderQuantity: '6', + pricing: [ + { + isTaxable: true, + isNetPrice: true, + countryCode: 'CH', + currencyCode: 'CHF', + amount: 10000, + }, + ], + }, + meta: {}, + content: { + de: { + vendor: 'Herstellername', + brand: 'Marke', + title: 'Produktname', + slug: 'produktname', + subtitle: 'Short description', + description: 'Long description', + labels: ['Neu'], + }, + }, + }, + }, + }, ], }, }, @@ -190,8 +235,8 @@ describe('Bulk Importer', () => { const Products = db.collection('products'); const result = await intervalUntilTimeout(async () => { - const product = await Products.findOne({ _id: 'A' }); - return product?.tags.includes('awesome'); + const product = await Products.findOne({ tags: 'awesome2' }); + return !!product; }, 3000); expect(result).toBe(true); From 98bb3080c6a53225f56926bcd1fa2ed25113cb43 Mon Sep 17 00:00:00 2001 From: Pascal Kaufmann Date: Fri, 21 May 2021 13:17:50 +0200 Subject: [PATCH 2/2] fix: allow to set the fileId so that the binary file is re-used --- packages/platform/.versions | 4 ++-- .../bulk-importer/handlers/product/upsertMedia.js | 9 +++++++-- packages/platform/package.js | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/platform/.versions b/packages/platform/.versions index 7fbf4d5bd4..700009dc7c 100644 --- a/packages/platform/.versions +++ b/packages/platform/.versions @@ -26,7 +26,7 @@ http@1.4.2 id-map@1.1.0 inter-process-messaging@0.1.1 littledata:synced-cron@1.5.1 -local-test:unchained:platform@0.61.9 +local-test:unchained:platform@0.61.10 logging@1.2.0 meteor@1.9.3 minimongo@1.6.2 @@ -79,7 +79,7 @@ unchained:core-subscriptions@0.61.0 unchained:core-users@0.61.0 unchained:core-warehousing@0.61.0 unchained:core-worker@0.61.0 -unchained:platform@0.61.9 +unchained:platform@0.61.10 unchained:roles@0.61.0 unchained:utils@0.61.0 underscore@1.0.10 diff --git a/packages/platform/bulk-importer/handlers/product/upsertMedia.js b/packages/platform/bulk-importer/handlers/product/upsertMedia.js index 3f3da9ea0e..3d593f6e8d 100644 --- a/packages/platform/bulk-importer/handlers/product/upsertMedia.js +++ b/packages/platform/bulk-importer/handlers/product/upsertMedia.js @@ -1,11 +1,16 @@ import { ProductMedia, Media } from 'meteor/unchained:core-products'; const upsertAsset = async (asset) => { + const { _id, ...assetData } = asset; + try { - const assetObject = await Media.insertWithRemoteURL(asset); + const assetObject = await Media.insertWithRemoteURL({ + fileId: _id, + ...assetData, + }); + if (!assetObject) throw new Error('Media not created'); return assetObject; } catch (e) { - const { _id, ...assetData } = asset; Media.update({ _id }, { $set: assetData }); return Media.findOne({ _id }); } diff --git a/packages/platform/package.js b/packages/platform/package.js index 70d4f93a05..6469687cc9 100644 --- a/packages/platform/package.js +++ b/packages/platform/package.js @@ -1,6 +1,6 @@ Package.describe({ name: 'unchained:platform', - version: '0.61.9', + version: '0.61.10', summary: 'Unchained Engine', git: 'https://github.com/unchainedshop/unchained', documentation: 'README.md',