@vendure/core 3.1.0-next.3 → 3.1.0
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/cli/populate.js +3 -1
- package/cli/populate.js.map +1 -1
- package/dist/api/common/request-context.d.ts +1 -1
- package/dist/api/common/request-context.js +1 -1
- package/dist/api/common/validate-custom-field-value.js +28 -0
- package/dist/api/common/validate-custom-field-value.js.map +1 -1
- package/dist/api/config/generate-active-order-types.js +2 -0
- package/dist/api/config/generate-active-order-types.js.map +1 -1
- package/dist/api/config/generate-resolvers.d.ts +10 -4
- package/dist/api/config/generate-resolvers.js +73 -7
- package/dist/api/config/generate-resolvers.js.map +1 -1
- package/dist/api/config/get-custom-fields-config-without-interfaces.d.ts +2 -0
- package/dist/api/config/get-custom-fields-config-without-interfaces.js +16 -11
- package/dist/api/config/get-custom-fields-config-without-interfaces.js.map +1 -1
- package/dist/api/config/graphql-custom-fields.js +116 -22
- package/dist/api/config/graphql-custom-fields.js.map +1 -1
- package/dist/api/resolvers/admin/draft-order.resolver.d.ts +3 -1
- package/dist/api/resolvers/admin/draft-order.resolver.js +26 -0
- package/dist/api/resolvers/admin/draft-order.resolver.js.map +1 -1
- package/dist/api/resolvers/admin/global-settings.resolver.d.ts +2 -0
- package/dist/api/resolvers/admin/global-settings.resolver.js +12 -0
- package/dist/api/resolvers/admin/global-settings.resolver.js.map +1 -1
- package/dist/api/resolvers/entity/order-line-entity.resolver.js +7 -3
- package/dist/api/resolvers/entity/order-line-entity.resolver.js.map +1 -1
- package/dist/api/resolvers/shop/shop-order.resolver.d.ts +2 -0
- package/dist/api/resolvers/shop/shop-order.resolver.js +38 -0
- package/dist/api/resolvers/shop/shop-order.resolver.js.map +1 -1
- package/dist/api/schema/admin-api/order.api.graphql +14 -12
- package/dist/api/schema/common/common-error-results.graphql +9 -0
- package/dist/api/schema/common/common-types.graphql +2 -1
- package/dist/api/schema/common/custom-field-types.graphql +99 -0
- package/dist/api/schema/shop-api/shop.api.graphql +30 -13
- package/dist/bootstrap.d.ts +56 -3
- package/dist/bootstrap.js +36 -6
- package/dist/bootstrap.js.map +1 -1
- package/dist/cache/cache-ttl-provider.d.ts +38 -0
- package/dist/cache/cache-ttl-provider.js +39 -0
- package/dist/cache/cache-ttl-provider.js.map +1 -0
- package/dist/cache/cache.d.ts +88 -0
- package/dist/cache/cache.js +79 -0
- package/dist/cache/cache.js.map +1 -0
- package/dist/cache/cache.service.d.ts +15 -0
- package/dist/cache/cache.service.js +25 -0
- package/dist/cache/cache.service.js.map +1 -1
- package/dist/cache/index.d.ts +2 -0
- package/dist/cache/index.js +2 -0
- package/dist/cache/index.js.map +1 -1
- package/dist/cache/request-context-cache.service.d.ts +14 -0
- package/dist/cache/request-context-cache.service.js +9 -0
- package/dist/cache/request-context-cache.service.js.map +1 -1
- package/dist/common/error/generated-graphql-admin-errors.d.ts +9 -0
- package/dist/common/error/generated-graphql-admin-errors.js +12 -2
- package/dist/common/error/generated-graphql-admin-errors.js.map +1 -1
- package/dist/common/error/generated-graphql-shop-errors.d.ts +9 -0
- package/dist/common/error/generated-graphql-shop-errors.js +12 -2
- package/dist/common/error/generated-graphql-shop-errors.js.map +1 -1
- package/dist/common/ttl-cache.d.ts +3 -0
- package/dist/common/ttl-cache.js +3 -0
- package/dist/common/ttl-cache.js.map +1 -1
- package/dist/common/types/entity-relation-paths.d.ts +2 -1
- package/dist/common/utils.d.ts +1 -1
- package/dist/common/utils.js +1 -1
- package/dist/common/utils.js.map +1 -1
- package/dist/config/catalog/default-stock-location-strategy.d.ts +15 -8
- package/dist/config/catalog/default-stock-location-strategy.js +30 -22
- package/dist/config/catalog/default-stock-location-strategy.js.map +1 -1
- package/dist/config/catalog/multi-channel-stock-location-strategy.d.ts +55 -0
- package/dist/config/catalog/multi-channel-stock-location-strategy.js +144 -0
- package/dist/config/catalog/multi-channel-stock-location-strategy.js.map +1 -0
- package/dist/config/config.module.js +2 -1
- package/dist/config/config.module.js.map +1 -1
- package/dist/config/custom-field/custom-field-types.d.ts +69 -5
- package/dist/config/default-config.js +12 -4
- package/dist/config/default-config.js.map +1 -1
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.js +4 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/order/order-interceptor.d.ts +233 -0
- package/dist/config/order/order-interceptor.js +3 -0
- package/dist/config/order/order-interceptor.js.map +1 -0
- package/dist/config/promotion/conditions/customer-group-condition.js +17 -12
- package/dist/config/promotion/conditions/customer-group-condition.js.map +1 -1
- package/dist/config/session-cache/default-session-cache-strategy.d.ts +34 -0
- package/dist/config/session-cache/default-session-cache-strategy.js +63 -0
- package/dist/config/session-cache/default-session-cache-strategy.js.map +1 -0
- package/dist/config/session-cache/session-cache-strategy.d.ts +13 -4
- package/dist/config/shipping-method/shipping-eligibility-checker.d.ts +4 -2
- package/dist/config/shipping-method/shipping-eligibility-checker.js +8 -5
- package/dist/config/shipping-method/shipping-eligibility-checker.js.map +1 -1
- package/dist/config/system/cache-strategy.d.ts +12 -0
- package/dist/config/system/in-memory-cache-strategy.d.ts +8 -0
- package/dist/config/system/in-memory-cache-strategy.js +26 -3
- package/dist/config/system/in-memory-cache-strategy.js.map +1 -1
- package/dist/config/tax/address-based-tax-zone-strategy.d.ts +24 -0
- package/dist/config/tax/address-based-tax-zone-strategy.js +39 -0
- package/dist/config/tax/address-based-tax-zone-strategy.js.map +1 -0
- package/dist/config/vendure-config.d.ts +15 -6
- package/dist/data-import/providers/importer/importer.js +8 -0
- package/dist/data-import/providers/importer/importer.js.map +1 -1
- package/dist/data-import/providers/populator/populator.js +0 -1
- package/dist/data-import/providers/populator/populator.js.map +1 -1
- package/dist/entity/custom-entity-fields.d.ts +14 -0
- package/dist/entity/custom-entity-fields.js +22 -1
- package/dist/entity/custom-entity-fields.js.map +1 -1
- package/dist/entity/history-entry/history-entry.entity.d.ts +4 -1
- package/dist/entity/history-entry/history-entry.entity.js +5 -0
- package/dist/entity/history-entry/history-entry.entity.js.map +1 -1
- package/dist/entity/payment/payment.entity.d.ts +4 -1
- package/dist/entity/payment/payment.entity.js +5 -0
- package/dist/entity/payment/payment.entity.js.map +1 -1
- package/dist/entity/refund/refund.entity.d.ts +4 -1
- package/dist/entity/refund/refund.entity.js +5 -0
- package/dist/entity/refund/refund.entity.js.map +1 -1
- package/dist/entity/register-custom-entity-fields.js +17 -2
- package/dist/entity/register-custom-entity-fields.js.map +1 -1
- package/dist/entity/session/session.entity.d.ts +4 -1
- package/dist/entity/session/session.entity.js +5 -0
- package/dist/entity/session/session.entity.js.map +1 -1
- package/dist/entity/shipping-line/shipping-line.entity.d.ts +5 -2
- package/dist/entity/shipping-line/shipping-line.entity.js +7 -2
- package/dist/entity/shipping-line/shipping-line.entity.js.map +1 -1
- package/dist/entity/stock-level/stock-level.entity.d.ts +4 -1
- package/dist/entity/stock-level/stock-level.entity.js +5 -0
- package/dist/entity/stock-level/stock-level.entity.js.map +1 -1
- package/dist/entity/stock-movement/stock-movement.entity.d.ts +4 -1
- package/dist/entity/stock-movement/stock-movement.entity.js +5 -0
- package/dist/entity/stock-movement/stock-movement.entity.js.map +1 -1
- package/dist/event-bus/events/stock-location-event.d.ts +18 -0
- package/dist/event-bus/events/stock-location-event.js +19 -0
- package/dist/event-bus/events/stock-location-event.js.map +1 -0
- package/dist/event-bus/index.d.ts +1 -0
- package/dist/event-bus/index.js +1 -0
- package/dist/event-bus/index.js.map +1 -1
- package/dist/i18n/messages/de.json +1 -0
- package/dist/i18n/messages/en.json +2 -0
- package/dist/plugin/default-cache-plugin/cache-item.entity.d.ts +1 -0
- package/dist/plugin/default-cache-plugin/cache-item.entity.js +4 -0
- package/dist/plugin/default-cache-plugin/cache-item.entity.js.map +1 -1
- package/dist/plugin/default-cache-plugin/cache-tag.entity.d.ts +9 -0
- package/dist/plugin/default-cache-plugin/cache-tag.entity.js +41 -0
- package/dist/plugin/default-cache-plugin/cache-tag.entity.js.map +1 -0
- package/dist/plugin/default-cache-plugin/default-cache-plugin.d.ts +21 -0
- package/dist/plugin/default-cache-plugin/default-cache-plugin.js +13 -1
- package/dist/plugin/default-cache-plugin/default-cache-plugin.js.map +1 -1
- package/dist/plugin/default-cache-plugin/sql-cache-strategy.d.ts +7 -6
- package/dist/plugin/default-cache-plugin/sql-cache-strategy.js +57 -13
- package/dist/plugin/default-cache-plugin/sql-cache-strategy.js.map +1 -1
- package/dist/plugin/default-search-plugin/default-search-plugin.js +4 -0
- package/dist/plugin/default-search-plugin/default-search-plugin.js.map +1 -1
- package/dist/plugin/default-search-plugin/indexer/indexer.controller.js +1 -0
- package/dist/plugin/default-search-plugin/indexer/indexer.controller.js.map +1 -1
- package/dist/plugin/index.d.ts +3 -0
- package/dist/plugin/index.js +3 -0
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/redis-cache-plugin/constants.d.ts +4 -0
- package/dist/plugin/redis-cache-plugin/constants.js +8 -0
- package/dist/plugin/redis-cache-plugin/constants.js.map +1 -0
- package/dist/plugin/redis-cache-plugin/redis-cache-plugin.d.ts +14 -0
- package/dist/plugin/redis-cache-plugin/redis-cache-plugin.js +47 -0
- package/dist/plugin/redis-cache-plugin/redis-cache-plugin.js.map +1 -0
- package/dist/plugin/redis-cache-plugin/redis-cache-strategy.d.ts +24 -0
- package/dist/plugin/redis-cache-plugin/redis-cache-strategy.js +104 -0
- package/dist/plugin/redis-cache-plugin/redis-cache-strategy.js.map +1 -0
- package/dist/plugin/redis-cache-plugin/types.d.ts +12 -0
- package/dist/plugin/redis-cache-plugin/types.js +3 -0
- package/dist/plugin/redis-cache-plugin/types.js.map +1 -0
- package/dist/plugin/vendure-plugin.d.ts +5 -0
- package/dist/plugin/vendure-plugin.js.map +1 -1
- package/dist/service/helpers/external-authentication/external-authentication.service.d.ts +1 -1
- package/dist/service/helpers/external-authentication/external-authentication.service.js +1 -1
- package/dist/service/helpers/facet-value-checker/facet-value-checker.d.ts +3 -4
- package/dist/service/helpers/facet-value-checker/facet-value-checker.js +11 -17
- package/dist/service/helpers/facet-value-checker/facet-value-checker.js.map +1 -1
- package/dist/service/helpers/order-modifier/order-modifier.js +14 -6
- package/dist/service/helpers/order-modifier/order-modifier.js.map +1 -1
- package/dist/service/helpers/utils/tree-relations-qb-joiner.js +1 -1
- package/dist/service/helpers/utils/tree-relations-qb-joiner.js.map +1 -1
- package/dist/service/services/channel.service.js +5 -0
- package/dist/service/services/channel.service.js.map +1 -1
- package/dist/service/services/order.service.d.ts +71 -1
- package/dist/service/services/order.service.js +270 -83
- package/dist/service/services/order.service.js.map +1 -1
- package/dist/service/services/payment.service.js +6 -4
- package/dist/service/services/payment.service.js.map +1 -1
- package/dist/service/services/product-variant.service.js +1 -1
- package/dist/service/services/product-variant.service.js.map +1 -1
- package/dist/service/services/promotion.service.js +1 -0
- package/dist/service/services/promotion.service.js.map +1 -1
- package/dist/service/services/role.service.js +6 -5
- package/dist/service/services/role.service.js.map +1 -1
- package/dist/service/services/stock-location.service.d.ts +3 -1
- package/dist/service/services/stock-location.service.js +9 -2
- package/dist/service/services/stock-location.service.js.map +1 -1
- package/package.json +22 -22
|
@@ -25,6 +25,7 @@ const generated_graphql_shop_errors_1 = require("../../common/error/generated-gr
|
|
|
25
25
|
const tax_utils_1 = require("../../common/tax-utils");
|
|
26
26
|
const utils_1 = require("../../common/utils");
|
|
27
27
|
const config_service_1 = require("../../config/config.service");
|
|
28
|
+
const vendure_logger_1 = require("../../config/logger/vendure-logger");
|
|
28
29
|
const transactional_connection_1 = require("../../connection/transactional-connection");
|
|
29
30
|
const order_entity_1 = require("../../entity/order/order.entity");
|
|
30
31
|
const order_line_entity_1 = require("../../entity/order-line/order-line.entity");
|
|
@@ -407,113 +408,249 @@ let OrderService = class OrderService {
|
|
|
407
408
|
* @description
|
|
408
409
|
* Adds an item to the Order, either creating a new OrderLine or
|
|
409
410
|
* incrementing an existing one.
|
|
411
|
+
*
|
|
412
|
+
* If you need to add multiple items to an Order, use `addItemsToOrder()` instead.
|
|
410
413
|
*/
|
|
411
414
|
async addItemToOrder(ctx, orderId, productVariantId, quantity, customFields, relations) {
|
|
412
|
-
const
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
this.assertAddingItemsState(order) ||
|
|
416
|
-
this.assertNotOverOrderItemsLimit(order, quantity) ||
|
|
417
|
-
this.assertNotOverOrderLineItemsLimit(existingOrderLine, quantity);
|
|
418
|
-
if (validationError) {
|
|
419
|
-
return validationError;
|
|
420
|
-
}
|
|
421
|
-
const variant = await this.connection.getEntityOrThrow(ctx, product_variant_entity_1.ProductVariant, productVariantId, {
|
|
422
|
-
relations: ['product'],
|
|
423
|
-
where: {
|
|
424
|
-
enabled: true,
|
|
425
|
-
deletedAt: (0, typeorm_1.IsNull)(),
|
|
426
|
-
},
|
|
427
|
-
loadEagerRelations: false,
|
|
428
|
-
});
|
|
429
|
-
if (variant.product.enabled === false) {
|
|
430
|
-
throw new errors_1.EntityNotFoundError('ProductVariant', productVariantId);
|
|
431
|
-
}
|
|
432
|
-
const existingQuantityInOtherLines = (0, shared_utils_1.summate)(order.lines.filter(l => (0, utils_1.idsAreEqual)(l.productVariantId, productVariantId) &&
|
|
433
|
-
!(0, utils_1.idsAreEqual)(l.id, existingOrderLine === null || existingOrderLine === void 0 ? void 0 : existingOrderLine.id)), 'quantity');
|
|
434
|
-
const correctedQuantity = await this.orderModifier.constrainQuantityToSaleable(ctx, variant, quantity, existingOrderLine === null || existingOrderLine === void 0 ? void 0 : existingOrderLine.quantity, existingQuantityInOtherLines);
|
|
435
|
-
if (correctedQuantity === 0) {
|
|
436
|
-
return new generated_graphql_shop_errors_1.InsufficientStockError({ order, quantityAvailable: correctedQuantity });
|
|
437
|
-
}
|
|
438
|
-
const orderLine = await this.orderModifier.getOrCreateOrderLine(ctx, order, productVariantId, customFields);
|
|
439
|
-
if (correctedQuantity < quantity) {
|
|
440
|
-
const newQuantity = (existingOrderLine ? existingOrderLine === null || existingOrderLine === void 0 ? void 0 : existingOrderLine.quantity : 0) + correctedQuantity;
|
|
441
|
-
await this.orderModifier.updateOrderLineQuantity(ctx, orderLine, newQuantity, order);
|
|
415
|
+
const result = await this.addItemsToOrder(ctx, orderId, [{ productVariantId, quantity, customFields }], relations);
|
|
416
|
+
if (result.errorResults.length) {
|
|
417
|
+
return result.errorResults[0];
|
|
442
418
|
}
|
|
443
419
|
else {
|
|
444
|
-
|
|
420
|
+
return result.order;
|
|
445
421
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* @description
|
|
425
|
+
* Adds multiple items to an Order. This method is more efficient than calling `addItemToOrder`
|
|
426
|
+
* multiple times, as it only needs to fetch the entire Order once, and only performs
|
|
427
|
+
* price adjustments once at the end.
|
|
428
|
+
*
|
|
429
|
+
* Since this method can return multiple error results, it is recommended to check the `errorResults`
|
|
430
|
+
* array to determine if any errors occurred.
|
|
431
|
+
*
|
|
432
|
+
* @since 3.1.0
|
|
433
|
+
*/
|
|
434
|
+
async addItemsToOrder(ctx, orderId, items, relations) {
|
|
435
|
+
const order = await this.getOrderOrThrow(ctx, orderId);
|
|
436
|
+
const errorResults = [];
|
|
437
|
+
const updatedOrderLines = [];
|
|
438
|
+
addItem: for (const item of items) {
|
|
439
|
+
const { productVariantId, quantity, customFields } = item;
|
|
440
|
+
const existingOrderLine = await this.orderModifier.getExistingOrderLine(ctx, order, productVariantId, customFields);
|
|
441
|
+
const validationError = this.assertQuantityIsPositive(quantity) ||
|
|
442
|
+
this.assertAddingItemsState(order) ||
|
|
443
|
+
this.assertNotOverOrderItemsLimit(order, quantity) ||
|
|
444
|
+
this.assertNotOverOrderLineItemsLimit(existingOrderLine, quantity);
|
|
445
|
+
if (validationError) {
|
|
446
|
+
errorResults.push(validationError);
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
const variant = await this.connection.getEntityOrThrow(ctx, product_variant_entity_1.ProductVariant, productVariantId, {
|
|
450
|
+
relations: ['product'],
|
|
451
|
+
where: {
|
|
452
|
+
enabled: true,
|
|
453
|
+
deletedAt: (0, typeorm_1.IsNull)(),
|
|
454
|
+
},
|
|
455
|
+
loadEagerRelations: false,
|
|
456
|
+
});
|
|
457
|
+
if (variant.product.enabled === false) {
|
|
458
|
+
throw new errors_1.EntityNotFoundError('ProductVariant', productVariantId);
|
|
459
|
+
}
|
|
460
|
+
const existingQuantityInOtherLines = (0, shared_utils_1.summate)(order.lines.filter(l => (0, utils_1.idsAreEqual)(l.productVariantId, productVariantId) &&
|
|
461
|
+
!(0, utils_1.idsAreEqual)(l.id, existingOrderLine === null || existingOrderLine === void 0 ? void 0 : existingOrderLine.id)), 'quantity');
|
|
462
|
+
const correctedQuantity = await this.orderModifier.constrainQuantityToSaleable(ctx, variant, quantity, existingOrderLine === null || existingOrderLine === void 0 ? void 0 : existingOrderLine.quantity, existingQuantityInOtherLines);
|
|
463
|
+
if (correctedQuantity === 0) {
|
|
464
|
+
errorResults.push(new generated_graphql_shop_errors_1.InsufficientStockError({ order, quantityAvailable: correctedQuantity }));
|
|
465
|
+
continue;
|
|
466
|
+
}
|
|
467
|
+
const { orderInterceptors } = this.configService.orderOptions;
|
|
468
|
+
for (const interceptor of orderInterceptors) {
|
|
469
|
+
if (interceptor.willAddItemToOrder) {
|
|
470
|
+
const error = await interceptor.willAddItemToOrder(ctx, order, {
|
|
471
|
+
productVariant: variant,
|
|
472
|
+
quantity: correctedQuantity,
|
|
473
|
+
customFields,
|
|
474
|
+
});
|
|
475
|
+
if (error) {
|
|
476
|
+
errorResults.push(new generated_graphql_shop_errors_1.OrderInterceptorError({ interceptorError: error }));
|
|
477
|
+
continue addItem;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
const orderLine = await this.orderModifier.getOrCreateOrderLine(ctx, order, productVariantId, customFields);
|
|
482
|
+
if (correctedQuantity < quantity) {
|
|
483
|
+
const newQuantity = (existingOrderLine ? existingOrderLine === null || existingOrderLine === void 0 ? void 0 : existingOrderLine.quantity : 0) + correctedQuantity;
|
|
484
|
+
await this.orderModifier.updateOrderLineQuantity(ctx, orderLine, newQuantity, order);
|
|
485
|
+
}
|
|
486
|
+
else {
|
|
487
|
+
await this.orderModifier.updateOrderLineQuantity(ctx, orderLine, correctedQuantity, order);
|
|
488
|
+
}
|
|
489
|
+
updatedOrderLines.push(orderLine);
|
|
490
|
+
const quantityWasAdjustedDown = correctedQuantity < quantity;
|
|
491
|
+
if (quantityWasAdjustedDown) {
|
|
492
|
+
errorResults.push(new generated_graphql_shop_errors_1.InsufficientStockError({ quantityAvailable: correctedQuantity, order }));
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
450
495
|
}
|
|
451
|
-
|
|
452
|
-
|
|
496
|
+
const updatedOrder = await this.applyPriceAdjustments(ctx, order, updatedOrderLines, relations);
|
|
497
|
+
// for any InsufficientStockError errors, we want to make sure we use the final updatedOrder
|
|
498
|
+
// after having applied all price adjustments
|
|
499
|
+
for (const [i, errorResult] of Object.entries(errorResults)) {
|
|
500
|
+
if (errorResult.__typename === 'InsufficientStockError') {
|
|
501
|
+
errorResults[+i] = new generated_graphql_shop_errors_1.InsufficientStockError({
|
|
502
|
+
quantityAvailable: errorResult.quantityAvailable,
|
|
503
|
+
order: updatedOrder,
|
|
504
|
+
});
|
|
505
|
+
}
|
|
453
506
|
}
|
|
507
|
+
return {
|
|
508
|
+
order: updatedOrder,
|
|
509
|
+
errorResults,
|
|
510
|
+
};
|
|
454
511
|
}
|
|
455
512
|
/**
|
|
456
513
|
* @description
|
|
457
514
|
* Adjusts the quantity and/or custom field values of an existing OrderLine.
|
|
515
|
+
*
|
|
516
|
+
* If you need to adjust multiple OrderLines, use `adjustOrderLines()` instead.
|
|
458
517
|
*/
|
|
459
518
|
async adjustOrderLine(ctx, orderId, orderLineId, quantity, customFields, relations) {
|
|
460
|
-
const
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
this.assertQuantityIsPositive(quantity) ||
|
|
464
|
-
this.assertNotOverOrderItemsLimit(order, quantity - orderLine.quantity) ||
|
|
465
|
-
this.assertNotOverOrderLineItemsLimit(orderLine, quantity - orderLine.quantity);
|
|
466
|
-
if (validationError) {
|
|
467
|
-
return validationError;
|
|
468
|
-
}
|
|
469
|
-
if (customFields != null) {
|
|
470
|
-
orderLine.customFields = customFields;
|
|
471
|
-
await this.customFieldRelationService.updateRelations(ctx, order_line_entity_1.OrderLine, { customFields }, orderLine);
|
|
472
|
-
}
|
|
473
|
-
const existingQuantityInOtherLines = (0, shared_utils_1.summate)(order.lines.filter(l => (0, utils_1.idsAreEqual)(l.productVariantId, orderLine.productVariantId) &&
|
|
474
|
-
!(0, utils_1.idsAreEqual)(l.id, orderLineId)), 'quantity');
|
|
475
|
-
const correctedQuantity = await this.orderModifier.constrainQuantityToSaleable(ctx, orderLine.productVariant, quantity, 0, existingQuantityInOtherLines);
|
|
476
|
-
let updatedOrderLines = [orderLine];
|
|
477
|
-
if (correctedQuantity === 0) {
|
|
478
|
-
order.lines = order.lines.filter(l => !(0, utils_1.idsAreEqual)(l.id, orderLine.id));
|
|
479
|
-
const deletedOrderLine = new order_line_entity_1.OrderLine(orderLine);
|
|
480
|
-
await this.connection.getRepository(ctx, order_line_entity_1.OrderLine).remove(orderLine);
|
|
481
|
-
await this.eventBus.publish(new order_line_event_1.OrderLineEvent(ctx, order, deletedOrderLine, 'deleted'));
|
|
482
|
-
updatedOrderLines = [];
|
|
519
|
+
const result = await this.adjustOrderLines(ctx, orderId, [{ orderLineId, quantity, customFields }], relations);
|
|
520
|
+
if (result.errorResults.length) {
|
|
521
|
+
return result.errorResults[0];
|
|
483
522
|
}
|
|
484
523
|
else {
|
|
485
|
-
|
|
524
|
+
return result.order;
|
|
486
525
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* @description
|
|
529
|
+
* Adjusts the quantity and/or custom field values of existing OrderLines.
|
|
530
|
+
* This method is more efficient than calling `adjustOrderLine` multiple times, as it only needs to fetch
|
|
531
|
+
* the entire Order once, and only performs price adjustments once at the end.
|
|
532
|
+
* Since this method can return multiple error results, it is recommended to check the `errorResults`
|
|
533
|
+
* array to determine if any errors occurred.
|
|
534
|
+
*
|
|
535
|
+
* @since 3.1.0
|
|
536
|
+
*/
|
|
537
|
+
async adjustOrderLines(ctx, orderId, lines, relations) {
|
|
538
|
+
const order = await this.getOrderOrThrow(ctx, orderId);
|
|
539
|
+
const errorResults = [];
|
|
540
|
+
const updatedOrderLines = [];
|
|
541
|
+
adjustLine: for (const line of lines) {
|
|
542
|
+
const { orderLineId, quantity, customFields } = line;
|
|
543
|
+
const orderLine = this.getOrderLineOrThrow(order, orderLineId);
|
|
544
|
+
const validationError = this.assertAddingItemsState(order) ||
|
|
545
|
+
this.assertQuantityIsPositive(quantity) ||
|
|
546
|
+
this.assertNotOverOrderItemsLimit(order, quantity - orderLine.quantity) ||
|
|
547
|
+
this.assertNotOverOrderLineItemsLimit(orderLine, quantity - orderLine.quantity);
|
|
548
|
+
if (validationError) {
|
|
549
|
+
errorResults.push(validationError);
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
const { orderInterceptors } = this.configService.orderOptions;
|
|
553
|
+
for (const interceptor of orderInterceptors) {
|
|
554
|
+
if (interceptor.willAdjustOrderLine) {
|
|
555
|
+
const error = await interceptor.willAdjustOrderLine(ctx, order, {
|
|
556
|
+
orderLine,
|
|
557
|
+
quantity,
|
|
558
|
+
customFields,
|
|
559
|
+
});
|
|
560
|
+
if (error) {
|
|
561
|
+
errorResults.push(new generated_graphql_shop_errors_1.OrderInterceptorError({ interceptorError: error }));
|
|
562
|
+
continue adjustLine;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
if (customFields != null) {
|
|
567
|
+
orderLine.customFields = customFields;
|
|
568
|
+
await this.customFieldRelationService.updateRelations(ctx, order_line_entity_1.OrderLine, { customFields }, orderLine);
|
|
569
|
+
}
|
|
570
|
+
const existingQuantityInOtherLines = (0, shared_utils_1.summate)(order.lines.filter(l => (0, utils_1.idsAreEqual)(l.productVariantId, orderLine.productVariantId) &&
|
|
571
|
+
!(0, utils_1.idsAreEqual)(l.id, orderLineId)), 'quantity');
|
|
572
|
+
const correctedQuantity = await this.orderModifier.constrainQuantityToSaleable(ctx, orderLine.productVariant, quantity, 0, existingQuantityInOtherLines);
|
|
573
|
+
if (correctedQuantity === 0) {
|
|
574
|
+
order.lines = order.lines.filter(l => !(0, utils_1.idsAreEqual)(l.id, orderLine.id));
|
|
575
|
+
const deletedOrderLine = new order_line_entity_1.OrderLine(orderLine);
|
|
576
|
+
await this.connection.getRepository(ctx, order_line_entity_1.OrderLine).remove(orderLine);
|
|
577
|
+
await this.eventBus.publish(new order_line_event_1.OrderLineEvent(ctx, order, deletedOrderLine, 'deleted'));
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
await this.orderModifier.updateOrderLineQuantity(ctx, orderLine, correctedQuantity, order);
|
|
581
|
+
updatedOrderLines.push(orderLine);
|
|
582
|
+
}
|
|
583
|
+
const quantityWasAdjustedDown = correctedQuantity < quantity;
|
|
584
|
+
if (quantityWasAdjustedDown) {
|
|
585
|
+
errorResults.push(new generated_graphql_shop_errors_1.InsufficientStockError({
|
|
586
|
+
quantityAvailable: correctedQuantity,
|
|
587
|
+
order,
|
|
588
|
+
}));
|
|
589
|
+
}
|
|
491
590
|
}
|
|
492
|
-
|
|
493
|
-
|
|
591
|
+
const updatedOrder = await this.applyPriceAdjustments(ctx, order, updatedOrderLines, relations);
|
|
592
|
+
for (const [i, errorResult] of Object.entries(errorResults)) {
|
|
593
|
+
if (errorResult.__typename === 'InsufficientStockError') {
|
|
594
|
+
errorResults[+i] = new generated_graphql_shop_errors_1.InsufficientStockError({
|
|
595
|
+
quantityAvailable: errorResult.quantityAvailable,
|
|
596
|
+
order: updatedOrder,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
494
599
|
}
|
|
600
|
+
return {
|
|
601
|
+
order: updatedOrder,
|
|
602
|
+
errorResults,
|
|
603
|
+
};
|
|
495
604
|
}
|
|
496
605
|
/**
|
|
497
606
|
* @description
|
|
498
607
|
* Removes the specified OrderLine from the Order.
|
|
608
|
+
*
|
|
609
|
+
* If you need to remove multiple OrderLines, use `removeItemsFromOrder()` instead.
|
|
499
610
|
*/
|
|
500
611
|
async removeItemFromOrder(ctx, orderId, orderLineId) {
|
|
612
|
+
return this.removeItemsFromOrder(ctx, orderId, [orderLineId]);
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* @description
|
|
616
|
+
* Removes the specified OrderLines from the Order.
|
|
617
|
+
* This method is more efficient than calling `removeItemFromOrder` multiple times, as it only needs to fetch
|
|
618
|
+
* the entire Order once, and only performs price adjustments once at the end.
|
|
619
|
+
*
|
|
620
|
+
* @since 3.1.0
|
|
621
|
+
*/
|
|
622
|
+
async removeItemsFromOrder(ctx, orderId, orderLineIds) {
|
|
501
623
|
const order = await this.getOrderOrThrow(ctx, orderId);
|
|
502
624
|
const validationError = this.assertAddingItemsState(order);
|
|
503
625
|
if (validationError) {
|
|
504
626
|
return validationError;
|
|
505
627
|
}
|
|
506
|
-
const
|
|
507
|
-
|
|
628
|
+
const orderLinesToDelete = [];
|
|
629
|
+
for (const orderLineId of orderLineIds) {
|
|
630
|
+
const orderLine = this.getOrderLineOrThrow(order, orderLineId);
|
|
631
|
+
const { orderInterceptors } = this.configService.orderOptions;
|
|
632
|
+
for (const interceptor of orderInterceptors) {
|
|
633
|
+
if (interceptor.willRemoveItemFromOrder) {
|
|
634
|
+
const error = await interceptor.willRemoveItemFromOrder(ctx, order, orderLine);
|
|
635
|
+
if (error) {
|
|
636
|
+
return new generated_graphql_shop_errors_1.OrderInterceptorError({ interceptorError: error });
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
orderLinesToDelete.push(orderLine);
|
|
641
|
+
}
|
|
642
|
+
order.lines = order.lines.filter(line => !orderLineIds.find(olId => (0, utils_1.idsAreEqual)(line.id, olId)));
|
|
508
643
|
// Persist the orderLine removal before applying price adjustments
|
|
509
644
|
// so that any hydration of the Order entity during the course of the
|
|
510
645
|
// `applyPriceAdjustments()` (e.g. in a ShippingEligibilityChecker etc)
|
|
511
646
|
// will not re-add the OrderLine.
|
|
512
647
|
await this.connection.getRepository(ctx, order_entity_1.Order).save(order, { reload: false });
|
|
513
648
|
const updatedOrder = await this.applyPriceAdjustments(ctx, order);
|
|
514
|
-
const
|
|
515
|
-
|
|
516
|
-
|
|
649
|
+
for (const orderLine of orderLinesToDelete) {
|
|
650
|
+
const deletedOrderLine = new order_line_entity_1.OrderLine(orderLine);
|
|
651
|
+
await this.connection.getRepository(ctx, order_line_entity_1.OrderLine).remove(orderLine);
|
|
652
|
+
await this.eventBus.publish(new order_line_event_1.OrderLineEvent(ctx, order, deletedOrderLine, 'deleted'));
|
|
653
|
+
}
|
|
517
654
|
return updatedOrder;
|
|
518
655
|
}
|
|
519
656
|
/**
|
|
@@ -675,6 +812,52 @@ let OrderService = class OrderService {
|
|
|
675
812
|
this.requestCache.set(ctx, constants_1.CacheKey.ActiveTaxZone_PPA, undefined);
|
|
676
813
|
return this.applyPriceAdjustments(ctx, order, order.lines);
|
|
677
814
|
}
|
|
815
|
+
/**
|
|
816
|
+
* @description
|
|
817
|
+
* Unsets the shipping address for the Order.
|
|
818
|
+
*
|
|
819
|
+
* @since 3.1.0
|
|
820
|
+
*/
|
|
821
|
+
async unsetShippingAddress(ctx, orderId) {
|
|
822
|
+
const order = await this.getOrderOrThrow(ctx, orderId);
|
|
823
|
+
await this.connection
|
|
824
|
+
.getRepository(ctx, order_entity_1.Order)
|
|
825
|
+
.createQueryBuilder('order')
|
|
826
|
+
.update(order_entity_1.Order)
|
|
827
|
+
.set({ shippingAddress: {} })
|
|
828
|
+
.where('id = :id', { id: order.id })
|
|
829
|
+
.execute();
|
|
830
|
+
order.shippingAddress = {};
|
|
831
|
+
// Since a changed ShippingAddress could alter the activeTaxZone,
|
|
832
|
+
// we will remove any cached activeTaxZone, so it can be re-calculated
|
|
833
|
+
// as needed.
|
|
834
|
+
this.requestCache.set(ctx, constants_1.CacheKey.ActiveTaxZone, undefined);
|
|
835
|
+
this.requestCache.set(ctx, constants_1.CacheKey.ActiveTaxZone_PPA, undefined);
|
|
836
|
+
return this.applyPriceAdjustments(ctx, order, order.lines);
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* @description
|
|
840
|
+
* Unsets the billing address for the Order.
|
|
841
|
+
*
|
|
842
|
+
* @since 3.1.0
|
|
843
|
+
*/
|
|
844
|
+
async unsetBillingAddress(ctx, orderId) {
|
|
845
|
+
const order = await this.getOrderOrThrow(ctx, orderId);
|
|
846
|
+
await this.connection
|
|
847
|
+
.getRepository(ctx, order_entity_1.Order)
|
|
848
|
+
.createQueryBuilder('order')
|
|
849
|
+
.update(order_entity_1.Order)
|
|
850
|
+
.set({ billingAddress: {} })
|
|
851
|
+
.where('id = :id', { id: order.id })
|
|
852
|
+
.execute();
|
|
853
|
+
order.billingAddress = {};
|
|
854
|
+
// Since a changed BillingAddress could alter the activeTaxZone,
|
|
855
|
+
// we will remove any cached activeTaxZone, so it can be re-calculated
|
|
856
|
+
// as needed.
|
|
857
|
+
this.requestCache.set(ctx, constants_1.CacheKey.ActiveTaxZone, undefined);
|
|
858
|
+
this.requestCache.set(ctx, constants_1.CacheKey.ActiveTaxZone_PPA, undefined);
|
|
859
|
+
return this.applyPriceAdjustments(ctx, order, order.lines);
|
|
860
|
+
}
|
|
678
861
|
/**
|
|
679
862
|
* @description
|
|
680
863
|
* Returns an array of quotes stating which {@link ShippingMethod}s may be applied to this Order.
|
|
@@ -1246,32 +1429,36 @@ let OrderService = class OrderService {
|
|
|
1246
1429
|
if (orderToDelete) {
|
|
1247
1430
|
await this.deleteOrder(ctx, orderToDelete);
|
|
1248
1431
|
}
|
|
1249
|
-
if (order &&
|
|
1432
|
+
if (order && linesToDelete) {
|
|
1250
1433
|
const orderId = order.id;
|
|
1251
|
-
for (const line of
|
|
1252
|
-
const result = await this.
|
|
1434
|
+
for (const line of linesToDelete) {
|
|
1435
|
+
const result = await this.removeItemFromOrder(ctx, orderId, line.orderLineId);
|
|
1253
1436
|
if (!(0, error_result_1.isGraphQlErrorResult)(result)) {
|
|
1254
1437
|
order = result;
|
|
1255
1438
|
}
|
|
1256
1439
|
}
|
|
1257
1440
|
}
|
|
1441
|
+
if (order && linesToInsert) {
|
|
1442
|
+
const orderId = order.id;
|
|
1443
|
+
const result = await this.addItemsToOrder(ctx, orderId, linesToInsert);
|
|
1444
|
+
order = result.order;
|
|
1445
|
+
}
|
|
1258
1446
|
if (order && linesToModify) {
|
|
1259
1447
|
const orderId = order.id;
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
if (!(0, error_result_1.isGraphQlErrorResult)(result)) {
|
|
1263
|
-
order = result;
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1448
|
+
const result = await this.adjustOrderLines(ctx, orderId, linesToModify);
|
|
1449
|
+
order = result.order;
|
|
1266
1450
|
}
|
|
1267
1451
|
if (order && linesToDelete) {
|
|
1268
1452
|
const orderId = order.id;
|
|
1269
|
-
|
|
1270
|
-
const result = await this.
|
|
1453
|
+
try {
|
|
1454
|
+
const result = await this.removeItemsFromOrder(ctx, orderId, linesToDelete.map(l => l.orderLineId));
|
|
1271
1455
|
if (!(0, error_result_1.isGraphQlErrorResult)(result)) {
|
|
1272
1456
|
order = result;
|
|
1273
1457
|
}
|
|
1274
1458
|
}
|
|
1459
|
+
catch (e) {
|
|
1460
|
+
vendure_logger_1.Logger.error(e.message, undefined, e.stack);
|
|
1461
|
+
}
|
|
1275
1462
|
}
|
|
1276
1463
|
const customer = await this.customerService.findOneByUserId(ctx, user.id);
|
|
1277
1464
|
if (order && customer) {
|