create license management
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common'
|
||||
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common'
|
||||
import { AdminUsersService } from './consumers.service'
|
||||
import { CreateConsumerDto, UpdateConsumerDto } from './dto/consumer.dto'
|
||||
|
||||
@@ -25,9 +25,4 @@ export class AdminUsersController {
|
||||
async update(@Param('id') id: string, @Body() data: UpdateConsumerDto) {
|
||||
return this.usersService.update(id, data)
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
async delete(@Param('id') id: string) {
|
||||
return this.usersService.delete(id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,15 @@ import { AdminUserAccountsModule } from './accounts/accounts.module'
|
||||
import { AdminConsumerBusinessActivitiesModule } from './business-activities/business-activities.module'
|
||||
import { AdminUsersController } from './consumers.controller'
|
||||
import { AdminUsersService } from './consumers.service'
|
||||
import { AdminConsumerLicensesModule } from './licenses/licenses.module'
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule, AdminUserAccountsModule, AdminConsumerBusinessActivitiesModule],
|
||||
imports: [
|
||||
PrismaModule,
|
||||
AdminUserAccountsModule,
|
||||
AdminConsumerBusinessActivitiesModule,
|
||||
AdminConsumerLicensesModule,
|
||||
],
|
||||
controllers: [AdminUsersController],
|
||||
providers: [AdminUsersService],
|
||||
exports: [AdminUserAccountsModule],
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { PasswordUtil } from '@/common/utils/password.util'
|
||||
import { AccountStatus, AccountType, ConsumerRole } from '@/generated/prisma/enums'
|
||||
import {
|
||||
AccountStatus,
|
||||
AccountType,
|
||||
ConsumerRole,
|
||||
LicenseStatus,
|
||||
PartnerStatus,
|
||||
} from '@/generated/prisma/enums'
|
||||
import { ConsumerCreateInput, ConsumerSelect } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { BadRequestException, Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { CreateConsumerDto, UpdateConsumerDto } from './dto/consumer.dto'
|
||||
|
||||
@@ -9,17 +16,33 @@ import { CreateConsumerDto, UpdateConsumerDto } from './dto/consumer.dto'
|
||||
export class AdminUsersService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
private readonly defaultSelect: ConsumerSelect = {
|
||||
id: true,
|
||||
first_name: true,
|
||||
last_name: true,
|
||||
mobile_number: true,
|
||||
status: true,
|
||||
created_at: true,
|
||||
license: {
|
||||
select: {
|
||||
id: true,
|
||||
starts_at: true,
|
||||
expires_at: true,
|
||||
status: true,
|
||||
partner: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
async findAll() {
|
||||
const [consumers, count] = await this.prisma.$transaction([
|
||||
this.prisma.consumer.findMany({
|
||||
select: {
|
||||
id: true,
|
||||
first_name: true,
|
||||
last_name: true,
|
||||
mobile_number: true,
|
||||
status: true,
|
||||
created_at: true,
|
||||
},
|
||||
select: this.defaultSelect,
|
||||
}),
|
||||
this.prisma.consumer.count(),
|
||||
])
|
||||
@@ -33,16 +56,12 @@ export class AdminUsersService {
|
||||
}
|
||||
|
||||
async findOne(id: string) {
|
||||
this.prisma.license.findFirst({
|
||||
where: {},
|
||||
})
|
||||
const consumer = await this.prisma.consumer.findUniqueOrThrow({
|
||||
where: { id },
|
||||
select: {
|
||||
id: true,
|
||||
first_name: true,
|
||||
last_name: true,
|
||||
mobile_number: true,
|
||||
status: true,
|
||||
created_at: true,
|
||||
},
|
||||
select: this.defaultSelect,
|
||||
})
|
||||
|
||||
return ResponseMapper.single({
|
||||
@@ -52,32 +71,79 @@ export class AdminUsersService {
|
||||
}
|
||||
|
||||
async create(data: CreateConsumerDto) {
|
||||
const { username, password, ...rest } = data
|
||||
return this.prisma.consumer.create({
|
||||
data: {
|
||||
...rest,
|
||||
accounts: {
|
||||
create: {
|
||||
role: ConsumerRole.OWNER,
|
||||
account: {
|
||||
create: {
|
||||
username,
|
||||
password: await PasswordUtil.hash(password),
|
||||
type: AccountType.CONSUMER,
|
||||
status: AccountStatus.ACTIVE,
|
||||
},
|
||||
const { username, password, license, ...rest } = data
|
||||
const dataToCreate: ConsumerCreateInput = {
|
||||
...rest,
|
||||
accounts: {
|
||||
create: {
|
||||
role: ConsumerRole.OWNER,
|
||||
account: {
|
||||
create: {
|
||||
username,
|
||||
password: await PasswordUtil.hash(password),
|
||||
type: AccountType.CONSUMER,
|
||||
status: AccountStatus.ACTIVE,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
if (license) {
|
||||
if (license.partner_id) {
|
||||
const partner = await this.prisma.partner.findUnique({
|
||||
where: {
|
||||
id: license.partner_id,
|
||||
status: PartnerStatus.ACTIVE,
|
||||
},
|
||||
select: {
|
||||
name: true,
|
||||
license_quota: true,
|
||||
_count: {
|
||||
select: {
|
||||
licenses: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!partner) {
|
||||
throw new BadRequestException('متاسفانه شریک تجاری مورد نظر شما یافت نشد')
|
||||
}
|
||||
const partnerLicensesRemainsQuota =
|
||||
partner.license_quota || 0 - partner._count.licenses
|
||||
|
||||
if (!partnerLicensesRemainsQuota) {
|
||||
throw new BadRequestException(
|
||||
`تعداد لایسنسهای فعلی شریک تجاری ${partner.name} به پایان رسیده است`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
dataToCreate.license = {
|
||||
create: {
|
||||
starts_at: license.starts_at,
|
||||
expires_at: new Date(
|
||||
new Date(license.starts_at).getFullYear() + 1,
|
||||
).toISOString(),
|
||||
status: LicenseStatus.ACTIVE,
|
||||
partner: {
|
||||
connect: {
|
||||
id: license.partner_id,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
return this.prisma.consumer.create({
|
||||
data: dataToCreate,
|
||||
select: this.defaultSelect,
|
||||
})
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateConsumerDto) {
|
||||
return this.prisma.admin.update({ where: { id }, data })
|
||||
}
|
||||
|
||||
async delete(id: string) {
|
||||
return this.prisma.admin.delete({ where: { id } })
|
||||
return this.prisma.consumer.update({
|
||||
where: { id },
|
||||
data,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ConsumerStatus } from '@/generated/prisma/enums'
|
||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||
import { IsEnum, IsString } from 'class-validator'
|
||||
import { ApiProperty, OmitType, PartialType } from '@nestjs/swagger'
|
||||
import { IsEnum, IsObject, IsString } from 'class-validator'
|
||||
import { CreateLicenseDto } from '../licenses/dto/license.dto'
|
||||
|
||||
export class CreateConsumerDto {
|
||||
@IsString()
|
||||
@@ -22,8 +23,16 @@ export class CreateConsumerDto {
|
||||
@IsString()
|
||||
@ApiProperty({ required: true })
|
||||
password: string
|
||||
|
||||
@IsObject()
|
||||
@ApiProperty()
|
||||
license: CreateLicenseDto
|
||||
}
|
||||
export class UpdateConsumerDto extends PartialType(CreateConsumerDto) {
|
||||
export class UpdateConsumerDto extends OmitType(PartialType(CreateConsumerDto), [
|
||||
'password',
|
||||
'username',
|
||||
'license',
|
||||
]) {
|
||||
@IsEnum(ConsumerStatus)
|
||||
@ApiProperty({ enum: ConsumerStatus })
|
||||
status: ConsumerStatus
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { LicenseStatus } from '@/generated/prisma/enums'
|
||||
import { ApiProperty, OmitType, PartialType } from '@nestjs/swagger'
|
||||
import { IsDateString, IsEnum } from 'class-validator'
|
||||
|
||||
export class CreateLicenseDto {
|
||||
@ApiProperty({ required: true, default: new Date().toISOString() })
|
||||
@IsDateString(
|
||||
{ strict: true },
|
||||
{ message: 'invoice_date must be a valid ISO-8601 string' },
|
||||
)
|
||||
starts_at: Date
|
||||
|
||||
@ApiProperty()
|
||||
@IsDateString(
|
||||
{ strict: true },
|
||||
{ message: 'invoice_date must be a valid ISO-8601 string' },
|
||||
)
|
||||
expires_at?: Date
|
||||
|
||||
@ApiProperty()
|
||||
partner_id: string
|
||||
}
|
||||
|
||||
export class UpdateLicenseDto extends OmitType(PartialType(CreateLicenseDto), [
|
||||
'starts_at',
|
||||
]) {
|
||||
@ApiProperty({ required: true, default: new Date().toISOString() })
|
||||
@IsDateString(
|
||||
{ strict: true },
|
||||
{ message: 'invoice_date must be a valid ISO-8601 string' },
|
||||
)
|
||||
starts_at: Date
|
||||
|
||||
@ApiProperty({ enum: LicenseStatus })
|
||||
@IsEnum(LicenseStatus)
|
||||
status?: LicenseStatus
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Body, Controller, Param, Patch, Post } from '@nestjs/common'
|
||||
import { ApiTags } from '@nestjs/swagger'
|
||||
import { CreateLicenseDto, UpdateLicenseDto } from './dto/license.dto'
|
||||
import { LicensesService } from './licenses.service'
|
||||
|
||||
@ApiTags('AdminConsumerAccounts')
|
||||
@Controller('admin/consumers/:consumerId/licenses')
|
||||
export class LicensesController {
|
||||
constructor(private readonly service: LicensesService) {}
|
||||
|
||||
@Post()
|
||||
async create(@Param('consumerId') consumerId: string, @Body() data: CreateLicenseDto) {
|
||||
return this.service.create(consumerId, data)
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
async update(@Param('id') id: string, @Body() data: UpdateLicenseDto) {
|
||||
return this.service.update(id, data)
|
||||
}
|
||||
|
||||
// @Delete(':id')
|
||||
// async delete(@Param('id') id: string) {
|
||||
// return this.service.delete(id)
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import { PrismaModule } from '@/prisma/prisma.module'
|
||||
import { Module } from '@nestjs/common'
|
||||
import { LicensesController } from './licenses.controller'
|
||||
import { LicensesService } from './licenses.service'
|
||||
|
||||
@Module({
|
||||
imports: [PrismaModule],
|
||||
controllers: [LicensesController],
|
||||
providers: [LicensesService],
|
||||
exports: [LicensesService],
|
||||
})
|
||||
export class AdminConsumerLicensesModule {}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { LicenseStatus } from '@/generated/prisma/enums'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { CreateLicenseDto, UpdateLicenseDto } from './dto/license.dto'
|
||||
|
||||
@Injectable()
|
||||
export class LicensesService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
private readonly setExpireDate = (starts_at: Date) => {
|
||||
return new Date(
|
||||
new Date(starts_at).setFullYear(new Date(starts_at).getFullYear() + 1),
|
||||
).toISOString()
|
||||
}
|
||||
|
||||
async create(consumerId: string, data: CreateLicenseDto) {
|
||||
const { starts_at, expires_at } = data
|
||||
const license = await this.prisma.license.create({
|
||||
data: {
|
||||
starts_at,
|
||||
expires_at: expires_at ?? this.setExpireDate(starts_at),
|
||||
partner: {
|
||||
connect: {
|
||||
id: data.partner_id,
|
||||
},
|
||||
},
|
||||
consumers: {
|
||||
connect: {
|
||||
id: consumerId,
|
||||
},
|
||||
},
|
||||
status: LicenseStatus.ACTIVE,
|
||||
},
|
||||
})
|
||||
return ResponseMapper.create(license)
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateLicenseDto) {
|
||||
const { starts_at, expires_at } = data
|
||||
const license = await this.prisma.license.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...data,
|
||||
starts_at,
|
||||
expires_at: expires_at ?? this.setExpireDate(starts_at),
|
||||
},
|
||||
})
|
||||
return ResponseMapper.update(license)
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ export class GoodsController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
create(@Param('guildId') guildId: string, @Body() data: CreateGuildGoodDto) {
|
||||
return this.goodsService.create(guildId, data)
|
||||
create(@Body() data: CreateGuildGoodDto) {
|
||||
return this.goodsService.create(data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ export class GoodsService {
|
||||
return ResponseMapper.single(good)
|
||||
}
|
||||
|
||||
async create(guild_id: string, data: CreateGuildGoodDto) {
|
||||
async create(data: CreateGuildGoodDto) {
|
||||
const { category_id, ...rest } = data
|
||||
|
||||
const good = await this.prisma.good.create({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common'
|
||||
import { CreateLicenseDto, UpdateLicenseDto } from './dto/license.dto'
|
||||
import { Body, Controller, Get, Param, Patch } from '@nestjs/common'
|
||||
import { UpdateLicenseDto } from './dto/license.dto'
|
||||
import { PartnerLicensesService } from './licenses.service'
|
||||
|
||||
@Controller('admin/licenses')
|
||||
@@ -16,11 +16,6 @@ export class LicensesController {
|
||||
return this.licensesService.findOne(id)
|
||||
}
|
||||
|
||||
@Post()
|
||||
async create(@Body() data: CreateLicenseDto) {
|
||||
return this.licensesService.create(data)
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
async update(@Param('id') id: string, @Body() data: UpdateLicenseDto) {
|
||||
return this.licensesService.update(id, data)
|
||||
|
||||
@@ -2,8 +2,7 @@ import { LicenseInclude } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { LicenseStatus } from 'generated/prisma/enums'
|
||||
import { CreateLicenseDto, UpdateLicenseDto } from './dto/license.dto'
|
||||
import { UpdateLicenseDto } from './dto/license.dto'
|
||||
|
||||
@Injectable()
|
||||
export class PartnerLicensesService {
|
||||
@@ -43,7 +42,6 @@ export class PartnerLicensesService {
|
||||
this.prisma.license.findMany({
|
||||
include: this.licenseInclude,
|
||||
omit: {
|
||||
pos_id: true,
|
||||
partner_id: true,
|
||||
},
|
||||
}),
|
||||
@@ -51,7 +49,7 @@ export class PartnerLicensesService {
|
||||
])
|
||||
return ResponseMapper.paginate(
|
||||
licenses.map(license => {
|
||||
const { pos, ...rest } = license
|
||||
const { ...rest } = license
|
||||
// @ts-ignore
|
||||
const { accounts, ...posRest } = pos
|
||||
return {
|
||||
@@ -71,12 +69,11 @@ export class PartnerLicensesService {
|
||||
where: { id },
|
||||
include: this.licenseInclude,
|
||||
omit: {
|
||||
pos_id: true,
|
||||
partner_id: true,
|
||||
},
|
||||
})
|
||||
if (license) {
|
||||
const { pos, ...rest } = license
|
||||
const { ...rest } = license
|
||||
// @ts-ignore
|
||||
const { accounts, ...posRest } = pos
|
||||
return ResponseMapper.single({
|
||||
@@ -89,24 +86,6 @@ export class PartnerLicensesService {
|
||||
return ResponseMapper.single(license)
|
||||
}
|
||||
|
||||
async create(data: CreateLicenseDto) {
|
||||
const date = new Date(data.starts_at || '')
|
||||
const expiresAt =
|
||||
data.expires_at || new Date(date.setFullYear(date.getFullYear() + 1))
|
||||
|
||||
const license = await this.prisma.license.create({
|
||||
data: {
|
||||
partner_id: data.partner_id,
|
||||
pos_id: data.pos_id,
|
||||
starts_at: date,
|
||||
expires_at: expiresAt,
|
||||
status: LicenseStatus.ACTIVE,
|
||||
},
|
||||
})
|
||||
|
||||
return ResponseMapper.create(license)
|
||||
}
|
||||
|
||||
async update(id: string, data: UpdateLicenseDto) {
|
||||
const license = await this.prisma.license.update({
|
||||
where: { id },
|
||||
|
||||
Reference in New Issue
Block a user