Files
stock-manager/src/services/item.service.ts
T

235 lines
5.6 KiB
TypeScript

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<number> => {
return prisma.item.count({ where: { deletedAt: { equals: null } } })
},
findAllWithAssetCount: async ({
page,
pageSize,
search,
}: {
page?: number
pageSize?: number
search?: string
}) => {
return paginate<ItemWithAssetCount>({
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<Item[]> => {
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<Item[]> => {
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<Item[]>
},
findByIdWithCategory: async (
id: string,
db: Prisma.TransactionClient | typeof prisma = prisma,
): Promise<ItemSummary | null> => {
return db.item.findUnique({
where: { id },
include: {
category: { select: { id: true, name: true } },
},
})
},
findByIdWithAssetCount: async (
id: string,
db: Prisma.TransactionClient | typeof prisma = prisma,
): Promise<ItemWithAssetCount | null> => {
return db.item.findUnique({
where: { id },
include: {
category: { select: { id: true, name: true } },
_count: { select: { assets: true } },
},
})
},
findByIdWithAssetAndMovementCount: async (
id: string,
): Promise<ItemWithAssetAndMovementCount | null> => {
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<Item | null> => {
return db.item.findFirst({
where: { name },
include: { category: true, assets: true, stockMovementLines: true },
}) as Promise<Item | null>
},
findById: async (
id: string,
db: Prisma.TransactionClient | typeof prisma = prisma,
): Promise<Item | null> => {
return db.item.findUnique({
where: { id },
include: { category: true, assets: true, stockMovementLines: true },
}) as Promise<Item | null>
},
findAllWithStock: async (): Promise<Item[]> => {
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<Item[]>
},
create: async (
data: Prisma.ItemCreateInput,
db: Prisma.TransactionClient | typeof prisma = prisma,
): Promise<Item> => {
return db.item.create({ data })
},
update: async (
id: string,
data: Prisma.ItemUpdateInput,
db: Prisma.TransactionClient | typeof prisma = prisma,
): Promise<Item> => {
return db.item.update({ where: { id }, data })
},
updateStock: async (
id: string,
quantity: number,
db: Prisma.TransactionClient | typeof prisma = prisma,
): Promise<Item> => {
return db.item.update({
where: { id },
data: { stock: { increment: quantity } },
})
},
decrementStockIfAvailable: async (
id: string,
quantity: number,
db: Prisma.TransactionClient | typeof prisma = prisma,
): Promise<boolean> => {
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<Item> => {
return db.item.update({
where: { id },
data: { deletedAt: new Date() },
})
},
}