Skip to content

Commit

Permalink
feat: updateRetorno
Browse files Browse the repository at this point in the history
  • Loading branch information
yxuo committed Mar 6, 2024
1 parent 434e7e3 commit 4709cb6
Show file tree
Hide file tree
Showing 19 changed files with 279 additions and 108 deletions.
6 changes: 3 additions & 3 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { Status } from 'src/statuses/entities/status.entity';
import { StatusEnum } from 'src/statuses/statuses.enum';
import { UsersService } from 'src/users/users.service';
import { HttpStatusMessage } from 'src/utils/enums/http-error-message.enum';
import { formatLog } from 'src/utils/logging';
import { formatLog } from 'src/utils/log-utils';
import { User } from '../users/entities/user.entity';
import { LoginResponseType } from '../utils/types/auth/login-response.type';
import { Nullable } from '../utils/types/nullable.type';
Expand All @@ -37,7 +37,7 @@ export class AuthService {
private forgotService: ForgotService,
private mailService: MailService,
private mailHistoryService: MailHistoryService,
) {}
) { }

async validateLogin(
loginDto: AuthEmailLoginDto,
Expand Down Expand Up @@ -397,7 +397,7 @@ export class AuthService {
this.logger.log(
formatLog(
'Email redefinir senha enviado com sucesso.' +
`\n - Detalhes: ${JSON.stringify({ mailSentInfo })}`,
`\n - Detalhes: ${JSON.stringify({ mailSentInfo })}`,
'forgotPassword()',
),
);
Expand Down
4 changes: 3 additions & 1 deletion src/cnab/entity/header-arquivo.entity.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { EntityHelper } from 'src/utils/entity-helper';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class HeaderArquivo extends EntityHelper {
Expand Down Expand Up @@ -33,4 +33,6 @@ export class HeaderArquivo extends EntityHelper {
hr_geracao: Date;
@Column({ type: Number, unique: false, nullable: true })
id_transacao: number;
@CreateDateColumn()
createdAt: Date;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export enum HeaderArquivoTipoArquivo {
Remessa = 'remessa',
Retorno = 'retorno',
}
4 changes: 3 additions & 1 deletion src/cnab/repository/header-arquivo.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { EntityCondition } from 'src/utils/types/entity-condition.type';
import { Nullable } from 'src/utils/types/nullable.type';
import { Repository } from 'typeorm';
import { FindOptionsOrder, Repository } from 'typeorm';
import { HeaderArquivo } from '../entity/header-arquivo.entity';
import { HeaderArquivoDTO } from '../dto/header-arquivo.dto';

Expand All @@ -24,9 +24,11 @@ export class HeaderArquivoRepository {

public async findOne(
fields: EntityCondition<HeaderArquivo> | EntityCondition<HeaderArquivo>[],
order?: FindOptionsOrder<HeaderArquivo>
): Promise<Nullable<HeaderArquivo>> {
return await this.HeaderArquivoRepository.findOne({
where: fields,
order: order,
});
}

Expand Down
65 changes: 60 additions & 5 deletions src/cnab/service/cnab.service.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,74 @@
import { Injectable } from '@nestjs/common';
import { Injectable, Logger } from '@nestjs/common';
import { SftpService } from 'src/sftp/sftp.service';
import { formatLog } from 'src/utils/log-utils';
import { ICnab240_104File } from '../interfaces/cnab-240/104/cnab-240-104-file.interface';
import { parseCnab240_104 } from '../utils/cnab-104-utils';
import { HeaderArquivoService } from './header-arquivo.service';
import { TransacaoService } from './transacao.service';

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

constructor(
private readonly headerArquivoService: HeaderArquivoService,
private readonly transacaoService: TransacaoService,
private headerArquivoService: HeaderArquivoService,
private transacaoService: TransacaoService,
private sftpService: SftpService,
) { }

public async updateTransacaoFromJae() {
await this.transacaoService.updateTransacaoFromJae()
}

public async sendNewCNABs() {
await this.headerArquivoService.saveRemessa()
/**
* This task will:
* 1. Read new Transacoes (with no data in CNAB tables yet, like headerArquivo etc)
* 2. Generate CnabFile
* 3. Save CnabFile to CNAB tables in database
* 4. Upload CNAB string to SFTP
*
* @throws `Error` if any subtask throws
*/
public async updateRemessa() {
const listAllTransacao = await this.transacaoService.getAll();
for (const transacao of listAllTransacao) {
if (!this.headerArquivoService.headerArquivoExists(transacao.id_transacao)) {
const { cnabString, cnabTables } = await this.headerArquivoService.generateCnab(transacao);
await this.headerArquivoService.saveRemessa(cnabTables);
await this.sftpService.submitFromString(cnabString, 'arquivo/123-wip-rem.txt');
}
}
}

/**
* This task will:
* 1. Get retorno from SFTP
* 2. Save retorno to CNAB tables
* 3. If successfull, move retorno to backup folder
*
* @throws `Error` if any subtask throws
*/
public async updateRetorno() {
const METHOD = 'updateRetorno()';
// Get retorno
const { cnabString, cnabName } = await this.sftpService.getFirstCnabRetorno();
if (!cnabName || !cnabString) {
this.logger.log(formatLog('Retorno não encontrado, abortando tarefa.', METHOD));
return;
}

// Save retorno, move backup
const retorno104 = parseCnab240_104(cnabString);
if (this.salvarRetorno(retorno104)) {
await this.sftpService.backupCnabRetorno(cnabName);
}
}

// CHAMAR MÉTODO PARA SALVAR RETORNO NO BANCO
salvarRetorno(a: ICnab240_104File): boolean {
console.log(a);
return true;
}
}
42 changes: 19 additions & 23 deletions src/cnab/service/header-arquivo.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import { HeaderLoteService } from './header-lote.service';
import { PagadorService } from './pagador.service';
import { TransacaoService } from './transacao.service';
import { SftpService } from 'src/sftp/sftp.service';
import { HeaderArquivoTipoArquivo } from '../enums/header-arquivo/header-arquivo-tipo-arquivo.enum';

@Injectable()
export class HeaderArquivoService {
Expand All @@ -55,22 +56,7 @@ export class HeaderArquivoService {
private sftpService: SftpService,
) { }

public async saveRemessa(): Promise<void> {
const listAllTransacao = await this.transacaoService.getAll();
for (const transacao of listAllTransacao) {
if (!this.headerArquivoExists(transacao.id_transacao)) {
const { cnabString, cnabTables } = await this.generateCnab(transacao);
await this.performSaveRemessa(cnabTables);
await this.sendCnabSFTP(cnabString);
}
}
}

private async sendCnabSFTP(cnabString: string) {
await this.sftpService.submitFromString(cnabString, 'arquivo/123-wip-rem.txt');
}

private async performSaveRemessa(cnabTables: ICnabTables) {
public async saveRemessa(cnabTables: ICnabTables) {
const headerLote = cnabTables.lotes[0].headerLote;
const detalhes = cnabTables.lotes[0].detalhes;
await this.headerArquivoRepository.save(cnabTables.headerArquivo);
Expand All @@ -85,9 +71,9 @@ export class HeaderArquivoService {
cnabTables: ICnabTables;
}> {
// get variables
const headerArquivoDTO = await this.transacaoToHeaderArquivoDTO(
const headerArquivoDTO = await this.getHeaderArquivoDTOFromTransacao(
transacao,
'remessa',
HeaderArquivoTipoArquivo.Remessa,
);
const headerLoteDTO = this.transacaoToHeaderLoteDTO(
transacao,
Expand Down Expand Up @@ -232,9 +218,9 @@ export class HeaderArquivoService {
return await this.headerArquivoRepository.findAll();
}

private async transacaoToHeaderArquivoDTO(
private async getHeaderArquivoDTOFromTransacao(
transacao: Transacao,
tipo_arquivo: string,
tipo_arquivo: HeaderArquivoTipoArquivo,
): Promise<HeaderArquivoDTO> {
const dto = new HeaderArquivoDTO();
const pagador = await this.pagadorService.getOneByIdPagador(transacao.id_pagador);
Expand Down Expand Up @@ -280,7 +266,7 @@ export class HeaderArquivoService {
return dto;
}

private async saveDetalhes(
public async saveDetalhes(
itemTransacao: ItemTransacao,
headerLoteDTO: HeaderLoteDTO,
registroAB: ICnab240_104RegistroAB,
Expand Down Expand Up @@ -321,8 +307,7 @@ export class HeaderArquivoService {
detalheB.id_detalhe_a = (await saveDetalheA).id_detalhe_a;
await this.detalheBService.save(detalheB);
}

private async headerArquivoExists(id_transacao: number): Promise<boolean> {
public async headerArquivoExists(id_transacao: number): Promise<boolean> {
const ret = await this.headerArquivoRepository.findOne({
id_transacao: id_transacao,
});
Expand All @@ -331,4 +316,15 @@ export class HeaderArquivoService {
}
return true;
}

/**
* Get the most recent CNAB Retorno Date saved in database.
*/
public async getMostRecentRetornoDate(): Promise<Date> {
const retorno = await this.headerArquivoRepository.findOne(
{ tipo_arquivo: HeaderArquivoTipoArquivo.Retorno },
{ createdAt: 'DESC' }
);
return retorno?.createdAt || new Date(0);
}
}
4 changes: 1 addition & 3 deletions src/cnab/service/transacao.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,10 @@ export class TransacaoService {
private pagadorService: PagadorService,
private bigqueryOrdemPagamentoService: BigqueryOrdemPagamentoService,
) { }

public async updateTransacaoFromJae() {
//Atualiza todos os favorecidos
await this.clienteFavorecidoService.updateAllFromUsers();

const ordensPagamento = await this.bigqueryOrdemPagamentoService.getCurrentWeek();

const pagador = await this.pagadorService.getOneByConta(PagadorContaEnum.JAE);
let idOrdemAux = "";

Expand Down
2 changes: 1 addition & 1 deletion src/cnab/utils/cnab-104-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
stringifyCnabFile,
} from './cnab-utils';

export function parseCnab104(cnabString: string): ICnab240_104File {
export function parseCnab240_104(cnabString: string): ICnab240_104File {
const fileDTO = getCnabFileFrom104({
headerArquivo: structuredClone(cnab240_104HeaderArquivoTemplate),
lotes: [{
Expand Down
8 changes: 8 additions & 0 deletions src/cnab/utils/cnab-field-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { CnabField } from '../types/cnab-field.type';

export type CropFillOnCrop = 'error' | 'cropLeft' | 'cropRight';

// #region stringifyCnabField

/**
* From CnabField get formatted value applying Picture.
*
Expand Down Expand Up @@ -313,6 +315,10 @@ export function getPictureTotalSize(field: CnabField) {
: ((i = getPictureNumberSize(field.picture)) => i.decimal + i.integer)();
}

// #endregion

// #region parseCnabField

export function parseCnabField(
cnabStringLine: string,
fieldDTO: CnabField,
Expand Down Expand Up @@ -359,4 +365,6 @@ export function validateParseCnabField(
*/
export function validateCnabFieldValue(field: CnabField) {
getStringFromCnabField(field);

// #endregion
}
31 changes: 25 additions & 6 deletions src/cron-jobs/cron-jobs.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { UsersService } from 'src/users/users.service';
import {
formatErrorMessage as formatErrorLog,
formatLog,
} from 'src/utils/logging';
} from 'src/utils/log-utils';
import { validateEmail } from 'validations-br';

/**
Expand All @@ -29,7 +29,8 @@ export enum CrobJobsEnum {
pollDb = 'pollDb',
bulkResendInvites = 'bulkResendInvites',
updateTransacaoFromJae = 'updateTransacaoFromJae',
sendNewCNABs = 'sendNewCNABs',
updateRemessa = 'updateRemessa',
updateRetorno = 'updateRetorno',
}

interface ICronJob {
Expand Down Expand Up @@ -121,11 +122,11 @@ export class CronJobsService implements OnModuleInit {
},
},
{
name: CrobJobsEnum.sendNewCNABs,
name: CrobJobsEnum.updateRemessa,
cronJobParameters: {
cronTime: '45 14 * * *', // 14:45 GMT = 11:45BRT (GMT-3)
onTick: async () => {
await this.sendNewCNABs();
await this.updateRemessa();
},
},
},
Expand Down Expand Up @@ -665,7 +666,25 @@ export class CronJobsService implements OnModuleInit {
await this.cnabService.updateTransacaoFromJae();
}

async sendNewCNABs() {
await this.cnabService.sendNewCNABs();
async updateRemessa() {
const METHOD = 'updateRemessa()';
try {
await this.cnabService.updateRemessa();
} catch (error) {
this.logger.error(formatLog(
`Erro, abortando: ${(error as Error).message}.`
, METHOD));
}
}

async updateRetorno() {
const METHOD = 'updateRetorno()';
try {
await this.cnabService.updateRetorno();
} catch (error) {
this.logger.error(formatLog(
`Erro, abortando: ${(error as Error).message}.`
, METHOD));
}
}
}
Loading

0 comments on commit 4709cb6

Please sign in to comment.