chore: add create customer and update customer for admin

This commit is contained in:
mahyargdz
2025-03-06 09:35:59 +03:30
parent c1f21e75f2
commit b92a65c22c
20 changed files with 674 additions and 399 deletions
@@ -0,0 +1,314 @@
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
import { DataSource, Not } from "typeorm";
import { CommonMessage, UserMessage } from "../../../common/enums/message.enum";
import { AddressService } from "../../address/providers/address.service";
import { UserSettingsService } from "../../settings/providers/user-settings.service";
import { PasswordService } from "../../utils/providers/password.service";
import { WalletsService } from "../../wallets/providers/wallets.service";
import { CreateCustomerDto } from "../DTO/create-customer.dto";
import { CreateLegalUserDto } from "../DTO/create-legal-user.dto";
import { CreateRealUserDto } from "../DTO/create-real-user.dto";
import { SearchCustomersDto } from "../DTO/search-customers.dto";
import { UpdateCustomerDto } from "../DTO/update-customer.dto";
import { FinancialType } from "../enums/financial-type.enum";
import { RoleEnum } from "../enums/role.enum";
import { LegalUserRepository } from "../repositories/legal-user.repository";
import { RealUserRepository } from "../repositories/real-user.repository";
import { RoleRepository } from "../repositories/roles.repository";
import { UserRepository } from "../repositories/users.repository";
@Injectable()
export class CustomersService {
private readonly logger = new Logger(CustomersService.name);
constructor(
private readonly addressService: AddressService,
private readonly dataSource: DataSource,
private readonly userRepository: UserRepository,
private readonly legalUserRepository: LegalUserRepository,
private readonly realUserRepository: RealUserRepository,
private readonly passwordService: PasswordService,
private readonly userSettingsService: UserSettingsService,
private readonly rolesRepository: RoleRepository,
private readonly walletsService: WalletsService,
) {}
async createCustomer(createDto: CreateCustomerDto) {
const queryRunner = this.dataSource.createQueryRunner();
try {
await queryRunner.connect();
await queryRunner.startTransaction();
const [existingEmail, existingNationalCode, existingPhone, userRole] = await Promise.all([
queryRunner.manager.findOne(this.userRepository.target, { where: { email: createDto.email } }),
queryRunner.manager.findOne(this.userRepository.target, { where: { nationalCode: createDto.nationalCode } }),
queryRunner.manager.findOne(this.userRepository.target, { where: { phone: createDto.phone } }),
queryRunner.manager.findOne(this.rolesRepository.target, { where: { name: RoleEnum.USER } }),
]);
if (existingEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
if (existingNationalCode) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
if (existingPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
if (!userRole) throw new BadRequestException(UserMessage.ROLE_NOT_FOUND);
const user = queryRunner.manager.create(this.userRepository.target, {
...createDto,
password: await this.passwordService.hashPassword(createDto.password),
roles: [userRole],
});
await queryRunner.manager.save(user);
await Promise.all([
this.userSettingsService.createUserSettings(user.id, queryRunner),
this.walletsService.createUserWallet(user.id, queryRunner),
]);
await this.createLegalUserData(createDto, user.id, queryRunner);
await queryRunner.commitTransaction();
return { message: CommonMessage.CREATED, user };
} catch (error) {
await queryRunner.rollbackTransaction();
this.logger.error("Error in create customer", error);
throw error;
} finally {
await queryRunner.release();
}
}
//************************************************ */
async updateCustomer(customerId: string, updateDto: UpdateCustomerDto) {
const queryRunner = this.dataSource.createQueryRunner();
try {
await queryRunner.connect();
await queryRunner.startTransaction();
const user = await queryRunner.manager.findOne(this.userRepository.target, { where: { id: customerId } });
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
if (updateDto.email) {
const existingEmail = await queryRunner.manager.findOne(this.userRepository.target, {
where: { email: updateDto.email, id: Not(user.id) },
});
if (existingEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST);
}
if (updateDto.nationalCode) {
const existingNationalCode = await queryRunner.manager.findOne(this.userRepository.target, {
where: { nationalCode: updateDto.nationalCode, id: Not(user.id) },
});
if (existingNationalCode) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
}
if (updateDto.phone) {
const existingPhone = await queryRunner.manager.findOne(this.userRepository.target, {
where: { phone: updateDto.phone, id: Not(user.id) },
});
if (existingPhone) throw new BadRequestException(UserMessage.PHONE_EXIST);
}
await queryRunner.manager.update(this.userRepository.target, { id: customerId }, updateDto);
const legalUser = await queryRunner.manager.findOne(this.legalUserRepository.target, { where: { user: { id: customerId } } });
if (!legalUser) throw new BadRequestException(UserMessage.LEGAL_DATA_NOT_FOUND);
if (updateDto.economicCode) {
const existingEconomicCode = await queryRunner.manager.findOne(this.legalUserRepository.target, {
where: { economicCode: updateDto.economicCode, id: Not(legalUser.id) },
});
if (existingEconomicCode) throw new BadRequestException(UserMessage.ECONOMIC_CODE_EXIST);
}
if (updateDto.registrationCode) {
const existingRegistrationCode = await queryRunner.manager.findOne(this.legalUserRepository.target, {
where: { registrationCode: updateDto.registrationCode, id: Not(legalUser.id) },
});
if (existingRegistrationCode) throw new BadRequestException(UserMessage.REGISTRATION_CODE_EXIST);
}
if (updateDto.nationalIdentity) {
const existingNationalIdentity = await queryRunner.manager.findOne(this.legalUserRepository.target, {
where: { nationalIdentity: updateDto.nationalIdentity, id: Not(legalUser.id) },
});
if (existingNationalIdentity) throw new BadRequestException(UserMessage.NATIONAL_IDENTITY_EXIST);
}
if (updateDto.cityId) {
const { city } = await this.addressService.getCity(+updateDto.cityId);
await queryRunner.manager.update(this.legalUserRepository.target, { id: legalUser.id }, { address: { city } });
}
const { address, ...legalUserUpdateData } = updateDto;
await queryRunner.manager.update(this.legalUserRepository.target, { id: legalUser.id }, legalUserUpdateData);
if (address) {
await queryRunner.manager.update(this.legalUserRepository.target, { id: legalUser.id }, { address: { fullAddress: address } });
}
await queryRunner.commitTransaction();
return {
message: CommonMessage.UPDATE_SUCCESS,
};
} catch (error) {
await queryRunner.rollbackTransaction();
this.logger.error("Error in update customer", error);
throw error;
} finally {
await queryRunner.release();
}
}
/************************************************************ */
async getCustomersCount() {
const count = await this.userRepository.count({ where: { roles: { name: RoleEnum.USER } } });
return count;
}
/************************************************************ */
async createRealUserData(createDto: CreateRealUserDto, userId: string, queryRunner = this.dataSource.createQueryRunner()) {
let transactionStarted = false;
try {
if (!queryRunner.isTransactionActive) {
await queryRunner.connect();
await queryRunner.startTransaction();
transactionStarted = true;
}
const user = await queryRunner.manager.findOne(this.userRepository.target, { where: { id: userId } });
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
if (user.financialType && user.financialType === FinancialType.LEGAL)
throw new BadRequestException(UserMessage.FINANCIAL_TYPE_IS_LEGAL);
const existingRealUser = await queryRunner.manager.findOne(this.realUserRepository.target, { where: { user: { id: userId } } });
if (existingRealUser) throw new BadRequestException(UserMessage.REAL_DATA_EXIST);
const duplicateChecks = await Promise.all([
queryRunner.manager.findOne(this.realUserRepository.target, { where: { nationalCode: createDto.nationalCode } }),
queryRunner.manager.findOne(this.realUserRepository.target, { where: { phone: createDto.phone } }),
]);
if (duplicateChecks[0]) throw new BadRequestException(UserMessage.NATIONAL_CODE_EXIST);
if (duplicateChecks[1]) throw new BadRequestException(UserMessage.PHONE_EXIST);
const { city } = await this.addressService.getCity(+createDto.cityId);
const realUser = queryRunner.manager.create(this.realUserRepository.target, {
...createDto,
user,
address: {
fullAddress: createDto.address,
city,
postalCode: createDto.postalCode,
},
});
await queryRunner.manager.save(realUser);
user.financialType = FinancialType.REAL;
await queryRunner.manager.save(user);
if (transactionStarted) await queryRunner.commitTransaction();
return {
message: CommonMessage.CREATED,
realUser,
};
} catch (error) {
if (transactionStarted) await queryRunner.rollbackTransaction();
throw error;
} finally {
if (transactionStarted) await queryRunner.release();
}
}
// /************************************************************ */
async createLegalUserData(createDto: CreateLegalUserDto, userId: string, queryRunner = this.dataSource.createQueryRunner()) {
let transactionStarted = false;
try {
if (!queryRunner.isTransactionActive) {
await queryRunner.connect();
await queryRunner.startTransaction();
transactionStarted = true;
}
const user = await queryRunner.manager.findOne(this.userRepository.target, { where: { id: userId } });
if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND);
if (user.financialType && user.financialType === FinancialType.REAL)
throw new BadRequestException(UserMessage.FINANCIAL_TYPE_IS_REAL);
const existingLegalUser = await queryRunner.manager.findOne(this.legalUserRepository.target, { where: { user: { id: user.id } } });
if (existingLegalUser) throw new BadRequestException(UserMessage.LEGAL_DATA_EXIST);
const duplicateChecks = await Promise.all([
queryRunner.manager.findOne(this.legalUserRepository.target, { where: { economicCode: createDto.economicCode } }),
queryRunner.manager.findOne(this.legalUserRepository.target, { where: { phone: createDto.phone } }),
queryRunner.manager.findOne(this.legalUserRepository.target, { where: { registrationCode: createDto.registrationCode } }),
queryRunner.manager.findOne(this.legalUserRepository.target, { where: { nationalIdentity: createDto.nationalIdentity } }),
]);
if (duplicateChecks[0]) throw new BadRequestException(UserMessage.ECONOMIC_CODE_EXIST);
if (duplicateChecks[1]) throw new BadRequestException(UserMessage.PHONE_EXIST);
if (duplicateChecks[2]) throw new BadRequestException(UserMessage.REGISTRATION_CODE_EXIST);
if (duplicateChecks[3]) throw new BadRequestException(UserMessage.NATIONAL_IDENTITY_EXIST);
const { city } = await this.addressService.getCity(+createDto.cityId);
const legalUser = queryRunner.manager.create(this.legalUserRepository.target, {
...createDto,
user,
address: {
fullAddress: createDto.address,
city,
postalCode: createDto.postalCode,
},
});
await queryRunner.manager.save(legalUser);
user.financialType = FinancialType.LEGAL;
await queryRunner.manager.save(user);
if (transactionStarted) await queryRunner.commitTransaction();
return {
message: CommonMessage.CREATED,
legalUser,
};
} catch (error) {
if (transactionStarted) await queryRunner.rollbackTransaction();
throw error;
} finally {
if (transactionStarted) await queryRunner.release();
}
}
/************************************************************ */
async getCustomers(queryDto: SearchCustomersDto) {
const [customers, count] = await this.userRepository.getCustomer(queryDto);
return { customers, count };
}
/************************************************************ */
async getCustomerById(userId: string) {
const customer = await this.userRepository.findOne({
where: { id: userId, roles: { name: RoleEnum.USER } },
relations: { legalUser: true, realUser: true },
});
return { customer };
}
}