This commit is contained in:
2026-02-04 13:49:07 +03:30
parent 5fd6611aca
commit de14d531e1
222 changed files with 7053 additions and 57956 deletions
-154
View File
@@ -1,154 +0,0 @@
import { Injectable } from '@nestjs/common'
import { ResponseMapper } from '../../common/response/response-mapper'
import { PrismaService } from '../../prisma/prisma.service'
@Injectable()
export class PosService {
constructor(private prisma: PrismaService) {}
async getInfo(posId: number) {
const info = await this.prisma.posAccount.findUniqueOrThrow({
where: { id: posId },
include: {
inventoryBankAccount: {
include: {
bankAccount: {
select: {
id: true,
name: true,
accountNumber: true,
branch: {
select: {
id: true,
name: true,
bank: { select: { id: true, name: true } },
},
},
},
},
inventory: {
select: { id: true, name: true },
},
},
},
},
})
const { inventoryBankAccount, ...rest } = info
return ResponseMapper.single({
...rest,
bankAccount: inventoryBankAccount?.bankAccount,
inventory: inventoryBankAccount?.inventory,
})
}
async getStock(
posId: number,
options: {
isAvailable?: boolean
page?: number
pageSize?: number
q?: string
productIds?: number[]
} = {},
) {
const { isAvailable, page = 1, pageSize = 50, q, productIds } = options
const pos = await this.prisma.posAccount.findUniqueOrThrow({
where: { id: posId },
select: { inventoryId: true },
})
const inventoryId = pos.inventoryId
let sql = `
SELECT sb.productId, sb.quantity - COALESCE(SUM(sr.quantity), 0) as availableQuantity, p.id, p.name, p.sku, p.description, p.salePrice, p.categoryId
FROM Stock_Balance sb
LEFT JOIN Stock_Reservations sr ON sb.productId = sr.productId AND sb.inventoryId = sr.inventoryId
LEFT JOIN Products p ON sb.productId = p.id
WHERE sb.inventoryId = ?
`
const params: any[] = [inventoryId]
if (productIds && productIds.length > 0) {
sql += ` AND sb.productId IN (${productIds.map(() => '?').join(',')})`
params.push(...productIds)
}
if (q) {
sql += ` AND (p.name LIKE ? OR p.sku LIKE ?)`
params.push(`%${q}%`, `%${q}%`)
}
sql += ` GROUP BY sb.productId`
if (isAvailable !== undefined) {
sql += isAvailable
? ` HAVING availableQuantity > 0`
: ` HAVING availableQuantity <= 0`
}
sql += ` ORDER BY sb.quantity DESC`
const items = await this.prisma.$queryRawUnsafe(sql, ...params)
const mapped = (items as any[]).map(item => ({
id: item.productId,
quantity: Number(item.availableQuantity),
product: {
id: item.id,
name: item.name,
sku: item.sku,
description: item.description,
salePrice: item.salePrice,
categoryId: item.categoryId,
},
}))
const count = mapped.length
const paginated = mapped.slice((page - 1) * pageSize, page * pageSize)
return ResponseMapper.paginate(paginated, count, page, pageSize)
}
async getProductCategories(posId: number) {
const pos = await this.prisma.posAccount.findUniqueOrThrow({
where: { id: posId },
select: { inventoryId: true },
})
const inventoryId = pos.inventoryId
const balances = await this.prisma.stockBalance.findMany({
where: { inventoryId },
select: {
product: { select: { id: true, category: { select: { id: true, name: true } } } },
quantity: true,
},
})
const map = new Map<
number,
{ id: number; name: string; totalQuantity: number; productCount: number }
>()
for (const b of balances) {
const product = b.product
const cat = product?.category
if (!cat) continue // skip products without category
const existing = map.get(cat.id)
if (existing) {
existing.totalQuantity += Number(b.quantity)
existing.productCount += 1
} else {
map.set(cat.id, {
id: cat.id,
name: cat.name,
totalQuantity: Number(b.quantity),
productCount: 1,
})
}
}
const categories = Array.from(map.values())
return ResponseMapper.list(categories)
}
}