Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(homol) fix: faster save, find favorecido, find detalheA #419

Merged
merged 20 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/auth-licensee/auth-licensee.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ import { AuthLicenseeLoginDto } from './dto/auth-licensee-login.dto';
import { AuthRegisterLicenseeDto } from './dto/auth-register-licensee.dto';
import { IALConcludeRegistration } from './interfaces/al-conclude-registration.interface';
import { IALInviteProfile } from './interfaces/al-invite-profile.interface';
import { CustomLogger } from 'src/utils/custom-logger';

@Injectable()
export class AuthLicenseeService {
private logger: Logger = new Logger('AuthLicenseeService', {
private logger = new CustomLogger('AuthLicenseeService', {
timestamp: true,
});

Expand Down
3 changes: 2 additions & 1 deletion src/auth/auth.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ import { AuthRegisterLoginDto } from './dto/auth-register-login.dto';
import { AuthResendEmailDto } from './dto/auth-resend-mail.dto';
import { AuthResetPasswordDto } from './dto/auth-reset-password.dto';
import { AuthUpdateDto } from './dto/auth-update.dto';
import { CustomLogger } from 'src/utils/custom-logger';

@ApiTags('Auth')
@Controller({
path: 'auth',
version: '1',
})
export class AuthController {
private logger: Logger = new Logger('AuthController', { timestamp: true });
private logger = new CustomLogger('AuthController', { timestamp: true });

constructor(
private readonly authService: AuthService,
Expand Down
3 changes: 2 additions & 1 deletion src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ import { AuthEmailLoginDto } from './dto/auth-email-login.dto';
import { AuthRegisterLoginDto } from './dto/auth-register-login.dto';
import { AuthResendEmailDto } from './dto/auth-resend-mail.dto';
import { AuthUpdateDto } from './dto/auth-update.dto';
import { CustomLogger } from 'src/utils/custom-logger';

@Injectable()
export class AuthService {
private logger: Logger = new Logger('AuthService', { timestamp: true });
private logger = new CustomLogger('AuthService', { timestamp: true });

constructor(
private jwtService: JwtService,
Expand Down
4 changes: 1 addition & 3 deletions src/bigquery/bigquery.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ export enum BigquerySource {
@Injectable()
export class BigqueryService {
private bigQueryInstances: Record<string, BigQuery> = {};
private logger: Logger = new CustomLogger(BigqueryService.name, {
timestamp: true,
});
private logger = new CustomLogger(BigqueryService.name, { timestamp: true });

constructor(private configService: ConfigService<AllConfigType>) {
const jsonCredentials = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import { bigToNumber } from 'src/utils/pipe-utils';
import { BigquerySource, BigqueryService } from '../bigquery.service';
import { BigqueryOrdemPagamento } from '../entities/ordem-pagamento.bigquery-entity';
import { IBigqueryFindOrdemPagamento } from '../interfaces/bigquery-find-ordem-pagamento.interface';
import { CustomLogger } from 'src/utils/custom-logger';

@Injectable()
export class BigqueryOrdemPagamentoRepository {
private logger: Logger = new Logger('BigqueryOrdemPagamentoRepository', {
timestamp: true,
});
private logger = new CustomLogger('BigqueryOrdemPagamentoRepository', { timestamp: true });

constructor(
private readonly bigqueryService: BigqueryService,
Expand Down
3 changes: 2 additions & 1 deletion src/bigquery/repositories/bigquery-transacao.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ import { BqTsansacaoTipoIntegracaoMap } from '../maps/bq-transacao-tipo-integrac
import { BqTransacaoTipoPagamentoMap } from '../maps/bq-transacao-tipo-pagamento.map';
import { BqTransacaoTipoTransacaoMap } from '../maps/bq-transacao-tipo-transacao.map';
import { logWarn } from 'src/utils/log-utils';
import { CustomLogger } from 'src/utils/custom-logger';

@Injectable()
export class BigqueryTransacaoRepository {
private logger: Logger = new Logger('BigqueryTransacaoRepository', {
private logger = new CustomLogger('BigqueryTransacaoRepository', {
timestamp: true,
});

Expand Down
15 changes: 4 additions & 11 deletions src/bigquery/services/bigquery-ordem-pagamento.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,18 @@ import { Injectable, Logger } from '@nestjs/common';
import { isFriday, nextFriday, subDays } from 'date-fns';
import { BigqueryOrdemPagamentoDTO } from '../dtos/bigquery-ordem-pagamento.dto';
import { BigqueryOrdemPagamentoRepository } from '../repositories/bigquery-ordem-pagamento.repository';
import { CustomLogger } from 'src/utils/custom-logger';

@Injectable()
export class BigqueryOrdemPagamentoService {
private logger: Logger = new Logger('BigqueryOrdemPagamentoService', {
timestamp: true,
});
private logger = new CustomLogger('BigqueryOrdemPagamentoService', { timestamp: true });

constructor(
private readonly bigqueryOrdemPagamentoRepository: BigqueryOrdemPagamentoRepository,
) {}
constructor(private readonly bigqueryOrdemPagamentoRepository: BigqueryOrdemPagamentoRepository) {}

/**
* Get data from current payment week (qui-qua). Also with older days.
*/
public async getFromWeek(
dataOrdemInicial: Date,
dataOrdemFinal: Date,
daysBefore = 0,
): Promise<BigqueryOrdemPagamentoDTO[]> {
public async getFromWeek(dataOrdemInicial: Date, dataOrdemFinal: Date, daysBefore = 0): Promise<BigqueryOrdemPagamentoDTO[]> {
const today = new Date();
let startDate: Date;
let endDate: Date;
Expand Down
30 changes: 10 additions & 20 deletions src/bigquery/services/bigquery-transacao.service.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
import { Injectable, Logger } from '@nestjs/common';
import { isFriday, nextFriday, subDays } from 'date-fns';
import { Injectable } from '@nestjs/common';
import { CustomLogger } from 'src/utils/custom-logger';
import { BigqueryTransacao } from '../entities/transacao.bigquery-entity';
import { BigqueryTransacaoRepository } from '../repositories/bigquery-transacao.repository';

@Injectable()
export class BigqueryTransacaoService {
private logger: Logger = new Logger('BigqueryOrdemPagamentoService', {
timestamp: true,
});
private logger = new CustomLogger('BigqueryOrdemPagamentoService', { timestamp: true });

constructor(
private readonly bigqueryTransacaoRepository: BigqueryTransacaoRepository,
) {}
constructor(private readonly bigqueryTransacaoRepository: BigqueryTransacaoRepository) {}

/**
* Obter dados da semana de pagamento (qui-qua).
*
* @param [daysBack=0] Pega a semana atual ou N dias atrás.
*/
public async getFromWeek(dataOrdemInicial: Date,dataOrdemFinal: Date,daysBack = 0): Promise<BigqueryTransacao[]> {
public async getFromWeek(dataOrdemInicial: Date, dataOrdemFinal: Date, daysBack = 0): Promise<BigqueryTransacao[]> {
const transacao = (
await this.bigqueryTransacaoRepository.findMany({
startDate: dataOrdemInicial,
Expand All @@ -33,23 +29,17 @@ export class BigqueryTransacaoService {
*/
public async getAll(): Promise<BigqueryTransacao[]> {
// Read
const ordemPgto = (await this.bigqueryTransacaoRepository.findMany()).map(
(i) => ({ ...i } as BigqueryTransacao),
);
const ordemPgto = (await this.bigqueryTransacaoRepository.findMany()).map((i) => ({ ...i } as BigqueryTransacao));
return ordemPgto;
}

/**
* A cada 10 dias, de hoje até a dataInicio, pesquisa e chama o callback
*/
public async getAllPaginated(
callback: (transacoes: BigqueryTransacao[]) => void,
cpfCnpjs: string[] = [],
) {
const transacoes: BigqueryTransacao[] =
await this.bigqueryTransacaoRepository.findMany({
manyCpfCnpj: cpfCnpjs,
});
public async getAllPaginated(callback: (transacoes: BigqueryTransacao[]) => void, cpfCnpjs: string[] = []) {
const transacoes: BigqueryTransacao[] = await this.bigqueryTransacaoRepository.findMany({
manyCpfCnpj: cpfCnpjs,
});
callback(transacoes);
}
}
8 changes: 5 additions & 3 deletions src/cnab/cnab.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,18 @@ export class CnabController {
};
}

@ApiQuery({ name: 'folder', description: ApiDescription({ _: 'Pasta para ler os retornos', default: '/retorno' }), required: false, type: String })
@ApiQuery({ name: 'folder', description: ApiDescription({ _: 'Pasta para ler os retornos', default: '`/retorno`' }), required: false, type: String })
@ApiQuery({ name: 'maxItems', description: ApiDescription({ _: 'Número máximo de itens para ler', min: 1 }), required: false, type: Number })
@HttpCode(HttpStatus.OK)
@ApiBearerAuth()
@UseGuards(AuthGuard('jwt'), RolesGuard)
@Roles(RoleEnum.admin)
@Get('updateRetorno')
async getUpdateRetorno(
@Query('folder', new ParseDatePipe()) folder: string | undefined, //
@Query('folder') folder: string | undefined, //
@Query('maxItems', new ParseNumberPipe({ min: 1, optional: true})) maxItems: number | undefined,
) {
return await this.cnabService.updateRetorno(folder);
return await this.cnabService.updateRetorno(folder, maxItems);
}

@ApiQuery({ name: 'dataOrdemInicial', description: 'Data da Ordem de Pagamento Inicial', required: true, type: Date })
Expand Down
52 changes: 38 additions & 14 deletions src/cnab/cnab.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,15 @@ import { RemessaRetornoService } from './service/pagamento/remessa-retorno.servi
import { TransacaoAgrupadoService } from './service/pagamento/transacao-agrupado.service';
import { TransacaoService } from './service/pagamento/transacao.service';
import { parseCnab240Extrato, parseCnab240Pagamento, stringifyCnab104File } from './utils/cnab/cnab-104-utils';
import { CommonHttpException } from 'src/utils/http-exception/common-http-exception';
import { formatErrMsg } from 'src/utils/log-utils';

/**
* User cases for CNAB and Payments
*/
@Injectable()
export class CnabService {
private logger: CustomLogger = new CustomLogger(CnabService.name, { timestamp: true });
private logger = new CustomLogger(CnabService.name, { timestamp: true });

constructor(
private arquivoPublicacaoService: ArquivoPublicacaoService, //
Expand Down Expand Up @@ -88,7 +90,7 @@ export class CnabService {

/**
* Obtém dados de OrdemPagamento e salva em ItemTransacao e afins, para gerar remessa.
*
*
* As datas de uma semana de pagamento são de sex-qui (D+1)
*
* Requirement: **Salvar novas transações Jaé** - {@link https://github.com/RJ-SMTR/api-cct/issues/207#issuecomment-1984421700 #207, items 3}
Expand Down Expand Up @@ -274,7 +276,9 @@ export class CnabService {
const startDate = new Date();
let count = 0;
try {
await queryRunner.startTransaction();
[, count] = await queryRunner.query(query);
await queryRunner.commitTransaction();
} catch (error) {
await queryRunner.rollbackTransaction();
} finally {
Expand Down Expand Up @@ -319,7 +323,7 @@ export class CnabService {
dataPagamento: ordem.dataPagamento,
pagador: pagador,
idOrdemPagamento: ordem.idOrdemPagamento,
status: new TransacaoStatus(TransacaoStatusEnum.created),
status: TransacaoStatus.fromEnum(TransacaoStatusEnum.created),
});
return transacao;
}
Expand Down Expand Up @@ -497,7 +501,7 @@ export class CnabService {
await this.remessaRetornoService.updateHeaderArquivoDTOFrom104(headerArquivoDTO, cnabHeaderArquivo);
await this.transacaoAgService.save({
id: transacaoAgId,
status: new TransacaoStatus(TransacaoStatusEnum.remessa),
status: TransacaoStatus.fromEnum(TransacaoStatusEnum.remessa),
});
}

Expand All @@ -524,32 +528,52 @@ export class CnabService {
* @param folder Example: `/retorno`
* @returns
*/
public async updateRetorno(folder?: string) {
public async updateRetorno(folder?: string, maxItems?: number) {
const METHOD = this.updateRetorno.name;
let { cnabString, cnabName } = await this.sftpService.getFirstCnabRetorno(folder);
const INVALID_FOLDERS = ['/backup/retorno/success', '/backup/retorno/failed'];
if (folder && INVALID_FOLDERS.includes(folder)) {
throw CommonHttpException.message(`Não é possível ler retornos das pastas ${INVALID_FOLDERS}`);
}
let { cnabName, cnabString } = await this.sftpService.getFirstCnabRetorno(folder);
const cnabs: string[] = [];
const success: any[] = [];
const failed: any[] = [];
const startDate = new Date();
while (cnabString) {
if (!cnabName || !cnabString) {
this.logger.log('Retorno não encontrado, abortando tarefa.', METHOD);
return;
}

this.logger.log('Leitura de retornos iniciada...', METHOD);
const startDateItem = new Date();
try {
const retorno104 = parseCnab240Pagamento(cnabString);
cnabs.push(cnabName);
await this.remessaRetornoService.saveRetorno(retorno104);
await this.sftpService.moveToBackup(cnabName, SftpBackupFolder.RetornoSuccess, cnabString);
const cnab = await this.sftpService.getFirstCnabRetorno(folder);
cnabString = cnab.cnabString;
cnabName = cnab.cnabName;
await this.sftpService.moveToBackup(cnabName, SftpBackupFolder.RetornoSuccess, cnabString, folder);
const durationItem = formatDateInterval(new Date(), startDateItem);
this.logger.log(`CNAB '${cnabName}' lido com sucesso - ${durationItem}`);
success.push(cnabName);
} catch (error) {
this.logger.error(`Erro ao processar CNAB retorno, movendo para backup de erros e finalizando... - ${error}`, error.stack, METHOD);
const durationItem = formatDateInterval(new Date(), startDateItem);
this.logger.error(`Erro ao processar CNAB ${cnabName}. Movendo para backup de erros e finalizando - ${durationItem} - ${formatErrMsg(error)}`, error.stack, METHOD);
if (!cnabName || !cnabString) {
this.logger.log('Retorno não encontrado, abortando tarefa.', METHOD);
return;
}
await this.sftpService.moveToBackup(cnabName, SftpBackupFolder.RetornoFailure, cnabString);
await this.sftpService.moveToBackup(cnabName, SftpBackupFolder.RetornoFailure, cnabString, folder);
failed.push(cnabName);
}
const cnab = await this.sftpService.getFirstCnabRetorno(folder);
cnabString = cnab.cnabString;
cnabName = cnab.cnabName;
}
return;
const duration = formatDateInterval(new Date(), startDate);
if (maxItems && cnabs.length >= maxItems) {
this.logger.log(`Leitura de retornos finalizou a leitura de ${cnabs.length}/${maxItems} CNABs - ${duration}`, METHOD);
}
this.logger.log(`Leitura de retornos finalizada com sucesso - ${duration}`, METHOD);
return { duration, cnabs: cnabs.length, success, failed };
}

/**
Expand Down
52 changes: 11 additions & 41 deletions src/cnab/entity/arquivo-publicacao.entity.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,6 @@
import { EntityHelper } from 'src/utils/entity-helper';
import {
asNullableStringOrNumber
} from 'src/utils/pipe-utils';
import {
AfterLoad,
Column,
CreateDateColumn,
DeepPartial,
Entity,
JoinColumn,
OneToOne,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
import { asNullableStringOrNumber } from 'src/utils/pipe-utils';
import { AfterLoad, Column, CreateDateColumn, DeepPartial, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm';
import { ItemTransacao } from './pagamento/item-transacao.entity';
import { isSameDay } from 'date-fns';

Expand All @@ -25,6 +13,9 @@ export class ArquivoPublicacao extends EntityHelper {
super();
if (arquivoPublicacao !== undefined) {
Object.assign(this, arquivoPublicacao);
if (arquivoPublicacao.itemTransacao) {
arquivoPublicacao.itemTransacao = new ItemTransacao(arquivoPublicacao.itemTransacao);
}
}
}
@PrimaryGeneratedColumn({
Expand Down Expand Up @@ -83,38 +74,17 @@ export class ArquivoPublicacao extends EntityHelper {
return !this.isPago && this.dataEfetivacao;
}

public static filterUnique(
publicacoes: ArquivoPublicacao[],
compare: ArquivoPublicacao,
) {
return publicacoes.filter(
(p) =>
p.itemTransacao.idConsorcio === compare.itemTransacao.idConsorcio &&
p.itemTransacao.idOperadora === compare.itemTransacao.idOperadora &&
isSameDay(p.itemTransacao.dataOrdem, compare.itemTransacao.dataOrdem),
);
public static filterUnique(publicacoes: ArquivoPublicacao[], compare: ArquivoPublicacao) {
return publicacoes.filter((p) => p.itemTransacao.idConsorcio === compare.itemTransacao.idConsorcio && p.itemTransacao.idOperadora === compare.itemTransacao.idOperadora && isSameDay(p.itemTransacao.dataOrdem, compare.itemTransacao.dataOrdem));
}

public static getUniqueUpdatePublicacoes(publicacoes: ArquivoPublicacao[]) {
const unique: ArquivoPublicacao[] = [];
publicacoes.forEach((publicacao) => {
const existing = ArquivoPublicacao.filterUnique(unique, publicacao)[0] as
| ArquivoPublicacao
| undefined;
const ocourences = ArquivoPublicacao.filterUnique(
publicacoes,
publicacao,
).sort(
(a, b) =>
b.itemTransacao.dataOrdem.getTime() -
a.itemTransacao.dataOrdem.getTime(),
);
const paid = ocourences.filter((i) => i.isPago)[0] as
| ArquivoPublicacao
| undefined;
const noErrors = ocourences.filter((i) => !i.getIsError())[0] as
| ArquivoPublicacao
| undefined;
const existing = ArquivoPublicacao.filterUnique(unique, publicacao)[0] as ArquivoPublicacao | undefined;
const ocourences = ArquivoPublicacao.filterUnique(publicacoes, publicacao).sort((a, b) => b.itemTransacao.dataOrdem.getTime() - a.itemTransacao.dataOrdem.getTime());
const paid = ocourences.filter((i) => i.isPago)[0] as ArquivoPublicacao | undefined;
const noErrors = ocourences.filter((i) => !i.getIsError())[0] as ArquivoPublicacao | undefined;
const recent = ocourences[0] as ArquivoPublicacao;
if (!existing) {
const newPublicacao = paid || noErrors || recent;
Expand Down
Loading
Loading