import { HttpException, HttpStatus, Inject, Injectable, Logger, forwardRef } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Between, FindOptionsWhere, ILike, In, LessThanOrEqual, MoreThanOrEqual, Not, Repository } from 'typeorm';
import { SalesForceBody, SalesForceQuery } from '../dto/sales-force.dto';
import { SalesForce } from '../entities/sales-force.entity';
import { OrganizationChartService } from '../organization-chart/organization-chart.services';
import { ClientService } from 'src/client/client.service';
import { SalesForceType } from '../entities/sales-force-type.entity';
import { SalesForceLevelConfig } from '../entities/sales-force-level-config.entity';
import { EdcService } from 'src/provider/edc_api/edc.services';
@Injectable()
export class SalesForceService {
private readonly logger = new Logger(SalesForceService.name);
constructor(
@InjectRepository(SalesForce)
private readonly salesForceRepository: Repository<SalesForce>,
@InjectRepository(SalesForceLevelConfig)
private readonly salesForceLevelConfigRepository: Repository<SalesForceLevelConfig>,
@InjectRepository(SalesForceType)
private readonly salesForceTypeRepository: Repository<SalesForceType>,
private organizationChartService: OrganizationChartService,
private readonly clientService: ClientService,
private readonly edcService: EdcService,
) { }
async createSalesForce(body: SalesForceBody, cdMtrix: number, authorization: string) {
const client = await this.clientService.findClientByMtrixCode({ mtrixCode: cdMtrix, clientType: 'F' });
if (!client) {
throw new HttpException('supplier_id_not_linked_client', HttpStatus.FAILED_DEPENDENCY)
}
const { countSalesForceLevel, client: clientLevel } = await this.clientService.getClientIdSalesForceLevel(client.id);
if (!client) {
throw new HttpException('supplier_id_not_config_in_client', HttpStatus.UNPROCESSABLE_ENTITY);
}
const salesForceType = await this.salesForceTypeRepository.findOneBy({ id: body.salesForceTypeId });
if (!salesForceType) {
throw new HttpException('sales_force_type_id_not_found', HttpStatus.UNPROCESSABLE_ENTITY);
}
if (client.useChannel) {
const distributorChannel = await this.edcService.getCanalDistribuidor(client.mtrixCode, authorization)
if (!body.channelSalesId && distributorChannel.recordset.length) {
throw new HttpException('client_with_channel_configured', HttpStatus.UNPROCESSABLE_ENTITY);
}
} else if (body.channelSalesId) {
throw new HttpException('client_with_channel_not_configured', HttpStatus.UNPROCESSABLE_ENTITY);
}
const existingSalesForce = await this.salesForceRepository.findBy({
published: true,
countLevel: countSalesForceLevel,
cdMtrix,
initDate: LessThanOrEqual(body.initDate), // Check if existing sales force end date is after or equal to the new sales force start date
finalDate: MoreThanOrEqual(body.finalDate), // Check if existing sales force start date is before or equal to the new sales force end date
});
const existChannel = existingSalesForce.find(item => item.channelSalesId === body.channelSalesId);
if (existChannel && body.published) {
throw new HttpException('sales_force_overlap_channel', HttpStatus.UNPROCESSABLE_ENTITY);
}
const existSalesForceType = existingSalesForce.find(item => item.salesForceTypeId === body.salesForceTypeId);
if (existSalesForceType && body.published) {
throw new HttpException('sales_force_overlap_sales_force_type_id', HttpStatus.UNPROCESSABLE_ENTITY);
}
const salesForce = await this.salesForceRepository.save({ ...body, clientId: client.id, cdMtrix, countLevel: countSalesForceLevel })
const salesForceLevelConfigArray = clientLevel.salesForceLevel.map(item => {
// let salesForceLevelConfig = new SalesForceLevelConfig();
item.color = item.color || '#FFFFFF'
return { ...item, salesForceId: salesForce.id } as SalesForceLevelConfig;
})
const salesForceleveConfig = await this.salesForceLevelConfigRepository.save(salesForceLevelConfigArray)
// const client = await this.clientService.findClientByMtrixCode({ mtrixCode: cdMtrix, clientType: 'F' })
const tree = await this.organizationChartService.createOrganizationChartInitSalesForce(salesForce.id, client.id);
return { ...salesForce, tree, salesForceleveConfig }
}
async putSalesForce(body: SalesForceBody, cdMtrix: number, id: number) {
const client = await this.clientService.findClientByMtrixCode({ mtrixCode: cdMtrix, clientType: 'F' })
if (!client) {
throw new HttpException('supplier_id_not_config_in_client', HttpStatus.UNPROCESSABLE_ENTITY)
}
const salesForceType = await this.salesForceTypeRepository.findOneBy({ id: body.salesForceTypeId })
if (!salesForceType) {
throw new HttpException('sales_force_type_id_not_found', HttpStatus.UNPROCESSABLE_ENTITY)
}
const salesForce = await this.salesForceRepository.findOne({
where: {
id,
cdMtrix
}
});
const existingSalesForce = await this.salesForceRepository.findBy({
id: Not(id),
published: true,
cdMtrix,
initDate: LessThanOrEqual(body.initDate), // Check if existing sales force end date is after or equal to the new sales force start date
finalDate: MoreThanOrEqual(body.finalDate), // Check if existing sales force start date is before or equal to the new sales force end date
});
const existChannel = existingSalesForce.find(item => item.channelSalesId === body.channelSalesId);
if (existChannel && body.published) {
throw new HttpException('sales_force_overlap_channel', HttpStatus.UNPROCESSABLE_ENTITY);
}
const existSalesForceType = existingSalesForce.find(item => item.salesForceTypeId === body.salesForceTypeId);
if (existSalesForceType && body.published) {
throw new HttpException('sales_force_overlap_sales_force_type_id', HttpStatus.UNPROCESSABLE_ENTITY);
}
salesForce.published = body.published;
salesForce.channelSalesId = body.channelSalesId;
salesForce.nameSalesForce = body.nameSalesForce;
salesForce.salesForceTypeId = body.salesForceTypeId;
salesForce.initDate = body.initDate;
salesForce.finalDate = body.finalDate;
return await this.salesForceRepository.save(salesForce)
}
async updateSalesForce(salesForce: SalesForce) {
return await this.salesForceRepository.save(salesForce)
}
async getSalesForce(query: SalesForceQuery, cdMtrix: number) {
const take = query.pageRows || 10;
const page = query.pageNumber || 1;
const skip = (page - 1) * take;
let where: FindOptionsWhere<SalesForce> = {
cdMtrix,
nameSalesForce: ILike(`%${query.nameSalesForce || ''}%`),
published: query.published,
channelSalesId: query.channelSalesId,
}
const [recordset, count] = await this.salesForceRepository.findAndCount({ where, skip, take, relations: ['salesForceType', 'salesForceLevelConfig'] });
return { recordset, count }
}
async deleteSalesForce(id: number, cdMtrix: number) {
const client = await this.clientService.findClientByMtrixCode({ mtrixCode: cdMtrix, clientType: 'F' })
if (!client) {
throw new HttpException('supplier_id_not_config_in_client', HttpStatus.UNPROCESSABLE_ENTITY)
}
return await this.salesForceRepository.softDelete({ id, cdMtrix });
}
async getSalesForceId(id: number, cdMtrix: number) {
const client = await this.clientService.findClientByMtrixCode({ mtrixCode: cdMtrix, clientType: 'F' })
if (!client) {
throw new HttpException('supplier_id_not_config_in_client', HttpStatus.UNPROCESSABLE_ENTITY)
}
return await this.salesForceRepository.findOne({
where: { id, cdMtrix },
relations: ['salesForceType', 'salesForceLevelConfig'],
order: {
'salesForceLevelConfig': { id: 'ASC' }
}
});
}
}