449 lines
11 KiB
TypeScript
449 lines
11 KiB
TypeScript
import {
|
|
forwardRef,
|
|
HttpException,
|
|
HttpStatus,
|
|
Inject,
|
|
Injectable,
|
|
} from '@nestjs/common';
|
|
import { CreateUserDto } from './dto/create-user.dto';
|
|
import { UpdateUserDto } from './dto/update-user.dto';
|
|
import { Connection, EntityNotFoundError, Not, Repository } from 'typeorm';
|
|
import { User } from './entities/user.entity';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { randomStringGenerator } from '@nestjs/common/utils/random-string-generator.util';
|
|
import { hashPassword } from '../helper/hash_password';
|
|
import { CoaService } from 'src/transaction/coa.service';
|
|
import { balanceType, coaType } from 'src/helper/enum-list';
|
|
import { RoleService } from 'src/configurable/roles.service';
|
|
import { InputCoaDto } from 'src/transaction/dto/input-coa.dto';
|
|
import * as uuid from 'uuid';
|
|
import { UserDetail } from './entities/user_detail.entity';
|
|
import { COA } from '../transaction/entities/coa.entity';
|
|
|
|
@Injectable()
|
|
export class UsersService {
|
|
constructor(
|
|
@InjectRepository(User)
|
|
private usersRepository: Repository<User>,
|
|
@InjectRepository(UserDetail)
|
|
private userDetailRepository: Repository<UserDetail>,
|
|
@Inject(
|
|
forwardRef(() => {
|
|
return CoaService;
|
|
}),
|
|
)
|
|
private coaService: CoaService,
|
|
private roleService: RoleService,
|
|
private connection: Connection,
|
|
) {}
|
|
|
|
async create(createUserDto: CreateUserDto, currentUser: any) {
|
|
const roles = await this.roleService.findOne(createUserDto.roleId);
|
|
const superior = await this.findByUsername(currentUser.username);
|
|
|
|
const check = await this.usersRepository.findOne({
|
|
username: createUserDto.username,
|
|
});
|
|
|
|
if (check) {
|
|
throw new HttpException(
|
|
{
|
|
statusCode: HttpStatus.NOT_ACCEPTABLE,
|
|
error: 'Username Already Exist',
|
|
},
|
|
HttpStatus.NOT_FOUND,
|
|
);
|
|
}
|
|
|
|
const salt = randomStringGenerator();
|
|
|
|
const userData = new User();
|
|
|
|
userData.id = uuid.v4();
|
|
userData.username = createUserDto.username;
|
|
userData.password = await hashPassword(createUserDto.password, salt);
|
|
userData.salt = salt;
|
|
if (createUserDto.superior) {
|
|
userData.superior = superior;
|
|
} else {
|
|
userData.superior = null;
|
|
userData.partner = createUserDto.partner;
|
|
}
|
|
userData.roles = roles;
|
|
|
|
await this.connection.transaction(async (manager) => {
|
|
const result = await manager.insert(User, userData);
|
|
|
|
const userDetailData = new UserDetail();
|
|
userDetailData.name = createUserDto.name;
|
|
userDetailData.phone_number = createUserDto.phone_number;
|
|
userDetailData.user = userData;
|
|
const user_detail = await manager.insert(UserDetail, userDetailData);
|
|
|
|
const dataCoaWallet = new InputCoaDto();
|
|
dataCoaWallet.user = userData;
|
|
dataCoaWallet.balanceType = balanceType.CREDIT;
|
|
dataCoaWallet.type = coaType.WALLET;
|
|
dataCoaWallet.coaEntityManager = manager;
|
|
await this.coaService.create(dataCoaWallet);
|
|
|
|
const dataCoaAR = new InputCoaDto();
|
|
dataCoaAR.user = userData;
|
|
dataCoaAR.balanceType = balanceType.DEBIT;
|
|
dataCoaAR.relatedUserId = superior.id;
|
|
dataCoaAR.type = coaType.ACCOUNT_RECEIVABLE;
|
|
dataCoaAR.coaEntityManager = manager;
|
|
await this.coaService.create(dataCoaAR);
|
|
|
|
if (createUserDto.superior) {
|
|
const dataCoaAP = new InputCoaDto();
|
|
dataCoaAP.user = userData;
|
|
dataCoaAP.balanceType = balanceType.CREDIT;
|
|
dataCoaAP.relatedUserId = superior.id;
|
|
dataCoaAP.type = coaType.ACCOUNT_PAYABLE;
|
|
dataCoaAP.coaEntityManager = manager;
|
|
await this.coaService.create(dataCoaAP);
|
|
}
|
|
});
|
|
|
|
return userData;
|
|
}
|
|
|
|
async findAll(page: number, id: string) {
|
|
const baseQuery = this.usersRepository
|
|
.createQueryBuilder('user')
|
|
.where('user.id != :id', {
|
|
id: id,
|
|
})
|
|
.leftJoinAndSelect('user.roles', 'roles', `roles.id = user.roles_id`)
|
|
.leftJoinAndMapOne(
|
|
'user.user_detail',
|
|
UserDetail,
|
|
'user_detail',
|
|
`user_detail.user = user.id`,
|
|
)
|
|
.leftJoinAndMapOne(
|
|
'user.coa',
|
|
COA,
|
|
'coa',
|
|
`coa.user = user.id and coa.type = '0'`,
|
|
)
|
|
.select([
|
|
'user.id',
|
|
'user.username',
|
|
'user.isActive',
|
|
'user.createdAt',
|
|
'roles.id',
|
|
'roles.name',
|
|
'user_detail',
|
|
'coa.amount',
|
|
]);
|
|
|
|
const data = await baseQuery
|
|
.orderBy('user.createdAt', 'DESC')
|
|
.skip(page * 10)
|
|
.take(10)
|
|
.getMany();
|
|
|
|
const totalData = await baseQuery.getCount();
|
|
|
|
return {
|
|
data,
|
|
count: totalData,
|
|
};
|
|
}
|
|
|
|
findByRoles(relationId: string, page: number, pageSize?: number) {
|
|
return this.usersRepository.findAndCount({
|
|
skip: page * (pageSize || 10),
|
|
take: pageSize || 10,
|
|
where: {
|
|
roles: relationId,
|
|
},
|
|
order: {
|
|
updatedAt: 'DESC',
|
|
},
|
|
});
|
|
}
|
|
|
|
async findBySuperrior(superriorId: string, page: number) {
|
|
const baseQuery = this.usersRepository
|
|
.createQueryBuilder('user')
|
|
.where('user.id != :id and user.superior_id = :superior', {
|
|
id: superriorId,
|
|
superior: superriorId,
|
|
})
|
|
.leftJoinAndSelect('user.roles', 'roles', `roles.id = user.roles_id`)
|
|
.leftJoinAndMapOne(
|
|
'user.user_detail',
|
|
UserDetail,
|
|
'user_detail',
|
|
`user_detail.user = user.id`,
|
|
)
|
|
.leftJoinAndMapOne(
|
|
'user.coa',
|
|
COA,
|
|
'coa',
|
|
`coa.user = user.id and coa.type = '0'`,
|
|
)
|
|
.select([
|
|
'user.id',
|
|
'user.username',
|
|
'user.isActive',
|
|
'roles.id',
|
|
'roles.name',
|
|
'user_detail',
|
|
'coa.amount',
|
|
]);
|
|
|
|
const data = await baseQuery
|
|
.skip(page * 10)
|
|
.take(10)
|
|
.getMany();
|
|
|
|
const totalData = await baseQuery.getCount();
|
|
|
|
return {
|
|
data,
|
|
count: totalData,
|
|
};
|
|
}
|
|
|
|
async findExist(id: string) {
|
|
try {
|
|
return await this.usersRepository.findOneOrFail(id);
|
|
} catch (e) {
|
|
if (e instanceof EntityNotFoundError) {
|
|
throw new HttpException(
|
|
{
|
|
statusCode: HttpStatus.NOT_FOUND,
|
|
error: 'User not found',
|
|
},
|
|
HttpStatus.NOT_FOUND,
|
|
);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
async findByUsername(username: string) {
|
|
try {
|
|
return await this.usersRepository.findOneOrFail({
|
|
where: {
|
|
username: username,
|
|
},
|
|
relations: ['superior', 'roles', 'partner'],
|
|
});
|
|
} catch (e) {
|
|
if (e instanceof EntityNotFoundError) {
|
|
throw new HttpException(
|
|
{
|
|
statusCode: HttpStatus.NOT_FOUND,
|
|
error: 'User not found',
|
|
},
|
|
HttpStatus.NOT_FOUND,
|
|
);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
async findOne(id: string) {
|
|
const coa = await this.coaService.findByUser(id, coaType.WALLET);
|
|
|
|
try {
|
|
const userData = await this.usersRepository
|
|
.createQueryBuilder('users')
|
|
.leftJoinAndSelect('users.roles', 'roles')
|
|
.leftJoinAndSelect('users.superior', 'superior')
|
|
.leftJoinAndSelect('users.userDetail', 'userDetail')
|
|
.where('users.id = :id', {
|
|
id: id,
|
|
})
|
|
.select([
|
|
'users.id',
|
|
'users.username',
|
|
'users.isActive',
|
|
'users.createdAt',
|
|
'roles.id',
|
|
'roles.name',
|
|
'superior.id',
|
|
'superior.username',
|
|
'userDetail.id',
|
|
'userDetail.name',
|
|
'userDetail.phone_number',
|
|
])
|
|
.getOne();
|
|
|
|
return {
|
|
...userData,
|
|
wallet: coa.amount,
|
|
};
|
|
} catch (e) {
|
|
if (e instanceof EntityNotFoundError) {
|
|
throw new HttpException(
|
|
{
|
|
statusCode: HttpStatus.NOT_FOUND,
|
|
error: 'User not found',
|
|
},
|
|
HttpStatus.NOT_FOUND,
|
|
);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
async update(id: string, updateUserDto: UpdateUserDto, currentUser: any) {
|
|
let userData;
|
|
let userDetailData;
|
|
|
|
try {
|
|
userData = await this.usersRepository.findOneOrFail(id);
|
|
userDetailData = await this.userDetailRepository.findOneOrFail({
|
|
where: {
|
|
user: userData,
|
|
},
|
|
});
|
|
} catch (e) {
|
|
if (e instanceof EntityNotFoundError) {
|
|
throw new HttpException(
|
|
{
|
|
statusCode: HttpStatus.NOT_FOUND,
|
|
error: 'User not found',
|
|
},
|
|
HttpStatus.NOT_FOUND,
|
|
);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
const check = await this.usersRepository.findOne({
|
|
username: updateUserDto.username,
|
|
id: Not(id),
|
|
});
|
|
|
|
if (check) {
|
|
throw new HttpException(
|
|
{
|
|
statusCode: HttpStatus.NOT_ACCEPTABLE,
|
|
error: 'Username Already Exist',
|
|
},
|
|
HttpStatus.NOT_FOUND,
|
|
);
|
|
}
|
|
|
|
userData.username = updateUserDto.username;
|
|
userData.partner = updateUserDto.partner;
|
|
userDetailData.name = updateUserDto.name;
|
|
userDetailData.phone_number = updateUserDto.phone_number;
|
|
|
|
await this.connection.transaction(async (manager) => {
|
|
await manager.save(userData);
|
|
await manager.save(userDetailData);
|
|
});
|
|
|
|
return userData;
|
|
}
|
|
|
|
async updatePassword(
|
|
id: string,
|
|
updateUserDto: UpdateUserDto,
|
|
currentUser: any,
|
|
) {
|
|
try {
|
|
const dataUser = await this.usersRepository.findOneOrFail(id);
|
|
dataUser.password = await hashPassword(
|
|
updateUserDto.password,
|
|
dataUser.salt,
|
|
);
|
|
const result = await this.usersRepository.save(dataUser);
|
|
return dataUser;
|
|
} catch (e) {
|
|
if (e instanceof EntityNotFoundError) {
|
|
throw new HttpException(
|
|
{
|
|
statusCode: HttpStatus.NOT_FOUND,
|
|
error: 'User not found',
|
|
},
|
|
HttpStatus.NOT_FOUND,
|
|
);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
setStatus = async (id: string, type: string) => {
|
|
const userData = new User();
|
|
|
|
if (type === 'active') {
|
|
userData.isActive = true;
|
|
} else {
|
|
userData.isActive = false;
|
|
}
|
|
|
|
await this.connection.transaction(async (manager) => {
|
|
await manager.update(User, { id: id }, userData);
|
|
});
|
|
|
|
return userData;
|
|
};
|
|
|
|
async remove(id: string) {
|
|
try {
|
|
await this.usersRepository.findOneOrFail(id);
|
|
} catch (e) {
|
|
if (e instanceof EntityNotFoundError) {
|
|
throw new HttpException(
|
|
{
|
|
statusCode: HttpStatus.NOT_FOUND,
|
|
error: 'User not found',
|
|
},
|
|
HttpStatus.NOT_FOUND,
|
|
);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
await this.usersRepository.delete(id);
|
|
}
|
|
|
|
async findOneByUsername(username: string) {
|
|
return this.usersRepository.findOneOrFail({
|
|
where: {
|
|
username,
|
|
isActive: true,
|
|
},
|
|
relations: ['roles', 'partner'],
|
|
});
|
|
}
|
|
|
|
async findOneByPartner(partnerId: string) {
|
|
try {
|
|
return this.usersRepository.findOneOrFail({
|
|
relations: ['roles'],
|
|
where: {
|
|
partner: partnerId,
|
|
},
|
|
});
|
|
} catch (e) {
|
|
if (e instanceof EntityNotFoundError) {
|
|
throw new HttpException(
|
|
{
|
|
statusCode: HttpStatus.NOT_FOUND,
|
|
error: 'User not found',
|
|
},
|
|
HttpStatus.NOT_FOUND,
|
|
);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
}
|