feat(cardex): implement cardex controller, service, and DTO for stock movements
feat(pos): add POS controller and service for order creation and stock retrieval refactor(pos): enhance stock and product category retrieval with pagination and mapping
This commit is contained in:
+5
-1
@@ -1,11 +1,13 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { AppController } from './app.controller'
|
||||
import { AppService } from './app.service'
|
||||
import { AuthModule } from './auth/auth.module'
|
||||
import { CustomersModule } from './customers/customers.module'
|
||||
import { InventoriesModule } from './inventories/inventories.module'
|
||||
import { InventoryTransferItemsModule } from './inventory-transfer-items/inventory-transfer-items.module'
|
||||
import { InventoryTransfersModule } from './inventory-transfers/inventory-transfers.module'
|
||||
import { PosModule } from './pos/pos.module'
|
||||
import { CardexModule } from './modules/cardex/cardex.module'
|
||||
import { PosModule } from './modules/pos/pos.module'
|
||||
import { PrismaModule } from './prisma/prisma.module'
|
||||
import { ProductBrandsModule } from './product-brands/product-brands.module'
|
||||
import { ProductCategoriesModule } from './product-categories/product-categories.module'
|
||||
@@ -28,6 +30,7 @@ import { UsersModule } from './users/users.module'
|
||||
imports: [
|
||||
PrismaModule,
|
||||
UsersModule,
|
||||
AuthModule,
|
||||
RolesModule,
|
||||
ProductsModule,
|
||||
ProductVariantsModule,
|
||||
@@ -48,6 +51,7 @@ import { UsersModule } from './users/users.module'
|
||||
StockAdjustmentsModule,
|
||||
StockBalanceModule,
|
||||
PosModule,
|
||||
CardexModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
import { Body, Controller, Get, Post, UseGuards } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { ResponseMapper } from '../common/response/response-mapper'
|
||||
import { AuthService } from './auth.service'
|
||||
import { CurrentUser } from './current-user.decorator'
|
||||
import { RefreshTokenDto } from './dto/refresh-token.dto'
|
||||
import { SendCodeDto } from './dto/send-code.dto'
|
||||
import { VerifyCodeDto } from './dto/verify-code.dto'
|
||||
import { JwtAuthGuard } from './jwt-auth.guard'
|
||||
|
||||
@ApiTags('auth')
|
||||
@Controller('auth')
|
||||
export class AuthController {
|
||||
constructor(private readonly auth: AuthService) {}
|
||||
|
||||
@Post('send-code')
|
||||
async sendCode(@Body() dto: SendCodeDto) {
|
||||
return this.auth.sendCode(dto)
|
||||
}
|
||||
|
||||
@Post('login')
|
||||
async login(@Body() dto: VerifyCodeDto) {
|
||||
return this.auth.loginWithCode(dto)
|
||||
}
|
||||
|
||||
@Post('refresh')
|
||||
async refresh(@Body() dto: RefreshTokenDto) {
|
||||
return this.auth.refreshToken(dto)
|
||||
}
|
||||
|
||||
@Post('logout')
|
||||
async logout(@Body() dto: RefreshTokenDto) {
|
||||
return this.auth.logout(dto.refreshToken)
|
||||
}
|
||||
|
||||
@Get('me')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
async me(@CurrentUser() user: any) {
|
||||
return ResponseMapper.single(user)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { JwtModule } from '@nestjs/jwt'
|
||||
import 'dotenv/config'
|
||||
import { env } from 'prisma/config'
|
||||
import { PrismaModule } from '../prisma/prisma.module'
|
||||
import { AuthController } from './auth.controller'
|
||||
import { AuthService } from './auth.service'
|
||||
import { JwtAuthGuard } from './jwt-auth.guard'
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
PrismaModule,
|
||||
JwtModule.register({
|
||||
secret: env('JWT_SECRET') || 'secret',
|
||||
signOptions: { expiresIn: Number(env('JWT_EXPIRES_IN')) || '15m' },
|
||||
}),
|
||||
],
|
||||
providers: [AuthService, JwtAuthGuard],
|
||||
controllers: [AuthController],
|
||||
exports: [AuthService, JwtAuthGuard],
|
||||
})
|
||||
export class AuthModule {}
|
||||
@@ -0,0 +1,126 @@
|
||||
import {
|
||||
BadRequestException,
|
||||
Injectable,
|
||||
NotFoundException,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common'
|
||||
import { JwtService } from '@nestjs/jwt'
|
||||
import { createHash, randomBytes } from 'crypto'
|
||||
import 'dotenv/config'
|
||||
import { env } from 'prisma/config'
|
||||
import { ResponseMapper } from '../common/response/response-mapper'
|
||||
import { PrismaService } from '../prisma/prisma.service'
|
||||
import { RefreshTokenDto } from './dto/refresh-token.dto'
|
||||
import { SendCodeDto } from './dto/send-code.dto'
|
||||
import { VerifyCodeDto } from './dto/verify-code.dto'
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
private readonly OTP_TTL_MINUTES = 2
|
||||
private readonly ACCESS_TOKEN_EXP = Number(env('JWT_EXPIRES_IN')) || '15m'
|
||||
private readonly REFRESH_TOKEN_EXP_DAYS = 30
|
||||
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private jwt: JwtService,
|
||||
) {}
|
||||
|
||||
private generateCode() {
|
||||
// For development you may want fixed code via env, otherwise random 5-digit
|
||||
const staticCode = process.env.OTP_STATIC_CODE
|
||||
if (staticCode) return staticCode
|
||||
return Math.floor(10000 + Math.random() * 90000).toString()
|
||||
}
|
||||
|
||||
async sendCode(dto: SendCodeDto) {
|
||||
const { mobileNumber } = dto
|
||||
const user = await this.prisma.user.findFirst({ where: { mobileNumber } })
|
||||
if (!user) {
|
||||
throw new NotFoundException('کاربری با این شماره تماس یافت نشد')
|
||||
}
|
||||
const code = this.generateCode()
|
||||
const expiresAt = new Date(Date.now() + this.OTP_TTL_MINUTES * 60 * 1000)
|
||||
|
||||
await this.prisma.otpCode.create({
|
||||
data: {
|
||||
mobileNumber,
|
||||
code,
|
||||
expiresAt,
|
||||
},
|
||||
})
|
||||
|
||||
// TODO: integrate SMS provider. For now return the code for dev.
|
||||
return {
|
||||
ok: true,
|
||||
}
|
||||
}
|
||||
|
||||
async loginWithCode(dto: VerifyCodeDto) {
|
||||
const { mobileNumber, code } = dto
|
||||
const user = await this.prisma.user.findFirst({
|
||||
where: { mobileNumber },
|
||||
include: {
|
||||
role: true,
|
||||
},
|
||||
})
|
||||
if (!user) {
|
||||
throw new NotFoundException('کاربری با این شماره تماس یافت نشد')
|
||||
}
|
||||
|
||||
const otp = await this.prisma.otpCode.findFirst({
|
||||
where: { mobileNumber, used: false },
|
||||
})
|
||||
|
||||
if (!otp) throw new BadRequestException('اطلاعات ورودی درست نیست')
|
||||
if (otp.used) throw new BadRequestException('کد قبلن استفاده شده است')
|
||||
if (otp.expiresAt.getTime() < Date.now())
|
||||
throw new BadRequestException('کد وارد شده منقضی شده است')
|
||||
if (otp.code !== code) throw new BadRequestException('کد وارد شده اشتباه است')
|
||||
|
||||
// mark used
|
||||
await this.prisma.otpCode.update({ where: { id: otp.id }, data: { used: true } })
|
||||
|
||||
const accessToken = this.jwt.sign(
|
||||
{ sub: user.id, mobileNumber },
|
||||
{ expiresIn: this.ACCESS_TOKEN_EXP },
|
||||
)
|
||||
const refreshTokenPlain = randomBytes(48).toString('hex')
|
||||
const tokenHash = createHash('sha256').update(refreshTokenPlain).digest('hex')
|
||||
const expiresAt = new Date(
|
||||
Date.now() + this.REFRESH_TOKEN_EXP_DAYS * 24 * 60 * 60 * 1000,
|
||||
)
|
||||
|
||||
await this.prisma.refreshToken.create({
|
||||
data: { tokenHash, userId: user.id, expiresAt },
|
||||
})
|
||||
|
||||
return ResponseMapper.single({ accessToken, refreshToken: refreshTokenPlain, user })
|
||||
}
|
||||
|
||||
async refreshToken(dto: RefreshTokenDto) {
|
||||
const { refreshToken } = dto
|
||||
const tokenHash = createHash('sha256').update(refreshToken).digest('hex')
|
||||
const record = await this.prisma.refreshToken.findFirst({ where: { tokenHash } })
|
||||
if (!record || record.revoked || record.expiresAt.getTime() < Date.now()) {
|
||||
throw new UnauthorizedException('Invalid refresh token')
|
||||
}
|
||||
|
||||
const user = await this.prisma.user.findUnique({ where: { id: record.userId } })
|
||||
if (!user) throw new UnauthorizedException('User not found')
|
||||
|
||||
const accessToken = this.jwt.sign(
|
||||
{ sub: user.id, mobileNumber: user.mobileNumber },
|
||||
{ expiresIn: this.ACCESS_TOKEN_EXP },
|
||||
)
|
||||
return { accessToken }
|
||||
}
|
||||
|
||||
async logout(refreshToken: string) {
|
||||
const tokenHash = createHash('sha256').update(refreshToken).digest('hex')
|
||||
await this.prisma.refreshToken.updateMany({
|
||||
where: { tokenHash },
|
||||
data: { revoked: true },
|
||||
})
|
||||
return { ok: true }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { createParamDecorator, ExecutionContext } from '@nestjs/common'
|
||||
|
||||
export const CurrentUser = createParamDecorator(
|
||||
(data: unknown, ctx: ExecutionContext) => {
|
||||
const req = ctx.switchToHttp().getRequest()
|
||||
return req.user
|
||||
},
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ApiProperty } from '@nestjs/swagger'
|
||||
import { IsString } from 'class-validator'
|
||||
|
||||
export class LoginDto {
|
||||
@ApiProperty({ description: 'Mobile number used as username', example: '09123456789' })
|
||||
@IsString()
|
||||
mobileNumber: string
|
||||
|
||||
@ApiProperty({ description: 'OTP password (one-time password)', example: '12345' })
|
||||
@IsString()
|
||||
password: string
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { ApiProperty } from '@nestjs/swagger'
|
||||
import { IsString } from 'class-validator'
|
||||
|
||||
export class RefreshTokenDto {
|
||||
@ApiProperty()
|
||||
@IsString()
|
||||
refreshToken: string
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { ApiProperty } from '@nestjs/swagger'
|
||||
import { IsString } from 'class-validator'
|
||||
|
||||
export class SendCodeDto {
|
||||
@ApiProperty({ example: '09123456789' })
|
||||
@IsString()
|
||||
mobileNumber: string
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { ApiProperty } from '@nestjs/swagger'
|
||||
import { IsString } from 'class-validator'
|
||||
|
||||
export class VerifyCodeDto {
|
||||
@ApiProperty({ example: '09123456789' })
|
||||
@IsString()
|
||||
mobileNumber: string
|
||||
|
||||
@ApiProperty({ example: '12345' })
|
||||
@IsString()
|
||||
code: string
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common'
|
||||
import { JwtService } from '@nestjs/jwt'
|
||||
import { Request } from 'express'
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard implements CanActivate {
|
||||
constructor(private jwt: JwtService) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const req = context.switchToHttp().getRequest<Request>()
|
||||
const auth = req.headers.authorization
|
||||
if (!auth) throw new UnauthorizedException('Missing Authorization header')
|
||||
|
||||
const parts = auth.split(' ')
|
||||
if (parts.length !== 2 || parts[0] !== 'Bearer') {
|
||||
throw new UnauthorizedException('Invalid Authorization header format')
|
||||
}
|
||||
|
||||
const token = parts[1]
|
||||
try {
|
||||
const payload = this.jwt.verify(token, {
|
||||
secret: process.env.JWT_SECRET || 'secret',
|
||||
})
|
||||
;(req as any).user = payload
|
||||
return true
|
||||
} catch (err) {
|
||||
throw new UnauthorizedException('Invalid or expired token')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,6 +107,16 @@ export type StockMovement = Prisma.StockMovementModel
|
||||
*
|
||||
*/
|
||||
export type StockBalance = Prisma.StockBalanceModel
|
||||
/**
|
||||
* Model OtpCode
|
||||
*
|
||||
*/
|
||||
export type OtpCode = Prisma.OtpCodeModel
|
||||
/**
|
||||
* Model RefreshToken
|
||||
*
|
||||
*/
|
||||
export type RefreshToken = Prisma.RefreshTokenModel
|
||||
/**
|
||||
* Model InventoryTransfer
|
||||
*
|
||||
|
||||
@@ -127,6 +127,16 @@ export type StockMovement = Prisma.StockMovementModel
|
||||
*
|
||||
*/
|
||||
export type StockBalance = Prisma.StockBalanceModel
|
||||
/**
|
||||
* Model OtpCode
|
||||
*
|
||||
*/
|
||||
export type OtpCode = Prisma.OtpCodeModel
|
||||
/**
|
||||
* Model RefreshToken
|
||||
*
|
||||
*/
|
||||
export type RefreshToken = Prisma.RefreshTokenModel
|
||||
/**
|
||||
* Model InventoryTransfer
|
||||
*
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -402,6 +402,8 @@ export const ModelName = {
|
||||
SalesInvoiceItem: 'SalesInvoiceItem',
|
||||
StockMovement: 'StockMovement',
|
||||
StockBalance: 'StockBalance',
|
||||
OtpCode: 'OtpCode',
|
||||
RefreshToken: 'RefreshToken',
|
||||
InventoryTransfer: 'InventoryTransfer',
|
||||
InventoryTransferItem: 'InventoryTransferItem',
|
||||
StockAdjustment: 'StockAdjustment',
|
||||
@@ -424,7 +426,7 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
||||
omit: GlobalOmitOptions
|
||||
}
|
||||
meta: {
|
||||
modelProps: "user" | "role" | "productVariant" | "product" | "productBrand" | "productCategory" | "supplier" | "customer" | "inventory" | "store" | "productCharge" | "order" | "purchaseReceipt" | "purchaseReceiptItem" | "salesInvoice" | "salesInvoiceItem" | "stockMovement" | "stockBalance" | "inventoryTransfer" | "inventoryTransferItem" | "stockAdjustment" | "triggerLog" | "inventory_overview" | "stock_cardex" | "stock_view"
|
||||
modelProps: "user" | "role" | "productVariant" | "product" | "productBrand" | "productCategory" | "supplier" | "customer" | "inventory" | "store" | "productCharge" | "order" | "purchaseReceipt" | "purchaseReceiptItem" | "salesInvoice" | "salesInvoiceItem" | "stockMovement" | "stockBalance" | "otpCode" | "refreshToken" | "inventoryTransfer" | "inventoryTransferItem" | "stockAdjustment" | "triggerLog" | "inventory_overview" | "stock_cardex" | "stock_view"
|
||||
txIsolationLevel: TransactionIsolationLevel
|
||||
}
|
||||
model: {
|
||||
@@ -1616,6 +1618,138 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
||||
}
|
||||
}
|
||||
}
|
||||
OtpCode: {
|
||||
payload: Prisma.$OtpCodePayload<ExtArgs>
|
||||
fields: Prisma.OtpCodeFieldRefs
|
||||
operations: {
|
||||
findUnique: {
|
||||
args: Prisma.OtpCodeFindUniqueArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$OtpCodePayload> | null
|
||||
}
|
||||
findUniqueOrThrow: {
|
||||
args: Prisma.OtpCodeFindUniqueOrThrowArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$OtpCodePayload>
|
||||
}
|
||||
findFirst: {
|
||||
args: Prisma.OtpCodeFindFirstArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$OtpCodePayload> | null
|
||||
}
|
||||
findFirstOrThrow: {
|
||||
args: Prisma.OtpCodeFindFirstOrThrowArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$OtpCodePayload>
|
||||
}
|
||||
findMany: {
|
||||
args: Prisma.OtpCodeFindManyArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$OtpCodePayload>[]
|
||||
}
|
||||
create: {
|
||||
args: Prisma.OtpCodeCreateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$OtpCodePayload>
|
||||
}
|
||||
createMany: {
|
||||
args: Prisma.OtpCodeCreateManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
delete: {
|
||||
args: Prisma.OtpCodeDeleteArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$OtpCodePayload>
|
||||
}
|
||||
update: {
|
||||
args: Prisma.OtpCodeUpdateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$OtpCodePayload>
|
||||
}
|
||||
deleteMany: {
|
||||
args: Prisma.OtpCodeDeleteManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
updateMany: {
|
||||
args: Prisma.OtpCodeUpdateManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
upsert: {
|
||||
args: Prisma.OtpCodeUpsertArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$OtpCodePayload>
|
||||
}
|
||||
aggregate: {
|
||||
args: Prisma.OtpCodeAggregateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.AggregateOtpCode>
|
||||
}
|
||||
groupBy: {
|
||||
args: Prisma.OtpCodeGroupByArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.OtpCodeGroupByOutputType>[]
|
||||
}
|
||||
count: {
|
||||
args: Prisma.OtpCodeCountArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.OtpCodeCountAggregateOutputType> | number
|
||||
}
|
||||
}
|
||||
}
|
||||
RefreshToken: {
|
||||
payload: Prisma.$RefreshTokenPayload<ExtArgs>
|
||||
fields: Prisma.RefreshTokenFieldRefs
|
||||
operations: {
|
||||
findUnique: {
|
||||
args: Prisma.RefreshTokenFindUniqueArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$RefreshTokenPayload> | null
|
||||
}
|
||||
findUniqueOrThrow: {
|
||||
args: Prisma.RefreshTokenFindUniqueOrThrowArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$RefreshTokenPayload>
|
||||
}
|
||||
findFirst: {
|
||||
args: Prisma.RefreshTokenFindFirstArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$RefreshTokenPayload> | null
|
||||
}
|
||||
findFirstOrThrow: {
|
||||
args: Prisma.RefreshTokenFindFirstOrThrowArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$RefreshTokenPayload>
|
||||
}
|
||||
findMany: {
|
||||
args: Prisma.RefreshTokenFindManyArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$RefreshTokenPayload>[]
|
||||
}
|
||||
create: {
|
||||
args: Prisma.RefreshTokenCreateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$RefreshTokenPayload>
|
||||
}
|
||||
createMany: {
|
||||
args: Prisma.RefreshTokenCreateManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
delete: {
|
||||
args: Prisma.RefreshTokenDeleteArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$RefreshTokenPayload>
|
||||
}
|
||||
update: {
|
||||
args: Prisma.RefreshTokenUpdateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$RefreshTokenPayload>
|
||||
}
|
||||
deleteMany: {
|
||||
args: Prisma.RefreshTokenDeleteManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
updateMany: {
|
||||
args: Prisma.RefreshTokenUpdateManyArgs<ExtArgs>
|
||||
result: BatchPayload
|
||||
}
|
||||
upsert: {
|
||||
args: Prisma.RefreshTokenUpsertArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.PayloadToResult<Prisma.$RefreshTokenPayload>
|
||||
}
|
||||
aggregate: {
|
||||
args: Prisma.RefreshTokenAggregateArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.AggregateRefreshToken>
|
||||
}
|
||||
groupBy: {
|
||||
args: Prisma.RefreshTokenGroupByArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.RefreshTokenGroupByOutputType>[]
|
||||
}
|
||||
count: {
|
||||
args: Prisma.RefreshTokenCountArgs<ExtArgs>
|
||||
result: runtime.Types.Utils.Optional<Prisma.RefreshTokenCountAggregateOutputType> | number
|
||||
}
|
||||
}
|
||||
}
|
||||
InventoryTransfer: {
|
||||
payload: Prisma.$InventoryTransferPayload<ExtArgs>
|
||||
fields: Prisma.InventoryTransferFieldRefs
|
||||
@@ -2289,6 +2423,30 @@ export const StockBalanceScalarFieldEnum = {
|
||||
export type StockBalanceScalarFieldEnum = (typeof StockBalanceScalarFieldEnum)[keyof typeof StockBalanceScalarFieldEnum]
|
||||
|
||||
|
||||
export const OtpCodeScalarFieldEnum = {
|
||||
id: 'id',
|
||||
mobileNumber: 'mobileNumber',
|
||||
code: 'code',
|
||||
used: 'used',
|
||||
expiresAt: 'expiresAt',
|
||||
createdAt: 'createdAt'
|
||||
} as const
|
||||
|
||||
export type OtpCodeScalarFieldEnum = (typeof OtpCodeScalarFieldEnum)[keyof typeof OtpCodeScalarFieldEnum]
|
||||
|
||||
|
||||
export const RefreshTokenScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tokenHash: 'tokenHash',
|
||||
userId: 'userId',
|
||||
revoked: 'revoked',
|
||||
expiresAt: 'expiresAt',
|
||||
createdAt: 'createdAt'
|
||||
} as const
|
||||
|
||||
export type RefreshTokenScalarFieldEnum = (typeof RefreshTokenScalarFieldEnum)[keyof typeof RefreshTokenScalarFieldEnum]
|
||||
|
||||
|
||||
export const InventoryTransferScalarFieldEnum = {
|
||||
id: 'id',
|
||||
code: 'code',
|
||||
@@ -2553,6 +2711,21 @@ export const StockMovementOrderByRelevanceFieldEnum = {
|
||||
export type StockMovementOrderByRelevanceFieldEnum = (typeof StockMovementOrderByRelevanceFieldEnum)[keyof typeof StockMovementOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const OtpCodeOrderByRelevanceFieldEnum = {
|
||||
mobileNumber: 'mobileNumber',
|
||||
code: 'code'
|
||||
} as const
|
||||
|
||||
export type OtpCodeOrderByRelevanceFieldEnum = (typeof OtpCodeOrderByRelevanceFieldEnum)[keyof typeof OtpCodeOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const RefreshTokenOrderByRelevanceFieldEnum = {
|
||||
tokenHash: 'tokenHash'
|
||||
} as const
|
||||
|
||||
export type RefreshTokenOrderByRelevanceFieldEnum = (typeof RefreshTokenOrderByRelevanceFieldEnum)[keyof typeof RefreshTokenOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const InventoryTransferOrderByRelevanceFieldEnum = {
|
||||
code: 'code',
|
||||
description: 'description'
|
||||
@@ -2778,6 +2951,8 @@ export type GlobalOmitConfig = {
|
||||
salesInvoiceItem?: Prisma.SalesInvoiceItemOmit
|
||||
stockMovement?: Prisma.StockMovementOmit
|
||||
stockBalance?: Prisma.StockBalanceOmit
|
||||
otpCode?: Prisma.OtpCodeOmit
|
||||
refreshToken?: Prisma.RefreshTokenOmit
|
||||
inventoryTransfer?: Prisma.InventoryTransferOmit
|
||||
inventoryTransferItem?: Prisma.InventoryTransferItemOmit
|
||||
stockAdjustment?: Prisma.StockAdjustmentOmit
|
||||
|
||||
@@ -69,6 +69,8 @@ export const ModelName = {
|
||||
SalesInvoiceItem: 'SalesInvoiceItem',
|
||||
StockMovement: 'StockMovement',
|
||||
StockBalance: 'StockBalance',
|
||||
OtpCode: 'OtpCode',
|
||||
RefreshToken: 'RefreshToken',
|
||||
InventoryTransfer: 'InventoryTransfer',
|
||||
InventoryTransferItem: 'InventoryTransferItem',
|
||||
StockAdjustment: 'StockAdjustment',
|
||||
@@ -374,6 +376,30 @@ export const StockBalanceScalarFieldEnum = {
|
||||
export type StockBalanceScalarFieldEnum = (typeof StockBalanceScalarFieldEnum)[keyof typeof StockBalanceScalarFieldEnum]
|
||||
|
||||
|
||||
export const OtpCodeScalarFieldEnum = {
|
||||
id: 'id',
|
||||
mobileNumber: 'mobileNumber',
|
||||
code: 'code',
|
||||
used: 'used',
|
||||
expiresAt: 'expiresAt',
|
||||
createdAt: 'createdAt'
|
||||
} as const
|
||||
|
||||
export type OtpCodeScalarFieldEnum = (typeof OtpCodeScalarFieldEnum)[keyof typeof OtpCodeScalarFieldEnum]
|
||||
|
||||
|
||||
export const RefreshTokenScalarFieldEnum = {
|
||||
id: 'id',
|
||||
tokenHash: 'tokenHash',
|
||||
userId: 'userId',
|
||||
revoked: 'revoked',
|
||||
expiresAt: 'expiresAt',
|
||||
createdAt: 'createdAt'
|
||||
} as const
|
||||
|
||||
export type RefreshTokenScalarFieldEnum = (typeof RefreshTokenScalarFieldEnum)[keyof typeof RefreshTokenScalarFieldEnum]
|
||||
|
||||
|
||||
export const InventoryTransferScalarFieldEnum = {
|
||||
id: 'id',
|
||||
code: 'code',
|
||||
@@ -638,6 +664,21 @@ export const StockMovementOrderByRelevanceFieldEnum = {
|
||||
export type StockMovementOrderByRelevanceFieldEnum = (typeof StockMovementOrderByRelevanceFieldEnum)[keyof typeof StockMovementOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const OtpCodeOrderByRelevanceFieldEnum = {
|
||||
mobileNumber: 'mobileNumber',
|
||||
code: 'code'
|
||||
} as const
|
||||
|
||||
export type OtpCodeOrderByRelevanceFieldEnum = (typeof OtpCodeOrderByRelevanceFieldEnum)[keyof typeof OtpCodeOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const RefreshTokenOrderByRelevanceFieldEnum = {
|
||||
tokenHash: 'tokenHash'
|
||||
} as const
|
||||
|
||||
export type RefreshTokenOrderByRelevanceFieldEnum = (typeof RefreshTokenOrderByRelevanceFieldEnum)[keyof typeof RefreshTokenOrderByRelevanceFieldEnum]
|
||||
|
||||
|
||||
export const InventoryTransferOrderByRelevanceFieldEnum = {
|
||||
code: 'code',
|
||||
description: 'description'
|
||||
|
||||
@@ -26,6 +26,8 @@ export type * from './models/SalesInvoice.js'
|
||||
export type * from './models/SalesInvoiceItem.js'
|
||||
export type * from './models/StockMovement.js'
|
||||
export type * from './models/StockBalance.js'
|
||||
export type * from './models/OtpCode.js'
|
||||
export type * from './models/RefreshToken.js'
|
||||
export type * from './models/InventoryTransfer.js'
|
||||
export type * from './models/InventoryTransferItem.js'
|
||||
export type * from './models/StockAdjustment.js'
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -245,17 +245,17 @@ export type RoleOrderByWithRelationInput = {
|
||||
|
||||
export type RoleWhereUniqueInput = Prisma.AtLeast<{
|
||||
id?: number
|
||||
name?: string
|
||||
AND?: Prisma.RoleWhereInput | Prisma.RoleWhereInput[]
|
||||
OR?: Prisma.RoleWhereInput[]
|
||||
NOT?: Prisma.RoleWhereInput | Prisma.RoleWhereInput[]
|
||||
name?: Prisma.StringFilter<"Role"> | string
|
||||
description?: Prisma.StringNullableFilter<"Role"> | string | null
|
||||
permissions?: Prisma.JsonNullableFilter<"Role">
|
||||
createdAt?: Prisma.DateTimeFilter<"Role"> | Date | string
|
||||
updatedAt?: Prisma.DateTimeFilter<"Role"> | Date | string
|
||||
deletedAt?: Prisma.DateTimeNullableFilter<"Role"> | Date | string | null
|
||||
users?: Prisma.UserListRelationFilter
|
||||
}, "id">
|
||||
}, "id" | "name">
|
||||
|
||||
export type RoleOrderByWithAggregationInput = {
|
||||
id?: Prisma.SortOrder
|
||||
|
||||
@@ -253,6 +253,7 @@ export type UserWhereInput = {
|
||||
deletedAt?: Prisma.DateTimeNullableFilter<"User"> | Date | string | null
|
||||
updatedAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
||||
role?: Prisma.XOR<Prisma.RoleScalarRelationFilter, Prisma.RoleWhereInput>
|
||||
refreshTokens?: Prisma.RefreshTokenListRelationFilter
|
||||
}
|
||||
|
||||
export type UserOrderByWithRelationInput = {
|
||||
@@ -266,6 +267,7 @@ export type UserOrderByWithRelationInput = {
|
||||
deletedAt?: Prisma.SortOrderInput | Prisma.SortOrder
|
||||
updatedAt?: Prisma.SortOrder
|
||||
role?: Prisma.RoleOrderByWithRelationInput
|
||||
refreshTokens?: Prisma.RefreshTokenOrderByRelationAggregateInput
|
||||
_relevance?: Prisma.UserOrderByRelevanceInput
|
||||
}
|
||||
|
||||
@@ -283,6 +285,7 @@ export type UserWhereUniqueInput = Prisma.AtLeast<{
|
||||
deletedAt?: Prisma.DateTimeNullableFilter<"User"> | Date | string | null
|
||||
updatedAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
||||
role?: Prisma.XOR<Prisma.RoleScalarRelationFilter, Prisma.RoleWhereInput>
|
||||
refreshTokens?: Prisma.RefreshTokenListRelationFilter
|
||||
}, "id" | "mobileNumber">
|
||||
|
||||
export type UserOrderByWithAggregationInput = {
|
||||
@@ -326,6 +329,7 @@ export type UserCreateInput = {
|
||||
deletedAt?: Date | string | null
|
||||
updatedAt?: Date | string
|
||||
role: Prisma.RoleCreateNestedOneWithoutUsersInput
|
||||
refreshTokens?: Prisma.RefreshTokenCreateNestedManyWithoutUserInput
|
||||
}
|
||||
|
||||
export type UserUncheckedCreateInput = {
|
||||
@@ -338,6 +342,7 @@ export type UserUncheckedCreateInput = {
|
||||
createdAt?: Date | string
|
||||
deletedAt?: Date | string | null
|
||||
updatedAt?: Date | string
|
||||
refreshTokens?: Prisma.RefreshTokenUncheckedCreateNestedManyWithoutUserInput
|
||||
}
|
||||
|
||||
export type UserUpdateInput = {
|
||||
@@ -349,6 +354,7 @@ export type UserUpdateInput = {
|
||||
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
role?: Prisma.RoleUpdateOneRequiredWithoutUsersNestedInput
|
||||
refreshTokens?: Prisma.RefreshTokenUpdateManyWithoutUserNestedInput
|
||||
}
|
||||
|
||||
export type UserUncheckedUpdateInput = {
|
||||
@@ -361,6 +367,7 @@ export type UserUncheckedUpdateInput = {
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
refreshTokens?: Prisma.RefreshTokenUncheckedUpdateManyWithoutUserNestedInput
|
||||
}
|
||||
|
||||
export type UserCreateManyInput = {
|
||||
@@ -459,6 +466,11 @@ export type UserOrderByRelationAggregateInput = {
|
||||
_count?: Prisma.SortOrder
|
||||
}
|
||||
|
||||
export type UserScalarRelationFilter = {
|
||||
is?: Prisma.UserWhereInput
|
||||
isNot?: Prisma.UserWhereInput
|
||||
}
|
||||
|
||||
export type StringFieldUpdateOperationsInput = {
|
||||
set?: string
|
||||
}
|
||||
@@ -521,6 +533,20 @@ export type UserUncheckedUpdateManyWithoutRoleNestedInput = {
|
||||
deleteMany?: Prisma.UserScalarWhereInput | Prisma.UserScalarWhereInput[]
|
||||
}
|
||||
|
||||
export type UserCreateNestedOneWithoutRefreshTokensInput = {
|
||||
create?: Prisma.XOR<Prisma.UserCreateWithoutRefreshTokensInput, Prisma.UserUncheckedCreateWithoutRefreshTokensInput>
|
||||
connectOrCreate?: Prisma.UserCreateOrConnectWithoutRefreshTokensInput
|
||||
connect?: Prisma.UserWhereUniqueInput
|
||||
}
|
||||
|
||||
export type UserUpdateOneRequiredWithoutRefreshTokensNestedInput = {
|
||||
create?: Prisma.XOR<Prisma.UserCreateWithoutRefreshTokensInput, Prisma.UserUncheckedCreateWithoutRefreshTokensInput>
|
||||
connectOrCreate?: Prisma.UserCreateOrConnectWithoutRefreshTokensInput
|
||||
upsert?: Prisma.UserUpsertWithoutRefreshTokensInput
|
||||
connect?: Prisma.UserWhereUniqueInput
|
||||
update?: Prisma.XOR<Prisma.XOR<Prisma.UserUpdateToOneWithWhereWithoutRefreshTokensInput, Prisma.UserUpdateWithoutRefreshTokensInput>, Prisma.UserUncheckedUpdateWithoutRefreshTokensInput>
|
||||
}
|
||||
|
||||
export type UserCreateWithoutRoleInput = {
|
||||
mobileNumber: string
|
||||
password: string
|
||||
@@ -529,6 +555,7 @@ export type UserCreateWithoutRoleInput = {
|
||||
createdAt?: Date | string
|
||||
deletedAt?: Date | string | null
|
||||
updatedAt?: Date | string
|
||||
refreshTokens?: Prisma.RefreshTokenCreateNestedManyWithoutUserInput
|
||||
}
|
||||
|
||||
export type UserUncheckedCreateWithoutRoleInput = {
|
||||
@@ -540,6 +567,7 @@ export type UserUncheckedCreateWithoutRoleInput = {
|
||||
createdAt?: Date | string
|
||||
deletedAt?: Date | string | null
|
||||
updatedAt?: Date | string
|
||||
refreshTokens?: Prisma.RefreshTokenUncheckedCreateNestedManyWithoutUserInput
|
||||
}
|
||||
|
||||
export type UserCreateOrConnectWithoutRoleInput = {
|
||||
@@ -583,6 +611,68 @@ export type UserScalarWhereInput = {
|
||||
updatedAt?: Prisma.DateTimeFilter<"User"> | Date | string
|
||||
}
|
||||
|
||||
export type UserCreateWithoutRefreshTokensInput = {
|
||||
mobileNumber: string
|
||||
password: string
|
||||
firstName: string
|
||||
lastName: string
|
||||
createdAt?: Date | string
|
||||
deletedAt?: Date | string | null
|
||||
updatedAt?: Date | string
|
||||
role: Prisma.RoleCreateNestedOneWithoutUsersInput
|
||||
}
|
||||
|
||||
export type UserUncheckedCreateWithoutRefreshTokensInput = {
|
||||
id?: number
|
||||
mobileNumber: string
|
||||
password: string
|
||||
firstName: string
|
||||
lastName: string
|
||||
roleId: number
|
||||
createdAt?: Date | string
|
||||
deletedAt?: Date | string | null
|
||||
updatedAt?: Date | string
|
||||
}
|
||||
|
||||
export type UserCreateOrConnectWithoutRefreshTokensInput = {
|
||||
where: Prisma.UserWhereUniqueInput
|
||||
create: Prisma.XOR<Prisma.UserCreateWithoutRefreshTokensInput, Prisma.UserUncheckedCreateWithoutRefreshTokensInput>
|
||||
}
|
||||
|
||||
export type UserUpsertWithoutRefreshTokensInput = {
|
||||
update: Prisma.XOR<Prisma.UserUpdateWithoutRefreshTokensInput, Prisma.UserUncheckedUpdateWithoutRefreshTokensInput>
|
||||
create: Prisma.XOR<Prisma.UserCreateWithoutRefreshTokensInput, Prisma.UserUncheckedCreateWithoutRefreshTokensInput>
|
||||
where?: Prisma.UserWhereInput
|
||||
}
|
||||
|
||||
export type UserUpdateToOneWithWhereWithoutRefreshTokensInput = {
|
||||
where?: Prisma.UserWhereInput
|
||||
data: Prisma.XOR<Prisma.UserUpdateWithoutRefreshTokensInput, Prisma.UserUncheckedUpdateWithoutRefreshTokensInput>
|
||||
}
|
||||
|
||||
export type UserUpdateWithoutRefreshTokensInput = {
|
||||
mobileNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
firstName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
lastName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
role?: Prisma.RoleUpdateOneRequiredWithoutUsersNestedInput
|
||||
}
|
||||
|
||||
export type UserUncheckedUpdateWithoutRefreshTokensInput = {
|
||||
id?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
mobileNumber?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
password?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
firstName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
lastName?: Prisma.StringFieldUpdateOperationsInput | string
|
||||
roleId?: Prisma.IntFieldUpdateOperationsInput | number
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
}
|
||||
|
||||
export type UserCreateManyRoleInput = {
|
||||
id?: number
|
||||
mobileNumber: string
|
||||
@@ -602,6 +692,7 @@ export type UserUpdateWithoutRoleInput = {
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
refreshTokens?: Prisma.RefreshTokenUpdateManyWithoutUserNestedInput
|
||||
}
|
||||
|
||||
export type UserUncheckedUpdateWithoutRoleInput = {
|
||||
@@ -613,6 +704,7 @@ export type UserUncheckedUpdateWithoutRoleInput = {
|
||||
createdAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
deletedAt?: Prisma.NullableDateTimeFieldUpdateOperationsInput | Date | string | null
|
||||
updatedAt?: Prisma.DateTimeFieldUpdateOperationsInput | Date | string
|
||||
refreshTokens?: Prisma.RefreshTokenUncheckedUpdateManyWithoutUserNestedInput
|
||||
}
|
||||
|
||||
export type UserUncheckedUpdateManyWithoutRoleInput = {
|
||||
@@ -627,6 +719,35 @@ export type UserUncheckedUpdateManyWithoutRoleInput = {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Count Type UserCountOutputType
|
||||
*/
|
||||
|
||||
export type UserCountOutputType = {
|
||||
refreshTokens: number
|
||||
}
|
||||
|
||||
export type UserCountOutputTypeSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
refreshTokens?: boolean | UserCountOutputTypeCountRefreshTokensArgs
|
||||
}
|
||||
|
||||
/**
|
||||
* UserCountOutputType without action
|
||||
*/
|
||||
export type UserCountOutputTypeDefaultArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the UserCountOutputType
|
||||
*/
|
||||
select?: Prisma.UserCountOutputTypeSelect<ExtArgs> | null
|
||||
}
|
||||
|
||||
/**
|
||||
* UserCountOutputType without action
|
||||
*/
|
||||
export type UserCountOutputTypeCountRefreshTokensArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
where?: Prisma.RefreshTokenWhereInput
|
||||
}
|
||||
|
||||
|
||||
export type UserSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetSelect<{
|
||||
id?: boolean
|
||||
@@ -639,6 +760,8 @@ export type UserSelect<ExtArgs extends runtime.Types.Extensions.InternalArgs = r
|
||||
deletedAt?: boolean
|
||||
updatedAt?: boolean
|
||||
role?: boolean | Prisma.RoleDefaultArgs<ExtArgs>
|
||||
refreshTokens?: boolean | Prisma.User$refreshTokensArgs<ExtArgs>
|
||||
_count?: boolean | Prisma.UserCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}, ExtArgs["result"]["user"]>
|
||||
|
||||
|
||||
@@ -658,12 +781,15 @@ export type UserSelectScalar = {
|
||||
export type UserOmit<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = runtime.Types.Extensions.GetOmit<"id" | "mobileNumber" | "password" | "firstName" | "lastName" | "roleId" | "createdAt" | "deletedAt" | "updatedAt", ExtArgs["result"]["user"]>
|
||||
export type UserInclude<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
role?: boolean | Prisma.RoleDefaultArgs<ExtArgs>
|
||||
refreshTokens?: boolean | Prisma.User$refreshTokensArgs<ExtArgs>
|
||||
_count?: boolean | Prisma.UserCountOutputTypeDefaultArgs<ExtArgs>
|
||||
}
|
||||
|
||||
export type $UserPayload<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
name: "User"
|
||||
objects: {
|
||||
role: Prisma.$RolePayload<ExtArgs>
|
||||
refreshTokens: Prisma.$RefreshTokenPayload<ExtArgs>[]
|
||||
}
|
||||
scalars: runtime.Types.Extensions.GetPayloadResult<{
|
||||
id: number
|
||||
@@ -1016,6 +1142,7 @@ readonly fields: UserFieldRefs;
|
||||
export interface Prisma__UserClient<T, Null = never, ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs, GlobalOmitOptions = {}> extends Prisma.PrismaPromise<T> {
|
||||
readonly [Symbol.toStringTag]: "PrismaPromise"
|
||||
role<T extends Prisma.RoleDefaultArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.RoleDefaultArgs<ExtArgs>>): Prisma.Prisma__RoleClient<runtime.Types.Result.GetResult<Prisma.$RolePayload<ExtArgs>, T, "findUniqueOrThrow", GlobalOmitOptions> | Null, Null, ExtArgs, GlobalOmitOptions>
|
||||
refreshTokens<T extends Prisma.User$refreshTokensArgs<ExtArgs> = {}>(args?: Prisma.Subset<T, Prisma.User$refreshTokensArgs<ExtArgs>>): Prisma.PrismaPromise<runtime.Types.Result.GetResult<Prisma.$RefreshTokenPayload<ExtArgs>, T, "findMany", GlobalOmitOptions> | Null>
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
@@ -1396,6 +1523,30 @@ export type UserDeleteManyArgs<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
limit?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* User.refreshTokens
|
||||
*/
|
||||
export type User$refreshTokensArgs<ExtArgs extends runtime.Types.Extensions.InternalArgs = runtime.Types.Extensions.DefaultArgs> = {
|
||||
/**
|
||||
* Select specific fields to fetch from the RefreshToken
|
||||
*/
|
||||
select?: Prisma.RefreshTokenSelect<ExtArgs> | null
|
||||
/**
|
||||
* Omit specific fields from the RefreshToken
|
||||
*/
|
||||
omit?: Prisma.RefreshTokenOmit<ExtArgs> | null
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
include?: Prisma.RefreshTokenInclude<ExtArgs> | null
|
||||
where?: Prisma.RefreshTokenWhereInput
|
||||
orderBy?: Prisma.RefreshTokenOrderByWithRelationInput | Prisma.RefreshTokenOrderByWithRelationInput[]
|
||||
cursor?: Prisma.RefreshTokenWhereUniqueInput
|
||||
take?: number
|
||||
skip?: number
|
||||
distinct?: Prisma.RefreshTokenScalarFieldEnum | Prisma.RefreshTokenScalarFieldEnum[]
|
||||
}
|
||||
|
||||
/**
|
||||
* User without action
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Controller, Get, Query } from '@nestjs/common'
|
||||
import { ApiQuery } from '@nestjs/swagger'
|
||||
import { CardexService } from './cardex.service'
|
||||
|
||||
@Controller('cardex')
|
||||
export class CardexController {
|
||||
constructor(private readonly service: CardexService) {}
|
||||
|
||||
@Get('')
|
||||
@ApiQuery({ name: 'startDate', required: true, type: Date })
|
||||
@ApiQuery({ name: 'endDate', required: false, type: Date })
|
||||
@ApiQuery({ name: 'inventoryId', required: false, type: Number })
|
||||
@ApiQuery({ name: 'productId', required: false, type: Number })
|
||||
async getStock(
|
||||
@Query('startDate') startDate: Date,
|
||||
@Query('endDate') endDate: Date,
|
||||
@Query('inventoryId') inventoryId: number,
|
||||
@Query('productId') productId: number,
|
||||
) {
|
||||
return this.service.getCardex({
|
||||
startDate,
|
||||
endDate,
|
||||
inventoryId,
|
||||
productId,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { PrismaModule } from '../../prisma/prisma.module'
|
||||
import { CardexController } from './cardex.controller'
|
||||
import { CardexService } from './cardex.service'
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule],
|
||||
controllers: [CardexController],
|
||||
providers: [CardexService],
|
||||
})
|
||||
export class CardexModule {}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import dayjs from 'dayjs'
|
||||
import { ResponseMapper } from '../../common/response/response-mapper'
|
||||
import { Prisma } from '../../generated/prisma/client'
|
||||
import { PrismaService } from '../../prisma/prisma.service'
|
||||
import { ReadCardexDto } from './dto/read-pos.dto'
|
||||
|
||||
@Injectable()
|
||||
export class CardexService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async getCardex({ startDate, endDate, inventoryId, productId }: ReadCardexDto) {
|
||||
if (!endDate) {
|
||||
endDate = dayjs(startDate).add(1, 'months').toDate()
|
||||
}
|
||||
const where: Prisma.StockMovementWhereInput = {}
|
||||
|
||||
if (inventoryId !== undefined) where.inventoryId = inventoryId
|
||||
if (productId !== undefined) where.productId = productId
|
||||
|
||||
if (startDate || endDate) {
|
||||
where.createdAt = {}
|
||||
if (startDate) where.createdAt.gte = new Date(startDate)
|
||||
if (endDate) where.createdAt.lte = new Date(endDate)
|
||||
}
|
||||
|
||||
const items = await this.prisma.stockMovement.findMany({
|
||||
where,
|
||||
include: { product: true, inventory: true },
|
||||
orderBy: { createdAt: 'desc' },
|
||||
})
|
||||
|
||||
const mapped = items.map(i => ({
|
||||
id: i.id,
|
||||
type: i.type,
|
||||
quantity: Number(i.quantity),
|
||||
fee: Number(i.fee),
|
||||
totalCost: Number(i.totalCost),
|
||||
referenceType: i.referenceType,
|
||||
referenceId: i.referenceId,
|
||||
createdAt: i.createdAt,
|
||||
avgCost: Number(i.avgCost),
|
||||
product: {
|
||||
name: i.product.name,
|
||||
sku: i.product.sku,
|
||||
id: i.productId,
|
||||
},
|
||||
inventory: {
|
||||
name: i.inventory.name,
|
||||
id: i.inventoryId,
|
||||
},
|
||||
}))
|
||||
|
||||
return ResponseMapper.list(mapped)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ApiPropertyOptional } from '@nestjs/swagger'
|
||||
import { IsDateString, IsNumber, IsOptional } from 'class-validator'
|
||||
|
||||
export class ReadCardexDto {
|
||||
@ApiPropertyOptional()
|
||||
@IsDateString()
|
||||
startDate: Date
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
endDate?: Date
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
inventoryId?: number
|
||||
|
||||
@ApiPropertyOptional()
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
productId?: number
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Module } from '@nestjs/common'
|
||||
import { PrismaModule } from '../prisma/prisma.module'
|
||||
import { PrismaModule } from '../../prisma/prisma.module'
|
||||
import { PosController } from './pos.controller'
|
||||
import { PosService } from './pos.service'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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 { ResponseMapper } from '../../common/response/response-mapper'
|
||||
import { Prisma } from '../../generated/prisma/client'
|
||||
import { PrismaService } from '../../prisma/prisma.service'
|
||||
import { CreateOrderDto } from './dto/create-pos.dto'
|
||||
|
||||
@Injectable()
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common'
|
||||
import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from '@nestjs/common'
|
||||
import { ApiQuery } from '@nestjs/swagger'
|
||||
import { CreateProductDto } from './dto/create-product.dto'
|
||||
import { UpdateProductDto } from './dto/update-product.dto'
|
||||
import { ProductsService } from './products.service'
|
||||
@@ -13,8 +14,10 @@ export class ProductsController {
|
||||
}
|
||||
|
||||
@Get()
|
||||
findAll() {
|
||||
return this.productsService.findAll()
|
||||
@ApiQuery({ name: 'page', required: false, type: Number, default: 1 })
|
||||
@ApiQuery({ name: 'pageSize', required: false, type: Number, default: 30 })
|
||||
findAll(@Query('page') page: number = 1, @Query('pageSize') pageSize: number = 30) {
|
||||
return this.productsService.findAll(page, pageSize)
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ShortEntity } from '../common/interfaces/response-models'
|
||||
import { ResponseMapper } from '../common/response/response-mapper'
|
||||
import { Prisma } from '../generated/prisma/client'
|
||||
import { PrismaService } from '../prisma/prisma.service'
|
||||
import { CreateProductDto } from './dto/create-product.dto'
|
||||
|
||||
@@ -28,10 +29,17 @@ export class ProductsService {
|
||||
return ResponseMapper.create(item)
|
||||
}
|
||||
|
||||
async findAll() {
|
||||
const items = await this.prisma.product.findMany({
|
||||
include: { brand: true, category: true, stockBalances: true },
|
||||
})
|
||||
async findAll(page = 1, pageSize = 20) {
|
||||
const query: Prisma.ProductFindManyArgs = {}
|
||||
|
||||
const [items, count] = await this.prisma.$transaction([
|
||||
this.prisma.product.findMany({
|
||||
include: { brand: true, category: true, stockBalances: true },
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
}),
|
||||
this.prisma.product.count(),
|
||||
])
|
||||
|
||||
const mapped = items.map(p => {
|
||||
const { brandId, categoryId, ...rest } = p as any
|
||||
@@ -48,7 +56,7 @@ export class ProductsService {
|
||||
|
||||
return { ...rest, brand, category, stock }
|
||||
})
|
||||
return ResponseMapper.list(mapped)
|
||||
return ResponseMapper.paginate(mapped, count, page, pageSize)
|
||||
}
|
||||
|
||||
async findOne(id: number) {
|
||||
|
||||
@@ -23,8 +23,8 @@ export class PurchaseReceiptItemsService {
|
||||
const item = await this.prisma.purchaseReceiptItem.create({ data: payload })
|
||||
return ResponseMapper.create(item)
|
||||
}
|
||||
async findAll(receiptId?: number) {
|
||||
const where = receiptId ? { receiptId: Number(receiptId) } : undefined
|
||||
async findAll(receiptId: number) {
|
||||
const where = { receiptId: Number(receiptId) }
|
||||
const items = await this.prisma.purchaseReceiptItem.findMany({
|
||||
where,
|
||||
include: { product: true },
|
||||
|
||||
@@ -47,7 +47,22 @@ export class PurchaseReceiptsService {
|
||||
async findOne(id: number) {
|
||||
const item = await this.prisma.purchaseReceipt.findUnique({
|
||||
where: { id },
|
||||
include: { supplier: true, inventory: true, items: true },
|
||||
include: {
|
||||
supplier: {
|
||||
select: {
|
||||
id: true,
|
||||
firstName: true,
|
||||
lastName: true,
|
||||
},
|
||||
},
|
||||
inventory: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
items: true,
|
||||
},
|
||||
})
|
||||
if (!item) return null
|
||||
return ResponseMapper.single(item)
|
||||
|
||||
@@ -17,9 +17,22 @@ export class SuppliersController {
|
||||
return this.suppliersService.findAll()
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
findOne(@Param('id') id: string) {
|
||||
return this.suppliersService.findOne(Number(id))
|
||||
@Get(':supplierId')
|
||||
findOne(@Param('supplierId') supplierId: string) {
|
||||
return this.suppliersService.findOne(Number(supplierId))
|
||||
}
|
||||
|
||||
@Get(':supplierId/invoices')
|
||||
getInvoices(@Param('supplierId') supplierId: string) {
|
||||
return this.suppliersService.getInvoices(Number(supplierId))
|
||||
}
|
||||
|
||||
@Get(':supplierId/invoices/:invoiceId')
|
||||
getInvoice(
|
||||
@Param('supplierId') supplierId: string,
|
||||
@Param('invoiceId') invoiceId: string,
|
||||
) {
|
||||
return this.suppliersService.getInvoice(Number(supplierId), Number(invoiceId))
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
|
||||
@@ -18,7 +18,82 @@ export class SuppliersService {
|
||||
async findOne(id: number) {
|
||||
const item = await this.prisma.supplier.findUnique({ where: { id } })
|
||||
if (!item) return null
|
||||
return ResponseMapper.single(item)
|
||||
const receiptsInfo = await this.prisma.purchaseReceipt.aggregate({
|
||||
where: {
|
||||
supplierId: id,
|
||||
},
|
||||
_count: true,
|
||||
_sum: {
|
||||
totalAmount: true,
|
||||
},
|
||||
})
|
||||
|
||||
return ResponseMapper.single({
|
||||
...item,
|
||||
receiptsOverview: {
|
||||
totalPayment: receiptsInfo._sum.totalAmount,
|
||||
count: receiptsInfo._count,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async getInvoices(supplierId: number) {
|
||||
const items = await this.prisma.purchaseReceipt.findMany({
|
||||
where: {
|
||||
supplierId,
|
||||
},
|
||||
include: {
|
||||
inventory: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
items: {
|
||||
select: {
|
||||
id: true,
|
||||
count: true,
|
||||
fee: true,
|
||||
total: true,
|
||||
product: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
sku: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
omit: {
|
||||
inventoryId: true,
|
||||
supplierId: true,
|
||||
},
|
||||
})
|
||||
return ResponseMapper.list(items)
|
||||
}
|
||||
|
||||
async getInvoice(supplierId: number, invoiceId: number) {
|
||||
const invoice = await this.prisma.purchaseReceipt.findUnique({
|
||||
where: {
|
||||
id: invoiceId,
|
||||
supplierId,
|
||||
},
|
||||
include: {
|
||||
inventory: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
items: true,
|
||||
},
|
||||
omit: {
|
||||
inventoryId: true,
|
||||
supplierId: true,
|
||||
},
|
||||
})
|
||||
return ResponseMapper.single(invoice)
|
||||
}
|
||||
|
||||
async update(id: number, data: any) {
|
||||
|
||||
Reference in New Issue
Block a user