183 lines
3.9 KiB
TypeScript
183 lines
3.9 KiB
TypeScript
"use server"
|
|
|
|
import { revalidatePath } from "next/cache"
|
|
|
|
import prisma from "@/lib/prisma"
|
|
import {
|
|
CreateItemFormType,
|
|
createItemSchema,
|
|
UpdateItemFormType,
|
|
updateItemSchema,
|
|
} from "@/lib/schemas/item.schemas"
|
|
import { getAuthenticatedUserId } from "@/services/auth.service"
|
|
import { ItemService } from "@/services/item.service"
|
|
|
|
export async function createItemAction(formData: CreateItemFormType) {
|
|
const validatedFields = createItemSchema.safeParse(formData)
|
|
|
|
if (!validatedFields.success) {
|
|
return {
|
|
errors: validatedFields.error.flatten().fieldErrors,
|
|
}
|
|
}
|
|
|
|
const { name, categoryId, stock } = validatedFields.data
|
|
|
|
if (stock < 0) {
|
|
return {
|
|
success: false,
|
|
errors: {
|
|
stock: ["Stock cannot be negative"],
|
|
},
|
|
}
|
|
}
|
|
|
|
try {
|
|
const existingItem = await ItemService.findByName(name)
|
|
|
|
if (existingItem) {
|
|
return {
|
|
success: false,
|
|
errors: {
|
|
name: ["An item with this name already exists"],
|
|
},
|
|
}
|
|
}
|
|
|
|
const item = await ItemService.create({
|
|
name,
|
|
category: { connect: { id: categoryId } },
|
|
stock: stock || 0,
|
|
})
|
|
|
|
if (stock > 0) {
|
|
await prisma.movement.create({
|
|
data: {
|
|
type: "IN",
|
|
itemId: item.id,
|
|
userId: await getAuthenticatedUserId(),
|
|
quantity: stock,
|
|
},
|
|
})
|
|
}
|
|
|
|
revalidatePath("/inventory/items")
|
|
|
|
return {
|
|
success: true,
|
|
message: "Item created successfully!",
|
|
}
|
|
} catch (error) {
|
|
console.error("Database error:", error)
|
|
return {
|
|
error: "Error creating item",
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function updateItemAction(formData: UpdateItemFormType) {
|
|
const validatedFields = updateItemSchema.safeParse(formData)
|
|
|
|
if (!validatedFields.success) {
|
|
return {
|
|
errors: validatedFields.error.flatten().fieldErrors,
|
|
}
|
|
}
|
|
|
|
const { id, stock, name, categoryId } = validatedFields.data
|
|
|
|
try {
|
|
const existingItem = await ItemService.findByIdWithAssetCount(id)
|
|
|
|
if (!existingItem) {
|
|
return {
|
|
success: false,
|
|
errors: {
|
|
id: ["Item not found"],
|
|
},
|
|
}
|
|
}
|
|
|
|
const existingItemByName = await ItemService.findByName(name)
|
|
|
|
if (existingItemByName && existingItemByName.id !== id) {
|
|
return {
|
|
success: false,
|
|
errors: { name: ["An item with this name already exists"] },
|
|
}
|
|
}
|
|
|
|
await ItemService.update(id, {
|
|
stock: stock || existingItem.stock,
|
|
name: name || existingItem.name,
|
|
category: { connect: { id: categoryId } },
|
|
})
|
|
|
|
const quantity = stock - existingItem.stock
|
|
|
|
if (stock && stock > existingItem.stock) {
|
|
await prisma.movement.create({
|
|
data: {
|
|
type: "IN",
|
|
itemId: id,
|
|
quantity,
|
|
userId: await getAuthenticatedUserId(),
|
|
},
|
|
})
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
message: "Item updated successfully!",
|
|
}
|
|
} catch (error) {
|
|
console.error("Database error:", error)
|
|
return {
|
|
error: "Failed to update item",
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function deleteItemAction(formData: FormData) {
|
|
const { id } = Object.fromEntries(formData) as { id: string }
|
|
|
|
try {
|
|
const existingItem = await ItemService.findByIdWithAssetCount(id)
|
|
|
|
if (!existingItem) {
|
|
return {
|
|
success: false,
|
|
errors: { id: ["Item not found"] },
|
|
}
|
|
}
|
|
|
|
if (existingItem._count.assets > 0) {
|
|
return {
|
|
success: false,
|
|
errors: { id: ["Item has assets, you cannot delete it"] },
|
|
}
|
|
}
|
|
|
|
if (existingItem.stock > 0) {
|
|
return {
|
|
success: false,
|
|
errors: { id: ["Item has stock, you cannot delete it"] },
|
|
}
|
|
}
|
|
|
|
await ItemService.delete(id)
|
|
|
|
revalidatePath("/inventory/items")
|
|
|
|
return {
|
|
success: true,
|
|
message: "Item deleted successfully!",
|
|
}
|
|
} catch (error) {
|
|
console.error("Database error:", error)
|
|
return {
|
|
error: "Failed to delete item",
|
|
}
|
|
}
|
|
}
|