@pinelab/vendure-plugin-qls-fulfillment 1.0.0-beta.17 → 1.0.0-beta.19

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.
@@ -24,7 +24,11 @@ const qls_order_service_1 = require("./services/qls-order.service");
24
24
  const qls_product_service_1 = require("./services/qls-product.service");
25
25
  let QlsPlugin = QlsPlugin_1 = class QlsPlugin {
26
26
  static init(options) {
27
- this.options = options;
27
+ this.options = {
28
+ synchronizeStockLevels: true,
29
+ autoPushOrders: true,
30
+ ...options,
31
+ };
28
32
  return QlsPlugin_1;
29
33
  }
30
34
  };
@@ -1,18 +1,17 @@
1
1
  import { OnApplicationBootstrap, OnModuleInit } from '@nestjs/common';
2
2
  import { ModuleRef } from '@nestjs/core';
3
- import { EventBus, ID, Job, JobQueueService, OrderService, RequestContext, TransactionalConnection } from '@vendure/core';
3
+ import { EventBus, ID, Job, JobQueueService, OrderService, RequestContext } from '@vendure/core';
4
+ import { QlsServicePoint, QlsServicePointSearchInput } from '../api/generated/graphql';
4
5
  import { IncomingOrderWebhook } from '../lib/client-types';
5
6
  import { QlsOrderJobData, QlsPluginOptions } from '../types';
6
- import { QlsServicePoint, QlsServicePointSearchInput } from '../api/generated/graphql';
7
7
  export declare class QlsOrderService implements OnModuleInit, OnApplicationBootstrap {
8
- private connection;
9
8
  private options;
10
9
  private jobQueueService;
11
10
  private eventBus;
12
11
  private orderService;
13
12
  private moduleRef;
14
13
  private orderJobQueue;
15
- constructor(connection: TransactionalConnection, options: QlsPluginOptions, jobQueueService: JobQueueService, eventBus: EventBus, orderService: OrderService, moduleRef: ModuleRef);
14
+ constructor(options: QlsPluginOptions, jobQueueService: JobQueueService, eventBus: EventBus, orderService: OrderService, moduleRef: ModuleRef);
16
15
  onApplicationBootstrap(): void;
17
16
  onModuleInit(): Promise<void>;
18
17
  /**
@@ -24,8 +24,7 @@ const util_1 = __importDefault(require("util"));
24
24
  const constants_1 = require("../constants");
25
25
  const qls_client_1 = require("../lib/qls-client");
26
26
  let QlsOrderService = class QlsOrderService {
27
- constructor(connection, options, jobQueueService, eventBus, orderService, moduleRef) {
28
- this.connection = connection;
27
+ constructor(options, jobQueueService, eventBus, orderService, moduleRef) {
29
28
  this.options = options;
30
29
  this.jobQueueService = jobQueueService;
31
30
  this.eventBus = eventBus;
@@ -35,6 +34,10 @@ let QlsOrderService = class QlsOrderService {
35
34
  onApplicationBootstrap() {
36
35
  // Listen for OrderPlacedEvent and add a job to the queue
37
36
  this.eventBus.ofType(core_2.OrderPlacedEvent).subscribe((event) => {
37
+ if (!this.options.autoPushOrders) {
38
+ core_2.Logger.info(`Auto push orders disabled, not triggering push order job for order ${event.order.code}`, constants_1.loggerCtx);
39
+ return;
40
+ }
38
41
  this.triggerPushOrder(event.ctx, event.order.id, event.order.code).catch((e) => {
39
42
  const error = (0, catch_unknown_1.asError)(e);
40
43
  core_2.Logger.error(`Failed to trigger push order job for order ${event.order.code}: ${error.message}`, constants_1.loggerCtx, error.stack);
@@ -87,7 +90,15 @@ let QlsOrderService = class QlsOrderService {
87
90
  }
88
91
  try {
89
92
  // Check if all products are available in QLS
90
- const qlsProducts = order.lines.map((line) => {
93
+ const qlsProducts = order.lines
94
+ .filter((line) => {
95
+ if (this.options.excludeVariantFromSync?.(ctx, line.productVariant)) {
96
+ core_2.Logger.info(`Product variant '${line.productVariant.sku}' not sent to QLS in order '${order.code}' because it is excluded from sync.`, constants_1.loggerCtx);
97
+ return false;
98
+ }
99
+ return true;
100
+ })
101
+ .map((line) => {
91
102
  if (!line.productVariant.customFields.qlsProductId) {
92
103
  throw new Error(`Product variant '${line.productVariant.sku}' does not have a QLS product ID set. Unable to push order '${order.code}' to QLS.`);
93
104
  }
@@ -115,10 +126,11 @@ let QlsOrderService = class QlsOrderService {
115
126
  !order.shippingAddress.countryCode) {
116
127
  throw new Error(`Shipping address for order '${order.code}' is missing one of required fields: streetLine1, postalCode, city, streetLine2, countryCode. Can not push order to QLS.`);
117
128
  }
129
+ const processable = (await this.options.processOrderFrom?.(ctx, order)) ?? new Date();
118
130
  const receiverContact = this.options.getReceiverContact?.(ctx, order);
119
131
  const qlsOrder = {
120
132
  customer_reference: order.code,
121
- processable: new Date().toISOString(), // Processable starting now
133
+ processable: processable.toISOString(),
122
134
  servicepoint_code: order.customFields?.qlsServicePointId,
123
135
  delivery_options: additionalOrderFields?.delivery_options ?? [],
124
136
  total_price: order.totalWithTax,
@@ -217,8 +229,8 @@ let QlsOrderService = class QlsOrderService {
217
229
  exports.QlsOrderService = QlsOrderService;
218
230
  exports.QlsOrderService = QlsOrderService = __decorate([
219
231
  (0, common_1.Injectable)(),
220
- __param(1, (0, common_1.Inject)(constants_1.PLUGIN_INIT_OPTIONS)),
221
- __metadata("design:paramtypes", [core_2.TransactionalConnection, Object, core_2.JobQueueService,
232
+ __param(0, (0, common_1.Inject)(constants_1.PLUGIN_INIT_OPTIONS)),
233
+ __metadata("design:paramtypes", [Object, core_2.JobQueueService,
222
234
  core_2.EventBus,
223
235
  core_2.OrderService,
224
236
  core_1.ModuleRef])
@@ -37,7 +37,8 @@ export declare class QlsProductService implements OnModuleInit, OnApplicationBoo
37
37
  */
38
38
  runFullSync(ctx: RequestContext): Promise<SyncProductsResult>;
39
39
  /**
40
- * Utility function to remove all products from QLS
40
+ * Utility function to remove all products from QLS.
41
+ * You might need to cancel active orders in QLS first, because products cannot be deleted if they are in an active order.
41
42
  */
42
43
  removeAllProductsFromQls(ctx: RequestContext): Promise<void>;
43
44
  /**
@@ -159,17 +159,19 @@ let QlsProductService = class QlsProductService {
159
159
  }
160
160
  }
161
161
  /**
162
- * Utility function to remove all products from QLS
162
+ * Utility function to remove all products from QLS.
163
+ * You might need to cancel active orders in QLS first, because products cannot be deleted if they are in an active order.
163
164
  */
164
165
  async removeAllProductsFromQls(ctx) {
165
166
  const client = await (0, qls_client_1.getQlsClient)(ctx, this.options);
166
167
  if (!client) {
167
168
  throw new Error(`QLS not enabled for channel ${ctx.channel.token}`);
168
169
  }
169
- core_1.Logger.warn(`Removed all products from QLS for channel ${ctx.channel.token}`, constants_1.loggerCtx);
170
+ core_1.Logger.warn(`Removing all products from QLS for channel ${ctx.channel.token}...`, constants_1.loggerCtx);
170
171
  const allProducts = await client.getAllFulfillmentProducts();
171
172
  for (const product of allProducts) {
172
173
  await client.deleteFulfillmentProduct(product.id);
174
+ core_1.Logger.info(`Removed product '${product.sku}' (${product.id}) from QLS`, constants_1.loggerCtx);
173
175
  await waitToPreventRateLimit();
174
176
  }
175
177
  core_1.Logger.warn(`Removed ${allProducts.length} products from QLS for channel ${ctx.channel.token}`, constants_1.loggerCtx);
@@ -400,7 +402,7 @@ let QlsProductService = class QlsProductService {
400
402
  * Update stock level for a variant based on the given available stock
401
403
  */
402
404
  async updateStock(ctx, variantId, availableStock) {
403
- if (this.options.disableStockSync) {
405
+ if (!this.options.synchronizeStockLevels) {
404
406
  core_1.Logger.warn(`Stock sync disabled. Not updating stock for variant '${variantId}'`, constants_1.loggerCtx);
405
407
  return;
406
408
  }
package/dist/types.d.ts CHANGED
@@ -21,10 +21,21 @@ export interface QlsPluginOptions {
21
21
  */
22
22
  webhookSecret: string;
23
23
  /**
24
- * Disable the pulling in of stock levels from QLS. When disabled, stock in Vendure will not be modified based on QLS stock levels.
25
- * Useful for testing out order sync separately, or testing against a QLS test env that has no stock for example
24
+ * Allows you to disable the pulling in of stock levels from QLS. When disabled, stock in Vendure will not be modified based on QLS stock levels.
25
+ * Defaults to true.
26
26
  */
27
- disableStockSync?: boolean;
27
+ synchronizeStockLevels?: boolean;
28
+ /**
29
+ * Allows you to disable the automatic pushing of orders to QLS. You can still push orders manually via the Admin UI.
30
+ * Defaults to true.
31
+ */
32
+ autoPushOrders?: boolean;
33
+ /**
34
+ * Allows you to define a date from when the order should be processed by QLS.
35
+ * You can for example make orders processable 2 hours from now, so that you can still edit the order in QLS
36
+ * Defaults to now.
37
+ */
38
+ processOrderFrom?: (ctx: RequestContext, order: Order) => Date | Promise<Date>;
28
39
  /**
29
40
  * Optional function to determine if a product variant should be excluded from syncing to QLS.
30
41
  * Return true to exclude the variant from sync, false or undefined to include it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pinelab/vendure-plugin-qls-fulfillment",
3
- "version": "1.0.0-beta.17",
3
+ "version": "1.0.0-beta.19",
4
4
  "description": "Vendure plugin to fulfill orders via QLS.",
5
5
  "keywords": [
6
6
  "fulfillment",