feat(items): adapt item flows to inventory schema defaults and SKU generation
This commit is contained in:
@@ -3,10 +3,12 @@ import prisma from "@/lib/prisma"
|
||||
import type { CreateItemData, UpdateItemData } from "@/schemas/item.schema"
|
||||
import { ItemService } from "@/services/item.service"
|
||||
import { MovementService } from "@/services/movement.service"
|
||||
import { buildItemSku } from "./item.helpers"
|
||||
|
||||
type FieldErrors = Record<string, string[]>
|
||||
|
||||
type CreateItemUseCaseInput = CreateItemData & {
|
||||
type CreateItemUseCaseInput = Omit<CreateItemData, "trackingType" | "status"> &
|
||||
Partial<Pick<CreateItemData, "trackingType" | "status">> & {
|
||||
actorId: string
|
||||
}
|
||||
|
||||
@@ -37,18 +39,19 @@ function isUniqueConstraintError(error: unknown) {
|
||||
)
|
||||
}
|
||||
|
||||
function buildSkuFromName(name: string) {
|
||||
return name
|
||||
.trim()
|
||||
.toUpperCase()
|
||||
.replace(/[^A-Z0-9]+/g, "-")
|
||||
.replace(/^-|-$/g, "")
|
||||
}
|
||||
|
||||
export async function createItemUseCase(
|
||||
input: CreateItemUseCaseInput,
|
||||
): Promise<ItemUseCaseResult> {
|
||||
const { actorId, name, categoryId, stock } = input
|
||||
const {
|
||||
actorId,
|
||||
name,
|
||||
categoryId,
|
||||
stock,
|
||||
trackingType = "QUANTITY",
|
||||
status = "ACTIVE",
|
||||
minStock,
|
||||
targetStock,
|
||||
} = input
|
||||
|
||||
if (stock < 0) {
|
||||
return itemError({ stock: ["Stock cannot be negative"] })
|
||||
@@ -64,11 +67,23 @@ export async function createItemUseCase(
|
||||
})
|
||||
}
|
||||
|
||||
const skuBase = buildItemSku(name)
|
||||
const existingSkuCount = await tx.item.count({
|
||||
where: {
|
||||
sku: {
|
||||
startsWith: skuBase,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const item = await ItemService.create(
|
||||
{
|
||||
sku: buildSkuFromName(name),
|
||||
sku: buildItemSku(name, existingSkuCount),
|
||||
name,
|
||||
trackingType: "QUANTITY",
|
||||
trackingType,
|
||||
status,
|
||||
minStock,
|
||||
targetStock,
|
||||
category: { connect: { id: categoryId } },
|
||||
stock: stock || 0,
|
||||
},
|
||||
@@ -103,7 +118,17 @@ export async function createItemUseCase(
|
||||
export async function updateItemUseCase(
|
||||
input: UpdateItemUseCaseInput,
|
||||
): Promise<ItemUseCaseResult> {
|
||||
const { actorId, id, stock, name, categoryId } = input
|
||||
const {
|
||||
actorId,
|
||||
id,
|
||||
stock,
|
||||
name,
|
||||
categoryId,
|
||||
trackingType,
|
||||
status,
|
||||
minStock,
|
||||
targetStock,
|
||||
} = input
|
||||
|
||||
try {
|
||||
return await prisma.$transaction(async (tx) => {
|
||||
@@ -122,21 +147,25 @@ export async function updateItemUseCase(
|
||||
await ItemService.update(
|
||||
id,
|
||||
{
|
||||
stock: stock || existingItem.stock,
|
||||
stock: stock ?? existingItem.stock,
|
||||
name: name || existingItem.name,
|
||||
trackingType: trackingType ?? existingItem.trackingType,
|
||||
status: status ?? existingItem.status,
|
||||
minStock: minStock ?? existingItem.minStock,
|
||||
targetStock: targetStock ?? existingItem.targetStock,
|
||||
category: { connect: { id: categoryId } },
|
||||
},
|
||||
tx,
|
||||
)
|
||||
|
||||
const quantity = stock - existingItem.stock
|
||||
const updatedStock = stock ?? existingItem.stock
|
||||
|
||||
if (stock && stock > existingItem.stock) {
|
||||
if (updatedStock > existingItem.stock) {
|
||||
await MovementService.create(
|
||||
{
|
||||
type: "IN",
|
||||
itemId: id,
|
||||
quantity,
|
||||
quantity: updatedStock - existingItem.stock,
|
||||
userId: actorId,
|
||||
},
|
||||
tx,
|
||||
|
||||
Reference in New Issue
Block a user