Feat(medusa): handle reservation quantity update for line items (#3484)

**What**
-  Raise exception if a reservation is updated or created to have larger quantity than is unfulfilled for a line-item

Fixes CORE-1249
This commit is contained in:
Philip Korsholm
2023-03-16 09:15:39 +00:00
committed by GitHub
parent 061a600f80
commit 38c8d49f46
6 changed files with 281 additions and 0 deletions
@@ -1,6 +1,8 @@
import { IsNumber, IsObject, IsOptional, IsString } from "class-validator"
import { isDefined } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import { IInventoryService } from "../../../../interfaces"
import { validateUpdateReservationQuantity } from "./utils/validate-reservation-quantity"
/**
* @oas [post] /admin/reservations
@@ -69,6 +71,17 @@ export default async (req, res) => {
const inventoryService: IInventoryService =
req.scope.resolve("inventoryService")
if (isDefined(validatedBody.line_item_id)) {
await validateUpdateReservationQuantity(
validatedBody.line_item_id,
validatedBody.quantity,
{
lineItemService: req.scope.resolve("lineItemService"),
inventoryService: req.scope.resolve("inventoryService"),
}
)
}
const reservation = await manager.transaction(async (manager) => {
return await inventoryService
.withTransaction(manager)
@@ -1,6 +1,9 @@
import { IsNumber, IsObject, IsOptional, IsString } from "class-validator"
import { isDefined, MedusaError } from "medusa-core-utils"
import { EntityManager } from "typeorm"
import { IInventoryService } from "../../../../interfaces"
import { LineItemService } from "../../../../services"
import { validateUpdateReservationQuantity } from "./utils/validate-reservation-quantity"
/**
* @oas [post] /admin/reservations/{id}
@@ -69,10 +72,24 @@ export default async (req, res) => {
}
const manager: EntityManager = req.scope.resolve("manager")
const lineItemService: LineItemService = req.scope.resolve("lineItemService")
const inventoryService: IInventoryService =
req.scope.resolve("inventoryService")
const reservation = await inventoryService.retrieveReservationItem(id)
if (reservation.line_item_id && isDefined(validatedBody.quantity)) {
await validateUpdateReservationQuantity(
reservation.line_item_id,
validatedBody.quantity - reservation.quantity,
{
lineItemService,
inventoryService,
}
)
}
const result = await manager.transaction(async (manager) => {
await inventoryService
.withTransaction(manager)
@@ -0,0 +1,31 @@
import { MedusaError } from "medusa-core-utils"
import { IInventoryService } from "../../../../../interfaces"
import { LineItemService } from "../../../../../services"
export const validateUpdateReservationQuantity = async (
lineItemId: string,
quantityUpdate: number,
context: {
lineItemService: LineItemService
inventoryService: IInventoryService
}
) => {
const { lineItemService, inventoryService } = context
const [reservationItems] = await inventoryService.listReservationItems({
line_item_id: lineItemId,
})
const totalQuantity = reservationItems.reduce(
(acc, cur) => acc + cur.quantity,
quantityUpdate
)
const lineItem = await lineItemService.retrieve(lineItemId)
if (totalQuantity > lineItem.quantity - (lineItem.fulfilled_quantity || 0)) {
throw new MedusaError(
MedusaError.Types.INVALID_DATA,
"The reservation quantity cannot be greater than the unfulfilled line item quantity"
)
}
}