Skip to content

Commit

Permalink
fix(docs): Correct free-gift-action example (#2524)
Browse files Browse the repository at this point in the history
  • Loading branch information
lzzfnc authored Nov 14, 2023
1 parent feecfae commit fedd554
Showing 1 changed file with 80 additions and 73 deletions.
153 changes: 80 additions & 73 deletions docs/docs/guides/core-concepts/promotions/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,88 +164,95 @@ A primary use-case of this API is to add a free gift to the Order. Here's an exa

```ts title="src/plugins/free-gift/free-gift.plugin.ts"
import {
ID, idsAreEqual, isGraphQlErrorResult, LanguageCode,
Logger, OrderLine, OrderService, PromotionItemAction, VendurePlugin,
} from '@vendure/core';
import { createHash } from 'crypto';
ID, idsAreEqual, isGraphQlErrorResult, LanguageCode, Logger,
OrderLine, OrderService, PromotionItemAction, VendurePlugin,
} from "@vendure/core";
import { createHash } from "crypto";

let orderService: OrderService;
export const freeGiftAction = new PromotionItemAction({
code: 'free_gift',
description: [{languageCode: LanguageCode.en, value: 'Add free gifts to the order'}],
args: {
productVariantIds: {
type: 'ID',
list: true,
ui: {component: 'product-selector-form-input'},
label: [{languageCode: LanguageCode.en, value: 'Gift product variants'}],
},
},
init(injector) {
orderService = injector.get(OrderService);
},
execute(ctx, orderItem, orderLine, args) {
// This part is responsible for ensuring the variants marked as
// "free gifts" have their price reduced to zero.
if (lineContainsIds(args.productVariantIds, orderLine)) {
const unitPrice = orderLine.productVariant.listPriceIncludesTax
? orderLine.unitPriceWithTax
: orderLine.unitPrice;
return -unitPrice;
}
return 0;
},
// The onActivate function is part of the side effect API, and
// allows us to perform some action whenever a Promotion becomes active
// due to it's conditions & constraints being satisfied.
async onActivate(ctx, order, args, promotion) {
for (const id of args.productVariantIds) {
if (
!order.lines.find(
(line) =>
idsAreEqual(line.productVariant.id, id) &&
line.customFields.freeGiftDescription == null,
)
) {
// The order does not yet contain this free gift, so add it
const result = await orderService.addItemToOrder(ctx, order.id, id, 1, {
freeGiftPromotionId: promotion.id.toString(),
});
if (isGraphQlErrorResult(result)) {
Logger.error(`Free gift action error for variantId "${id}": ${result.message}`);
}
}
}
},
// The onDeactivate function is the other part of the side effect API and is called
// when an active Promotion becomes no longer active. It should reverse any
// side effect performed by the onActivate function.
async onDeactivate(ctx, order, args, promotion) {
const linesWithFreeGift = order.lines.filter(
(line) => line.customFields.freeGiftPromotionId === promotion.id.toString(),
);
for (const line of linesWithFreeGift) {
await orderService.removeItemFromOrder(ctx, order.id, line.id);
}
},
code: "free_gift",
description: [{ languageCode: LanguageCode.en, value: "Add free gifts to the order" }],
args: {
productVariantIds: {
type: "ID",
list: true,
ui: { component: "product-selector-form-input" },
label: [{ languageCode: LanguageCode.en, value: "Gift product variants" }],
},
},
init(injector) {
orderService = injector.get(OrderService);
},
execute(ctx, orderLine, args) {
// This part is responsible for ensuring the variants marked as
// "free gifts" have their price reduced to zero
if (lineContainsIds(args.productVariantIds, orderLine)) {
const unitPrice = orderLine.productVariant.listPriceIncludesTax
? orderLine.unitPriceWithTax
: orderLine.unitPrice;
return -unitPrice;
}
return 0;
},
// The onActivate function is part of the side effect API, and
// allows us to perform some action whenever a Promotion becomes active
// due to it's conditions & constraints being satisfied.
async onActivate(ctx, order, args, promotion) {
for (const id of args.productVariantIds) {
if (
!order.lines.find(
(line) =>
idsAreEqual(line.productVariant.id, id) &&
line.customFields.freeGiftPromotionId == null
)
) {
// The order does not yet contain this free gift, so add it
const result = await orderService.addItemToOrder(ctx, order.id, id, 1, {
freeGiftPromotionId: promotion.id.toString(),
});
if (isGraphQlErrorResult(result)) {
Logger.error(`Free gift action error for variantId "${id}": ${result.message}`);
}
}
}
},
// The onDeactivate function is the other part of the side effect API and is called
// when an active Promotion becomes no longer active. It should reverse any
// side effect performed by the onActivate function.
async onDeactivate(ctx, order, args, promotion) {
const linesWithFreeGift = order.lines.filter(
(line) => line.customFields.freeGiftPromotionId === promotion.id.toString()
);
for (const line of linesWithFreeGift) {
await orderService.removeItemFromOrder(ctx, order.id, line.id);
}
},
});

function lineContainsIds(ids: ID[], line: OrderLine): boolean {
return !!ids.find((id) => idsAreEqual(id, line.productVariant.id));
return !!ids.find((id) => idsAreEqual(id, line.productVariant.id));
}

@VendurePlugin({
configuration: config => {
config.promotionOptions.promotionActions.push(freeGiftAction);
config.customFields.OrderItem.push(
{
name: 'freeGiftPromotionId',
type: 'string',
public: true,
readonly: true,
nullable: true,
})
}
configuration: (config) => {
config.customFields.OrderLine.push({
name: "freeGiftPromotionId",
type: "string",
public: true,
readonly: true,
nullable: true,
});
config.customFields.OrderLine.push({
name: "freeGiftDescription",
type: "string",
public: true,
readonly: true,
nullable: true,
});
config.promotionOptions.promotionActions.push(freeGiftAction);
return config;
},
})
export class FreeGiftPromotionPlugin {}
```
Expand Down

0 comments on commit fedd554

Please sign in to comment.