creates webhook and cron job to update inventory
This commit is contained in:
1 parent
c18677d5f2
commit
e69c3aba01
10 files changed
+317
-22
No files matched your search
@@ -0,0 +1,15 @@
|
||||
import { Router } from "express"
|
||||
import bodyParser from "body-parser"
|
||||
|
||||
export default (container) => {
|
||||
const app = Router()
|
||||
|
||||
app.post("/brightpearl/inventory-update", bodyParser.json(), async (req, res) => {
|
||||
const { id } = req.body
|
||||
const brightpearlService = req.scope.resolve("brightpearlService")
|
||||
await brightpearlService.updateInventory(id)
|
||||
res.sendStatus(200)
|
||||
})
|
||||
|
||||
return app
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
const inventorySync = container => {
|
||||
const brightpearlService = container.resolve("brightpearlService")
|
||||
const eventBus = container.resolve("eventBusService")
|
||||
const pattern = "43 4,10,14,20 * * *" // nice for tests "*/10 * * * * *"
|
||||
eventBus.createCronJob("inventory-sync", {}, pattern, brightpearlService.syncInventory())
|
||||
}
|
||||
|
||||
export default inventorySync
|
||||
@@ -0,0 +1,6 @@
|
||||
const webhookLoader = async (container) => {
|
||||
const brightpearlService = container.resolve("brightpearlService")
|
||||
await brightpearlService.verifyWebhooks()
|
||||
}
|
||||
|
||||
export default webhookLoader
|
||||
@@ -2,10 +2,11 @@ import { BaseService } from "medusa-interfaces"
|
||||
import Brightpearl from "../utils/brightpearl"
|
||||
|
||||
class BrightpearlService extends BaseService {
|
||||
constructor({ totalsService, regionService, orderService, discountService }, options) {
|
||||
constructor({ totalsService, productVariantService, regionService, orderService, discountService }, options) {
|
||||
super()
|
||||
|
||||
this.options = options
|
||||
this.productVariantService_ = productVariantService
|
||||
this.regionService_ = regionService
|
||||
this.orderService_ = orderService
|
||||
this.totalsService_ = totalsService
|
||||
@@ -19,6 +20,69 @@ class BrightpearlService extends BaseService {
|
||||
})
|
||||
}
|
||||
|
||||
async verifyWebhooks() {
|
||||
const hooks = [
|
||||
{
|
||||
subscribeTo: "product.modified.on-hand-modified",
|
||||
httpMethod: "POST",
|
||||
uriTemplate: `${this.options.backend_url}/brightpearl/inventory-update`,
|
||||
bodyTemplate: '{"account": "${account-code}", "lifecycleEvent": "${lifecycle-event}", "resourceType": "${resource-type}", "id": "${resource-id}" }',
|
||||
contentType: "application/json",
|
||||
idSetAccepted: false,
|
||||
}
|
||||
]
|
||||
|
||||
const installedHooks = await this.brightpearl_.webhooks.list().catch(() => [])
|
||||
for (const hook of hooks) {
|
||||
const isInstalled = installedHooks.find(i =>
|
||||
i.subscribeTo === hook.subscribeTo &&
|
||||
i.httpMethod === hook.httpMethod &&
|
||||
i.uriTemplate === hook.uriTemplate &&
|
||||
i.bodyTemplate === hook.bodyTemplate &&
|
||||
i.contentType === hook.contentType &&
|
||||
i.idSetAccepted === hook.idSetAccepted
|
||||
)
|
||||
|
||||
if (!isInstalled) {
|
||||
await this.brightpearl_.webhooks.create(hook)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async syncInventory() {
|
||||
const variants = await this.productVariantService_.list()
|
||||
return Promise.all(variants.map(async v => {
|
||||
const brightpearlProduct = await this.retrieveProductBySKU(v.sku)
|
||||
if (!brightpearlProduct) {
|
||||
return
|
||||
}
|
||||
|
||||
const { productId } = brightpearlProduct
|
||||
const availability = await this.brightpearl_.products.retrieveAvailability(productId)
|
||||
const onHand = availability[productId].total.onHand
|
||||
|
||||
return this.productVariantService_.update(v._id, {
|
||||
inventory_quantity: onHand
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
async updateInventory(productId) {
|
||||
const brightpearlProduct = await this.brightpearl_.products.retrieve(productId)
|
||||
const availability = await this.brightpearl_.products.retrieveAvailability(productId)
|
||||
|
||||
const onHand = availability[productId].total.onHand
|
||||
|
||||
const sku = brightpearlProduct.identity.sku
|
||||
const [ variant ] = await this.productVariantService_.list({ sku })
|
||||
|
||||
if (variant && variant.manage_inventory) {
|
||||
await this.productVariantService_.update(variant._id, {
|
||||
inventory_quantity: onHand
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
async createGoodsOutNote(fromOrder, shipment) {
|
||||
const id = fromOrder.metadata && fromOrder.metadata.brightpearl_sales_order_id
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ class BrightpearlClient {
|
||||
},
|
||||
})
|
||||
|
||||
this.webhooks = this.buildWebhookEndpoints()
|
||||
this.payments = this.buildPaymentEndpoints()
|
||||
this.warehouses = this.buildWarehouseEndpoints()
|
||||
this.orders = this.buildOrderEndpoints()
|
||||
@@ -31,6 +32,25 @@ class BrightpearlClient {
|
||||
})
|
||||
}
|
||||
|
||||
buildWebhookEndpoints = () => {
|
||||
return {
|
||||
list: () => {
|
||||
return this.client_.request({
|
||||
url: `/integration-service/webhook`,
|
||||
method: "GET",
|
||||
})
|
||||
.then(({ data }) => data.response)
|
||||
},
|
||||
create: (data) => {
|
||||
return this.client_.request({
|
||||
url: `/integration-service/webhook`,
|
||||
method: "POST",
|
||||
data
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buildPaymentEndpoints = () => {
|
||||
return {
|
||||
create: (payment) => {
|
||||
@@ -128,6 +148,18 @@ class BrightpearlClient {
|
||||
|
||||
buildProductEndpoints = () => {
|
||||
return {
|
||||
retrieveAvailability: productId => {
|
||||
return this.client_.request({
|
||||
url: `/warehouse-service/product-availability/${productId}`,
|
||||
})
|
||||
.then(({ data }) => data.response && data.response)
|
||||
},
|
||||
retrieve: (productId) => {
|
||||
return this.client_.request({
|
||||
url: `/product-service/product/${productId}`,
|
||||
})
|
||||
.then(({ data }) => data.response && data.response[0])
|
||||
},
|
||||
retrieveBySKU: (sku) => {
|
||||
return this.client_.request({
|
||||
url: `/product-service/product-search?SKU=${sku}`,
|
||||
|
||||
Reference in new issue
Block a user