ppob-backend/src/users/users.service.ts
2021-12-14 15:18:25 +07:00

316 lines
7.6 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,
Equal,
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';
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
@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 dataCoaWallet = new InputCoaDto();
dataCoaWallet.user = userData;
dataCoaWallet.balanceType = balanceType.CREDIT;
dataCoaWallet.type = coaType.WALLET;
dataCoaWallet.coaEntityManager = manager;
await this.coaService.create(dataCoaWallet);
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);
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);
}
});
return userData;
}
findAll(page: number, id: string) {
return this.usersRepository.findAndCount({
skip: page * 10,
take: 10,
order: {
version: 'DESC',
},
where: {
id: Not(Equal(id)),
},
});
}
findByRoles(relationId: string, page: number) {
return this.usersRepository.findAndCount({
skip: page * 10,
take: 10,
where: {
roles: relationId,
},
order: {
updatedAt: 'DESC',
},
});
}
findBySuperrior(superriorId: string, page: number) {
return this.usersRepository.findAndCount({
skip: page * 10,
take: 10,
relations: ['roles'],
where: {
superior: superriorId,
},
order: {
updatedAt: 'DESC',
},
});
}
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: 'Data not found',
},
HttpStatus.NOT_FOUND,
);
} else {
throw e;
}
}
}
async findByUsername(username: string) {
try {
return await this.usersRepository.findOneOrFail({
where: {
username: username,
},
relations: ['roles'],
});
} catch (e) {
if (e instanceof EntityNotFoundError) {
throw new HttpException(
{
statusCode: HttpStatus.NOT_FOUND,
error: 'Data 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.findOneOrFail({
where: {
id: id,
},
relations: ['roles', 'superior'],
});
return {
...userData,
wallet: coa.amount,
};
} catch (e) {
if (e instanceof EntityNotFoundError) {
throw new HttpException(
{
statusCode: HttpStatus.NOT_FOUND,
error: 'Data not found',
},
HttpStatus.NOT_FOUND,
);
} else {
throw e;
}
}
}
async update(id: string, updateUserDto: UpdateUserDto, currentUser: any) {
try {
await this.usersRepository.findOneOrFail(id);
} catch (e) {
if (e instanceof EntityNotFoundError) {
throw new HttpException(
{
statusCode: HttpStatus.NOT_FOUND,
error: 'Data 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,
);
}
const userData = new User();
userData.id = id;
userData.username = updateUserDto.username;
userData.partner = updateUserDto.partner;
await this.connection.transaction(async (manager) => {
const result = 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: 'Data not found',
},
HttpStatus.NOT_FOUND,
);
} else {
throw e;
}
}
await this.usersRepository.delete(id);
}
async findOneByUsername(username: string) {
return this.usersRepository.findOneOrFail({
where: {
username,
},
relations: ['roles'],
});
}
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: 'Data not found',
},
HttpStatus.NOT_FOUND,
);
} else {
throw e;
}
}
}
}