Skip to content

Commit

Permalink
Merge pull request #292 from Pinelab-studio/feat/picqer-virtual-stock
Browse files Browse the repository at this point in the history
Feat/picqer virtual stock
  • Loading branch information
martijnvdbrug authored Nov 14, 2023
2 parents 23fff13 + 05f6826 commit 1c4a087
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
4 changes: 4 additions & 0 deletions packages/vendure-plugin-picqer/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 2.2.0 (2023-11-14)

- Update stock of virtual/assembled products based on assembled_stock webhook

# 2.2.0 (2023-11-02)

- Always created products as active in Picqer
Expand Down
2 changes: 1 addition & 1 deletion packages/vendure-plugin-picqer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pinelab/vendure-plugin-picqer",
"version": "2.2.0",
"version": "2.2.1",
"description": "Vendure plugin syncing to orders and stock with Picqer",
"author": "Martijn van de Brug <[email protected]>",
"homepage": "https://pinelab-plugins.com/",
Expand Down
7 changes: 6 additions & 1 deletion packages/vendure-plugin-picqer/src/api/picqer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ export class PicqerService implements OnApplicationBootstrap {
const eventsToRegister: WebhookEvent[] = [
'orders.status_changed',
'products.free_stock_changed',
'products.assembled_stock_changed',
];
for (const hookEvent of eventsToRegister) {
// Use first 4 digits of webhook secret as name, so we can identify the hook
Expand Down Expand Up @@ -280,7 +281,11 @@ export class PicqerService implements OnApplicationBootstrap {
);
throw new ForbiddenError();
}
if (input.body.event === 'products.free_stock_changed') {
if (
input.body.event === 'products.free_stock_changed' ||
input.body.event === 'products.assembled_stock_changed'
) {
const data = input.body.data;
await this.updateStockBySkus(ctx, [input.body.data]);
} else if (input.body.event === 'orders.status_changed') {
await this.handleOrderStatusChanged(ctx, input.body.data);
Expand Down
4 changes: 3 additions & 1 deletion packages/vendure-plugin-picqer/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,10 @@ export interface WebhookInput {
export type IncomingWebhook =
| IncomingProductWebhook
| IncomingOrderStatusWebhook;

export type WebhookEvent =
| 'products.free_stock_changed'
| 'products.assembled_stock_changed'
| 'orders.status_changed';

export interface WebhookData {
Expand All @@ -295,7 +297,7 @@ export interface IncomingOrderStatusWebhook {
export interface IncomingProductWebhook {
idhook: number;
name: string;
event: 'products.free_stock_changed';
event: 'products.free_stock_changed' | 'products.assembled_stock_changed';
event_triggered_at: string;
data: ProductData;
}
32 changes: 30 additions & 2 deletions packages/vendure-plugin-picqer/test/picqer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,17 @@ describe('Picqer plugin', function () {

it('Should have created hooks when config was updated', async () => {
// Expect 1 created hook: stock change
await expect(createdHooks.length).toBe(2);
await expect(createdHooks.length).toBe(3);
await expect(createdHooks[0].event).toBe('orders.status_changed');
await expect(createdHooks[0].address).toBe(
`https://example-vendure.io/picqer/hooks/${E2E_DEFAULT_CHANNEL_TOKEN}`
);
await expect(createdHooks[0].secret).toBeDefined();
await expect(createdHooks[0].name).toBeDefined();
await expect(createdHooks[1].event).toBe('products.free_stock_changed');
await expect(createdHooks[2].event).toBe(
'products.assembled_stock_changed'
);
});

it('Should get Picqer config after upsert', async () => {
Expand Down Expand Up @@ -383,7 +386,7 @@ describe('Picqer plugin', function () {
expect(updatedProduct!.price).toBe(123.45);
});

it('Should update stock level on incoming webhook', async () => {
it('Should update stock level on incoming "free_stock" webhook', async () => {
const body = {
event: 'products.free_stock_changed',
data: {
Expand All @@ -407,6 +410,31 @@ describe('Picqer plugin', function () {
expect(variant?.stockOnHand).toBe(543);
});

it('Should update stock level on incoming "assembled_stock" webhook', async () => {
const body = {
event: 'products.assembled_stock_changed',
data: {
productcode: 'L2201308',
stock: [{ freestock: 2, idwarehouse: 2 }],
},
};
const res = await adminClient.fetch(
`http://localhost:3050/picqer/hooks/${E2E_DEFAULT_CHANNEL_TOKEN}`,
{
method: 'POST',
body: JSON.stringify(body),
headers: {
'X-Picqer-Signature': createSignature(body, 'test-api-key'),
},
}
);
const variants = await getAllVariants(adminClient);
const variant = variants.find((v) => v.sku === 'L2201308');
console.log(variant);
expect(res.ok).toBe(true);
expect(variant?.stockOnHand).toBe(2);
});

it('Should fail with invalid signature', async () => {
const res = await adminClient.fetch(
`http://localhost:3050/picqer/hooks/${E2E_DEFAULT_CHANNEL_TOKEN}`,
Expand Down

0 comments on commit 1c4a087

Please sign in to comment.