feat: implement POS order management system
- Added CreateOrderDto and CreateOrderItemDto for order creation. - Developed PosOrdersController to handle order-related endpoints. - Created PosOrdersService for business logic related to orders. - Implemented PosOrdersWorkflow for order processing workflows. - Established Prisma integration for database operations in orders. - Introduced SalesInvoicesModule and related DTOs for sales invoice management. - Enhanced SalesInvoicesService and SalesInvoicesWorkflow for invoice processing.
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
import { Type } from 'class-transformer'
|
||||
import { IsInt, IsNumber, IsOptional, IsString } from 'class-validator'
|
||||
|
||||
export class CreateSalesInvoiceDto {
|
||||
@IsString()
|
||||
code: string
|
||||
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
totalAmount: number
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
customerId?: number
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Type } from 'class-transformer'
|
||||
import { IsInt, IsNumber, IsOptional, IsString } from 'class-validator'
|
||||
|
||||
export class UpdateSalesInvoiceDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
code?: string
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsNumber()
|
||||
totalAmount?: number
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
description?: string
|
||||
|
||||
@IsOptional()
|
||||
@Type(() => Number)
|
||||
@IsInt()
|
||||
customerId?: number | null
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import { Controller, Delete, Get, Param } from '@nestjs/common'
|
||||
import { SalesInvoicesService } from './sales-invoices.service'
|
||||
|
||||
@Controller('sales-invoices')
|
||||
export class SalesInvoicesController {
|
||||
constructor(private readonly service: SalesInvoicesService) {}
|
||||
|
||||
// @Post()
|
||||
// create(@Body() dto: CreateSalesInvoiceDto) {
|
||||
// return this.service.create(dto)
|
||||
// }
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.service.findAll()
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
findOne(@Param('id') id: string) {
|
||||
return this.service.findOne(Number(id))
|
||||
}
|
||||
|
||||
// @Patch(':id')
|
||||
// update(@Param('id') id: string, @Body() dto: UpdateSalesInvoiceDto) {
|
||||
// return this.service.update(Number(id), dto)
|
||||
// }
|
||||
|
||||
@Delete(':id')
|
||||
remove(@Param('id') id: string) {
|
||||
return this.service.remove(Number(id))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { PrismaModule } from '../../prisma/prisma.module'
|
||||
import { SalesInvoicesController } from './sales-invoices.controller'
|
||||
import { SalesInvoicesService } from './sales-invoices.service'
|
||||
import { SalesInvoicesWorkflow } from './sales-invoices.workflow'
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule],
|
||||
controllers: [SalesInvoicesController],
|
||||
providers: [SalesInvoicesService, SalesInvoicesWorkflow],
|
||||
exports: [SalesInvoicesWorkflow],
|
||||
})
|
||||
export class SalesInvoicesModule {}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from '../../common/response/response-mapper'
|
||||
import { PrismaService } from '../../prisma/prisma.service'
|
||||
|
||||
@Injectable()
|
||||
export class SalesInvoicesService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
// async create(dto: CreateSalesInvoiceDto) {
|
||||
// const payload: any = { ...dto }
|
||||
// if (Object.prototype.hasOwnProperty.call(payload, 'customerId')) {
|
||||
// payload.customer = { connect: { id: Number(payload.customerId) } }
|
||||
// delete payload.customerId
|
||||
// }
|
||||
|
||||
// const item = await this.prisma.salesInvoice.create({ data: payload })
|
||||
// return ResponseMapper.create(item)
|
||||
// }
|
||||
|
||||
async findAll() {
|
||||
const items = await this.prisma.salesInvoice.findMany({ include: { customer: true } })
|
||||
return ResponseMapper.list(items)
|
||||
}
|
||||
|
||||
async findOne(id: number) {
|
||||
const item = await this.prisma.salesInvoice.findUnique({
|
||||
where: { id },
|
||||
include: { items: true, customer: true },
|
||||
})
|
||||
if (!item) return null
|
||||
return ResponseMapper.single(item)
|
||||
}
|
||||
|
||||
// async update(id: number, data: any) {
|
||||
// const payload: any = { ...data }
|
||||
// if (Object.prototype.hasOwnProperty.call(payload, 'customerId')) {
|
||||
// if (payload.customerId === null) payload.customer = { disconnect: true }
|
||||
// else payload.customer = { connect: { id: Number(payload.customerId) } }
|
||||
// delete payload.customerId
|
||||
// }
|
||||
// const item = await this.prisma.salesInvoice.update({ where: { id }, data: payload })
|
||||
// return ResponseMapper.update(item)
|
||||
// }
|
||||
|
||||
async remove(id: number) {
|
||||
const item = await this.prisma.salesInvoice.delete({ where: { id } })
|
||||
return ResponseMapper.single(item)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import {
|
||||
MovementReferenceType,
|
||||
MovementType,
|
||||
Prisma,
|
||||
} from '../../generated/prisma/client'
|
||||
|
||||
export class SalesInvoicesWorkflow {
|
||||
constructor() {}
|
||||
|
||||
async onCreateByOrder(tx: Prisma.TransactionClient, orderId: number) {
|
||||
const { posAccount } = await tx.order.findUniqueOrThrow({
|
||||
where: { id: orderId },
|
||||
select: { posAccount: { select: { inventoryId: true, id: true } } },
|
||||
})
|
||||
|
||||
const posInventoryId = posAccount.inventoryId
|
||||
const orderItems = await tx.orderItem.findMany({
|
||||
where: {
|
||||
orderId,
|
||||
},
|
||||
})
|
||||
|
||||
await tx.stockMovement.createMany({
|
||||
data: orderItems.map(item => ({
|
||||
productId: item.productId,
|
||||
orderId,
|
||||
type: MovementType.OUT,
|
||||
referenceType: MovementReferenceType.SALES,
|
||||
referenceId: String(orderId),
|
||||
quantity: item.quantity,
|
||||
inventoryId: posInventoryId,
|
||||
unitPrice: item.unitPrice,
|
||||
totalCost: item.totalAmount,
|
||||
avgCost: item.unitPrice,
|
||||
})),
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user