refactor user accounts structure
This commit is contained in:
@@ -1,16 +1,32 @@
|
||||
import { IsNumber, IsOptional, IsString } from 'class-validator'
|
||||
import { PartnerStatus } from '@/generated/prisma/enums'
|
||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||
import { IsEnum, IsNumber, IsOptional, IsString } from 'class-validator'
|
||||
|
||||
export class CreatePartnerDto {
|
||||
@IsString()
|
||||
@ApiProperty({ required: true })
|
||||
name: string
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
code?: string
|
||||
@ApiProperty({ required: true })
|
||||
code: string
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@ApiProperty({ required: true })
|
||||
license_quota?: number
|
||||
|
||||
@IsString()
|
||||
@ApiProperty({ required: true })
|
||||
username: string
|
||||
|
||||
@IsString()
|
||||
@ApiProperty({ required: true })
|
||||
password: string
|
||||
}
|
||||
|
||||
export class UpdatePartnerDto extends CreatePartnerDto {}
|
||||
export class UpdatePartnerDto extends PartialType(CreatePartnerDto) {
|
||||
@IsEnum(PartnerStatus)
|
||||
@ApiProperty({ enum: PartnerStatus })
|
||||
status: PartnerStatus
|
||||
}
|
||||
|
||||
@@ -8,101 +8,100 @@ export class PartnerLicensesService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async findAll(partnerId: string) {
|
||||
const licenses = await this.prisma.license.findMany({
|
||||
where: { partner_id: partnerId },
|
||||
include: {
|
||||
pos: {
|
||||
include: {
|
||||
complex: true,
|
||||
provider: true,
|
||||
|
||||
accounts: {
|
||||
include: {
|
||||
user: true,
|
||||
},
|
||||
omit: {
|
||||
business_id: true,
|
||||
partner_id: true,
|
||||
provider_id: true,
|
||||
pos_id: true,
|
||||
},
|
||||
},
|
||||
device: {
|
||||
include: {
|
||||
brand: true,
|
||||
},
|
||||
omit: {
|
||||
brand_id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
omit: {
|
||||
pos_id: true,
|
||||
partner_id: true,
|
||||
},
|
||||
})
|
||||
return ResponseMapper.list(
|
||||
licenses.map(license => {
|
||||
const { pos, ...rest } = license
|
||||
const { accounts, ...posRest } = pos
|
||||
return {
|
||||
account: accounts[0],
|
||||
pos: posRest,
|
||||
...rest,
|
||||
}
|
||||
}),
|
||||
)
|
||||
// const licenses = await this.prisma.license.findMany({
|
||||
// where: { partner_id: partnerId },
|
||||
// include: {
|
||||
// pos: {
|
||||
// include: {
|
||||
// complex: true,
|
||||
// provider: true,
|
||||
// accounts: {
|
||||
// include: {
|
||||
// user: true,
|
||||
// },
|
||||
// omit: {
|
||||
// business_id: true,
|
||||
// partner_id: true,
|
||||
// provider_id: true,
|
||||
// pos_id: true,
|
||||
// },
|
||||
// },
|
||||
// device: {
|
||||
// include: {
|
||||
// brand: true,
|
||||
// },
|
||||
// omit: {
|
||||
// brand_id: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// omit: {
|
||||
// pos_id: true,
|
||||
// partner_id: true,
|
||||
// },
|
||||
// })
|
||||
// return ResponseMapper.list(
|
||||
// licenses.map(license => {
|
||||
// const { pos, ...rest } = license
|
||||
// const { accounts, ...posRest } = pos
|
||||
// return {
|
||||
// account: accounts[0],
|
||||
// pos: posRest,
|
||||
// ...rest,
|
||||
// }
|
||||
// }),
|
||||
// )
|
||||
}
|
||||
|
||||
async findOne(partnerId: string, id: string) {
|
||||
const license = await this.prisma.license.findFirst({
|
||||
where: { id, partner_id: partnerId },
|
||||
include: {
|
||||
pos: {
|
||||
include: {
|
||||
complex: true,
|
||||
provider: true,
|
||||
// const license = await this.prisma.license.findFirst({
|
||||
// where: { id, partner_id: partnerId },
|
||||
// include: {
|
||||
// pos: {
|
||||
// include: {
|
||||
// complex: true,
|
||||
// provider: true,
|
||||
|
||||
accounts: {
|
||||
include: {
|
||||
user: true,
|
||||
},
|
||||
omit: {
|
||||
business_id: true,
|
||||
partner_id: true,
|
||||
provider_id: true,
|
||||
pos_id: true,
|
||||
},
|
||||
},
|
||||
device: {
|
||||
include: {
|
||||
brand: true,
|
||||
},
|
||||
omit: {
|
||||
brand_id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
omit: {
|
||||
pos_id: true,
|
||||
partner_id: true,
|
||||
},
|
||||
})
|
||||
if (license) {
|
||||
const { pos, ...rest } = license
|
||||
const { accounts, ...posRest } = pos
|
||||
return ResponseMapper.single({
|
||||
account: accounts[0],
|
||||
pos: posRest,
|
||||
...rest,
|
||||
})
|
||||
}
|
||||
// accounts: {
|
||||
// include: {
|
||||
// user: true,
|
||||
// },
|
||||
// omit: {
|
||||
// business_id: true,
|
||||
// partner_id: true,
|
||||
// provider_id: true,
|
||||
// pos_id: true,
|
||||
// },
|
||||
// },
|
||||
// device: {
|
||||
// include: {
|
||||
// brand: true,
|
||||
// },
|
||||
// omit: {
|
||||
// brand_id: true,
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// omit: {
|
||||
// pos_id: true,
|
||||
// partner_id: true,
|
||||
// },
|
||||
// })
|
||||
// if (license) {
|
||||
// const { pos, ...rest } = license
|
||||
// const { accounts, ...posRest } = pos
|
||||
// return ResponseMapper.single({
|
||||
// account: accounts[0],
|
||||
// pos: posRest,
|
||||
// ...rest,
|
||||
// })
|
||||
// }
|
||||
|
||||
return ResponseMapper.single(license)
|
||||
return ResponseMapper.single({})
|
||||
}
|
||||
|
||||
async create(partnerId: string, data: CreatePartnerLicenseDto) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Body, Controller, Delete, Get, Param, Patch, Post } from '@nestjs/common'
|
||||
import { AccountsService } from './accounts.service'
|
||||
import { CreateAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
import { CreatePartnerAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
|
||||
@Controller('admin/partners/:partnerId/accounts')
|
||||
export class AccountsController {
|
||||
@@ -17,7 +17,10 @@ export class AccountsController {
|
||||
}
|
||||
|
||||
@Post()
|
||||
async create(@Param('partnerId') partnerId: string, @Body() data: CreateAccountDto) {
|
||||
async create(
|
||||
@Param('partnerId') partnerId: string,
|
||||
@Body() data: CreatePartnerAccountDto,
|
||||
) {
|
||||
return this.accountsService.create(partnerId, data)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,67 +1,66 @@
|
||||
import { PartnerAccountSelect } from '@/generated/prisma/models'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
import { PasswordUtil } from 'common/utils/password.util'
|
||||
import { AccountStatus, AccountType } from 'generated/prisma/enums'
|
||||
import { CreateAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
import { AccountStatus, AccountType, PartnerRole } from 'generated/prisma/enums'
|
||||
import { CreatePartnerAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||
|
||||
@Injectable()
|
||||
export class AccountsService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async findAll(partnerId: string) {
|
||||
const accounts = await this.prisma.account.findMany({
|
||||
where: { partner_id: partnerId },
|
||||
omit: {
|
||||
password: true,
|
||||
user_id: true,
|
||||
partner_id: true,
|
||||
type: true,
|
||||
pos_id: true,
|
||||
provider_id: true,
|
||||
business_id: true,
|
||||
private readonly defaultSelect = {
|
||||
id: true,
|
||||
role: true,
|
||||
created_at: true,
|
||||
account: {
|
||||
select: {
|
||||
username: true,
|
||||
status: true,
|
||||
},
|
||||
},
|
||||
} as PartnerAccountSelect
|
||||
|
||||
async findAll(partnerId: string) {
|
||||
const accounts = await this.prisma.partnerAccount.findMany({
|
||||
where: { user_id: partnerId },
|
||||
select: this.defaultSelect,
|
||||
})
|
||||
return ResponseMapper.list(accounts)
|
||||
}
|
||||
|
||||
async findOne(id: string) {
|
||||
const account = await this.prisma.account.findUnique({
|
||||
const account = await this.prisma.partnerAccount.findUnique({
|
||||
where: { id },
|
||||
omit: { password: true, user_id: true },
|
||||
include: {
|
||||
partner: true,
|
||||
user: true,
|
||||
},
|
||||
select: this.defaultSelect,
|
||||
})
|
||||
return ResponseMapper.single(account)
|
||||
}
|
||||
|
||||
async create(partnerId: string, data: CreateAccountDto) {
|
||||
const { username, password, ...userData } = data
|
||||
async create(partnerId: string, data: CreatePartnerAccountDto) {
|
||||
const { username, password } = data
|
||||
|
||||
const result = await this.prisma.$transaction(async tx => {
|
||||
let user = await tx.user.upsert({
|
||||
where: {
|
||||
mobile_number: userData.mobile_number,
|
||||
},
|
||||
update: {},
|
||||
create: userData,
|
||||
})
|
||||
|
||||
const hashedPassword = await PasswordUtil.hash(password)
|
||||
|
||||
const dataToCreate = {
|
||||
username,
|
||||
status: AccountStatus.ACTIVE,
|
||||
password: hashedPassword,
|
||||
user_id: user.id,
|
||||
type: AccountType.PARTNER,
|
||||
partner_id: partnerId, // Connect account to partner
|
||||
}
|
||||
|
||||
const account = await tx.account.create({
|
||||
data: dataToCreate,
|
||||
const account = await tx.partnerAccount.create({
|
||||
data: {
|
||||
role: PartnerRole.MANAGER,
|
||||
account: {
|
||||
create: {
|
||||
username,
|
||||
password: hashedPassword,
|
||||
status: AccountStatus.ACTIVE,
|
||||
type: AccountType.PARTNER,
|
||||
},
|
||||
},
|
||||
user: {
|
||||
connect: {
|
||||
id: partnerId,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return account
|
||||
|
||||
@@ -1,37 +1,20 @@
|
||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||
import { AccountStatus, AccountType } from 'generated/prisma/enums'
|
||||
import { CreateUserDto } from '../../../users/dto/user.dto'
|
||||
import { PartnerRole } from 'generated/prisma/enums'
|
||||
|
||||
export class CreateAccountDto extends CreateUserDto {
|
||||
export class CreatePartnerAccountDto {
|
||||
@IsString()
|
||||
@ApiProperty({})
|
||||
username: string
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(AccountType)
|
||||
type?: AccountType
|
||||
|
||||
@IsString()
|
||||
@ApiProperty({})
|
||||
password: string
|
||||
}
|
||||
|
||||
export class UpdateAccountDto {
|
||||
export class UpdateAccountDto extends PartialType(CreatePartnerAccountDto) {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
username?: string
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(AccountType)
|
||||
type?: AccountType
|
||||
|
||||
@IsOptional()
|
||||
@IsEnum(AccountStatus)
|
||||
status?: AccountStatus
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
password?: string
|
||||
|
||||
// @IsOptional()
|
||||
// @IsString()
|
||||
// user_id?: string
|
||||
@IsEnum(PartnerRole)
|
||||
@ApiProperty({ enum: PartnerRole })
|
||||
role?: PartnerRole
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import { PasswordUtil } from '@/common/utils/password.util'
|
||||
import {
|
||||
AccountStatus,
|
||||
AccountType,
|
||||
PartnerRole,
|
||||
PartnerStatus,
|
||||
} from '@/generated/prisma/enums'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import { Injectable } from '@nestjs/common'
|
||||
import { ResponseMapper } from 'common/response/response-mapper'
|
||||
@@ -8,23 +15,7 @@ export class PartnersService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async findAll() {
|
||||
// const partners = await this.prisma.$transaction(async tx => {
|
||||
// const partners = await this.prisma.partner.findMany().then()
|
||||
// const preparedPartners = await partners.map(async partner => {
|
||||
// const relatedLicenseCount = await this.prisma.license.count({
|
||||
// where: {
|
||||
// partner_id: partner.id,
|
||||
// },
|
||||
// })
|
||||
|
||||
// return {
|
||||
// ...partner,
|
||||
// remained_license: Math.min((partner?.licenseQuota, 0) - relatedLicenseCount, 0),
|
||||
// }
|
||||
// })
|
||||
// console.log(preparedPartners)
|
||||
const partners = await this.prisma.partner.findMany()
|
||||
|
||||
return ResponseMapper.list(partners)
|
||||
}
|
||||
|
||||
@@ -39,14 +30,37 @@ export class PartnersService {
|
||||
},
|
||||
}),
|
||||
])
|
||||
|
||||
return ResponseMapper.single({
|
||||
...partner,
|
||||
remained_license: Math.min((partner?.license_quota, 0) - relatedLicenseCount, 0),
|
||||
remained_license: Math.max(
|
||||
(partner?.license_quota || 0) - (relatedLicenseCount || 0),
|
||||
0,
|
||||
),
|
||||
})
|
||||
}
|
||||
|
||||
async create(data: CreatePartnerDto) {
|
||||
const partner = await this.prisma.partner.create({ data })
|
||||
const { username, password, ...rest } = data
|
||||
const partner = await this.prisma.partner.create({
|
||||
data: {
|
||||
...rest,
|
||||
status: PartnerStatus.ACTIVE,
|
||||
accounts: {
|
||||
create: {
|
||||
role: PartnerRole.OWNER,
|
||||
account: {
|
||||
create: {
|
||||
username,
|
||||
password: await PasswordUtil.hash(data.password),
|
||||
status: AccountStatus.ACTIVE,
|
||||
type: AccountType.PARTNER,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
return ResponseMapper.create(partner)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user