@unchainedshop/core 5.0.0-alpha.1 → 5.0.0-alpha.10
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/README.md +92 -546
- package/lib/bulk-exporter/createBulkExporter.js +1 -1
- package/lib/bulk-exporter/handlers/exportProductsHandler.js +2 -2
- package/lib/bulk-importer/handlers/assortment/create.js +1 -3
- package/lib/bulk-importer/handlers/assortment/update.js +1 -1
- package/lib/bulk-importer/handlers/product/create.d.ts +150 -35
- package/lib/bulk-importer/handlers/product/create.js +35 -16
- package/lib/bulk-importer/handlers/product/update.d.ts +78 -36
- package/lib/bulk-importer/handlers/product/update.js +8 -48
- package/lib/core-index.d.ts +1 -2
- package/lib/core-index.js +2 -18
- package/lib/directors/BaseDiscountAdapter.d.ts +3 -0
- package/lib/directors/BaseDiscountDirector.d.ts +2 -2
- package/lib/directors/BaseDiscountDirector.js +7 -9
- package/lib/directors/BasePricingDirector.d.ts +2 -2
- package/lib/directors/BasePricingDirector.js +3 -6
- package/lib/directors/BaseWorker.js +3 -2
- package/lib/directors/DeliveryDirector.d.ts +1 -1
- package/lib/directors/DeliveryDirector.js +2 -12
- package/lib/directors/DeliveryPricingDirector.js +1 -10
- package/lib/directors/EnrollmentAdapter.js +0 -1
- package/lib/directors/EnrollmentDirector.d.ts +1 -1
- package/lib/directors/EnrollmentDirector.js +3 -15
- package/lib/directors/FileDirector.d.ts +4 -4
- package/lib/directors/FileDirector.js +2 -13
- package/lib/directors/FilterDirector.d.ts +1 -1
- package/lib/directors/FilterDirector.js +25 -32
- package/lib/directors/OrderDiscountDirector.d.ts +1 -15
- package/lib/directors/OrderDiscountDirector.js +1 -13
- package/lib/directors/OrderPricingDirector.js +1 -10
- package/lib/directors/OrderPricingSheet.d.ts +1 -0
- package/lib/directors/OrderPricingSheet.js +17 -17
- package/lib/directors/PaymentDirector.d.ts +1 -1
- package/lib/directors/PaymentDirector.js +2 -12
- package/lib/directors/PaymentPricingDirector.js +1 -10
- package/lib/directors/ProductDiscountDirector.d.ts +1 -15
- package/lib/directors/ProductDiscountDirector.js +1 -13
- package/lib/directors/ProductPricingDirector.js +1 -10
- package/lib/directors/QuotationDirector.d.ts +1 -1
- package/lib/directors/QuotationDirector.js +2 -14
- package/lib/directors/WarehousingDirector.js +16 -34
- package/lib/directors/WorkerDirector.d.ts +7 -1
- package/lib/directors/WorkerDirector.js +29 -29
- package/lib/directors/registryDirector.d.ts +2 -0
- package/lib/directors/registryDirector.js +6 -0
- package/lib/errors.d.ts +1 -0
- package/lib/errors.js +5 -0
- package/lib/factory/index.d.ts +12 -1
- package/lib/factory/index.js +12 -1
- package/lib/factory/registerAssortmentSearchFilter.d.ts +2 -1
- package/lib/factory/registerAssortmentSearchFilter.js +6 -3
- package/lib/factory/registerDeliveryPricing.d.ts +7 -0
- package/lib/factory/registerDeliveryPricing.js +30 -0
- package/lib/factory/registerDeliveryProvider.d.ts +12 -0
- package/lib/factory/registerDeliveryProvider.js +46 -0
- package/lib/factory/registerEnrollment.d.ts +18 -0
- package/lib/factory/registerEnrollment.js +43 -0
- package/lib/factory/registerFileAdapter.d.ts +17 -0
- package/lib/factory/registerFileAdapter.js +24 -0
- package/lib/factory/registerOrderDiscount.d.ts +13 -0
- package/lib/factory/registerOrderDiscount.js +39 -0
- package/lib/factory/registerOrderPricing.d.ts +7 -0
- package/lib/factory/registerOrderPricing.js +30 -0
- package/lib/factory/registerPaymentPricing.d.ts +7 -0
- package/lib/factory/registerPaymentPricing.js +30 -0
- package/lib/factory/registerPaymentProvider.d.ts +15 -0
- package/lib/factory/registerPaymentProvider.js +53 -0
- package/lib/factory/registerProductDiscount.d.ts +20 -0
- package/lib/factory/registerProductDiscount.js +47 -0
- package/lib/factory/registerProductDiscoverabilityFilter.d.ts +2 -1
- package/lib/factory/registerProductDiscoverabilityFilter.js +6 -3
- package/lib/factory/registerProductPricing.d.ts +7 -0
- package/lib/factory/registerProductPricing.js +30 -0
- package/lib/factory/registerProductSearchFilter.d.ts +2 -1
- package/lib/factory/registerProductSearchFilter.js +4 -3
- package/lib/factory/registerQuotation.d.ts +12 -0
- package/lib/factory/registerQuotation.js +52 -0
- package/lib/factory/registerVirtualWarehousing.js +1 -1
- package/lib/factory/registerWorker.js +1 -1
- package/lib/plugins/PluginRegistry.d.ts +1 -0
- package/lib/plugins/PluginRegistry.js +11 -2
- package/lib/services/addMultipleCartProducts.js +3 -2
- package/lib/services/bulkAssignProductsToAssortment.d.ts +8 -0
- package/lib/services/bulkAssignProductsToAssortment.js +11 -0
- package/lib/services/bulkDeleteUsers.d.ts +7 -0
- package/lib/services/bulkDeleteUsers.js +11 -0
- package/lib/services/bulkRemoveFilters.d.ts +7 -0
- package/lib/services/bulkRemoveFilters.js +10 -0
- package/lib/services/bulkRemoveProducts.d.ts +7 -0
- package/lib/services/bulkRemoveProducts.js +23 -0
- package/lib/services/bulkSetFilterActive.d.ts +8 -0
- package/lib/services/bulkSetFilterActive.js +12 -0
- package/lib/services/checkoutOrder.js +4 -0
- package/lib/services/createFilter.d.ts +3 -0
- package/lib/services/createFilter.js +6 -0
- package/lib/services/createFilterOption.d.ts +5 -0
- package/lib/services/createFilterOption.js +8 -0
- package/lib/services/createSignedURL.js +2 -1
- package/lib/services/deleteCart.d.ts +2 -0
- package/lib/services/deleteCart.js +7 -0
- package/lib/services/deleteDeadCarts.d.ts +2 -0
- package/lib/services/deleteDeadCarts.js +17 -0
- package/lib/services/deleteUser.js +2 -5
- package/lib/services/index.d.ts +24 -1
- package/lib/services/index.js +24 -1
- package/lib/services/initCartProviders.js +1 -0
- package/lib/services/isTokenInvalidateable.d.ts +3 -1
- package/lib/services/isTokenInvalidateable.js +2 -2
- package/lib/services/loadFilterOptions.js +3 -3
- package/lib/services/processEnrollment.js +2 -1
- package/lib/services/processOrder.js +3 -2
- package/lib/services/processQuotation.js +11 -13
- package/lib/services/proposeQuotation.js +3 -0
- package/lib/services/removeFilterOption.d.ts +6 -0
- package/lib/services/removeFilterOption.js +8 -0
- package/lib/services/removeProduct.js +2 -1
- package/lib/services/reserveOrderDiscountsForCheckout.d.ts +5 -0
- package/lib/services/reserveOrderDiscountsForCheckout.js +34 -0
- package/lib/services/simulateProductDispatching.d.ts +3 -1
- package/lib/services/simulateProductDispatching.js +3 -3
- package/lib/services/simulateProductInventory.d.ts +3 -1
- package/lib/services/simulateProductInventory.js +3 -3
- package/lib/services/supportedDeliveryProviders.js +9 -0
- package/lib/services/supportedPaymentProviders.js +9 -0
- package/lib/services/supportedWarehousingProviders.js +9 -0
- package/lib/services/updateCalculation.js +2 -1
- package/lib/services/updateFilter.d.ts +3 -0
- package/lib/services/updateFilter.js +8 -0
- package/lib/services/uploadFileFromStream.js +2 -1
- package/lib/services/validateOrder.js +7 -8
- package/package.json +29 -23
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { OrderDiscountAdapter, } from "../core-index.js";
|
|
2
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
+
export default function registerOrderDiscount({ adapterId, isValidForSystemTriggering, isValidForCodeTriggering, discountForPricingAdapterKey, reserve, release, }) {
|
|
4
|
+
const adapter = {
|
|
5
|
+
...OrderDiscountAdapter,
|
|
6
|
+
key: `shop.unchained.discount.order-${adapterId}`,
|
|
7
|
+
label: 'Order Discount: ' + adapterId,
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
actions: async ({ context }) => {
|
|
10
|
+
return {
|
|
11
|
+
...(await OrderDiscountAdapter.actions({ context })),
|
|
12
|
+
isValidForSystemTriggering: async () => {
|
|
13
|
+
return isValidForSystemTriggering ? isValidForSystemTriggering(context) : false;
|
|
14
|
+
},
|
|
15
|
+
isValidForCodeTriggering: async ({ code }) => {
|
|
16
|
+
return isValidForCodeTriggering ? isValidForCodeTriggering(code, context) : false;
|
|
17
|
+
},
|
|
18
|
+
discountForPricingAdapterKey: (params) => {
|
|
19
|
+
return discountForPricingAdapterKey(params, context);
|
|
20
|
+
},
|
|
21
|
+
reserve: async ({ code }) => {
|
|
22
|
+
return reserve ? reserve(code, context) : {};
|
|
23
|
+
},
|
|
24
|
+
release: async () => {
|
|
25
|
+
if (release)
|
|
26
|
+
await release(context);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
const plugin = {
|
|
32
|
+
key: adapter.key,
|
|
33
|
+
label: adapter.label,
|
|
34
|
+
version: adapter.version,
|
|
35
|
+
adapters: [adapter],
|
|
36
|
+
};
|
|
37
|
+
pluginRegistry.register(plugin);
|
|
38
|
+
return plugin;
|
|
39
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type IPlugin, type IOrderPricingSheet, type OrderPricingAdapterContext } from '../core-index.ts';
|
|
2
|
+
export default function registerOrderPricing({ adapterId, orderIndex, isActivatedFor, calculate, }: {
|
|
3
|
+
adapterId: string;
|
|
4
|
+
orderIndex?: number;
|
|
5
|
+
isActivatedFor?: (context: OrderPricingAdapterContext) => boolean;
|
|
6
|
+
calculate: (sheet: IOrderPricingSheet, context: OrderPricingAdapterContext) => Promise<void>;
|
|
7
|
+
}): IPlugin;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { OrderPricingAdapter, } from "../core-index.js";
|
|
2
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
+
export default function registerOrderPricing({ adapterId, orderIndex, isActivatedFor, calculate, }) {
|
|
4
|
+
const adapter = {
|
|
5
|
+
...OrderPricingAdapter,
|
|
6
|
+
key: `shop.unchained.pricing.order-${adapterId}`,
|
|
7
|
+
label: 'Order Pricing: ' + adapterId,
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
orderIndex: orderIndex ?? 0,
|
|
10
|
+
isActivatedFor: (context) => (isActivatedFor ? isActivatedFor(context) : true),
|
|
11
|
+
actions: (params) => {
|
|
12
|
+
const pricingAdapter = OrderPricingAdapter.actions(params);
|
|
13
|
+
return {
|
|
14
|
+
...pricingAdapter,
|
|
15
|
+
calculate: async () => {
|
|
16
|
+
await calculate(pricingAdapter.resultSheet(), params.context);
|
|
17
|
+
return pricingAdapter.calculate();
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const plugin = {
|
|
23
|
+
key: adapter.key,
|
|
24
|
+
label: adapter.label,
|
|
25
|
+
version: adapter.version,
|
|
26
|
+
adapters: [adapter],
|
|
27
|
+
};
|
|
28
|
+
pluginRegistry.register(plugin);
|
|
29
|
+
return plugin;
|
|
30
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type IPlugin, type IPaymentPricingSheet, type PaymentPricingAdapterContext } from '../core-index.ts';
|
|
2
|
+
export default function registerPaymentPricing({ adapterId, orderIndex, isActivatedFor, calculate, }: {
|
|
3
|
+
adapterId: string;
|
|
4
|
+
orderIndex?: number;
|
|
5
|
+
isActivatedFor?: (context: PaymentPricingAdapterContext) => boolean;
|
|
6
|
+
calculate: (sheet: IPaymentPricingSheet, context: PaymentPricingAdapterContext) => Promise<void>;
|
|
7
|
+
}): IPlugin;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PaymentPricingAdapter, } from "../core-index.js";
|
|
2
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
+
export default function registerPaymentPricing({ adapterId, orderIndex, isActivatedFor, calculate, }) {
|
|
4
|
+
const adapter = {
|
|
5
|
+
...PaymentPricingAdapter,
|
|
6
|
+
key: `shop.unchained.pricing.payment-${adapterId}`,
|
|
7
|
+
label: 'Payment Pricing: ' + adapterId,
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
orderIndex: orderIndex ?? 0,
|
|
10
|
+
isActivatedFor: (context) => (isActivatedFor ? isActivatedFor(context) : true),
|
|
11
|
+
actions: (params) => {
|
|
12
|
+
const pricingAdapter = PaymentPricingAdapter.actions(params);
|
|
13
|
+
return {
|
|
14
|
+
...pricingAdapter,
|
|
15
|
+
calculate: async () => {
|
|
16
|
+
await calculate(pricingAdapter.resultSheet(), params.context);
|
|
17
|
+
return pricingAdapter.calculate();
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const plugin = {
|
|
23
|
+
key: adapter.key,
|
|
24
|
+
label: adapter.label,
|
|
25
|
+
version: adapter.version,
|
|
26
|
+
adapters: [adapter],
|
|
27
|
+
};
|
|
28
|
+
pluginRegistry.register(plugin);
|
|
29
|
+
return plugin;
|
|
30
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PaymentConfiguration } from '@unchainedshop/core-payment';
|
|
2
|
+
import { PaymentProviderType } from '@unchainedshop/core-payment';
|
|
3
|
+
import { type PaymentContext, type PaymentChargeActionResult, type PaymentError, type IPlugin } from '../core-index.ts';
|
|
4
|
+
export default function registerPaymentProvider({ adapterId, type, charge, sign, validate, isActive, isPayLaterAllowed, configurationError, cancel, confirm, }: {
|
|
5
|
+
adapterId: string;
|
|
6
|
+
type?: PaymentProviderType;
|
|
7
|
+
charge: false | ((configuration: PaymentConfiguration, context: PaymentContext) => Promise<PaymentChargeActionResult | false>);
|
|
8
|
+
sign?: (configuration: PaymentConfiguration, context: PaymentContext) => Promise<string | null>;
|
|
9
|
+
validate?: (configuration: PaymentConfiguration, context: PaymentContext) => Promise<boolean>;
|
|
10
|
+
isActive?: boolean;
|
|
11
|
+
isPayLaterAllowed?: boolean;
|
|
12
|
+
configurationError?: PaymentError | null;
|
|
13
|
+
cancel?: (configuration: PaymentConfiguration, context: PaymentContext) => Promise<boolean>;
|
|
14
|
+
confirm?: (configuration: PaymentConfiguration, context: PaymentContext) => Promise<boolean>;
|
|
15
|
+
}): IPlugin;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { PaymentProviderType } from '@unchainedshop/core-payment';
|
|
2
|
+
import { PaymentAdapter, } from "../core-index.js";
|
|
3
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
4
|
+
export default function registerPaymentProvider({ adapterId, type, charge, sign, validate, isActive, isPayLaterAllowed, configurationError, cancel, confirm, }) {
|
|
5
|
+
const providerType = type ?? PaymentProviderType.GENERIC;
|
|
6
|
+
const adapter = {
|
|
7
|
+
...PaymentAdapter,
|
|
8
|
+
key: `shop.unchained.payment.${adapterId}`,
|
|
9
|
+
label: 'Payment: ' + adapterId,
|
|
10
|
+
version: '1.0.0',
|
|
11
|
+
initialConfiguration: [],
|
|
12
|
+
typeSupported: (t) => {
|
|
13
|
+
return t === providerType;
|
|
14
|
+
},
|
|
15
|
+
actions: (config, context) => {
|
|
16
|
+
return {
|
|
17
|
+
...PaymentAdapter.actions(config, context),
|
|
18
|
+
isActive: () => {
|
|
19
|
+
return isActive ?? true;
|
|
20
|
+
},
|
|
21
|
+
isPayLaterAllowed: () => {
|
|
22
|
+
return isPayLaterAllowed ?? false;
|
|
23
|
+
},
|
|
24
|
+
configurationError: () => {
|
|
25
|
+
return configurationError ?? null;
|
|
26
|
+
},
|
|
27
|
+
sign: async () => {
|
|
28
|
+
return sign ? sign(config, context) : null;
|
|
29
|
+
},
|
|
30
|
+
validate: async () => {
|
|
31
|
+
return validate ? validate(config, context) : false;
|
|
32
|
+
},
|
|
33
|
+
cancel: async () => {
|
|
34
|
+
return cancel ? cancel(config, context) : false;
|
|
35
|
+
},
|
|
36
|
+
confirm: async () => {
|
|
37
|
+
return confirm ? confirm(config, context) : false;
|
|
38
|
+
},
|
|
39
|
+
charge: async () => {
|
|
40
|
+
return typeof charge === 'function' ? await charge(config, context) : charge;
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
const plugin = {
|
|
46
|
+
key: adapter.key,
|
|
47
|
+
label: adapter.label,
|
|
48
|
+
version: adapter.version,
|
|
49
|
+
adapters: [adapter],
|
|
50
|
+
};
|
|
51
|
+
pluginRegistry.register(plugin);
|
|
52
|
+
return plugin;
|
|
53
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type IPlugin, type IPricingSheet, type ProductDiscountConfiguration } from '../core-index.ts';
|
|
2
|
+
import type { PricingCalculation } from '@unchainedshop/utils';
|
|
3
|
+
export default function registerProductDiscount({ adapterId, orderIndex, isManualAdditionAllowed, isManualRemovalAllowed, isValidForSystemTriggering, isValidForCodeTriggering, discountForPricingAdapterKey, reserve, release, }: {
|
|
4
|
+
adapterId: string;
|
|
5
|
+
orderIndex?: number;
|
|
6
|
+
isManualAdditionAllowed?: (code?: string) => Promise<boolean>;
|
|
7
|
+
isManualRemovalAllowed?: () => Promise<boolean>;
|
|
8
|
+
isValidForSystemTriggering?: () => Promise<boolean>;
|
|
9
|
+
isValidForCodeTriggering?: (params: {
|
|
10
|
+
code: string;
|
|
11
|
+
}) => Promise<boolean>;
|
|
12
|
+
discountForPricingAdapterKey: (params: {
|
|
13
|
+
pricingAdapterKey: string;
|
|
14
|
+
calculationSheet: IPricingSheet<PricingCalculation>;
|
|
15
|
+
}) => ProductDiscountConfiguration | null;
|
|
16
|
+
reserve?: (params: {
|
|
17
|
+
code?: string;
|
|
18
|
+
}) => Promise<any>;
|
|
19
|
+
release?: () => Promise<void>;
|
|
20
|
+
}): IPlugin;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ProductDiscountAdapter, } from "../core-index.js";
|
|
2
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
+
export default function registerProductDiscount({ adapterId, orderIndex, isManualAdditionAllowed, isManualRemovalAllowed, isValidForSystemTriggering, isValidForCodeTriggering, discountForPricingAdapterKey, reserve, release, }) {
|
|
4
|
+
const adapter = {
|
|
5
|
+
...ProductDiscountAdapter,
|
|
6
|
+
key: `shop.unchained.discount.product-${adapterId}`,
|
|
7
|
+
label: 'Product Discount: ' + adapterId,
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
orderIndex: orderIndex ?? 0,
|
|
10
|
+
isManualAdditionAllowed: async (code) => {
|
|
11
|
+
return isManualAdditionAllowed
|
|
12
|
+
? isManualAdditionAllowed(code)
|
|
13
|
+
: ProductDiscountAdapter.isManualAdditionAllowed(code);
|
|
14
|
+
},
|
|
15
|
+
isManualRemovalAllowed: async () => {
|
|
16
|
+
return isManualRemovalAllowed
|
|
17
|
+
? isManualRemovalAllowed()
|
|
18
|
+
: ProductDiscountAdapter.isManualRemovalAllowed();
|
|
19
|
+
},
|
|
20
|
+
actions: async (params) => {
|
|
21
|
+
return {
|
|
22
|
+
...(await ProductDiscountAdapter.actions(params)),
|
|
23
|
+
isValidForSystemTriggering: async () => {
|
|
24
|
+
return isValidForSystemTriggering ? isValidForSystemTriggering() : false;
|
|
25
|
+
},
|
|
26
|
+
isValidForCodeTriggering: async ({ code }) => {
|
|
27
|
+
return isValidForCodeTriggering ? isValidForCodeTriggering({ code }) : false;
|
|
28
|
+
},
|
|
29
|
+
discountForPricingAdapterKey,
|
|
30
|
+
reserve: async ({ code }) => {
|
|
31
|
+
return reserve ? reserve({ code }) : {};
|
|
32
|
+
},
|
|
33
|
+
release: async () => {
|
|
34
|
+
return release ? release() : undefined;
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
const plugin = {
|
|
40
|
+
key: adapter.key,
|
|
41
|
+
label: adapter.label,
|
|
42
|
+
version: adapter.version,
|
|
43
|
+
adapters: [adapter],
|
|
44
|
+
};
|
|
45
|
+
pluginRegistry.register(plugin);
|
|
46
|
+
return plugin;
|
|
47
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type IPlugin } from '../core-index.ts';
|
|
2
|
-
export default function registerProductDiscoverabilityFilter({ orderIndex, hiddenTagValue, }: {
|
|
2
|
+
export default function registerProductDiscoverabilityFilter({ adapterId, orderIndex, hiddenTagValue, }: {
|
|
3
|
+
adapterId?: string;
|
|
3
4
|
orderIndex?: number;
|
|
4
5
|
hiddenTagValue?: string;
|
|
5
6
|
}): IPlugin;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { FilterAdapter } from "../core-index.js";
|
|
2
2
|
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
-
export default function registerProductDiscoverabilityFilter({ orderIndex = 0, hiddenTagValue = 'hidden', }) {
|
|
3
|
+
export default function registerProductDiscoverabilityFilter({ adapterId, orderIndex = 0, hiddenTagValue = 'hidden', }) {
|
|
4
|
+
const id = adapterId ?? crypto.randomUUID();
|
|
4
5
|
const adapter = {
|
|
5
6
|
...FilterAdapter,
|
|
6
|
-
key: `shop.unchained.filters.product-discoverability-${
|
|
7
|
-
label:
|
|
7
|
+
key: `shop.unchained.filters.product-discoverability-${id}`,
|
|
8
|
+
label: adapterId
|
|
9
|
+
? `Product Discoverability Filter: ${adapterId}`
|
|
10
|
+
: 'Product Discoverability Filter (auto-generated)',
|
|
8
11
|
version: '1.0.0',
|
|
9
12
|
orderIndex,
|
|
10
13
|
actions: (params) => {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type IPlugin, type IProductPricingSheet, type ProductPricingAdapterContext } from '../core-index.ts';
|
|
2
|
+
export default function registerProductPricing({ adapterId, orderIndex, isActivatedFor, calculate, }: {
|
|
3
|
+
adapterId: string;
|
|
4
|
+
orderIndex?: number;
|
|
5
|
+
isActivatedFor?: (context: ProductPricingAdapterContext) => boolean;
|
|
6
|
+
calculate: (sheet: IProductPricingSheet, context: ProductPricingAdapterContext) => Promise<void>;
|
|
7
|
+
}): IPlugin;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ProductPricingAdapter, } from "../core-index.js";
|
|
2
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
+
export default function registerProductPricing({ adapterId, orderIndex, isActivatedFor, calculate, }) {
|
|
4
|
+
const adapter = {
|
|
5
|
+
...ProductPricingAdapter,
|
|
6
|
+
key: `shop.unchained.pricing.product-${adapterId}`,
|
|
7
|
+
label: 'Product Pricing: ' + adapterId,
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
orderIndex: orderIndex ?? 0,
|
|
10
|
+
isActivatedFor: (context) => (isActivatedFor ? isActivatedFor(context) : true),
|
|
11
|
+
actions: (params) => {
|
|
12
|
+
const pricingAdapter = ProductPricingAdapter.actions(params);
|
|
13
|
+
return {
|
|
14
|
+
...pricingAdapter,
|
|
15
|
+
calculate: async () => {
|
|
16
|
+
await calculate(pricingAdapter.resultSheet(), params.context);
|
|
17
|
+
return pricingAdapter.calculate();
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
const plugin = {
|
|
23
|
+
key: adapter.key,
|
|
24
|
+
label: adapter.label,
|
|
25
|
+
version: adapter.version,
|
|
26
|
+
adapters: [adapter],
|
|
27
|
+
};
|
|
28
|
+
pluginRegistry.register(plugin);
|
|
29
|
+
return plugin;
|
|
30
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { SearchQuery } from '@unchainedshop/core-filters';
|
|
2
2
|
import { type IPlugin } from '../core-index.ts';
|
|
3
|
-
export default function registerProductSearchFilter({ orderIndex, search, }: {
|
|
3
|
+
export default function registerProductSearchFilter({ adapterId, orderIndex, search, }: {
|
|
4
|
+
adapterId?: string;
|
|
4
5
|
orderIndex?: number;
|
|
5
6
|
search: (params: SearchQuery & {
|
|
6
7
|
queryString: string;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { FilterAdapter } from "../core-index.js";
|
|
2
2
|
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
-
export default function registerProductSearchFilter({ orderIndex = 0, search, }) {
|
|
3
|
+
export default function registerProductSearchFilter({ adapterId, orderIndex = 0, search, }) {
|
|
4
|
+
const id = adapterId ?? crypto.randomUUID();
|
|
4
5
|
const adapter = {
|
|
5
6
|
...FilterAdapter,
|
|
6
|
-
key: `shop.unchained.filters.product-search-${
|
|
7
|
-
label: 'Product Search Filter (auto-generated)',
|
|
7
|
+
key: `shop.unchained.filters.product-search-${id}`,
|
|
8
|
+
label: adapterId ? `Product Search Filter: ${adapterId}` : 'Product Search Filter (auto-generated)',
|
|
8
9
|
version: '1.0.0',
|
|
9
10
|
orderIndex,
|
|
10
11
|
actions: (params) => {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { QuotationItemConfiguration, QuotationProposal } from '@unchainedshop/core-quotations';
|
|
2
|
+
import { type QuotationContext, type IPlugin } from '../core-index.ts';
|
|
3
|
+
export default function registerQuotation({ adapterId, isManualRequestVerificationRequired, isManualProposalRequired, quote, submitRequest, verifyRequest, rejectRequest, transformItemConfiguration, }: {
|
|
4
|
+
adapterId: string;
|
|
5
|
+
isManualRequestVerificationRequired?: boolean;
|
|
6
|
+
isManualProposalRequired?: boolean;
|
|
7
|
+
quote?: (context: QuotationContext) => Promise<QuotationProposal>;
|
|
8
|
+
submitRequest?: (context: QuotationContext) => Promise<boolean>;
|
|
9
|
+
verifyRequest?: (context: QuotationContext) => Promise<boolean>;
|
|
10
|
+
rejectRequest?: (context: QuotationContext) => Promise<boolean>;
|
|
11
|
+
transformItemConfiguration?: (params: QuotationItemConfiguration, context: QuotationContext) => Promise<QuotationItemConfiguration | null>;
|
|
12
|
+
}): IPlugin;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { QuotationAdapter, } from "../core-index.js";
|
|
2
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
3
|
+
export default function registerQuotation({ adapterId, isManualRequestVerificationRequired, isManualProposalRequired, quote, submitRequest, verifyRequest, rejectRequest, transformItemConfiguration, }) {
|
|
4
|
+
const adapter = {
|
|
5
|
+
...QuotationAdapter,
|
|
6
|
+
key: `shop.unchained.quotation.${adapterId}`,
|
|
7
|
+
label: 'Quotation: ' + adapterId,
|
|
8
|
+
version: '1.0.0',
|
|
9
|
+
isActivatedFor: () => {
|
|
10
|
+
return true;
|
|
11
|
+
},
|
|
12
|
+
actions: (context) => {
|
|
13
|
+
return {
|
|
14
|
+
...QuotationAdapter.actions(context),
|
|
15
|
+
configurationError: () => {
|
|
16
|
+
return null;
|
|
17
|
+
},
|
|
18
|
+
isManualRequestVerificationRequired: async () => {
|
|
19
|
+
return isManualRequestVerificationRequired ?? true;
|
|
20
|
+
},
|
|
21
|
+
isManualProposalRequired: async () => {
|
|
22
|
+
return isManualProposalRequired ?? true;
|
|
23
|
+
},
|
|
24
|
+
quote: async () => {
|
|
25
|
+
return quote ? quote(context) : {};
|
|
26
|
+
},
|
|
27
|
+
submitRequest: async () => {
|
|
28
|
+
return submitRequest ? submitRequest(context) : true;
|
|
29
|
+
},
|
|
30
|
+
verifyRequest: async () => {
|
|
31
|
+
return verifyRequest ? verifyRequest(context) : true;
|
|
32
|
+
},
|
|
33
|
+
rejectRequest: async () => {
|
|
34
|
+
return rejectRequest ? rejectRequest(context) : true;
|
|
35
|
+
},
|
|
36
|
+
transformItemConfiguration: async (params) => {
|
|
37
|
+
return transformItemConfiguration
|
|
38
|
+
? transformItemConfiguration(params, context)
|
|
39
|
+
: { quantity: params.quantity, configuration: params.configuration };
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
const plugin = {
|
|
45
|
+
key: adapter.key,
|
|
46
|
+
label: adapter.label,
|
|
47
|
+
version: adapter.version,
|
|
48
|
+
adapters: [adapter],
|
|
49
|
+
};
|
|
50
|
+
pluginRegistry.register(plugin);
|
|
51
|
+
return plugin;
|
|
52
|
+
}
|
|
@@ -5,7 +5,7 @@ export default function registerVirtualWarehousing({ adapterId, orderIndex = 0,
|
|
|
5
5
|
const adapter = {
|
|
6
6
|
...WarehousingAdapter,
|
|
7
7
|
key: 'shop.unchained.warehousing.virtual.' + adapterId,
|
|
8
|
-
label: 'Virtual
|
|
8
|
+
label: 'Virtual Warehousing: ' + adapterId,
|
|
9
9
|
version: '1.0.0',
|
|
10
10
|
orderIndex,
|
|
11
11
|
initialConfiguration: [{ key: 'shipping-hub', value: 'Shipping Hub' }],
|
|
@@ -5,7 +5,7 @@ export default function registerWorker({ type, external, maxParallelAllocations,
|
|
|
5
5
|
...WorkerAdapter,
|
|
6
6
|
key: 'shop.unchained.worker.' + type.toLowerCase(),
|
|
7
7
|
label: 'Worker: ' + type,
|
|
8
|
-
version: '1.0',
|
|
8
|
+
version: '1.0.0',
|
|
9
9
|
external: external ?? false,
|
|
10
10
|
maxParallelAllocations,
|
|
11
11
|
type,
|
|
@@ -5,9 +5,11 @@ class PluginRegistry {
|
|
|
5
5
|
moduleFactories = [];
|
|
6
6
|
skippedPlugins = new Set();
|
|
7
7
|
register(plugin) {
|
|
8
|
-
|
|
8
|
+
const registered = this.plugins.get(plugin.key);
|
|
9
|
+
if (registered) {
|
|
9
10
|
logger.warn(`Plugin ${plugin.key} already registered, skipping`, {
|
|
10
11
|
label: plugin.label,
|
|
12
|
+
registeredLabel: registered.label,
|
|
11
13
|
});
|
|
12
14
|
return;
|
|
13
15
|
}
|
|
@@ -93,13 +95,20 @@ class PluginRegistry {
|
|
|
93
95
|
for (const plugin of this.plugins.values()) {
|
|
94
96
|
if (!plugin.adapters)
|
|
95
97
|
continue;
|
|
98
|
+
if (this.skippedPlugins.has(plugin.key))
|
|
99
|
+
continue;
|
|
96
100
|
for (const adapter of plugin.adapters) {
|
|
97
101
|
if (adapter.adapterType === adapterType) {
|
|
98
102
|
result.push(adapter);
|
|
99
103
|
}
|
|
100
104
|
}
|
|
101
105
|
}
|
|
102
|
-
return result;
|
|
106
|
+
return result.toSorted((left, right) => (left.orderIndex ?? 0) - (right.orderIndex ?? 0));
|
|
107
|
+
}
|
|
108
|
+
getAllAdapters() {
|
|
109
|
+
return this.getAllPlugins()
|
|
110
|
+
.filter((plugin) => !this.skippedPlugins.has(plugin.key))
|
|
111
|
+
.flatMap((plugin) => plugin.adapters ?? []);
|
|
103
112
|
}
|
|
104
113
|
hasPlugin(key) {
|
|
105
114
|
return this.plugins.has(key);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ordersSettings } from '@unchainedshop/core-orders';
|
|
2
|
+
import { createServiceError } from "../errors.js";
|
|
2
3
|
export async function addMultipleCartProductsService({ orderId, items, context, }) {
|
|
3
4
|
const order = await this.orders.findOrder({ orderId });
|
|
4
5
|
if (!order)
|
|
@@ -6,10 +7,10 @@ export async function addMultipleCartProductsService({ orderId, items, context,
|
|
|
6
7
|
for (const { productId, quantity, configuration } of items) {
|
|
7
8
|
const originalProduct = await this.products.findProduct({ productId });
|
|
8
9
|
if (!originalProduct) {
|
|
9
|
-
throw
|
|
10
|
+
throw createServiceError('ProductNotFoundError', `Product not found: ${productId}`);
|
|
10
11
|
}
|
|
11
12
|
if (quantity < 1) {
|
|
12
|
-
throw
|
|
13
|
+
throw createServiceError('InvalidQuantityError', `Invalid quantity for product: ${productId}`);
|
|
13
14
|
}
|
|
14
15
|
const product = await this.products.resolveOrderableProduct(originalProduct, { configuration });
|
|
15
16
|
await ordersSettings.validateOrderPosition({ order, product, configuration, quantityDiff: quantity }, { modules: this, ...context });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Modules } from '../modules.ts';
|
|
2
|
+
export declare function bulkAssignProductsToAssortmentService(this: Modules, { assortmentId, productIds }: {
|
|
3
|
+
assortmentId: string;
|
|
4
|
+
productIds: string[];
|
|
5
|
+
}): Promise<{
|
|
6
|
+
successIds: string[];
|
|
7
|
+
failedIds: string[];
|
|
8
|
+
}>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { executeBulkOperation } from '@unchainedshop/utils';
|
|
2
|
+
export async function bulkAssignProductsToAssortmentService({ assortmentId, productIds }) {
|
|
3
|
+
const result = await executeBulkOperation(productIds, async (productId) => {
|
|
4
|
+
if (!(await this.products.productExists({ productId })))
|
|
5
|
+
throw new Error('not-found');
|
|
6
|
+
const assignment = await this.assortments.products.create({ assortmentId, productId });
|
|
7
|
+
if (!assignment)
|
|
8
|
+
throw new Error('create-failed');
|
|
9
|
+
});
|
|
10
|
+
return result;
|
|
11
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { executeBulkOperation } from '@unchainedshop/utils';
|
|
2
|
+
import { deleteUserService } from "./deleteUser.js";
|
|
3
|
+
export async function bulkDeleteUsersService({ userIds }) {
|
|
4
|
+
return executeBulkOperation(userIds, async (userId) => {
|
|
5
|
+
if (!(await this.users.userExists({ userId })))
|
|
6
|
+
throw new Error('not-found');
|
|
7
|
+
const result = await deleteUserService.call(this, { userId });
|
|
8
|
+
if (!result)
|
|
9
|
+
throw new Error('delete-failed');
|
|
10
|
+
});
|
|
11
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { executeBulkOperation } from '@unchainedshop/utils';
|
|
2
|
+
import { removeFilterService } from "./removeFilter.js";
|
|
3
|
+
export async function bulkRemoveFiltersService({ filterIds }) {
|
|
4
|
+
return executeBulkOperation(filterIds, async (filterId) => {
|
|
5
|
+
const filter = await this.filters.findFilter({ filterId });
|
|
6
|
+
if (!filter)
|
|
7
|
+
throw new Error('not-found');
|
|
8
|
+
await removeFilterService.call(this, { filter });
|
|
9
|
+
});
|
|
10
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { executeBulkOperation } from '@unchainedshop/utils';
|
|
2
|
+
import { removeProductService } from "./removeProduct.js";
|
|
3
|
+
export async function bulkRemoveProductsService({ productIds }) {
|
|
4
|
+
return executeBulkOperation(productIds, async (productId) => {
|
|
5
|
+
if (!(await this.products.productExists({ productId })))
|
|
6
|
+
throw new Error('not-found');
|
|
7
|
+
if (await this.products.firstActiveProductBundle(productId)) {
|
|
8
|
+
throw new Error('linked-to-active-bundle');
|
|
9
|
+
}
|
|
10
|
+
if (await this.products.firstActiveProductProxy(productId)) {
|
|
11
|
+
throw new Error('linked-to-active-variation');
|
|
12
|
+
}
|
|
13
|
+
if (await this.quotations.openQuotationWithProduct({ productId })) {
|
|
14
|
+
throw new Error('linked-to-quotation');
|
|
15
|
+
}
|
|
16
|
+
if (await this.enrollments.openEnrollmentWithProduct({ productId })) {
|
|
17
|
+
throw new Error('linked-to-enrollment');
|
|
18
|
+
}
|
|
19
|
+
const result = await removeProductService.call(this, { productId });
|
|
20
|
+
if (!result)
|
|
21
|
+
throw new Error('already-deleted');
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { executeBulkOperation } from '@unchainedshop/utils';
|
|
2
|
+
import { updateFilterService } from "./updateFilter.js";
|
|
3
|
+
export async function bulkSetFilterActiveService({ filterIds, isActive }) {
|
|
4
|
+
return executeBulkOperation(filterIds, async (filterId) => {
|
|
5
|
+
const filter = await this.filters.findFilter({ filterId });
|
|
6
|
+
if (!filter)
|
|
7
|
+
throw new Error('not-found');
|
|
8
|
+
if (!(await updateFilterService.call(this, filterId, { isActive }))) {
|
|
9
|
+
throw new Error('update-failed');
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
}
|