@unchainedshop/core 5.0.0-alpha.1 → 5.0.0-alpha.11
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-exporter/handlers/exportUsersHandler.js +1 -0
- 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/BasePricingSheet.d.ts +2 -0
- 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/DeliveryPricingSheet.js +9 -4
- package/lib/directors/EnrollmentAdapter.d.ts +11 -1
- package/lib/directors/EnrollmentAdapter.js +7 -2
- package/lib/directors/EnrollmentDirector.d.ts +3 -2
- package/lib/directors/EnrollmentDirector.js +9 -19
- 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 +16 -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/PaymentPricingSheet.js +9 -4
- package/lib/directors/ProductDiscountDirector.d.ts +1 -15
- package/lib/directors/ProductDiscountDirector.js +1 -13
- package/lib/directors/ProductPricingAdapter.d.ts +1 -0
- package/lib/directors/ProductPricingDirector.js +2 -10
- package/lib/directors/ProductPricingSheet.js +7 -4
- package/lib/directors/QuotationAdapter.js +5 -2
- 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 +25 -0
- package/lib/factory/registerEnrollment.js +41 -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 +13 -0
- package/lib/factory/registerQuotation.js +53 -0
- package/lib/factory/registerVirtualWarehousing.js +1 -1
- package/lib/factory/registerWorker.js +1 -1
- package/lib/plugins/PluginRegistry.d.ts +2 -1
- package/lib/plugins/PluginRegistry.js +19 -4
- package/lib/services/addCartQuotation.d.ts +9 -13
- package/lib/services/addCartQuotation.js +43 -38
- 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/calculateDiscountTotal.d.ts +5 -1
- package/lib/services/calculateDiscountTotal.js +36 -28
- package/lib/services/checkoutOrder.js +8 -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/deleteUser.js +2 -5
- package/lib/services/index.d.ts +32 -1
- package/lib/services/index.js +32 -1
- package/lib/services/initCartProviders.js +1 -0
- package/lib/services/initializeEnrollment.d.ts +1 -1
- package/lib/services/initializeEnrollment.js +11 -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/migrateOrderCart.js +2 -2
- package/lib/services/migrateUserData.js +3 -0
- package/lib/services/processEnrollment.js +8 -4
- package/lib/services/processOrder.js +7 -6
- 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/reserveOrderQuotationsForCheckout.d.ts +8 -0
- package/lib/services/reserveOrderQuotationsForCheckout.js +49 -0
- package/lib/services/simulateConfigurablePriceRange.js +1 -1
- package/lib/services/simulateDeliveryPricing.js +1 -1
- package/lib/services/simulatePaymentPricing.js +1 -1
- 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/suspendEnrollment.d.ts +5 -0
- package/lib/services/suspendEnrollment.js +21 -0
- package/lib/services/terminateEnrollment.d.ts +6 -2
- package/lib/services/terminateEnrollment.js +27 -7
- package/lib/services/updateCalculation.js +2 -1
- package/lib/services/updateCartItem.d.ts +7 -7
- package/lib/services/updateCartItem.js +28 -25
- package/lib/services/updateEnrollmentPlan.d.ts +5 -0
- package/lib/services/updateEnrollmentPlan.js +26 -0
- 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 +13 -9
- package/package.json +29 -23
- package/lib/errors/common.d.ts +0 -568
- package/lib/errors/common.js +0 -789
- package/lib/errors/index.d.ts +0 -1
- package/lib/errors/index.js +0 -1
- package/lib/services/addCartDiscount.d.ts +0 -10
- package/lib/services/addCartDiscount.js +0 -27
- package/lib/services/addCartItem.d.ts +0 -15
- package/lib/services/addCartItem.js +0 -41
- package/lib/services/addEmail.d.ts +0 -7
- package/lib/services/addEmail.js +0 -17
- package/lib/services/addProductAssignment.d.ts +0 -3
- package/lib/services/addProductAssignment.js +0 -63
- package/lib/services/authenticateWithPassword.d.ts +0 -15
- package/lib/services/authenticateWithPassword.js +0 -34
- package/lib/services/changePassword.d.ts +0 -10
- package/lib/services/changePassword.js +0 -19
- package/lib/services/countOrdersWithFilters.d.ts +0 -3
- package/lib/services/countOrdersWithFilters.js +0 -25
- package/lib/services/createAssortment.d.ts +0 -7
- package/lib/services/createAssortment.js +0 -10
- package/lib/services/createBookmark.d.ts +0 -8
- package/lib/services/createBookmark.js +0 -21
- package/lib/services/createDeliveryProvider.d.ts +0 -6
- package/lib/services/createDeliveryProvider.js +0 -19
- package/lib/services/createEnrollment.d.ts +0 -17
- package/lib/services/createEnrollment.js +0 -33
- package/lib/services/createProduct.d.ts +0 -7
- package/lib/services/createProduct.js +0 -8
- package/lib/services/createProductBundleItem.d.ts +0 -5
- package/lib/services/createProductBundleItem.js +0 -25
- package/lib/services/createProductReview.d.ts +0 -8
- package/lib/services/createProductReview.js +0 -12
- package/lib/services/deliverOrder.d.ts +0 -5
- package/lib/services/deliverOrder.js +0 -26
- package/lib/services/findActiveWorkTypes.d.ts +0 -2
- package/lib/services/findActiveWorkTypes.js +0 -6
- package/lib/services/findDeliveryInterfaces.d.ts +0 -7
- package/lib/services/findDeliveryInterfaces.js +0 -13
- package/lib/services/findOrdersWithFilters.d.ts +0 -9
- package/lib/services/findOrdersWithFilters.js +0 -25
- package/lib/services/findPaymentInterfaces.d.ts +0 -7
- package/lib/services/findPaymentInterfaces.js +0 -13
- package/lib/services/findWarehousingInterfaces.d.ts +0 -7
- package/lib/services/findWarehousingInterfaces.js +0 -13
- package/lib/services/getDeliveryDiscounts.d.ts +0 -8
- package/lib/services/getDeliveryDiscounts.js +0 -14
- package/lib/services/getPaymentDiscounts.d.ts +0 -8
- package/lib/services/getPaymentDiscounts.js +0 -14
- package/lib/services/getShopInfo.d.ts +0 -25
- package/lib/services/getShopInfo.js +0 -47
- package/lib/services/impersonateUser.d.ts +0 -8
- package/lib/services/impersonateUser.js +0 -20
- package/lib/services/loginAsGuest.d.ts +0 -10
- package/lib/services/loginAsGuest.js +0 -19
- package/lib/services/obfuscateWorkerData.d.ts +0 -4
- package/lib/services/obfuscateWorkerData.js +0 -4
- package/lib/services/orderPricingAccessors.d.ts +0 -18
- package/lib/services/orderPricingAccessors.js +0 -29
- package/lib/services/payOrder.d.ts +0 -5
- package/lib/services/payOrder.js +0 -25
- package/lib/services/registerUser.d.ts +0 -14
- package/lib/services/registerUser.js +0 -44
- package/lib/services/removeBookmark.d.ts +0 -6
- package/lib/services/removeBookmark.js +0 -10
- package/lib/services/removeCartItem.d.ts +0 -6
- package/lib/services/removeCartItem.js +0 -19
- package/lib/services/resetPasswordWithMigration.d.ts +0 -14
- package/lib/services/resetPasswordWithMigration.js +0 -31
- package/lib/services/resolveWorkType.d.ts +0 -1
- package/lib/services/resolveWorkType.js +0 -7
- package/lib/services/searchProductsWithAssortment.d.ts +0 -19
- package/lib/services/searchProductsWithAssortment.js +0 -17
- package/lib/services/toggleBookmark.d.ts +0 -8
- package/lib/services/toggleBookmark.js +0 -33
- package/lib/services/updateCart.d.ts +0 -15
- package/lib/services/updateCart.js +0 -27
- package/lib/services/updateEnrollment.d.ts +0 -13
- package/lib/services/updateEnrollment.js +0 -36
- package/lib/services/verifyEmailWithMigration.d.ts +0 -15
- package/lib/services/verifyEmailWithMigration.js +0 -23
|
@@ -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,
|
|
@@ -35,8 +35,9 @@ declare class PluginRegistry {
|
|
|
35
35
|
getPlugin(key: string): IPlugin | undefined;
|
|
36
36
|
getAllPlugins(): IPlugin[];
|
|
37
37
|
getAdapters(adapterType: symbol): IBaseAdapter[];
|
|
38
|
+
getAllAdapters(): IBaseAdapter[];
|
|
38
39
|
hasPlugin(key: string): boolean;
|
|
39
|
-
clear(): void;
|
|
40
|
+
clear(): () => void;
|
|
40
41
|
}
|
|
41
42
|
export declare const pluginRegistry: PluginRegistry;
|
|
42
43
|
export {};
|
|
@@ -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,21 +95,34 @@ 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);
|
|
106
115
|
}
|
|
107
116
|
clear() {
|
|
108
|
-
this
|
|
117
|
+
const { plugins, moduleFactories, skippedPlugins } = this;
|
|
118
|
+
this.plugins = new Map();
|
|
109
119
|
this.moduleFactories = [];
|
|
110
|
-
this.skippedPlugins
|
|
120
|
+
this.skippedPlugins = new Set();
|
|
121
|
+
return () => {
|
|
122
|
+
this.plugins = plugins;
|
|
123
|
+
this.moduleFactories = moduleFactories;
|
|
124
|
+
this.skippedPlugins = skippedPlugins;
|
|
125
|
+
};
|
|
111
126
|
}
|
|
112
127
|
}
|
|
113
128
|
export const pluginRegistry = new PluginRegistry();
|
|
@@ -1,16 +1,12 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type
|
|
1
|
+
import { type Order, type OrderPosition } from '@unchainedshop/core-orders';
|
|
2
|
+
import { type Quotation } from '@unchainedshop/core-quotations';
|
|
3
3
|
import type { Modules } from '../modules.ts';
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
quantity
|
|
8
|
-
configuration
|
|
4
|
+
export declare function addCartQuotationService(this: Modules, { order, quotation, quantity, configuration, }: {
|
|
5
|
+
order: Order;
|
|
6
|
+
quotation: Quotation;
|
|
7
|
+
quantity?: number | null;
|
|
8
|
+
configuration?: {
|
|
9
9
|
key: string;
|
|
10
10
|
value: string;
|
|
11
|
-
}[];
|
|
12
|
-
|
|
13
|
-
countryCode: string;
|
|
14
|
-
context: unknown;
|
|
15
|
-
}
|
|
16
|
-
export declare function addCartQuotationService(this: Modules, params: AddCartQuotationParams): Promise<OrderPosition>;
|
|
11
|
+
}[] | null;
|
|
12
|
+
}, unchainedAPI?: Record<string, any>): Promise<OrderPosition>;
|
|
@@ -1,52 +1,57 @@
|
|
|
1
|
+
import { ordersSettings } from '@unchainedshop/core-orders';
|
|
1
2
|
import { QuotationStatus } from '@unchainedshop/core-quotations';
|
|
2
3
|
import { QuotationDirector } from "../directors/QuotationDirector.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const { orderId, quotationId, quantity, configuration, user, countryCode, context } = params;
|
|
8
|
-
if (quantity < 1) {
|
|
9
|
-
throw new OrderQuantityTooLowError({ quantity });
|
|
10
|
-
}
|
|
11
|
-
const quotation = await this.quotations.findQuotation({ quotationId });
|
|
12
|
-
if (!quotation) {
|
|
13
|
-
throw new QuotationNotFoundError({ quotationId });
|
|
14
|
-
}
|
|
4
|
+
import { createServiceError } from "../errors.js";
|
|
5
|
+
import { isQuotationReserved } from "./reserveOrderQuotationsForCheckout.js";
|
|
6
|
+
export async function addCartQuotationService({ order, quotation, quantity, configuration, }, unchainedAPI = {}) {
|
|
7
|
+
const context = { ...unchainedAPI, modules: this };
|
|
15
8
|
if (quotation.status !== QuotationStatus.PROPOSED) {
|
|
16
|
-
throw
|
|
9
|
+
throw createServiceError('QuotationWrongStatusError', `Quotation ${quotation._id} is ${quotation.status}, not PROPOSED`);
|
|
17
10
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
user,
|
|
21
|
-
countryCode,
|
|
22
|
-
});
|
|
23
|
-
if (!order) {
|
|
24
|
-
throw new OrderNotFoundError({ orderId: orderId || null });
|
|
11
|
+
if (quotation.currencyCode !== order.currencyCode) {
|
|
12
|
+
throw createServiceError('QuotationInvalidError', `Quotation ${quotation._id} is not in the currency of order ${order._id}`);
|
|
25
13
|
}
|
|
26
|
-
if (
|
|
27
|
-
throw
|
|
14
|
+
if (await isQuotationReserved.call(this, quotation._id, { exceptOrderId: order._id })) {
|
|
15
|
+
throw createServiceError('QuotationInvalidError', `Quotation ${quotation._id} is reserved by another order`);
|
|
28
16
|
}
|
|
29
|
-
|
|
30
|
-
|
|
17
|
+
const product = await this.products.findProduct({ productId: quotation.productId });
|
|
18
|
+
if (!product) {
|
|
19
|
+
throw createServiceError('ProductNotFoundError', `Product not found: ${quotation.productId}`);
|
|
31
20
|
}
|
|
21
|
+
const existingPosition = (await this.orders.positions.findOrderPositions({ orderId: order._id })).find((position) => position.quotationId === quotation._id);
|
|
22
|
+
const existingQuantity = existingPosition?.quantity || 0;
|
|
23
|
+
const requestedQuantity = existingQuantity + (quantity ?? quotation.quantity ?? 1);
|
|
32
24
|
const director = await QuotationDirector.actions({ quotation }, context);
|
|
33
25
|
const quotationConfiguration = await director.transformItemConfiguration({
|
|
34
|
-
quantity,
|
|
35
|
-
configuration,
|
|
26
|
+
quantity: requestedQuantity,
|
|
27
|
+
configuration: configuration ?? existingPosition?.configuration ?? [],
|
|
36
28
|
});
|
|
37
29
|
if (!quotationConfiguration) {
|
|
38
|
-
throw
|
|
30
|
+
throw createServiceError('QuotationItemConfigurationError', `Quotation ${quotation._id} does not take quantity ${requestedQuantity}`);
|
|
39
31
|
}
|
|
40
|
-
const
|
|
41
|
-
|
|
32
|
+
const lineQuantity = quotationConfiguration.quantity || requestedQuantity;
|
|
33
|
+
await ordersSettings.validateOrderPosition({
|
|
34
|
+
order,
|
|
35
|
+
product,
|
|
42
36
|
configuration: quotationConfiguration.configuration,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
quantityDiff: lineQuantity - existingQuantity,
|
|
38
|
+
}, context);
|
|
39
|
+
const position = existingPosition
|
|
40
|
+
? await this.orders.positions.updateProductItem({
|
|
41
|
+
orderPositionId: existingPosition._id,
|
|
42
|
+
quantity: lineQuantity,
|
|
43
|
+
configuration: quotationConfiguration.configuration ?? null,
|
|
44
|
+
})
|
|
45
|
+
: await this.orders.positions.addProductItem({
|
|
46
|
+
quantity: lineQuantity,
|
|
47
|
+
configuration: quotationConfiguration.configuration,
|
|
48
|
+
quotationId: quotation._id,
|
|
49
|
+
productId: quotation.productId,
|
|
50
|
+
originalProductId: quotation.productId,
|
|
51
|
+
orderId: order._id,
|
|
52
|
+
});
|
|
53
|
+
if (!position) {
|
|
54
|
+
throw createServiceError('OrderItemNotFoundError', `Order item not found: ${existingPosition?._id}`);
|
|
55
|
+
}
|
|
56
|
+
return position;
|
|
52
57
|
}
|
|
@@ -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
|
+
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { Order, OrderDiscount } from '@unchainedshop/core-orders';
|
|
2
2
|
import type { Modules } from '../modules.ts';
|
|
3
|
-
export declare function calculateDiscountTotalService(this: Modules, order: Order, orderDiscount: OrderDiscount
|
|
3
|
+
export declare function calculateDiscountTotalService(this: Modules, order: Order, orderDiscount: OrderDiscount, { useNetPrice }?: {
|
|
4
|
+
useNetPrice?: boolean;
|
|
5
|
+
}): Promise<{
|
|
4
6
|
amount: number;
|
|
5
7
|
currencyCode: string;
|
|
8
|
+
isTaxable: boolean;
|
|
9
|
+
isNetPrice: boolean;
|
|
6
10
|
}>;
|
|
@@ -1,44 +1,52 @@
|
|
|
1
1
|
import { OrderPricingRowCategory, OrderPricingSheet, DeliveryPricingRowCategory, DeliveryPricingSheet, ProductPricingRowCategory, ProductPricingSheet, PaymentPricingRowCategory, PaymentPricingSheet, } from "../directors/index.js";
|
|
2
|
-
export async function calculateDiscountTotalService(order, orderDiscount) {
|
|
3
|
-
const
|
|
2
|
+
export async function calculateDiscountTotalService(order, orderDiscount, { useNetPrice = false } = {}) {
|
|
3
|
+
const discountId = orderDiscount._id;
|
|
4
4
|
const orderDelivery = await this.orders.deliveries.findDelivery({
|
|
5
5
|
orderDeliveryId: order.deliveryId,
|
|
6
6
|
});
|
|
7
|
-
const orderDeliveryDiscountSum = DeliveryPricingSheet({
|
|
8
|
-
calculation: orderDelivery?.calculation || [],
|
|
9
|
-
currencyCode: order.currencyCode,
|
|
10
|
-
}).total({ category: DeliveryPricingRowCategory.Discount, discountId: orderDiscountId });
|
|
11
7
|
const orderPayment = await this.orders.payments.findOrderPayment({
|
|
12
8
|
orderPaymentId: order.paymentId,
|
|
13
9
|
});
|
|
14
|
-
const orderPaymentDiscountSum = PaymentPricingSheet({
|
|
15
|
-
calculation: orderPayment?.calculation || [],
|
|
16
|
-
currencyCode: order.currencyCode,
|
|
17
|
-
}).total({ category: PaymentPricingRowCategory.Discount, discountId: orderDiscountId });
|
|
18
10
|
const orderPositions = await this.orders.positions.findOrderPositions({
|
|
19
11
|
orderId: order._id,
|
|
20
12
|
});
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
...
|
|
37
|
-
|
|
13
|
+
const discountedSheets = [
|
|
14
|
+
{
|
|
15
|
+
category: DeliveryPricingRowCategory.Discount,
|
|
16
|
+
sheet: DeliveryPricingSheet({
|
|
17
|
+
calculation: orderDelivery?.calculation || [],
|
|
18
|
+
currencyCode: order.currencyCode,
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
category: PaymentPricingRowCategory.Discount,
|
|
23
|
+
sheet: PaymentPricingSheet({
|
|
24
|
+
calculation: orderPayment?.calculation || [],
|
|
25
|
+
currencyCode: order.currencyCode,
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
...orderPositions.map((orderPosition) => ({
|
|
29
|
+
category: ProductPricingRowCategory.Discount,
|
|
30
|
+
sheet: ProductPricingSheet({
|
|
31
|
+
calculation: orderPosition.calculation || [],
|
|
32
|
+
currencyCode: order.currencyCode,
|
|
33
|
+
quantity: orderPosition.quantity,
|
|
34
|
+
}),
|
|
35
|
+
})),
|
|
36
|
+
{
|
|
37
|
+
category: OrderPricingRowCategory.Discounts,
|
|
38
|
+
sheet: OrderPricingSheet({
|
|
39
|
+
calculation: order.calculation,
|
|
40
|
+
currencyCode: order.currencyCode,
|
|
41
|
+
}),
|
|
42
|
+
},
|
|
38
43
|
];
|
|
39
|
-
const amount =
|
|
44
|
+
const amount = discountedSheets.reduce((sum, { category, sheet }) => sum + (sheet.total({ category, discountId, useNetPrice }).amount || 0), 0);
|
|
45
|
+
const taxAmount = discountedSheets.reduce((sum, { category, sheet }) => sum + sheet.taxSum({ baseCategory: category, discountId }), 0);
|
|
40
46
|
return {
|
|
41
47
|
amount,
|
|
42
48
|
currencyCode: order.currencyCode,
|
|
49
|
+
isTaxable: taxAmount !== 0,
|
|
50
|
+
isNetPrice: useNetPrice,
|
|
43
51
|
};
|
|
44
52
|
}
|
|
@@ -2,6 +2,8 @@ import { OrderStatus } from '@unchainedshop/core-orders';
|
|
|
2
2
|
import { nextUserCartService } from "./nextUserCart.js";
|
|
3
3
|
import { validateOrderService } from "./validateOrder.js";
|
|
4
4
|
import { processOrderService } from "./processOrder.js";
|
|
5
|
+
import { reserveOrderDiscountsForCheckout } from "./reserveOrderDiscountsForCheckout.js";
|
|
6
|
+
import { reserveOrderQuotationsForCheckout } from "./reserveOrderQuotationsForCheckout.js";
|
|
5
7
|
export async function checkoutOrderService(orderId, transactionContext) {
|
|
6
8
|
const order = await this.orders.findOrder({ orderId });
|
|
7
9
|
if (!order)
|
|
@@ -10,7 +12,11 @@ export async function checkoutOrderService(orderId, transactionContext) {
|
|
|
10
12
|
return order;
|
|
11
13
|
await validateOrderService.bind(this)(order);
|
|
12
14
|
const lock = await this.orders.acquireLock(order._id, 'checkout');
|
|
15
|
+
let discounts;
|
|
16
|
+
let quotations;
|
|
13
17
|
try {
|
|
18
|
+
quotations = await reserveOrderQuotationsForCheckout.call(this, order);
|
|
19
|
+
discounts = await reserveOrderDiscountsForCheckout.call(this, order);
|
|
14
20
|
const processedOrder = await processOrderService.bind(this)(order, transactionContext);
|
|
15
21
|
if (processedOrder.billingAddress) {
|
|
16
22
|
await this.users.updateLastBillingAddress(processedOrder.userId, processedOrder.billingAddress);
|
|
@@ -27,6 +33,8 @@ export async function checkoutOrderService(orderId, transactionContext) {
|
|
|
27
33
|
return processedOrder;
|
|
28
34
|
}
|
|
29
35
|
finally {
|
|
36
|
+
await discounts?.release();
|
|
37
|
+
await quotations?.release();
|
|
30
38
|
await lock.release();
|
|
31
39
|
}
|
|
32
40
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FilterDirector } from "../core-index.js";
|
|
2
|
+
export async function createFilterOptionService(filterId, { value }) {
|
|
3
|
+
const filter = await this.filters.createFilterOption(filterId, { value });
|
|
4
|
+
if (filter) {
|
|
5
|
+
await FilterDirector.invalidateProductIdCache(filter, { modules: this });
|
|
6
|
+
}
|
|
7
|
+
return filter;
|
|
8
|
+
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { getFileFromFileData } from '@unchainedshop/core-files';
|
|
2
2
|
import { getFileAdapter } from "../utils/getFileAdapter.js";
|
|
3
|
+
import { createServiceError } from "../errors.js";
|
|
3
4
|
export async function createSignedURLService({ directoryName, fileName, meta }) {
|
|
4
5
|
const fileUploadAdapter = getFileAdapter();
|
|
5
6
|
const preparedFileData = await fileUploadAdapter.createSignedURL(directoryName, fileName, {
|
|
6
7
|
modules: this,
|
|
7
8
|
});
|
|
8
9
|
if (!preparedFileData)
|
|
9
|
-
throw
|
|
10
|
+
throw createServiceError('SignedURLPreparationError', 'Could not prepare signed URL');
|
|
10
11
|
const fileData = getFileFromFileData(preparedFileData, meta);
|
|
11
12
|
const fileId = await this.files.create(fileData);
|
|
12
13
|
const file = await this.files.findFile({ fileId });
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export async function deleteCartService(orderId) {
|
|
2
|
+
await this.orders.positions.deleteOrderPositions(orderId);
|
|
3
|
+
await this.orders.payments.deleteOrderPayments(orderId);
|
|
4
|
+
await this.orders.deliveries.deleteOrderDeliveries(orderId);
|
|
5
|
+
await this.orders.discounts.deleteOrderDiscounts(orderId);
|
|
6
|
+
return this.orders.delete(orderId);
|
|
7
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { deleteCartService } from "./deleteCart.js";
|
|
1
2
|
export async function deleteUserService({ userId }) {
|
|
2
3
|
const user = await this.users.markDeleted(userId);
|
|
3
4
|
if (!user)
|
|
@@ -11,11 +12,7 @@ export async function deleteUserService({ userId }) {
|
|
|
11
12
|
}
|
|
12
13
|
const carts = (await this.orders.findOrders({ userId, includeCarts: true })).filter((c) => c.status === null);
|
|
13
14
|
await Array.fromAsync(carts, async (userCart) => {
|
|
14
|
-
await
|
|
15
|
-
await this.orders.payments.deleteOrderPayments(userCart?._id);
|
|
16
|
-
await this.orders.deliveries.deleteOrderDeliveries(userCart?._id);
|
|
17
|
-
await this.orders.discounts.deleteOrderDiscounts(userCart?._id);
|
|
18
|
-
await this.orders.delete(userCart?._id);
|
|
15
|
+
await deleteCartService.bind(this)(userCart._id);
|
|
19
16
|
});
|
|
20
17
|
const ordersCount = await this.orders.count({ userId, includeCarts: true });
|
|
21
18
|
const quotationsCount = await this.quotations.count({ userId });
|