@oronts/vendure-data-hub-plugin 0.1.3 → 0.1.5
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/CHANGELOG.md +46 -1
- package/README.md +30 -8
- package/dashboard/components/pipelines/PipelineEditor.tsx +159 -5
- package/dashboard/components/pipelines/ReactFlowPipelineEditor.tsx +3 -3
- package/dashboard/components/pipelines/shared/NodePropertiesPanel.tsx +42 -4
- package/dashboard/components/pipelines/shared/StepListItem.tsx +2 -2
- package/dashboard/components/shared/CodeEditor.tsx +289 -0
- package/dashboard/components/shared/schema-form/fields/TextareaField.tsx +19 -4
- package/dashboard/components/shared/step-config/AdapterSelector.tsx +2 -2
- package/dashboard/components/shared/step-config/OperatorFieldInput.tsx +19 -0
- package/dashboard/components/shared/step-config/RouteConfigComponent.tsx +218 -29
- package/dashboard/components/shared/step-config/StepConfigPanel.tsx +37 -17
- package/dashboard/components/shared/step-config/ValidateConfigComponent.tsx +2 -2
- package/dashboard/constants/ui-dimensions.ts +2 -1
- package/dashboard/constants/ui-states.ts +1 -0
- package/dashboard/gql/graphql.ts +13 -1
- package/dashboard/hooks/use-adapter-catalog.ts +4 -32
- package/dashboard/routes/connections/ConnectionDetail.tsx +7 -1
- package/dashboard/routes/pipelines/RunDetailsPanel.tsx +1 -1
- package/dashboard/routes/pipelines/components/PipelineActionButtons.tsx +3 -3
- package/dashboard/routes/pipelines/utils/pipeline-conversion.ts +3 -5
- package/dashboard/utils/formatters.ts +6 -4
- package/dist/dashboard/components/pipelines/PipelineEditor.tsx +159 -5
- package/dist/dashboard/components/pipelines/ReactFlowPipelineEditor.tsx +3 -3
- package/dist/dashboard/components/pipelines/shared/NodePropertiesPanel.tsx +42 -4
- package/dist/dashboard/components/pipelines/shared/StepListItem.tsx +2 -2
- package/dist/dashboard/components/shared/CodeEditor.tsx +289 -0
- package/dist/dashboard/components/shared/schema-form/fields/TextareaField.tsx +19 -4
- package/dist/dashboard/components/shared/step-config/AdapterSelector.tsx +2 -2
- package/dist/dashboard/components/shared/step-config/OperatorFieldInput.tsx +19 -0
- package/dist/dashboard/components/shared/step-config/RouteConfigComponent.tsx +218 -29
- package/dist/dashboard/components/shared/step-config/StepConfigPanel.tsx +37 -17
- package/dist/dashboard/components/shared/step-config/ValidateConfigComponent.tsx +2 -2
- package/dist/dashboard/constants/ui-dimensions.ts +2 -1
- package/dist/dashboard/constants/ui-states.ts +1 -0
- package/dist/dashboard/gql/graphql.ts +13 -1
- package/dist/dashboard/hooks/use-adapter-catalog.ts +4 -32
- package/dist/dashboard/routes/connections/ConnectionDetail.tsx +7 -1
- package/dist/dashboard/routes/pipelines/RunDetailsPanel.tsx +1 -1
- package/dist/dashboard/routes/pipelines/components/PipelineActionButtons.tsx +3 -3
- package/dist/dashboard/routes/pipelines/utils/pipeline-conversion.ts +3 -5
- package/dist/dashboard/utils/formatters.ts +6 -4
- package/dist/shared/types/adapter-config.types.d.ts +148 -4
- package/dist/shared/types/adapter-config.types.d.ts.map +1 -1
- package/dist/shared/types/index.d.ts +1 -1
- package/dist/shared/types/index.d.ts.map +1 -1
- package/dist/shared/types/index.js.map +1 -1
- package/dist/shared/types/loader.types.d.ts +4 -0
- package/dist/shared/types/loader.types.d.ts.map +1 -1
- package/dist/shared/types/step.types.d.ts +6 -0
- package/dist/shared/types/step.types.d.ts.map +1 -1
- package/dist/shared/types/trigger.types.d.ts +0 -4
- package/dist/shared/types/trigger.types.d.ts.map +1 -1
- package/dist/src/adapters/registry.d.ts.map +1 -1
- package/dist/src/adapters/registry.js +2 -1
- package/dist/src/adapters/registry.js.map +1 -1
- package/dist/src/api/controllers/webhook.controller.d.ts +10 -0
- package/dist/src/api/controllers/webhook.controller.d.ts.map +1 -1
- package/dist/src/api/controllers/webhook.controller.js +50 -10
- package/dist/src/api/controllers/webhook.controller.js.map +1 -1
- package/dist/src/api/resolvers/queue.resolver.d.ts +3 -1
- package/dist/src/api/resolvers/queue.resolver.d.ts.map +1 -1
- package/dist/src/api/resolvers/queue.resolver.js +6 -5
- package/dist/src/api/resolvers/queue.resolver.js.map +1 -1
- package/dist/src/api/schema/pipeline.schema.d.ts +1 -1
- package/dist/src/api/schema/pipeline.schema.d.ts.map +1 -1
- package/dist/src/api/schema/pipeline.schema.js +4 -0
- package/dist/src/api/schema/pipeline.schema.js.map +1 -1
- package/dist/src/api/schema/test.schema.d.ts +1 -1
- package/dist/src/api/schema/test.schema.d.ts.map +1 -1
- package/dist/src/api/schema/test.schema.js +5 -1
- package/dist/src/api/schema/test.schema.js.map +1 -1
- package/dist/src/bootstrap/seed-data.js +1 -1
- package/dist/src/bootstrap/seed-data.js.map +1 -1
- package/dist/src/constants/adapter-schema-options.d.ts +65 -0
- package/dist/src/constants/adapter-schema-options.d.ts.map +1 -1
- package/dist/src/constants/adapter-schema-options.js +91 -7
- package/dist/src/constants/adapter-schema-options.js.map +1 -1
- package/dist/src/constants/builtin-adapters.d.ts +1 -1
- package/dist/src/constants/builtin-adapters.d.ts.map +1 -1
- package/dist/src/constants/builtin-adapters.js +19 -1
- package/dist/src/constants/builtin-adapters.js.map +1 -1
- package/dist/src/constants/core.d.ts +10 -0
- package/dist/src/constants/core.d.ts.map +1 -1
- package/dist/src/constants/core.js +10 -0
- package/dist/src/constants/core.js.map +1 -1
- package/dist/src/constants/defaults/webhook-defaults.d.ts +2 -0
- package/dist/src/constants/defaults/webhook-defaults.d.ts.map +1 -1
- package/dist/src/constants/defaults/webhook-defaults.js +2 -0
- package/dist/src/constants/defaults/webhook-defaults.js.map +1 -1
- package/dist/src/constants/enum-metadata.d.ts.map +1 -1
- package/dist/src/constants/enum-metadata.js +3 -0
- package/dist/src/constants/enum-metadata.js.map +1 -1
- package/dist/src/constants/hook-stage-metadata.d.ts.map +1 -1
- package/dist/src/constants/hook-stage-metadata.js +42 -0
- package/dist/src/constants/hook-stage-metadata.js.map +1 -1
- package/dist/src/constants/services.d.ts.map +1 -1
- package/dist/src/constants/services.js +7 -0
- package/dist/src/constants/services.js.map +1 -1
- package/dist/src/constants/time.d.ts +2 -0
- package/dist/src/constants/time.d.ts.map +1 -1
- package/dist/src/constants/time.js +2 -0
- package/dist/src/constants/time.js.map +1 -1
- package/dist/src/data-hub.plugin.d.ts.map +1 -1
- package/dist/src/data-hub.plugin.js +2 -2
- package/dist/src/data-hub.plugin.js.map +1 -1
- package/dist/src/entities/pipeline/pipeline-run.entity.d.ts +4 -0
- package/dist/src/entities/pipeline/pipeline-run.entity.d.ts.map +1 -1
- package/dist/src/entities/pipeline/pipeline-run.entity.js +8 -0
- package/dist/src/entities/pipeline/pipeline-run.entity.js.map +1 -1
- package/dist/src/extractors/cdc/cdc.extractor.d.ts.map +1 -1
- package/dist/src/extractors/cdc/cdc.extractor.js +7 -2
- package/dist/src/extractors/cdc/cdc.extractor.js.map +1 -1
- package/dist/src/extractors/cdc/types.d.ts +1 -1
- package/dist/src/extractors/cdc/types.d.ts.map +1 -1
- package/dist/src/extractors/extractor-handler-registry.d.ts.map +1 -1
- package/dist/src/extractors/extractor-handler-registry.js +3 -0
- package/dist/src/extractors/extractor-handler-registry.js.map +1 -1
- package/dist/src/extractors/vendure-query/helpers.d.ts +9 -4
- package/dist/src/extractors/vendure-query/helpers.d.ts.map +1 -1
- package/dist/src/extractors/vendure-query/helpers.js +98 -32
- package/dist/src/extractors/vendure-query/helpers.js.map +1 -1
- package/dist/src/extractors/vendure-query/schema.d.ts.map +1 -1
- package/dist/src/extractors/vendure-query/schema.js +13 -0
- package/dist/src/extractors/vendure-query/schema.js.map +1 -1
- package/dist/src/feeds/generators/csv-feed.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/csv-feed.generator.js +5 -4
- package/dist/src/feeds/generators/csv-feed.generator.js.map +1 -1
- package/dist/src/feeds/generators/facebook-catalog.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/facebook-catalog.generator.js +83 -114
- package/dist/src/feeds/generators/facebook-catalog.generator.js.map +1 -1
- package/dist/src/feeds/generators/feed-constants.d.ts +1 -0
- package/dist/src/feeds/generators/feed-constants.d.ts.map +1 -1
- package/dist/src/feeds/generators/feed-constants.js +1 -0
- package/dist/src/feeds/generators/feed-constants.js.map +1 -1
- package/dist/src/feeds/generators/feed-helpers.d.ts +10 -8
- package/dist/src/feeds/generators/feed-helpers.d.ts.map +1 -1
- package/dist/src/feeds/generators/feed-helpers.js +24 -4
- package/dist/src/feeds/generators/feed-helpers.js.map +1 -1
- package/dist/src/feeds/generators/feed-item-builder.d.ts +59 -0
- package/dist/src/feeds/generators/feed-item-builder.d.ts.map +1 -0
- package/dist/src/feeds/generators/feed-item-builder.js +93 -0
- package/dist/src/feeds/generators/feed-item-builder.js.map +1 -0
- package/dist/src/feeds/generators/google-shopping.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/google-shopping.generator.js +52 -64
- package/dist/src/feeds/generators/google-shopping.generator.js.map +1 -1
- package/dist/src/feeds/generators/json-feed.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/json-feed.generator.js +4 -3
- package/dist/src/feeds/generators/json-feed.generator.js.map +1 -1
- package/dist/src/feeds/generators/xml-feed.generator.d.ts.map +1 -1
- package/dist/src/feeds/generators/xml-feed.generator.js +6 -5
- package/dist/src/feeds/generators/xml-feed.generator.js.map +1 -1
- package/dist/src/gql/generated.d.ts +13 -1
- package/dist/src/gql/generated.d.ts.map +1 -1
- package/dist/src/gql/generated.js.map +1 -1
- package/dist/src/index.d.ts +3 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +7 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/loaders/asset/asset.loader.d.ts.map +1 -1
- package/dist/src/loaders/asset/asset.loader.js +5 -1
- package/dist/src/loaders/asset/asset.loader.js.map +1 -1
- package/dist/src/loaders/base/validation-builder.d.ts +128 -3
- package/dist/src/loaders/base/validation-builder.d.ts.map +1 -1
- package/dist/src/loaders/base/validation-builder.js +177 -6
- package/dist/src/loaders/base/validation-builder.js.map +1 -1
- package/dist/src/loaders/collection/collection.loader.d.ts.map +1 -1
- package/dist/src/loaders/collection/collection.loader.js +22 -1
- package/dist/src/loaders/collection/collection.loader.js.map +1 -1
- package/dist/src/loaders/collection/helpers.d.ts +16 -1
- package/dist/src/loaders/collection/helpers.d.ts.map +1 -1
- package/dist/src/loaders/collection/helpers.js +37 -0
- package/dist/src/loaders/collection/helpers.js.map +1 -1
- package/dist/src/loaders/customer/customer.loader.d.ts.map +1 -1
- package/dist/src/loaders/customer/customer.loader.js +13 -1
- package/dist/src/loaders/customer/customer.loader.js.map +1 -1
- package/dist/src/loaders/customer/helpers.d.ts +15 -3
- package/dist/src/loaders/customer/helpers.d.ts.map +1 -1
- package/dist/src/loaders/customer/helpers.js +188 -7
- package/dist/src/loaders/customer/helpers.js.map +1 -1
- package/dist/src/loaders/facet-value/facet-value.loader.d.ts.map +1 -1
- package/dist/src/loaders/facet-value/facet-value.loader.js +18 -0
- package/dist/src/loaders/facet-value/facet-value.loader.js.map +1 -1
- package/dist/src/loaders/facet-value/types.d.ts +1 -1
- package/dist/src/loaders/facet-value/types.js +1 -1
- package/dist/src/loaders/facet-value/types.js.map +1 -1
- package/dist/src/loaders/order/helpers.d.ts +16 -2
- package/dist/src/loaders/order/helpers.d.ts.map +1 -1
- package/dist/src/loaders/order/helpers.js +108 -0
- package/dist/src/loaders/order/helpers.js.map +1 -1
- package/dist/src/loaders/order/order.loader.d.ts +38 -0
- package/dist/src/loaders/order/order.loader.d.ts.map +1 -1
- package/dist/src/loaders/order/order.loader.js +238 -24
- package/dist/src/loaders/order/order.loader.js.map +1 -1
- package/dist/src/loaders/order/types.d.ts +10 -3
- package/dist/src/loaders/order/types.d.ts.map +1 -1
- package/dist/src/loaders/order/types.js +13 -2
- package/dist/src/loaders/order/types.js.map +1 -1
- package/dist/src/loaders/product/product.loader.d.ts.map +1 -1
- package/dist/src/loaders/product/product.loader.js +18 -2
- package/dist/src/loaders/product/product.loader.js.map +1 -1
- package/dist/src/loaders/product-variant/helpers.d.ts +20 -0
- package/dist/src/loaders/product-variant/helpers.d.ts.map +1 -0
- package/dist/src/loaders/product-variant/helpers.js +103 -0
- package/dist/src/loaders/product-variant/helpers.js.map +1 -0
- package/dist/src/loaders/product-variant/product-variant.loader.d.ts.map +1 -1
- package/dist/src/loaders/product-variant/product-variant.loader.js +76 -10
- package/dist/src/loaders/product-variant/product-variant.loader.js.map +1 -1
- package/dist/src/loaders/product-variant/types.d.ts +7 -0
- package/dist/src/loaders/product-variant/types.d.ts.map +1 -1
- package/dist/src/loaders/product-variant/types.js.map +1 -1
- package/dist/src/loaders/promotion/helpers.d.ts +29 -0
- package/dist/src/loaders/promotion/helpers.d.ts.map +1 -1
- package/dist/src/loaders/promotion/helpers.js +68 -0
- package/dist/src/loaders/promotion/helpers.js.map +1 -1
- package/dist/src/loaders/promotion/promotion.loader.d.ts.map +1 -1
- package/dist/src/loaders/promotion/promotion.loader.js +12 -2
- package/dist/src/loaders/promotion/promotion.loader.js.map +1 -1
- package/dist/src/loaders/shared-helpers.d.ts +42 -2
- package/dist/src/loaders/shared-helpers.d.ts.map +1 -1
- package/dist/src/loaders/shared-helpers.js +384 -5
- package/dist/src/loaders/shared-helpers.js.map +1 -1
- package/dist/src/operators/data/copy.operator.js +2 -2
- package/dist/src/operators/data/copy.operator.js.map +1 -1
- package/dist/src/operators/data/rename.operator.js +1 -1
- package/dist/src/operators/data/rename.operator.js.map +1 -1
- package/dist/src/operators/helpers.d.ts.map +1 -1
- package/dist/src/operators/helpers.js +11 -1
- package/dist/src/operators/helpers.js.map +1 -1
- package/dist/src/operators/operator-runtime-registry.d.ts +2 -2
- package/dist/src/operators/operator-runtime-registry.d.ts.map +1 -1
- package/dist/src/operators/operator-runtime-registry.js +1 -1
- package/dist/src/operators/operator-runtime-registry.js.map +1 -1
- package/dist/src/operators/script/script.operators.d.ts.map +1 -1
- package/dist/src/operators/script/script.operators.js +9 -3
- package/dist/src/operators/script/script.operators.js.map +1 -1
- package/dist/src/runtime/config-types.d.ts +6 -0
- package/dist/src/runtime/config-types.d.ts.map +1 -1
- package/dist/src/runtime/executor-helpers.d.ts +77 -0
- package/dist/src/runtime/executor-helpers.d.ts.map +1 -0
- package/dist/src/runtime/executor-helpers.js +143 -0
- package/dist/src/runtime/executor-helpers.js.map +1 -0
- package/dist/src/runtime/executors/export.executor.d.ts +3 -1
- package/dist/src/runtime/executors/export.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/export.executor.js +15 -3
- package/dist/src/runtime/executors/export.executor.js.map +1 -1
- package/dist/src/runtime/executors/exporters/export-handler-registry.d.ts.map +1 -1
- package/dist/src/runtime/executors/exporters/export-handler-registry.js +5 -0
- package/dist/src/runtime/executors/exporters/export-handler-registry.js.map +1 -1
- package/dist/src/runtime/executors/exporters/export-handler.types.d.ts +3 -0
- package/dist/src/runtime/executors/exporters/export-handler.types.d.ts.map +1 -1
- package/dist/src/runtime/executors/exporters/export-handler.types.js.map +1 -1
- package/dist/src/runtime/executors/exporters/export-helpers.d.ts +1 -0
- package/dist/src/runtime/executors/exporters/export-helpers.d.ts.map +1 -1
- package/dist/src/runtime/executors/exporters/export-helpers.js +32 -3
- package/dist/src/runtime/executors/exporters/export-helpers.js.map +1 -1
- package/dist/src/runtime/executors/exporters/http-export.handler.js +4 -4
- package/dist/src/runtime/executors/exporters/http-export.handler.js.map +1 -1
- package/dist/src/runtime/executors/extractors/file-extract.handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/extractors/file-extract.handler.js +33 -13
- package/dist/src/runtime/executors/extractors/file-extract.handler.js.map +1 -1
- package/dist/src/runtime/executors/extractors/memory-extract.handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/extractors/memory-extract.handler.js +17 -9
- package/dist/src/runtime/executors/extractors/memory-extract.handler.js.map +1 -1
- package/dist/src/runtime/executors/feed.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/feed.executor.js +11 -2
- package/dist/src/runtime/executors/feed.executor.js.map +1 -1
- package/dist/src/runtime/executors/feeds/feed-handler-registry.d.ts.map +1 -1
- package/dist/src/runtime/executors/feeds/feed-handler-registry.js +4 -0
- package/dist/src/runtime/executors/feeds/feed-handler-registry.js.map +1 -1
- package/dist/src/runtime/executors/gate.executor.d.ts +3 -1
- package/dist/src/runtime/executors/gate.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/gate.executor.js +47 -26
- package/dist/src/runtime/executors/gate.executor.js.map +1 -1
- package/dist/src/runtime/executors/loaders/channel-handler.d.ts +3 -1
- package/dist/src/runtime/executors/loaders/channel-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/channel-handler.js +14 -4
- package/dist/src/runtime/executors/loaders/channel-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/collection-handler.d.ts +14 -2
- package/dist/src/runtime/executors/loaders/collection-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/collection-handler.js +93 -22
- package/dist/src/runtime/executors/loaders/collection-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/customer-group-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/customer-group-handler.js +2 -27
- package/dist/src/runtime/executors/loaders/customer-group-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/customer-handler.d.ts +6 -1
- package/dist/src/runtime/executors/loaders/customer-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/customer-handler.js +95 -13
- package/dist/src/runtime/executors/loaders/customer-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/deletion-handler.d.ts +39 -0
- package/dist/src/runtime/executors/loaders/deletion-handler.d.ts.map +1 -0
- package/dist/src/runtime/executors/loaders/deletion-handler.js +414 -0
- package/dist/src/runtime/executors/loaders/deletion-handler.js.map +1 -0
- package/dist/src/runtime/executors/loaders/facet-handler.d.ts +18 -3
- package/dist/src/runtime/executors/loaders/facet-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/facet-handler.js +127 -26
- package/dist/src/runtime/executors/loaders/facet-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/index.d.ts +2 -0
- package/dist/src/runtime/executors/loaders/index.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/index.js +5 -1
- package/dist/src/runtime/executors/loaders/index.js.map +1 -1
- package/dist/src/runtime/executors/loaders/inventory-adjust-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/inventory-adjust-handler.js +2 -28
- package/dist/src/runtime/executors/loaders/inventory-adjust-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/inventory-handler.d.ts +2 -1
- package/dist/src/runtime/executors/loaders/inventory-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/inventory-handler.js +8 -6
- package/dist/src/runtime/executors/loaders/inventory-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/loader-handler-registry.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/loader-handler-registry.js +117 -3
- package/dist/src/runtime/executors/loaders/loader-handler-registry.js.map +1 -1
- package/dist/src/runtime/executors/loaders/order-handler.d.ts +31 -3
- package/dist/src/runtime/executors/loaders/order-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/order-handler.js +194 -14
- package/dist/src/runtime/executors/loaders/order-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/order-upsert-handler.d.ts +15 -0
- package/dist/src/runtime/executors/loaders/order-upsert-handler.d.ts.map +1 -0
- package/dist/src/runtime/executors/loaders/order-upsert-handler.js +89 -0
- package/dist/src/runtime/executors/loaders/order-upsert-handler.js.map +1 -0
- package/dist/src/runtime/executors/loaders/payment-method-handler.d.ts +11 -2
- package/dist/src/runtime/executors/loaders/payment-method-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/payment-method-handler.js +78 -33
- package/dist/src/runtime/executors/loaders/payment-method-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/product-handler.d.ts +14 -0
- package/dist/src/runtime/executors/loaders/product-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/product-handler.js +91 -19
- package/dist/src/runtime/executors/loaders/product-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/promotion-handler.d.ts +9 -2
- package/dist/src/runtime/executors/loaders/promotion-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/promotion-handler.js +115 -68
- package/dist/src/runtime/executors/loaders/promotion-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/shared-lookups.d.ts +35 -1
- package/dist/src/runtime/executors/loaders/shared-lookups.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/shared-lookups.js +102 -0
- package/dist/src/runtime/executors/loaders/shared-lookups.js.map +1 -1
- package/dist/src/runtime/executors/loaders/shipping-method-handler.d.ts +11 -6
- package/dist/src/runtime/executors/loaders/shipping-method-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/shipping-method-handler.js +168 -61
- package/dist/src/runtime/executors/loaders/shipping-method-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/stock-location-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/stock-location-handler.js +2 -27
- package/dist/src/runtime/executors/loaders/stock-location-handler.js.map +1 -1
- package/dist/src/runtime/executors/loaders/variant-handler.d.ts.map +1 -1
- package/dist/src/runtime/executors/loaders/variant-handler.js +85 -12
- package/dist/src/runtime/executors/loaders/variant-handler.js.map +1 -1
- package/dist/src/runtime/executors/sink-handler-registry.d.ts +7 -11
- package/dist/src/runtime/executors/sink-handler-registry.d.ts.map +1 -1
- package/dist/src/runtime/executors/sink-handler-registry.js +374 -8
- package/dist/src/runtime/executors/sink-handler-registry.js.map +1 -1
- package/dist/src/runtime/executors/sink.executor.d.ts +1 -0
- package/dist/src/runtime/executors/sink.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/sink.executor.js +82 -12
- package/dist/src/runtime/executors/sink.executor.js.map +1 -1
- package/dist/src/runtime/executors/transform.executor.d.ts.map +1 -1
- package/dist/src/runtime/executors/transform.executor.js +31 -2
- package/dist/src/runtime/executors/transform.executor.js.map +1 -1
- package/dist/src/runtime/orchestration/graph-executor.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/graph-executor.js +3 -2
- package/dist/src/runtime/orchestration/graph-executor.js.map +1 -1
- package/dist/src/runtime/orchestration/helpers.d.ts +4 -1
- package/dist/src/runtime/orchestration/helpers.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/helpers.js +7 -2
- package/dist/src/runtime/orchestration/helpers.js.map +1 -1
- package/dist/src/runtime/orchestration/linear-executor.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/linear-executor.js +3 -2
- package/dist/src/runtime/orchestration/linear-executor.js.map +1 -1
- package/dist/src/runtime/orchestration/replay-executor.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/replay-executor.js +3 -2
- package/dist/src/runtime/orchestration/replay-executor.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/export-step.strategy.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/export-step.strategy.js +12 -12
- package/dist/src/runtime/orchestration/step-strategies/export-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/feed-step.strategy.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/feed-step.strategy.js +12 -12
- package/dist/src/runtime/orchestration/step-strategies/feed-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/load-step.strategy.js +2 -2
- package/dist/src/runtime/orchestration/step-strategies/load-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/sink-step.strategy.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/sink-step.strategy.js +12 -12
- package/dist/src/runtime/orchestration/step-strategies/sink-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/step-dispatcher.d.ts.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/step-dispatcher.js +4 -3
- package/dist/src/runtime/orchestration/step-strategies/step-dispatcher.js.map +1 -1
- package/dist/src/runtime/orchestration/step-strategies/transform-step.strategy.js +4 -4
- package/dist/src/runtime/orchestration/step-strategies/transform-step.strategy.js.map +1 -1
- package/dist/src/runtime/orchestration/types.d.ts +1 -0
- package/dist/src/runtime/orchestration/types.d.ts.map +1 -1
- package/dist/src/runtime/utils.d.ts.map +1 -1
- package/dist/src/runtime/utils.js +8 -1
- package/dist/src/runtime/utils.js.map +1 -1
- package/dist/src/sdk/adapters/queue/index.d.ts +1 -0
- package/dist/src/sdk/adapters/queue/index.d.ts.map +1 -1
- package/dist/src/sdk/adapters/queue/index.js +1 -0
- package/dist/src/sdk/adapters/queue/index.js.map +1 -1
- package/dist/src/sdk/adapters/queue/internal.adapter.d.ts +32 -0
- package/dist/src/sdk/adapters/queue/internal.adapter.d.ts.map +1 -0
- package/dist/src/sdk/adapters/queue/internal.adapter.js +68 -0
- package/dist/src/sdk/adapters/queue/internal.adapter.js.map +1 -0
- package/dist/src/sdk/adapters/queue/queue-adapter.registry.d.ts.map +1 -1
- package/dist/src/sdk/adapters/queue/queue-adapter.registry.js +3 -0
- package/dist/src/sdk/adapters/queue/queue-adapter.registry.js.map +1 -1
- package/dist/src/sdk/adapters/queue/rabbitmq.adapter.d.ts.map +1 -1
- package/dist/src/sdk/adapters/queue/rabbitmq.adapter.js +2 -1
- package/dist/src/sdk/adapters/queue/rabbitmq.adapter.js.map +1 -1
- package/dist/src/sdk/constants.d.ts +2 -2
- package/dist/src/sdk/constants.d.ts.map +1 -1
- package/dist/src/sdk/dsl/pipeline-builder.d.ts +8 -2
- package/dist/src/sdk/dsl/pipeline-builder.d.ts.map +1 -1
- package/dist/src/sdk/dsl/pipeline-builder.js +115 -19
- package/dist/src/sdk/dsl/pipeline-builder.js.map +1 -1
- package/dist/src/sdk/dsl/step-configs.d.ts +73 -7
- package/dist/src/sdk/dsl/step-configs.d.ts.map +1 -1
- package/dist/src/services/events/consumer-discovery.d.ts.map +1 -1
- package/dist/src/services/events/consumer-discovery.js +13 -11
- package/dist/src/services/events/consumer-discovery.js.map +1 -1
- package/dist/src/services/events/consumer-lifecycle.d.ts.map +1 -1
- package/dist/src/services/events/consumer-lifecycle.js +19 -15
- package/dist/src/services/events/consumer-lifecycle.js.map +1 -1
- package/dist/src/services/events/event-trigger.service.d.ts.map +1 -1
- package/dist/src/services/events/event-trigger.service.js +8 -3
- package/dist/src/services/events/event-trigger.service.js.map +1 -1
- package/dist/src/services/events/hook.service.d.ts.map +1 -1
- package/dist/src/services/events/hook.service.js +7 -3
- package/dist/src/services/events/hook.service.js.map +1 -1
- package/dist/src/services/events/message-processing.d.ts.map +1 -1
- package/dist/src/services/events/message-processing.js +13 -8
- package/dist/src/services/events/message-processing.js.map +1 -1
- package/dist/src/services/logger/datahub-logger.d.ts +7 -0
- package/dist/src/services/logger/datahub-logger.d.ts.map +1 -1
- package/dist/src/services/logger/datahub-logger.js +9 -0
- package/dist/src/services/logger/datahub-logger.js.map +1 -1
- package/dist/src/services/pipeline/pipeline-runner.service.d.ts +3 -1
- package/dist/src/services/pipeline/pipeline-runner.service.d.ts.map +1 -1
- package/dist/src/services/pipeline/pipeline-runner.service.js +14 -4
- package/dist/src/services/pipeline/pipeline-runner.service.js.map +1 -1
- package/dist/src/services/pipeline/pipeline.service.d.ts.map +1 -1
- package/dist/src/services/pipeline/pipeline.service.js +8 -2
- package/dist/src/services/pipeline/pipeline.service.js.map +1 -1
- package/dist/src/services/storage/retention.service.d.ts.map +1 -1
- package/dist/src/services/storage/retention.service.js +22 -0
- package/dist/src/services/storage/retention.service.js.map +1 -1
- package/dist/src/services/testing/step-test.service.d.ts.map +1 -1
- package/dist/src/services/testing/step-test.service.js +17 -1
- package/dist/src/services/testing/step-test.service.js.map +1 -1
- package/dist/src/services/validation/definition-validation.service.d.ts.map +1 -1
- package/dist/src/services/validation/definition-validation.service.js +4 -1
- package/dist/src/services/validation/definition-validation.service.js.map +1 -1
- package/dist/src/services/validation/trigger-validation.d.ts.map +1 -1
- package/dist/src/services/validation/trigger-validation.js +79 -12
- package/dist/src/services/validation/trigger-validation.js.map +1 -1
- package/dist/src/types/index.d.ts +1 -0
- package/dist/src/types/index.d.ts.map +1 -1
- package/dist/src/types/index.js.map +1 -1
- package/dist/src/types/loader-configs.d.ts +1071 -0
- package/dist/src/types/loader-configs.d.ts.map +1 -0
- package/dist/src/types/loader-configs.js +54 -0
- package/dist/src/types/loader-configs.js.map +1 -0
- package/dist/src/types/step-configs.d.ts +14 -5
- package/dist/src/types/step-configs.d.ts.map +1 -1
- package/dist/src/types/step-configs.js +3 -0
- package/dist/src/types/step-configs.js.map +1 -1
- package/dist/src/utils/code-security.utils.d.ts +18 -0
- package/dist/src/utils/code-security.utils.d.ts.map +1 -1
- package/dist/src/utils/code-security.utils.js +125 -9
- package/dist/src/utils/code-security.utils.js.map +1 -1
- package/dist/src/validation/pipeline-definition.validator.js +2 -1
- package/dist/src/validation/pipeline-definition.validator.js.map +1 -1
- package/docs/developer-guide/README.md +2 -0
- package/docs/developer-guide/dsl/pipeline-builder.md +12 -0
- package/docs/developer-guide/extending/README.md +230 -10
- package/docs/developer-guide/extending/custom-sinks.md +87 -0
- package/docs/developer-guide/extending/events.md +4 -1
- package/docs/examples/validation-error-messages.md +246 -0
- package/docs/guides/multi-channel.md +1190 -0
- package/docs/guides/multi-currency.md +881 -0
- package/docs/guides/multi-entity.md +597 -0
- package/docs/guides/multi-language.md +957 -0
- package/docs/reference/README.md +11 -4
- package/docs/reference/extractors.md +30 -0
- package/docs/reference/loaders.md +359 -21
- package/docs/reference/operators-complete.md +1251 -0
- package/docs/reference/operators.md +36 -2
- package/docs/reference/sinks.md +7 -6
- package/docs/reference/step-types.md +12 -5
- package/docs/user-guide/pipelines.md +82 -13
- package/package.json +1 -1
- package/shared/types/adapter-config.types.ts +162 -2
- package/shared/types/index.ts +12 -0
- package/shared/types/loader.types.ts +4 -0
- package/shared/types/step.types.ts +6 -0
- package/shared/types/trigger.types.ts +0 -4
|
@@ -0,0 +1,881 @@
|
|
|
1
|
+
# Multi-Currency Guide
|
|
2
|
+
|
|
3
|
+
Complete guide to multi-currency pricing in the Data Hub plugin.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Introduction
|
|
8
|
+
|
|
9
|
+
### What is Multi-Currency Support?
|
|
10
|
+
|
|
11
|
+
Multi-currency support allows you to define different prices for products and variants across multiple currencies:
|
|
12
|
+
- **Single-currency mode** - One price for all channels (simple, common)
|
|
13
|
+
- **Multi-currency mode** - Different prices per currency (international stores)
|
|
14
|
+
- **Channel-based** - Each channel has its own currency settings
|
|
15
|
+
- **Price updates** - Update prices without modifying other product fields
|
|
16
|
+
|
|
17
|
+
### The Problem
|
|
18
|
+
|
|
19
|
+
**Before discovering `priceByCurrencyField`**, users only knew about single-currency pricing:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// BEFORE: Single currency only
|
|
23
|
+
.load('import-products', {
|
|
24
|
+
priceField: 'price' // One price for all channels
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
// Input data:
|
|
28
|
+
{ name: 'T-Shirt', price: 29.99 }
|
|
29
|
+
|
|
30
|
+
// Result: All channels get USD $29.99 (or whatever the channel's currency is)
|
|
31
|
+
// European customers pay €29.99 (incorrect conversion!)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### The Solution
|
|
35
|
+
|
|
36
|
+
**Multi-currency fields** let you specify different prices for each currency:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// AFTER: Multi-currency support
|
|
40
|
+
.load('import-products', {
|
|
41
|
+
priceByCurrencyField: 'prices' // ← Different price per currency
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// Input data:
|
|
45
|
+
{
|
|
46
|
+
name: 'T-Shirt',
|
|
47
|
+
prices: {
|
|
48
|
+
USD: 29.99,
|
|
49
|
+
EUR: 24.99,
|
|
50
|
+
GBP: 21.99
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Result:
|
|
55
|
+
// - US channel: $29.99
|
|
56
|
+
// - EU channel: €24.99
|
|
57
|
+
// - UK channel: £21.99
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Channel-Currency Relationship
|
|
63
|
+
|
|
64
|
+
### How Channels & Currencies Work Together
|
|
65
|
+
|
|
66
|
+
Channels define which currencies are available:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
// Channel configuration determines valid currencies
|
|
70
|
+
const usChannel = {
|
|
71
|
+
code: 'us-channel',
|
|
72
|
+
defaultCurrencyCode: 'USD',
|
|
73
|
+
availableCurrencyCodes: ['USD']
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const euChannel = {
|
|
77
|
+
code: 'eu-channel',
|
|
78
|
+
defaultCurrencyCode: 'EUR',
|
|
79
|
+
availableCurrencyCodes: ['EUR', 'GBP', 'CHF'] // Multi-currency channel
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Setting Up Multi-Currency Channels
|
|
84
|
+
|
|
85
|
+
Use the Channel loader to configure currency support:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Create multi-currency channel
|
|
89
|
+
.load('create-channels', {
|
|
90
|
+
adapterCode: 'channelUpsert',
|
|
91
|
+
codeField: 'code',
|
|
92
|
+
defaultCurrencyCodeField: 'defaultCurrency',
|
|
93
|
+
availableCurrencyCodesField: 'currencies'
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
// Input data:
|
|
97
|
+
[
|
|
98
|
+
{
|
|
99
|
+
code: 'us-store',
|
|
100
|
+
defaultCurrency: 'USD',
|
|
101
|
+
currencies: ['USD']
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
code: 'eu-store',
|
|
105
|
+
defaultCurrency: 'EUR',
|
|
106
|
+
currencies: ['EUR', 'GBP', 'CHF'] // Supports 3 currencies
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Available fields in Channel loader:**
|
|
112
|
+
- `defaultCurrencyCodeField` - Primary currency for the channel
|
|
113
|
+
- `availableCurrencyCodesField` - Array of supported currencies
|
|
114
|
+
- `defaultLanguageCodeField` - Primary language
|
|
115
|
+
- `availableLanguageCodesField` - Array of supported languages
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Product Pricing
|
|
120
|
+
|
|
121
|
+
### Single-Currency Pricing (Simple)
|
|
122
|
+
|
|
123
|
+
For stores with one currency, use `priceField`:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
.load('import-products', {
|
|
127
|
+
adapterCode: 'productUpsert',
|
|
128
|
+
nameField: 'name',
|
|
129
|
+
priceField: 'price', // ← Single price value
|
|
130
|
+
skuField: 'sku'
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
// CSV input:
|
|
134
|
+
// name,sku,price
|
|
135
|
+
// T-Shirt,TSH-001,29.99
|
|
136
|
+
// Jeans,JNS-001,59.99
|
|
137
|
+
|
|
138
|
+
// Result: All products get the same numeric price
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**How it works:**
|
|
142
|
+
1. Price is converted to minor units (cents): `29.99 → 2999`
|
|
143
|
+
2. Applied to variant with channel's currency
|
|
144
|
+
3. Displayed as `$29.99` in USD channel or `€29.99` in EUR channel
|
|
145
|
+
|
|
146
|
+
**Use when:**
|
|
147
|
+
- You only sell in one currency
|
|
148
|
+
- All channels use the same currency
|
|
149
|
+
- You handle currency conversion externally
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
### Multi-Currency Pricing (International)
|
|
154
|
+
|
|
155
|
+
For international stores, use `priceByCurrencyField`:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
.load('import-products', {
|
|
159
|
+
adapterCode: 'productUpsert',
|
|
160
|
+
nameField: 'name',
|
|
161
|
+
priceByCurrencyField: 'prices', // ← Object with currency→price mapping
|
|
162
|
+
skuField: 'sku'
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
// JSON input:
|
|
166
|
+
[
|
|
167
|
+
{
|
|
168
|
+
name: 'Premium T-Shirt',
|
|
169
|
+
sku: 'TSH-PREM-001',
|
|
170
|
+
prices: {
|
|
171
|
+
USD: 29.99,
|
|
172
|
+
EUR: 24.99,
|
|
173
|
+
GBP: 21.99,
|
|
174
|
+
JPY: 3200
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
name: 'Designer Jeans',
|
|
179
|
+
sku: 'JNS-DSGN-001',
|
|
180
|
+
prices: {
|
|
181
|
+
USD: 89.99,
|
|
182
|
+
EUR: 74.99,
|
|
183
|
+
GBP: 64.99,
|
|
184
|
+
JPY: 9800
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
]
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
**Multi-currency object format:**
|
|
191
|
+
```typescript
|
|
192
|
+
prices: {
|
|
193
|
+
[currencyCode: string]: number
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Examples:
|
|
197
|
+
{ EUR: 29.99, USD: 34.99 }
|
|
198
|
+
{ GBP: 19.99, EUR: 23.99, USD: 27.99 }
|
|
199
|
+
{ JPY: 3500, USD: 29.99 } // JPY has no decimals
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**How it works:**
|
|
203
|
+
1. Plugin converts each price to minor units
|
|
204
|
+
2. Creates price entry for each currency
|
|
205
|
+
3. Vendure automatically selects correct price based on channel's currency
|
|
206
|
+
4. If currency missing for a channel, Vendure falls back to default behavior
|
|
207
|
+
|
|
208
|
+
**Use when:**
|
|
209
|
+
- You sell in multiple countries
|
|
210
|
+
- You set prices manually per market (no automatic conversion)
|
|
211
|
+
- Different pricing strategies per region (e.g., EU includes VAT, US doesn't)
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### CSV Multi-Currency Format
|
|
216
|
+
|
|
217
|
+
For CSV imports, use JSON-encoded objects:
|
|
218
|
+
|
|
219
|
+
```csv
|
|
220
|
+
name,sku,prices
|
|
221
|
+
Basic T-Shirt,TSH-001,"{""USD"": 29.99, ""EUR"": 24.99, ""GBP"": 21.99}"
|
|
222
|
+
Premium Hoodie,HDI-001,"{""USD"": 59.99, ""EUR"": 49.99, ""GBP"": 44.99}"
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Pipeline configuration:**
|
|
226
|
+
```typescript
|
|
227
|
+
.extract('csv-file', {
|
|
228
|
+
filePath: '/data/products.csv'
|
|
229
|
+
})
|
|
230
|
+
.transform('parse-json-fields', {
|
|
231
|
+
fields: 'prices' // Parse JSON string to object
|
|
232
|
+
})
|
|
233
|
+
.load('import-products', {
|
|
234
|
+
priceByCurrencyField: 'prices'
|
|
235
|
+
})
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
## Variant Pricing
|
|
241
|
+
|
|
242
|
+
Variants support the same single/multi-currency pattern:
|
|
243
|
+
|
|
244
|
+
### Single-Currency Variant
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
.load('import-variants', {
|
|
248
|
+
adapterCode: 'variantUpsert',
|
|
249
|
+
skuField: 'sku',
|
|
250
|
+
nameField: 'name',
|
|
251
|
+
priceField: 'price' // ← Single price
|
|
252
|
+
})
|
|
253
|
+
|
|
254
|
+
// Input:
|
|
255
|
+
{ sku: 'TSH-S-RED', name: 'Small Red T-Shirt', price: 29.99 }
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Multi-Currency Variant
|
|
259
|
+
|
|
260
|
+
```typescript
|
|
261
|
+
.load('import-variants', {
|
|
262
|
+
adapterCode: 'variantUpsert',
|
|
263
|
+
skuField: 'sku',
|
|
264
|
+
nameField: 'name',
|
|
265
|
+
priceByCurrencyField: 'prices' // ← Multiple currencies
|
|
266
|
+
})
|
|
267
|
+
|
|
268
|
+
// Input:
|
|
269
|
+
{
|
|
270
|
+
sku: 'TSH-S-RED',
|
|
271
|
+
name: 'Small Red T-Shirt',
|
|
272
|
+
prices: {
|
|
273
|
+
USD: 29.99,
|
|
274
|
+
EUR: 24.99,
|
|
275
|
+
GBP: 21.99
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**Available fields:**
|
|
281
|
+
- **Product loader**: `priceField` OR `priceByCurrencyField`
|
|
282
|
+
- **Variant loader**: `priceField` OR `priceByCurrencyField`
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Currency Conversion Strategies
|
|
287
|
+
|
|
288
|
+
### Manual Pricing (Recommended)
|
|
289
|
+
|
|
290
|
+
Set prices manually per currency based on market conditions:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
// Input data with manual prices
|
|
294
|
+
{
|
|
295
|
+
name: 'Product A',
|
|
296
|
+
sku: 'PROD-A',
|
|
297
|
+
prices: {
|
|
298
|
+
USD: 99.99, // US market
|
|
299
|
+
EUR: 84.99, // EU market (includes VAT)
|
|
300
|
+
GBP: 74.99, // UK market (competitive pricing)
|
|
301
|
+
JPY: 11000 // Japan market (rounded to nearest 100)
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
**Advantages:**
|
|
307
|
+
- Full control over pricing per market
|
|
308
|
+
- Can account for VAT differences
|
|
309
|
+
- Market-specific pricing strategies
|
|
310
|
+
- Psychological pricing (e.g., .99 endings)
|
|
311
|
+
|
|
312
|
+
**Use when:**
|
|
313
|
+
- You have dedicated pricing teams per region
|
|
314
|
+
- Tax/VAT varies significantly
|
|
315
|
+
- Competitive pricing differs by market
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
### Automatic Conversion
|
|
320
|
+
|
|
321
|
+
Use TRANSFORM operators to calculate prices from a base currency:
|
|
322
|
+
|
|
323
|
+
```typescript
|
|
324
|
+
.extract('database', { query: 'SELECT * FROM products' })
|
|
325
|
+
.transform('calculate-fields', {
|
|
326
|
+
calculations: {
|
|
327
|
+
'prices.EUR': 'price * 0.85', // EUR = USD × 0.85
|
|
328
|
+
'prices.GBP': 'price * 0.73', // GBP = USD × 0.73
|
|
329
|
+
'prices.JPY': 'price * 110' // JPY = USD × 110
|
|
330
|
+
}
|
|
331
|
+
})
|
|
332
|
+
.load('import-products', {
|
|
333
|
+
priceByCurrencyField: 'prices'
|
|
334
|
+
})
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Real-time conversion with ENRICH step:**
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
.extract('csv-file', { filePath: '/data/products.csv' })
|
|
341
|
+
.enrich('http-lookup', {
|
|
342
|
+
url: 'https://api.exchangerate.host/latest?base=USD',
|
|
343
|
+
responseField: 'rates',
|
|
344
|
+
targetField: 'exchangeRates'
|
|
345
|
+
})
|
|
346
|
+
.transform('calculate-fields', {
|
|
347
|
+
calculations: {
|
|
348
|
+
'prices.EUR': 'price * exchangeRates.EUR',
|
|
349
|
+
'prices.GBP': 'price * exchangeRates.GBP',
|
|
350
|
+
'prices.JPY': 'price * exchangeRates.JPY'
|
|
351
|
+
}
|
|
352
|
+
})
|
|
353
|
+
.load('import-products', {
|
|
354
|
+
priceByCurrencyField: 'prices'
|
|
355
|
+
})
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**Advantages:**
|
|
359
|
+
- Consistent pricing based on exchange rates
|
|
360
|
+
- Automatic updates when base price changes
|
|
361
|
+
- Less manual work
|
|
362
|
+
|
|
363
|
+
**Disadvantages:**
|
|
364
|
+
- Doesn't account for VAT differences
|
|
365
|
+
- May result in odd prices (e.g., €24.73 instead of €24.99)
|
|
366
|
+
- Ignores market-specific strategies
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Price Update Workflows
|
|
371
|
+
|
|
372
|
+
### Update Prices Only (Don't Touch Product Data)
|
|
373
|
+
|
|
374
|
+
Use `UPDATE` strategy with price fields only:
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
// Pipeline that ONLY updates prices (doesn't modify name, description, etc.)
|
|
378
|
+
.extract('csv-file', { filePath: '/data/price-updates.csv' })
|
|
379
|
+
.load('update-prices', {
|
|
380
|
+
adapterCode: 'productUpsert',
|
|
381
|
+
strategy: 'UPDATE', // ← Only update existing products
|
|
382
|
+
slugField: 'slug',
|
|
383
|
+
priceByCurrencyField: 'newPrices', // ← Only price field configured
|
|
384
|
+
// Intentionally NO nameField, descriptionField, etc.
|
|
385
|
+
})
|
|
386
|
+
|
|
387
|
+
// Input CSV:
|
|
388
|
+
// slug,newPrices
|
|
389
|
+
// basic-tshirt,"{""USD"": 24.99, ""EUR"": 19.99}"
|
|
390
|
+
// premium-hoodie,"{""USD"": 54.99, ""EUR"": 44.99}"
|
|
391
|
+
|
|
392
|
+
// Result:
|
|
393
|
+
// - Prices updated for all currencies
|
|
394
|
+
// - Name, description, facets, assets unchanged ✅
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**How it works:**
|
|
398
|
+
1. `strategy: 'UPDATE'` → only existing products are modified
|
|
399
|
+
2. Only `slugField` and `priceByCurrencyField` configured
|
|
400
|
+
3. ProductHandler only updates configured fields
|
|
401
|
+
4. All other fields (name, description, etc.) remain unchanged
|
|
402
|
+
|
|
403
|
+
**Use cases:**
|
|
404
|
+
- Daily price sync from pricing system
|
|
405
|
+
- Seasonal price adjustments
|
|
406
|
+
- Promotional pricing
|
|
407
|
+
- Currency fluctuation updates
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
### Bulk Price Updates Across Channels
|
|
412
|
+
|
|
413
|
+
Update prices for specific channels only:
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
// Update US channel prices only
|
|
417
|
+
.load('update-us-prices', {
|
|
418
|
+
adapterCode: 'variantUpsert',
|
|
419
|
+
strategy: 'UPDATE',
|
|
420
|
+
channel: 'us-channel', // ← Target specific channel
|
|
421
|
+
skuField: 'sku',
|
|
422
|
+
priceField: 'newPrice' // Single currency for this channel
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
// Input:
|
|
426
|
+
// sku,newPrice
|
|
427
|
+
// TSH-001,34.99
|
|
428
|
+
// JNS-001,69.99
|
|
429
|
+
|
|
430
|
+
// Result: Only US channel prices updated, EU/UK unchanged
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
---
|
|
434
|
+
|
|
435
|
+
### Scheduled Price Changes
|
|
436
|
+
|
|
437
|
+
Combine with SCHEDULE trigger for automatic updates:
|
|
438
|
+
|
|
439
|
+
```typescript
|
|
440
|
+
const pipeline = {
|
|
441
|
+
name: 'Daily Price Sync',
|
|
442
|
+
trigger: {
|
|
443
|
+
type: 'SCHEDULE',
|
|
444
|
+
cron: '0 2 * * *' // 2 AM daily
|
|
445
|
+
},
|
|
446
|
+
steps: [
|
|
447
|
+
{
|
|
448
|
+
type: 'EXTRACT',
|
|
449
|
+
adapterCode: 'databaseExtract',
|
|
450
|
+
config: {
|
|
451
|
+
query: `
|
|
452
|
+
SELECT sku, usd_price, eur_price, gbp_price
|
|
453
|
+
FROM pricing_updates
|
|
454
|
+
WHERE updated_at > NOW() - INTERVAL '1 DAY'
|
|
455
|
+
`
|
|
456
|
+
}
|
|
457
|
+
},
|
|
458
|
+
{
|
|
459
|
+
type: 'TRANSFORM',
|
|
460
|
+
adapterCode: 'mapFields',
|
|
461
|
+
config: {
|
|
462
|
+
mappings: {
|
|
463
|
+
'prices.USD': 'usd_price',
|
|
464
|
+
'prices.EUR': 'eur_price',
|
|
465
|
+
'prices.GBP': 'gbp_price'
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
type: 'LOAD',
|
|
471
|
+
adapterCode: 'variantUpsert',
|
|
472
|
+
config: {
|
|
473
|
+
strategy: 'UPDATE',
|
|
474
|
+
skuField: 'sku',
|
|
475
|
+
priceByCurrencyField: 'prices'
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
]
|
|
479
|
+
};
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## Integration Examples
|
|
485
|
+
|
|
486
|
+
### Example 1: PIM Import with Multi-Currency
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
// Import products from PIM with international pricing
|
|
490
|
+
.extract('rest-api', {
|
|
491
|
+
url: 'https://pim.example.com/api/products',
|
|
492
|
+
auth: { type: 'API_KEY', apiKey: 'secret' }
|
|
493
|
+
})
|
|
494
|
+
.transform('map-fields', {
|
|
495
|
+
mappings: {
|
|
496
|
+
name: 'product_name',
|
|
497
|
+
slug: 'product_slug',
|
|
498
|
+
sku: 'sku_code',
|
|
499
|
+
'prices.USD': 'price_us',
|
|
500
|
+
'prices.EUR': 'price_eu',
|
|
501
|
+
'prices.GBP': 'price_uk',
|
|
502
|
+
'prices.JPY': 'price_jp'
|
|
503
|
+
}
|
|
504
|
+
})
|
|
505
|
+
.load('import-products', {
|
|
506
|
+
adapterCode: 'productUpsert',
|
|
507
|
+
strategy: 'UPSERT',
|
|
508
|
+
priceByCurrencyField: 'prices'
|
|
509
|
+
})
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
**PIM API response:**
|
|
513
|
+
```json
|
|
514
|
+
[
|
|
515
|
+
{
|
|
516
|
+
"product_name": "Wireless Mouse",
|
|
517
|
+
"product_slug": "wireless-mouse",
|
|
518
|
+
"sku_code": "MOUSE-W-001",
|
|
519
|
+
"price_us": 29.99,
|
|
520
|
+
"price_eu": 24.99,
|
|
521
|
+
"price_uk": 21.99,
|
|
522
|
+
"price_jp": 3200
|
|
523
|
+
}
|
|
524
|
+
]
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
---
|
|
528
|
+
|
|
529
|
+
### Example 2: ERP Price Sync
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
// Daily price sync from ERP system
|
|
533
|
+
.extract('database', {
|
|
534
|
+
type: 'MSSQL',
|
|
535
|
+
query: `
|
|
536
|
+
SELECT
|
|
537
|
+
ProductSKU,
|
|
538
|
+
USDPrice,
|
|
539
|
+
EURPrice,
|
|
540
|
+
GBPPrice,
|
|
541
|
+
LastModified
|
|
542
|
+
FROM PricingMaster
|
|
543
|
+
WHERE LastModified >= DATEADD(day, -1, GETDATE())
|
|
544
|
+
`
|
|
545
|
+
})
|
|
546
|
+
.transform('calculate-fields', {
|
|
547
|
+
calculations: {
|
|
548
|
+
'prices.USD': 'USDPrice',
|
|
549
|
+
'prices.EUR': 'EURPrice',
|
|
550
|
+
'prices.GBP': 'GBPPrice'
|
|
551
|
+
}
|
|
552
|
+
})
|
|
553
|
+
.load('sync-prices', {
|
|
554
|
+
adapterCode: 'variantUpsert',
|
|
555
|
+
strategy: 'UPDATE', // Only update existing variants
|
|
556
|
+
skuField: 'ProductSKU',
|
|
557
|
+
priceByCurrencyField: 'prices'
|
|
558
|
+
})
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
### Example 3: Multi-Currency + Multi-Channel
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
// Import with both multi-currency AND multi-channel support
|
|
567
|
+
.extract('csv-file', { filePath: '/data/products.csv' })
|
|
568
|
+
.load('import-products', {
|
|
569
|
+
adapterCode: 'productUpsert',
|
|
570
|
+
nameField: 'name',
|
|
571
|
+
priceByCurrencyField: 'prices', // ← Multi-currency
|
|
572
|
+
channelsField: 'channels', // ← Multi-channel
|
|
573
|
+
translationsField: 'translations' // ← Multi-language
|
|
574
|
+
})
|
|
575
|
+
|
|
576
|
+
// Input data:
|
|
577
|
+
{
|
|
578
|
+
name: 'Global Product',
|
|
579
|
+
prices: {
|
|
580
|
+
USD: 99.99,
|
|
581
|
+
EUR: 84.99,
|
|
582
|
+
GBP: 74.99
|
|
583
|
+
},
|
|
584
|
+
channels: ['us-store', 'eu-store', 'uk-store'],
|
|
585
|
+
translations: [
|
|
586
|
+
{ languageCode: 'en', name: 'Global Product' },
|
|
587
|
+
{ languageCode: 'de', name: 'Globales Produkt' },
|
|
588
|
+
{ languageCode: 'fr', name: 'Produit Mondial' }
|
|
589
|
+
]
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Result:
|
|
593
|
+
// - Available in 3 channels
|
|
594
|
+
// - Correct price per channel's currency
|
|
595
|
+
// - Translated name per channel's language
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## Complete Field Reference
|
|
601
|
+
|
|
602
|
+
### Product Loader
|
|
603
|
+
|
|
604
|
+
| Field | Type | Description |
|
|
605
|
+
|-------|------|-------------|
|
|
606
|
+
| `priceField` | `string \| number` | Single price for variant (converted to channel currency) |
|
|
607
|
+
| `priceByCurrencyField` | `Record<string, number>` | Multi-currency prices `{ USD: 29.99, EUR: 24.99 }` |
|
|
608
|
+
| `nameField` | `string` | Product name |
|
|
609
|
+
| `slugField` | `string` | Product slug (unique identifier) |
|
|
610
|
+
| `skuField` | `string` | Variant SKU |
|
|
611
|
+
| `channelsField` | `string[] \| string` | Array of channel codes |
|
|
612
|
+
| `translationsField` | `Array` | Multi-language translations |
|
|
613
|
+
| `strategy` | `'CREATE' \| 'UPDATE' \| 'UPSERT'` | Load strategy |
|
|
614
|
+
|
|
615
|
+
### Variant Loader
|
|
616
|
+
|
|
617
|
+
| Field | Type | Description |
|
|
618
|
+
|-------|------|-------------|
|
|
619
|
+
| `priceField` | `string \| number` | Single price for variant |
|
|
620
|
+
| `priceByCurrencyField` | `Record<string, number>` | Multi-currency prices |
|
|
621
|
+
| `skuField` | `string` | Variant SKU (unique identifier) |
|
|
622
|
+
| `nameField` | `string` | Variant name |
|
|
623
|
+
| `productSlug` | `string` | Parent product slug (for variant creation) |
|
|
624
|
+
| `channelsField` | `string[] \| string` | Array of channel codes |
|
|
625
|
+
| `strategy` | `'CREATE' \| 'UPDATE' \| 'UPSERT'` | Load strategy |
|
|
626
|
+
|
|
627
|
+
### Channel Loader
|
|
628
|
+
|
|
629
|
+
| Field | Type | Description |
|
|
630
|
+
|-------|------|-------------|
|
|
631
|
+
| `codeField` | `string` | Channel code (unique identifier) |
|
|
632
|
+
| `defaultCurrencyCodeField` | `CurrencyCode` | Primary currency (e.g., 'USD', 'EUR') |
|
|
633
|
+
| `availableCurrencyCodesField` | `CurrencyCode[]` | Supported currencies `['EUR', 'GBP', 'CHF']` |
|
|
634
|
+
| `defaultLanguageCodeField` | `LanguageCode` | Primary language (e.g., 'en', 'de') |
|
|
635
|
+
| `availableLanguageCodesField` | `LanguageCode[]` | Supported languages |
|
|
636
|
+
| `pricesIncludeTaxField` | `boolean` | Whether displayed prices include tax |
|
|
637
|
+
|
|
638
|
+
---
|
|
639
|
+
|
|
640
|
+
## Best Practices
|
|
641
|
+
|
|
642
|
+
### 1. Choose the Right Field
|
|
643
|
+
|
|
644
|
+
```typescript
|
|
645
|
+
// ✅ GOOD: Multi-currency for international stores
|
|
646
|
+
.load('import-products', {
|
|
647
|
+
priceByCurrencyField: 'prices'
|
|
648
|
+
})
|
|
649
|
+
|
|
650
|
+
// ❌ BAD: Single-currency when you have multi-currency data
|
|
651
|
+
.load('import-products', {
|
|
652
|
+
priceField: 'price' // Loses currency-specific pricing!
|
|
653
|
+
})
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
### 2. Always Include All Active Currencies
|
|
657
|
+
|
|
658
|
+
```typescript
|
|
659
|
+
// ✅ GOOD: All channel currencies included
|
|
660
|
+
prices: {
|
|
661
|
+
USD: 99.99,
|
|
662
|
+
EUR: 84.99,
|
|
663
|
+
GBP: 74.99
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
// ❌ BAD: Missing EUR (EU channel gets fallback price)
|
|
667
|
+
prices: {
|
|
668
|
+
USD: 99.99,
|
|
669
|
+
GBP: 74.99
|
|
670
|
+
// EUR missing!
|
|
671
|
+
}
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
### 3. Use UPDATE Strategy for Price-Only Changes
|
|
675
|
+
|
|
676
|
+
```typescript
|
|
677
|
+
// ✅ GOOD: Only price field configured
|
|
678
|
+
.load('update-prices', {
|
|
679
|
+
strategy: 'UPDATE',
|
|
680
|
+
priceByCurrencyField: 'prices'
|
|
681
|
+
// No nameField, descriptionField, etc.
|
|
682
|
+
})
|
|
683
|
+
|
|
684
|
+
// ❌ BAD: UPSERT with all fields (might overwrite manual changes)
|
|
685
|
+
.load('update-prices', {
|
|
686
|
+
strategy: 'UPSERT',
|
|
687
|
+
nameField: 'name',
|
|
688
|
+
descriptionField: 'description',
|
|
689
|
+
priceByCurrencyField: 'prices' // Risk of data loss!
|
|
690
|
+
})
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
### 4. Handle Missing Currencies Gracefully
|
|
694
|
+
|
|
695
|
+
```typescript
|
|
696
|
+
// Validate currency data before loading
|
|
697
|
+
.validate('check-required', {
|
|
698
|
+
rules: [
|
|
699
|
+
{ field: 'prices.USD', required: true },
|
|
700
|
+
{ field: 'prices.EUR', required: true },
|
|
701
|
+
{ field: 'prices.GBP', required: true }
|
|
702
|
+
]
|
|
703
|
+
})
|
|
704
|
+
.load('import-products', {
|
|
705
|
+
priceByCurrencyField: 'prices'
|
|
706
|
+
})
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
### 5. Minor Units Conversion is Automatic
|
|
710
|
+
|
|
711
|
+
```typescript
|
|
712
|
+
// You provide decimal prices
|
|
713
|
+
prices: { USD: 29.99, EUR: 24.99 }
|
|
714
|
+
|
|
715
|
+
// Plugin automatically converts to minor units (cents)
|
|
716
|
+
// USD: 2999, EUR: 2499
|
|
717
|
+
|
|
718
|
+
// ❌ DON'T manually convert
|
|
719
|
+
prices: { USD: 2999, EUR: 2499 } // Will become $29.99 → $2,999.00!
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
### 6. Test with Dry Run
|
|
723
|
+
|
|
724
|
+
```typescript
|
|
725
|
+
// Test multi-currency pricing before production
|
|
726
|
+
const pipeline = {
|
|
727
|
+
name: 'Test Multi-Currency',
|
|
728
|
+
dryRun: true, // ← Simulate without changes
|
|
729
|
+
steps: [
|
|
730
|
+
// ... your steps
|
|
731
|
+
]
|
|
732
|
+
};
|
|
733
|
+
|
|
734
|
+
// Check logs to verify currency prices are correct
|
|
735
|
+
```
|
|
736
|
+
|
|
737
|
+
---
|
|
738
|
+
|
|
739
|
+
## Troubleshooting
|
|
740
|
+
|
|
741
|
+
### Wrong Prices in Specific Channels
|
|
742
|
+
|
|
743
|
+
**Problem**: US channel shows €24.99 instead of $29.99
|
|
744
|
+
|
|
745
|
+
**Solution**: Verify channel currency configuration
|
|
746
|
+
|
|
747
|
+
```typescript
|
|
748
|
+
// Check channel setup
|
|
749
|
+
.load('verify-channels', {
|
|
750
|
+
adapterCode: 'channelUpsert',
|
|
751
|
+
defaultCurrencyCodeField: 'currency'
|
|
752
|
+
})
|
|
753
|
+
|
|
754
|
+
// Ensure it matches your price data
|
|
755
|
+
{ code: 'us-store', currency: 'USD' } // Should be USD, not EUR
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
---
|
|
759
|
+
|
|
760
|
+
### Prices Not Updating
|
|
761
|
+
|
|
762
|
+
**Problem**: Running price sync pipeline but prices unchanged
|
|
763
|
+
|
|
764
|
+
**Solutions:**
|
|
765
|
+
|
|
766
|
+
1. **Wrong strategy**
|
|
767
|
+
```typescript
|
|
768
|
+
// ✅ Use UPDATE to modify existing products
|
|
769
|
+
strategy: 'UPDATE'
|
|
770
|
+
|
|
771
|
+
// ❌ CREATE won't update existing
|
|
772
|
+
strategy: 'CREATE'
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
2. **Wrong identifier field**
|
|
776
|
+
```typescript
|
|
777
|
+
// ✅ Match by slug for products
|
|
778
|
+
slugField: 'product_slug'
|
|
779
|
+
|
|
780
|
+
// ✅ Match by SKU for variants
|
|
781
|
+
skuField: 'variant_sku'
|
|
782
|
+
|
|
783
|
+
// ❌ Missing identifier
|
|
784
|
+
// (neither slugField nor skuField configured)
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
---
|
|
788
|
+
|
|
789
|
+
### Currency Conversion Errors
|
|
790
|
+
|
|
791
|
+
**Problem**: Prices too high/low after import
|
|
792
|
+
|
|
793
|
+
**Solution**: Check decimal vs. minor units
|
|
794
|
+
|
|
795
|
+
```typescript
|
|
796
|
+
// ✅ CORRECT: Provide decimal prices
|
|
797
|
+
{ USD: 29.99, EUR: 24.99 }
|
|
798
|
+
// Plugin converts: 29.99 → 2999 cents
|
|
799
|
+
|
|
800
|
+
// ❌ WRONG: Providing minor units
|
|
801
|
+
{ USD: 2999, EUR: 2499 }
|
|
802
|
+
// Plugin converts: 2999 → 299900 cents ($2,999.00!)
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
---
|
|
806
|
+
|
|
807
|
+
### Missing Currencies
|
|
808
|
+
|
|
809
|
+
**Problem**: Some currencies not appearing in Admin UI
|
|
810
|
+
|
|
811
|
+
**Cause**: Channel doesn't list currency in `availableCurrencyCodes`
|
|
812
|
+
|
|
813
|
+
**Solution**: Update channel configuration
|
|
814
|
+
|
|
815
|
+
```typescript
|
|
816
|
+
.load('add-currency', {
|
|
817
|
+
adapterCode: 'channelUpsert',
|
|
818
|
+
strategy: 'UPDATE',
|
|
819
|
+
codeField: 'code',
|
|
820
|
+
availableCurrencyCodesField: 'currencies'
|
|
821
|
+
})
|
|
822
|
+
|
|
823
|
+
// Input:
|
|
824
|
+
{ code: 'eu-store', currencies: ['EUR', 'GBP', 'CHF'] }
|
|
825
|
+
```
|
|
826
|
+
|
|
827
|
+
---
|
|
828
|
+
|
|
829
|
+
## Summary
|
|
830
|
+
|
|
831
|
+
### Key Concepts
|
|
832
|
+
|
|
833
|
+
1. **Two pricing modes**: `priceField` (single) vs `priceByCurrencyField` (multi)
|
|
834
|
+
2. **Channel configuration**: Channels define available currencies
|
|
835
|
+
3. **Automatic conversion**: Plugin converts decimal → minor units
|
|
836
|
+
4. **Price-only updates**: Use `UPDATE` strategy with only price field
|
|
837
|
+
5. **Works with both loaders**: Product and Variant loaders support both modes
|
|
838
|
+
|
|
839
|
+
### When to Use Each Mode
|
|
840
|
+
|
|
841
|
+
| Scenario | Field to Use | Example |
|
|
842
|
+
|----------|-------------|---------|
|
|
843
|
+
| Single-currency store | `priceField` | US-only store with USD |
|
|
844
|
+
| International store | `priceByCurrencyField` | EU + UK + US with 3 currencies |
|
|
845
|
+
| Price sync only | `priceByCurrencyField` + `strategy: 'UPDATE'` | Daily ERP price updates |
|
|
846
|
+
| Auto conversion | `priceField` + TRANSFORM operators | Calculate from base USD |
|
|
847
|
+
| Manual per market | `priceByCurrencyField` | Different pricing strategies |
|
|
848
|
+
|
|
849
|
+
### Quick Start Template
|
|
850
|
+
|
|
851
|
+
```typescript
|
|
852
|
+
// Complete multi-currency pipeline
|
|
853
|
+
.extract('csv-file', {
|
|
854
|
+
filePath: '/data/international-products.csv'
|
|
855
|
+
})
|
|
856
|
+
.transform('parse-json-fields', {
|
|
857
|
+
fields: 'prices' // Parse JSON string to object
|
|
858
|
+
})
|
|
859
|
+
.load('import-products', {
|
|
860
|
+
adapterCode: 'productUpsert',
|
|
861
|
+
strategy: 'UPSERT',
|
|
862
|
+
nameField: 'name',
|
|
863
|
+
slugField: 'slug',
|
|
864
|
+
skuField: 'sku',
|
|
865
|
+
priceByCurrencyField: 'prices', // ← Multi-currency pricing
|
|
866
|
+
channelsField: 'channels' // ← Multi-channel assignment
|
|
867
|
+
})
|
|
868
|
+
|
|
869
|
+
// CSV format:
|
|
870
|
+
// name,slug,sku,prices,channels
|
|
871
|
+
// "T-Shirt","tshirt","TSH-001","{""USD"": 29.99, ""EUR"": 24.99}","us-store,eu-store"
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
---
|
|
875
|
+
|
|
876
|
+
## Related Guides
|
|
877
|
+
|
|
878
|
+
- [Multi-Channel Guide](./multi-channel.md) - Channel assignment and management
|
|
879
|
+
- [Multi-Language Guide](./multi-language.md) - Translations and language support
|
|
880
|
+
- [Multi-Entity Mode Guide](./multi-entity.md) - Complex nested entity handling
|
|
881
|
+
- [Loader Reference](../reference/loaders.md) - Complete loader field documentation
|