fix: creates restock functionality

This commit is contained in:
Sebastian Rindom committed 2021-04-06 12:22:19 +02:00
1 parent 0a80b098a4
commit 2b2555004e
17 files changed
+2673 -259

No files matched your search

@@ -0,0 +1,10 @@
import { Router } from "express"
import routes from "./routes"
export default (container) => {
const app = Router()
routes(app)
return app
}
@@ -0,0 +1 @@
export default (fn) => (...args) => fn(...args).catch(args[2])
@@ -0,0 +1,5 @@
import { default as wrap } from "./await-middleware"
export default {
wrap,
}
@@ -0,0 +1,24 @@
import { Validator, MedusaError } from "medusa-core-utils"
export default async (req, res) => {
const { variant_id } = req.parmas
const schema = Validator.object().keys({
email: Validator.string().required(),
})
const { value, error } = schema.validate(req.body)
if (error) {
throw new MedusaError(MedusaError.Types.INVALID_DATA, error.details)
}
try {
const restockNotificationService = req.scope.resolve(
"restockNotificationService"
)
await restockNotificationService.addEmail(variant_id, value.email)
res.sendStatus(200)
} catch (err) {
res.sendStatus(400).json({ message: err.message })
}
}
@@ -0,0 +1,16 @@
import { Router } from "express"
import bodyParser from "body-parser"
import middlewares from "../middleware"
const route = Router()
export default (app) => {
app.use("/restock-notifications", route)
route.post(
"/variants/:variant_id",
bodyParser.raw({ type: "application/json" }),
middlewares.wrap(require("./add-email").default)
)
return app
}
@@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from "typeorm"
export class restockNotification1617703530229 implements MigrationInterface {
name = "restockNotification1617703530229"
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TABLE "restock_notification" ("variant_id" character varying NOT NULL, "emails" jsonb NOT NULL, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), CONSTRAINT "PK_49181ca04caac807fcec321705a" PRIMARY KEY ("variant_id"))`
)
await queryRunner.query(
`ALTER TABLE "restock_notification" ADD CONSTRAINT "FK_49181ca04caac807fcec321705a" FOREIGN KEY ("variant_id") REFERENCES "product_variant"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`
)
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "restock_notification" DROP CONSTRAINT "FK_49181ca04caac807fcec321705a"`
)
await queryRunner.query(`DROP TABLE "restock_notification"`)
}
}
@@ -1,16 +1,10 @@
import { MedusaError } from "medusa-core-utils"
import { BaseService } from "medusa-interfaces"
import { RestockNotification } from "../models/restock-notification"
class RestockNotificationService extends BaseService {
constructor(
{
manager,
eventBusService,
productVariantService,
restockNotificationRepository,
},
options
) {
constructor({ manager, eventBusService, productVariantService }, options) {
super()
this.manager_ = manager
@@ -19,23 +13,17 @@ class RestockNotificationService extends BaseService {
this.productVariantService_ = productVariantService
this.restockNotificationRepo_ = restockNotificationRepository
this.eventBus_ = eventBusService
}
async retrieve(variantId) {
const restockRepo = this.manager_.getCustomRepository(
this.restockNotificationRepo_
)
const restockRepo = this.manager_.getRepository(RestockNotification)
return await restockRepo.findOne({ where: { variant_id: variantId } })
}
async addEmail(variantId, email) {
return this.atomicPhase_(async (manager) => {
const restockRepo = manager.getCustomRepository(
this.restockNotificationRepo_
)
const restockRepo = manager.getRepository(RestockNotification)
const existing = await this.retrieve(variantId)
if (existing) {
@@ -66,6 +54,13 @@ class RestockNotificationService extends BaseService {
})
}
async delete(variantId) {
return this.atomicPhase_(async (manager) => {
const restockRepo = manager.getRepository(RestockNotification)
return restockRepo.delete(variantId)
})
}
async triggerRestock(variantId) {
return this.atomicPhase_(async (manager) => {
const existing = await this.retrieve(variantId)
@@ -73,7 +68,13 @@ class RestockNotificationService extends BaseService {
return
}
const variant = await this.productVariantService_.retrieve(variantId)
if (variant.inventory_quantity > 0) {
await eventBus_
.withTransaction(manager)
.emit("restock_notification.restocked")
await this.delete(variantId)
}
})
}
}
@@ -1,81 +1,19 @@
class VariantSubscriber {
constructor({
eventBusService,
restockNotificationService,
productVariantService,
}) {
constructor({ eventBusService, restockNotificationService }) {
this.restockNotificationService_ = restockNotificationService
eventBusService.subscribe("product_variant.updated", this.handleVariantUpdate)
eventBusService.subscribe(
"product_variant.updated",
this.handleVariantUpdate
)
}
registerClaim = async (data) => {
const { id } = data
const fromClaim = await this.claimService_.retrieve(id, {
relations: [
"order",
"order.payments",
"order.region",
"order.claims",
"order.discounts",
"claim_items",
"return_order",
"return_order.items",
"return_order.shipping_method",
"additional_items",
"shipping_address",
"shipping_methods",
],
})
const fromOrder = fromClaim.order
if (fromClaim.type === "replace") {
await this.brightpearlService_.createClaim(fromOrder, fromClaim)
} else if (fromClaim.type === "refund") {
await this.brightpearlService_.createClaimCredit(fromOrder, fromClaim)
handleVariantUpdate = async (data) => {
const { id, fields } = data
if (fields.includes("inventory_quantity")) {
return this.restockNotificationService_.triggerRestock(id)
}
}
registerShipment = async (data) => {
const { fulfillment_id } = data
const shipment = await this.fulfillmentService_.retrieve(fulfillment_id)
const noteId = shipment.metadata.goods_out_note
if (noteId) {
await this.brightpearlService_.registerGoodsOutTrackingNumber(
noteId,
shipment
)
await this.brightpearlService_.registerGoodsOutShipped(noteId, shipment)
}
}
registerReturn = async (data) => {
const { id, return_id } = data
const order = await this.orderService_.retrieve(id, {
relations: ["region", "payments"],
})
const fromReturn = await this.returnService_.retrieve(return_id, {
relations: ["items"],
})
return this.brightpearlService_
.createSalesCredit(order, fromReturn)
.catch((err) => console.log(err))
}
registerRefund = async (data) => {
const { id, refund_id } = data
const order = await this.orderService_.retrieve(id, {
relations: ["region", "payments"],
})
const refund = await this.paymentProviderService_.retrieveRefund(refund_id)
return this.brightpearlService_
.createRefundCredit(order, refund)
.catch((err) => console.log(err))
}
}
export default OrderSubscriber
export default VariantSubscriber