feat(database): initialize database schema and triggers

- Created initial database schema with tables for Users, Roles, Products, and related entities.
- Added foreign key constraints to maintain data integrity across tables.
- Implemented triggers for managing stock movements on insert, update, and delete operations.
- Developed scripts to dump existing triggers and pull trigger definitions from the database.
This commit is contained in:
2025-12-10 16:54:08 +03:30
parent 807f6c2087
commit 41d7dd8802
26 changed files with 1108 additions and 515 deletions
File diff suppressed because one or more lines are too long
@@ -2151,6 +2151,7 @@ export const PurchaseReceiptItemScalarFieldEnum = {
count: 'count',
fee: 'fee',
total: 'total',
description: 'description',
createdAt: 'createdAt',
receiptId: 'receiptId',
productId: 'productId'
@@ -2445,6 +2446,13 @@ export const PurchaseReceiptOrderByRelevanceFieldEnum = {
export type PurchaseReceiptOrderByRelevanceFieldEnum = (typeof PurchaseReceiptOrderByRelevanceFieldEnum)[keyof typeof PurchaseReceiptOrderByRelevanceFieldEnum]
export const PurchaseReceiptItemOrderByRelevanceFieldEnum = {
description: 'description'
} as const
export type PurchaseReceiptItemOrderByRelevanceFieldEnum = (typeof PurchaseReceiptItemOrderByRelevanceFieldEnum)[keyof typeof PurchaseReceiptItemOrderByRelevanceFieldEnum]
export const SalesInvoiceOrderByRelevanceFieldEnum = {
code: 'code',
description: 'description'
@@ -302,6 +302,7 @@ export const PurchaseReceiptItemScalarFieldEnum = {
count: 'count',
fee: 'fee',
total: 'total',
description: 'description',
createdAt: 'createdAt',
receiptId: 'receiptId',
productId: 'productId'
@@ -596,6 +597,13 @@ export const PurchaseReceiptOrderByRelevanceFieldEnum = {
export type PurchaseReceiptOrderByRelevanceFieldEnum = (typeof PurchaseReceiptOrderByRelevanceFieldEnum)[keyof typeof PurchaseReceiptOrderByRelevanceFieldEnum]
export const PurchaseReceiptItemOrderByRelevanceFieldEnum = {
description: 'description'
} as const
export type PurchaseReceiptItemOrderByRelevanceFieldEnum = (typeof PurchaseReceiptItemOrderByRelevanceFieldEnum)[keyof typeof PurchaseReceiptItemOrderByRelevanceFieldEnum]
export const SalesInvoiceOrderByRelevanceFieldEnum = {
code: 'code',
description: 'description'
@@ -49,6 +49,7 @@ export type PurchaseReceiptItemMinAggregateOutputType = {
count: runtime.Decimal | null
fee: runtime.Decimal | null
total: runtime.Decimal | null
description: string | null
createdAt: Date | null
receiptId: number | null
productId: number | null
@@ -59,6 +60,7 @@ export type PurchaseReceiptItemMaxAggregateOutputType = {
count: runtime.Decimal | null
fee: runtime.Decimal | null
total: runtime.Decimal | null
description: string | null
createdAt: Date | null
receiptId: number | null
productId: number | null
@@ -69,6 +71,7 @@ export type PurchaseReceiptItemCountAggregateOutputType = {
count: number
fee: number
total: number
description: number
createdAt: number
receiptId: number
productId: number
@@ -99,6 +102,7 @@ export type PurchaseReceiptItemMinAggregateInputType = {
count?: true
fee?: true
total?: true
description?: true
createdAt?: true
receiptId?: true
productId?: true
@@ -109,6 +113,7 @@ export type PurchaseReceiptItemMaxAggregateInputType = {
count?: true
fee?: true
total?: true
description?: true
createdAt?: true
receiptId?: true
productId?: true
@@ -119,6 +124,7 @@ export type PurchaseReceiptItemCountAggregateInputType = {
count?: true
fee?: true
total?: true
description?: true
createdAt?: true
receiptId?: true
productId?: true
@@ -216,6 +222,7 @@ export type PurchaseReceiptItemGroupByOutputType = {
count: runtime.Decimal
fee: runtime.Decimal
total: runtime.Decimal
description: string | null
createdAt: Date
receiptId: number
productId: number
@@ -249,6 +256,7 @@ export type PurchaseReceiptItemWhereInput = {
count?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.StringNullableFilter<"PurchaseReceiptItem"> | string | null
createdAt?: Prisma.DateTimeFilter<"PurchaseReceiptItem"> | Date | string
receiptId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
productId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
@@ -261,11 +269,13 @@ export type PurchaseReceiptItemOrderByWithRelationInput = {
count?: Prisma.SortOrder
fee?: Prisma.SortOrder
total?: Prisma.SortOrder
description?: Prisma.SortOrderInput | Prisma.SortOrder
createdAt?: Prisma.SortOrder
receiptId?: Prisma.SortOrder
productId?: Prisma.SortOrder
product?: Prisma.ProductOrderByWithRelationInput
receipt?: Prisma.PurchaseReceiptOrderByWithRelationInput
_relevance?: Prisma.PurchaseReceiptItemOrderByRelevanceInput
}
export type PurchaseReceiptItemWhereUniqueInput = Prisma.AtLeast<{
@@ -276,6 +286,7 @@ export type PurchaseReceiptItemWhereUniqueInput = Prisma.AtLeast<{
count?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.StringNullableFilter<"PurchaseReceiptItem"> | string | null
createdAt?: Prisma.DateTimeFilter<"PurchaseReceiptItem"> | Date | string
receiptId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
productId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
@@ -288,6 +299,7 @@ export type PurchaseReceiptItemOrderByWithAggregationInput = {
count?: Prisma.SortOrder
fee?: Prisma.SortOrder
total?: Prisma.SortOrder
description?: Prisma.SortOrderInput | Prisma.SortOrder
createdAt?: Prisma.SortOrder
receiptId?: Prisma.SortOrder
productId?: Prisma.SortOrder
@@ -306,6 +318,7 @@ export type PurchaseReceiptItemScalarWhereWithAggregatesInput = {
count?: Prisma.DecimalWithAggregatesFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalWithAggregatesFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalWithAggregatesFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.StringNullableWithAggregatesFilter<"PurchaseReceiptItem"> | string | null
createdAt?: Prisma.DateTimeWithAggregatesFilter<"PurchaseReceiptItem"> | Date | string
receiptId?: Prisma.IntWithAggregatesFilter<"PurchaseReceiptItem"> | number
productId?: Prisma.IntWithAggregatesFilter<"PurchaseReceiptItem"> | number
@@ -315,6 +328,7 @@ export type PurchaseReceiptItemCreateInput = {
count: runtime.Decimal | runtime.DecimalJsLike | number | string
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
total: runtime.Decimal | runtime.DecimalJsLike | number | string
description?: string | null
createdAt?: Date | string
product: Prisma.ProductCreateNestedOneWithoutPurchaseReceiptItemsInput
receipt: Prisma.PurchaseReceiptCreateNestedOneWithoutItemsInput
@@ -325,6 +339,7 @@ export type PurchaseReceiptItemUncheckedCreateInput = {
count: runtime.Decimal | runtime.DecimalJsLike | number | string
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
total: runtime.Decimal | runtime.DecimalJsLike | number | string
description?: string | null
createdAt?: Date | string
receiptId: number
productId: number
@@ -334,6 +349,7 @@ export type PurchaseReceiptItemUpdateInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
product?: Prisma.ProductUpdateOneRequiredWithoutPurchaseReceiptItemsNestedInput
receipt?: Prisma.PurchaseReceiptUpdateOneRequiredWithoutItemsNestedInput
@@ -344,6 +360,7 @@ export type PurchaseReceiptItemUncheckedUpdateInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
receiptId?: Prisma.IntFieldUpdateOperationsInput | number
productId?: Prisma.IntFieldUpdateOperationsInput | number
@@ -354,6 +371,7 @@ export type PurchaseReceiptItemCreateManyInput = {
count: runtime.Decimal | runtime.DecimalJsLike | number | string
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
total: runtime.Decimal | runtime.DecimalJsLike | number | string
description?: string | null
createdAt?: Date | string
receiptId: number
productId: number
@@ -363,6 +381,7 @@ export type PurchaseReceiptItemUpdateManyMutationInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
}
@@ -371,6 +390,7 @@ export type PurchaseReceiptItemUncheckedUpdateManyInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
receiptId?: Prisma.IntFieldUpdateOperationsInput | number
productId?: Prisma.IntFieldUpdateOperationsInput | number
@@ -386,11 +406,18 @@ export type PurchaseReceiptItemOrderByRelationAggregateInput = {
_count?: Prisma.SortOrder
}
export type PurchaseReceiptItemOrderByRelevanceInput = {
fields: Prisma.PurchaseReceiptItemOrderByRelevanceFieldEnum | Prisma.PurchaseReceiptItemOrderByRelevanceFieldEnum[]
sort: Prisma.SortOrder
search: string
}
export type PurchaseReceiptItemCountOrderByAggregateInput = {
id?: Prisma.SortOrder
count?: Prisma.SortOrder
fee?: Prisma.SortOrder
total?: Prisma.SortOrder
description?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
receiptId?: Prisma.SortOrder
productId?: Prisma.SortOrder
@@ -410,6 +437,7 @@ export type PurchaseReceiptItemMaxOrderByAggregateInput = {
count?: Prisma.SortOrder
fee?: Prisma.SortOrder
total?: Prisma.SortOrder
description?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
receiptId?: Prisma.SortOrder
productId?: Prisma.SortOrder
@@ -420,6 +448,7 @@ export type PurchaseReceiptItemMinOrderByAggregateInput = {
count?: Prisma.SortOrder
fee?: Prisma.SortOrder
total?: Prisma.SortOrder
description?: Prisma.SortOrder
createdAt?: Prisma.SortOrder
receiptId?: Prisma.SortOrder
productId?: Prisma.SortOrder
@@ -522,6 +551,7 @@ export type PurchaseReceiptItemCreateWithoutProductInput = {
count: runtime.Decimal | runtime.DecimalJsLike | number | string
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
total: runtime.Decimal | runtime.DecimalJsLike | number | string
description?: string | null
createdAt?: Date | string
receipt: Prisma.PurchaseReceiptCreateNestedOneWithoutItemsInput
}
@@ -531,6 +561,7 @@ export type PurchaseReceiptItemUncheckedCreateWithoutProductInput = {
count: runtime.Decimal | runtime.DecimalJsLike | number | string
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
total: runtime.Decimal | runtime.DecimalJsLike | number | string
description?: string | null
createdAt?: Date | string
receiptId: number
}
@@ -569,6 +600,7 @@ export type PurchaseReceiptItemScalarWhereInput = {
count?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFilter<"PurchaseReceiptItem"> | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.StringNullableFilter<"PurchaseReceiptItem"> | string | null
createdAt?: Prisma.DateTimeFilter<"PurchaseReceiptItem"> | Date | string
receiptId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
productId?: Prisma.IntFilter<"PurchaseReceiptItem"> | number
@@ -578,6 +610,7 @@ export type PurchaseReceiptItemCreateWithoutReceiptInput = {
count: runtime.Decimal | runtime.DecimalJsLike | number | string
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
total: runtime.Decimal | runtime.DecimalJsLike | number | string
description?: string | null
createdAt?: Date | string
product: Prisma.ProductCreateNestedOneWithoutPurchaseReceiptItemsInput
}
@@ -587,6 +620,7 @@ export type PurchaseReceiptItemUncheckedCreateWithoutReceiptInput = {
count: runtime.Decimal | runtime.DecimalJsLike | number | string
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
total: runtime.Decimal | runtime.DecimalJsLike | number | string
description?: string | null
createdAt?: Date | string
productId: number
}
@@ -622,6 +656,7 @@ export type PurchaseReceiptItemCreateManyProductInput = {
count: runtime.Decimal | runtime.DecimalJsLike | number | string
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
total: runtime.Decimal | runtime.DecimalJsLike | number | string
description?: string | null
createdAt?: Date | string
receiptId: number
}
@@ -630,6 +665,7 @@ export type PurchaseReceiptItemUpdateWithoutProductInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
receipt?: Prisma.PurchaseReceiptUpdateOneRequiredWithoutItemsNestedInput
}
@@ -639,6 +675,7 @@ export type PurchaseReceiptItemUncheckedUpdateWithoutProductInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
receiptId?: Prisma.IntFieldUpdateOperationsInput | number
}
@@ -648,6 +685,7 @@ export type PurchaseReceiptItemUncheckedUpdateManyWithoutProductInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
receiptId?: Prisma.IntFieldUpdateOperationsInput | number
}
@@ -657,6 +695,7 @@ export type PurchaseReceiptItemCreateManyReceiptInput = {
count: runtime.Decimal | runtime.DecimalJsLike | number | string
fee: runtime.Decimal | runtime.DecimalJsLike | number | string
total: runtime.Decimal | runtime.DecimalJsLike | number | string
description?: string | null
createdAt?: Date | string
productId: number
}
@@ -665,6 +704,7 @@ export type PurchaseReceiptItemUpdateWithoutReceiptInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
product?: Prisma.ProductUpdateOneRequiredWithoutPurchaseReceiptItemsNestedInput
}
@@ -674,6 +714,7 @@ export type PurchaseReceiptItemUncheckedUpdateWithoutReceiptInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
productId?: Prisma.IntFieldUpdateOperationsInput | number
}
@@ -683,6 +724,7 @@ export type PurchaseReceiptItemUncheckedUpdateManyWithoutReceiptInput = {
count?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
fee?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
total?: Prisma.DecimalFieldUpdateOperationsInput | runtime.Decimal | runtime.DecimalJsLike | number | string
description?: Prisma.NullableStringFieldUpdateOperationsInput | string | null
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
productId?: Prisma.IntFieldUpdateOperationsInput | number
}
@@ -694,6 +736,7 @@ export type PurchaseReceiptItemSelect<ExtArgs extends runtime.Types.Extensions.I
count?: boolean
fee?: boolean
total?: boolean
description?: boolean
createdAt?: boolean
receiptId?: boolean
productId?: boolean
@@ -708,12 +751,13 @@ export type PurchaseReceiptItemSelectScalar = {
count?: boolean
fee?: boolean
total?: boolean
description?: boolean
createdAt?: boolean
receiptId?: boolean
productId?: boolean
}
export type PurchaseReceiptItemOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "count" | "fee" | "total" | "createdAt" | "receiptId" | "productId", ExtArgs["result"]["purchaseReceiptItem"]>
export type PurchaseReceiptItemOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "count" | "fee" | "total" | "description" | "createdAt" | "receiptId" | "productId", ExtArgs["result"]["purchaseReceiptItem"]>
export type PurchaseReceiptItemInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
product?: boolean | Prisma.ProductDefaultArgs<ExtArgs>
receipt?: boolean | Prisma.PurchaseReceiptDefaultArgs<ExtArgs>
@@ -730,6 +774,7 @@ export type $PurchaseReceiptItemPayload<ExtArgs extends runtime.Types.Extensions
count: runtime.Decimal
fee: runtime.Decimal
total: runtime.Decimal
description: string | null
createdAt: Date
receiptId: number
productId: number
@@ -1108,6 +1153,7 @@ export interface PurchaseReceiptItemFieldRefs {
readonly count: Prisma.FieldRef<"PurchaseReceiptItem", 'Decimal'>
readonly fee: Prisma.FieldRef<"PurchaseReceiptItem", 'Decimal'>
readonly total: Prisma.FieldRef<"PurchaseReceiptItem", 'Decimal'>
readonly description: Prisma.FieldRef<"PurchaseReceiptItem", 'String'>
readonly createdAt: Prisma.FieldRef<"PurchaseReceiptItem", 'DateTime'>
readonly receiptId: Prisma.FieldRef<"PurchaseReceiptItem", 'Int'>
readonly productId: Prisma.FieldRef<"PurchaseReceiptItem", 'Int'>
@@ -31,4 +31,9 @@ export class InventoriesController {
remove(@Param('id') id: string) {
return this.inventoriesService.remove(Number(id))
}
@Get(':id/stock-movements')
findStockMovements(@Param('id') id: string) {
return this.inventoriesService.findStockMovements(Number(id))
}
}
+21 -39
View File
@@ -1,5 +1,4 @@
import { Injectable } from '@nestjs/common'
import { ShortEntity } from '../common/interfaces/response-models'
import { ResponseMapper } from '../common/response/response-mapper'
import { PrismaService } from '../prisma/prisma.service'
@@ -12,52 +11,18 @@ export class InventoriesService {
}
async findAll() {
const items = await this.prisma.inventory.findMany({
include: { productCharges: { include: { product: true } } },
})
const items = await this.prisma.inventory.findMany()
const mapped = items.map(i => {
const productsMap: Record<number, ShortEntity> = {}
for (const pc of i.productCharges ?? []) {
if (pc.product) {
productsMap[pc.product.id] = { id: pc.product.id, name: pc.product.name }
}
}
const groupedProducts = Object.values(productsMap)
const { productCharges, ...rest } = i as any
return { ...rest, groupedProducts }
})
return ResponseMapper.list(mapped)
return ResponseMapper.list(items)
}
async findOne(id: number) {
const item = await this.prisma.inventory.findUnique({
where: { id },
include: { productCharges: { include: { product: true } } },
include: { purchaseReceipts: true },
})
if (!item) return null
const productsMap: Record<number, { id: number; name: string; count: number }> = {}
for (const pc of item.productCharges ?? []) {
const pid = pc.productId
const pname = pc.product?.name ?? `#${pid}`
if (!productsMap[pid]) productsMap[pid] = { id: pid, name: pname, count: 0 }
productsMap[pid].count += Number(pc.count)
}
const productsWithCount = Object.values(productsMap)
const groupedProducts: ShortEntity[] = productsWithCount.map(p => ({
id: p.id,
name: p.name,
}))
const { productCharges, ...rest } = item as any
const itemWithCounts = {
...rest,
products: productsWithCount,
groupedProducts,
}
return ResponseMapper.single(itemWithCounts)
return ResponseMapper.single(item)
}
async update(id: number, data: any) {
@@ -69,4 +34,21 @@ export class InventoriesService {
const item = await this.prisma.inventory.delete({ where: { id } })
return ResponseMapper.single(item)
}
async findStockMovements(inventoryId: number) {
// Return a flat list of stock movements, each including its product info
const movements = await this.prisma.stockMovement.findMany({
where: { inventoryId },
include: { product: true },
})
// Map each movement to have a 'products' array (even if only one product)
const mapped = movements.map(movement => {
const { product, ...rest } = movement
return {
...rest,
products: product ? [product] : [],
}
})
return ResponseMapper.list(mapped)
}
}
@@ -1,24 +1,25 @@
import { Type } from 'class-transformer'
import { IsInt, IsNumber } from 'class-validator'
import { IsNotEmpty, IsNumber, Min } from 'class-validator'
export class CreatePurchaseReceiptItemDto {
@Type(() => Number)
@IsNumber()
@Min(0)
count: number
@Type(() => Number)
@IsNumber()
@Min(0)
fee: number
@Type(() => Number)
@IsNumber()
@Min(0)
total: number
@Type(() => Number)
@IsInt()
receiptId: number
@Type(() => Number)
@IsInt()
@IsNotEmpty()
productId: number
description?: string
}
@@ -9,15 +9,17 @@ export class PurchaseReceiptItemsService {
async create(dto: CreatePurchaseReceiptItemDto) {
const payload: any = { ...dto }
if (Object.prototype.hasOwnProperty.call(payload, 'receiptId')) {
payload.receipt = { connect: { id: Number(payload.receiptId) } }
delete payload.receiptId
}
if (Object.prototype.hasOwnProperty.call(payload, 'productId')) {
payload.product = { connect: { id: Number(payload.productId) } }
delete payload.productId
}
if (Object.prototype.hasOwnProperty.call(payload, 'receiptId')) {
payload.receipt = { connect: { id: Number(payload.receiptId) } }
delete payload.receiptId
}
payload.fee = String(payload.fee)
payload.count = String(payload.count)
payload.total = String(payload.total)
const item = await this.prisma.purchaseReceiptItem.create({ data: payload })
return ResponseMapper.create(item)
}
@@ -1,5 +1,6 @@
import { Type } from 'class-transformer'
import { IsInt, IsNumber, IsOptional, IsString } from 'class-validator'
import { ArrayMinSize, IsInt, IsNumber, IsOptional, IsString } from 'class-validator'
import { CreatePurchaseReceiptItemDto } from '../../purchase-receipt-items/dto/create-purchase-receipt-item.dto'
export class CreatePurchaseReceiptDto {
@IsString()
@@ -20,4 +21,8 @@ export class CreatePurchaseReceiptDto {
@Type(() => Number)
@IsInt()
inventoryId: number
@Type(() => Array)
@ArrayMinSize(1)
items: Array<Omit<CreatePurchaseReceiptItemDto, 'receiptId'>>
}
@@ -1,5 +1,6 @@
import { Injectable } from '@nestjs/common'
import { ResponseMapper } from '../common/response/response-mapper'
import { Prisma } from '../generated/prisma/client'
import { PrismaService } from '../prisma/prisma.service'
import { CreatePurchaseReceiptDto } from './dto/create-purchase-receipt.dto'
@@ -8,17 +9,32 @@ export class PurchaseReceiptsService {
constructor(private prisma: PrismaService) {}
async create(dto: CreatePurchaseReceiptDto) {
const payload: any = { ...dto }
if (Object.prototype.hasOwnProperty.call(payload, 'supplierId')) {
payload.supplier = { connect: { id: Number(payload.supplierId) } }
delete payload.supplierId
const data: Prisma.PurchaseReceiptCreateInput = {
code: dto.code,
totalAmount: new Prisma.Decimal(dto.totalAmount),
description: dto.description ?? null,
supplier: { connect: { id: dto.supplierId } },
inventory: { connect: { id: dto.inventoryId } },
items: dto.items?.length
? {
create: dto.items.map((item, idx) => {
const mapped = {
count: new Prisma.Decimal(item.count ?? 0),
fee: new Prisma.Decimal(item.fee ?? 0),
total: new Prisma.Decimal(item.total ?? 0),
description: item.description ?? null,
product: { connect: { id: item.productId } },
}
console.log(`[create] Step 3: Mapped item ${idx}:`, mapped)
return mapped
}),
}
: undefined,
}
if (Object.prototype.hasOwnProperty.call(payload, 'inventoryId')) {
payload.inventory = { connect: { id: Number(payload.inventoryId) } }
delete payload.inventoryId
}
const item = await this.prisma.purchaseReceipt.create({ data: payload })
const item = await this.prisma.purchaseReceipt.create({
data,
include: { items: true },
})
return ResponseMapper.create(item)
}