import type { Prisma } from "@/generated/prisma/client" import { paginate } from "@/lib/paginate" import prisma from "@/lib/prisma" import type { Item, ItemSummary, ItemWithAssetAndMovementCount, ItemWithAssetCount, } from "@/types" export const ItemService = { findAllItemsCount: async (): Promise => { return prisma.item.count({ where: { deletedAt: { equals: null } } }) }, findAllWithAssetCount: async ({ page, pageSize, search, }: { page?: number pageSize?: number search?: string }) => { return paginate({ model: prisma.item, page, pageSize, where: { deletedAt: null, ...(search ? { name: { contains: search, mode: "insensitive" }, } : {}), }, orderBy: { name: "asc" }, select: { id: true, name: true, stock: true, category: { select: { id: true, name: true } }, _count: { select: { assets: true } }, }, }) }, findAll: async (opts?: { includeCategory?: boolean includeAssets?: boolean includeMovements?: boolean }): Promise => { return prisma.item.findMany({ include: { category: !!opts?.includeCategory, assets: opts?.includeAssets ? { select: { id: true, serialNumber: true, status: true } } : false, stockMovementLines: opts?.includeMovements ? { select: { id: true, stockDelta: true, movement: { select: { type: true } }, }, } : false, }, }) }, findAllAssignable: async (): Promise => { return prisma.item.findMany({ where: { deletedAt: null, OR: [ { stock: { gt: 0 }, assets: { some: {} }, }, { stock: 0, assets: { some: {} }, }, { stock: 0, assets: { none: {} }, }, ], }, orderBy: { name: "asc" }, }) as Promise }, findByIdWithCategory: async ( id: string, db: Prisma.TransactionClient | typeof prisma = prisma, ): Promise => { return db.item.findUnique({ where: { id }, include: { category: { select: { id: true, name: true } }, }, }) }, findByIdWithAssetCount: async ( id: string, db: Prisma.TransactionClient | typeof prisma = prisma, ): Promise => { return db.item.findUnique({ where: { id }, include: { category: { select: { id: true, name: true } }, _count: { select: { assets: true } }, }, }) }, findByIdWithAssetAndMovementCount: async ( id: string, ): Promise => { const item = await prisma.item.findUnique({ where: { id }, include: { category: { select: { id: true, name: true } }, _count: { select: { assets: true, stockMovementLines: true } }, }, }) return item ? { ...item, _count: { assets: item._count.assets, movements: item._count.stockMovementLines, }, } : null }, findByName: async ( name: string, db: Prisma.TransactionClient | typeof prisma = prisma, ): Promise => { return db.item.findFirst({ where: { name }, include: { category: true, assets: true, stockMovementLines: true }, }) as Promise }, findById: async ( id: string, db: Prisma.TransactionClient | typeof prisma = prisma, ): Promise => { return db.item.findUnique({ where: { id }, include: { category: true, assets: true, stockMovementLines: true }, }) as Promise }, findAllWithStock: async (): Promise => { return prisma.item.findMany({ orderBy: { name: "asc" }, where: { stock: { gt: 0 }, deletedAt: { equals: null }, }, include: { category: true, assets: { select: { id: true, serialNumber: true, status: true } }, stockMovementLines: { select: { id: true, stockDelta: true, movement: { select: { type: true } }, }, }, }, }) as Promise }, create: async ( data: Prisma.ItemCreateInput, db: Prisma.TransactionClient | typeof prisma = prisma, ): Promise => { return db.item.create({ data }) }, update: async ( id: string, data: Prisma.ItemUpdateInput, db: Prisma.TransactionClient | typeof prisma = prisma, ): Promise => { return db.item.update({ where: { id }, data }) }, updateStock: async ( id: string, quantity: number, db: Prisma.TransactionClient | typeof prisma = prisma, ): Promise => { return db.item.update({ where: { id }, data: { stock: { increment: quantity } }, }) }, decrementStockIfAvailable: async ( id: string, quantity: number, db: Prisma.TransactionClient | typeof prisma = prisma, ): Promise => { const result = await db.item.updateMany({ where: { id, stock: { gte: quantity }, }, data: { stock: { decrement: quantity } }, }) return result.count === 1 }, delete: async ( id: string, db: Prisma.TransactionClient | typeof prisma = prisma, ): Promise => { return db.item.update({ where: { id }, data: { deletedAt: new Date() }, }) }, }