diff --git a/package.json b/package.json index c72b6d12..ca18153d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "api-cct", - "version": "0.13.1", + "version": "0.13.2", "description": "", "author": "", "private": true, diff --git a/src/cnab/cnab-manutencao.controller.ts b/src/cnab/cnab-manutencao.controller.ts index 32515195..9213195d 100644 --- a/src/cnab/cnab-manutencao.controller.ts +++ b/src/cnab/cnab-manutencao.controller.ts @@ -31,6 +31,7 @@ export class CnabManutencaoController { @ApiQuery({ name: 'dataPagamento', type: String, required: false, description: ApiDescription({ _: 'Data de pagamento', default: 'O dia de hoje' }) }) @ApiQuery({ name: 'isConference', type: Boolean, required: true, description: 'Conferencia - Se o remessa será gerado numa tabela de teste.', example: true }) @ApiQuery({ name: 'isCancelamento', type: Boolean, required: true, description: 'Cancelamento', example: false }) + @ApiQuery({ name: 'isTeste', type: Boolean, required: true, description: 'Define se o CNAB Remessa usará o parâmetro de Teste', example: false }) @ApiQuery({ name: 'nsaInicial', type: Number, required: false, description: ApiDescription({ default: 'O NSA atual' }) }) @ApiQuery({ name: 'nsaFinal', type: Number, required: false, description: ApiDescription({ default: 'nsaInicial' }) }) @ApiQuery({ name: 'dataCancelamento', type: String, required: false, description: ApiDescription({ _: 'Data de vencimento da transação a ser cancelada (DetalheA).', 'Required if': 'isCancelamento = true' }), example: '2024-07-16' }) @@ -41,6 +42,7 @@ export class CnabManutencaoController { @Query('dataPagamento', new ParseDatePipe({ transform: true, optional: true })) dataPagamento: Date | undefined, // Date | undefined @Query('isConference') isConference: boolean, @Query('isCancelamento') isCancelamento: boolean, + @Query('isTeste') isTeste: boolean, @Query('nsaInicial', new ParseNumberPipe({ min: 1, optional: true })) nsaInicial: number | undefined, @Query('nsaFinal', new ParseNumberPipe({ min: 1, optional: true })) nsaFinal: number | undefined, @Query('dataCancelamento', new ParseDatePipe({ transform: true, optional: true })) _dataCancelamento: any, // Date | undefined @@ -59,6 +61,7 @@ export class CnabManutencaoController { dataPgto: dataPagamento, isConference, isCancelamento, + isTeste, nsaInicial, nsaFinal, dataCancelamento, @@ -77,6 +80,7 @@ export class CnabManutencaoController { @ApiQuery({ name: 'dt_pagamento', description: ApiDescription({ _: 'Data Pagamento', default: 'O dia de hoje' }), required: false, type: String }) @ApiQuery({ name: 'isConference', description: 'Conferencia - Se o remessa será gerado numa tabela de teste.', required: true, type: Boolean, example: true }) @ApiQuery({ name: 'isCancelamento', description: 'Cancelamento', required: true, type: Boolean, example: false }) + @ApiQuery({ name: 'isTeste', type: Boolean, required: true, description: 'Define se o CNAB Remessa usará o parâmetro de Teste', example: false }) @ApiQuery({ name: 'nsaInicial', description: ApiDescription({ default: 'O NSA atual' }), required: false, type: Number }) @ApiQuery({ name: 'nsaFinal', description: ApiDescription({ default: 'nsaInicial' }), required: false, type: Number }) @ApiQuery({ name: 'dataCancelamento', description: ApiDescription({ _: 'Data de vencimento da transação a ser cancelada (DetalheA).', 'Required if': 'isCancelamento = true' }), required: false, type: String, example: '2024-07-16' }) @@ -89,6 +93,7 @@ export class CnabManutencaoController { @Query('dt_pagamento', new ParseDatePipe({ transform: true, optional: true })) _dataPgto: any, // Date | undefined @Query('isConference') isConference: boolean, @Query('isCancelamento') isCancelamento: boolean, + @Query('isTeste') isTeste: boolean, @Query('nsaInicial', new ParseNumberPipe({ min: 1, optional: true })) nsaInicial: number | undefined, @Query('nsaFinal', new ParseNumberPipe({ min: 1, optional: true })) nsaFinal: number | undefined, @Query('dataCancelamento', new ParseDatePipe({ transform: true, optional: true })) _dataCancelamento: any, // Date | undefined @@ -110,6 +115,7 @@ export class CnabManutencaoController { dataPgto, isConference, isCancelamento, + isTeste, nsaInicial, nsaFinal, dataCancelamento, diff --git a/src/cnab/cnab.service.ts b/src/cnab/cnab.service.ts index 9f1ed971..32b8e6af 100644 --- a/src/cnab/cnab.service.ts +++ b/src/cnab/cnab.service.ts @@ -5,6 +5,7 @@ import { BigqueryOrdemPagamentoDTO } from 'src/bigquery/dtos/bigquery-ordem-paga import { BigqueryTransacao } from 'src/bigquery/entities/transacao.bigquery-entity'; import { BigqueryOrdemPagamentoService } from 'src/bigquery/services/bigquery-ordem-pagamento.service'; import { BigqueryTransacaoService } from 'src/bigquery/services/bigquery-transacao.service'; +import { LancamentoStatus } from 'src/lancamento/enums/lancamento-status.enum'; import { LancamentoService } from 'src/lancamento/lancamento.service'; import { cnabSettings } from 'src/settings/cnab.settings'; import { SettingsService } from 'src/settings/settings.service'; @@ -55,7 +56,6 @@ 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 { LancamentoStatus } from 'src/lancamento/enums/lancamento-status.enum'; /** * User cases for CNAB and Payments @@ -98,12 +98,13 @@ export class CnabService { dataPgto: Date | undefined; isConference: boolean; isCancelamento: boolean; + isTeste: boolean; nsaInicial: number | undefined; nsaFinal: number | undefined; dataCancelamento: Date | undefined; }) { const METHOD = 'getGenerateRemessaJae'; - const { consorcio, dataCancelamento, dataOrdemFinal, dataOrdemInicial, dataPgto, diasAnteriores, isCancelamento, isConference, nsaFinal, nsaInicial } = args; + const { consorcio, dataCancelamento, dataOrdemFinal, dataOrdemInicial, dataPgto, diasAnteriores, isCancelamento, isConference, nsaFinal, nsaInicial, isTeste } = args; const duration = { saveTransacoesJae: '', generateRemessa: '', sendRemessa: '', total: '' }; const startDate = new Date(); let now = new Date(); @@ -121,6 +122,7 @@ export class CnabService { dataPgto, isConference, isCancelamento, + isTeste, nsaInicial, nsaFinal, dataCancelamento, @@ -148,12 +150,13 @@ export class CnabService { dataPgto: Date | undefined; isConference: boolean; isCancelamento: boolean; + isTeste: boolean; nsaInicial: number | undefined; nsaFinal: number | undefined; dataCancelamento: Date | undefined; }) { const METHOD = 'getGenerateRemessaLancamento'; - const { dataCancelamento, dataOrdemFinal, dataOrdemInicial, dataPgto, isCancelamento, isConference, nsaFinal, nsaInicial } = args; + const { dataCancelamento, dataOrdemFinal, dataOrdemInicial, dataPgto, isCancelamento, isConference, isTeste, nsaFinal, nsaInicial } = args; const duration = { saveTransacoesJae: '', generateRemessa: '', sendRemessa: '', total: '' }; const startDate = new Date(); let now = new Date(); @@ -171,6 +174,7 @@ export class CnabService { dataPgto, isConference, isCancelamento, + isTeste, nsaInicial, nsaFinal, dataCancelamento, @@ -471,6 +475,7 @@ export class CnabService { dataPgto?: Date; isConference: boolean; isCancelamento: boolean; + isTeste: boolean; /** Default: current NSA */ nsaInicial?: number; /** Default: nsaInicial */ @@ -480,7 +485,7 @@ export class CnabService { const METHOD = this.sendRemessa.name; const currentNSA = parseInt((await this.settingsService.getOneBySettingData(cnabSettings.any__cnab_current_nsa)).value); - const { tipo, dataPgto, isConference, isCancelamento } = args; + const { tipo, dataPgto, isConference, isCancelamento, isTeste } = args; let nsaInicial = args.nsaInicial || currentNSA; let nsaFinal = args.nsaFinal || nsaInicial; const dataCancelamento = args?.dataCancelamento || new Date(); @@ -498,12 +503,12 @@ export class CnabService { } for (const transacaoAg of transacoesAg) { const headerArquivoDTO = await this.remessaRetornoService.saveHeaderArquivoDTO(transacaoAg, isConference); - const lotes = await this.remessaRetornoService.getLotes(transacaoAg.pagador, headerArquivoDTO, isConference, dataPgto); - const cnab104 = this.remessaRetornoService.generateFile(headerArquivoDTO, lotes); + const headerLoteDTOs = await this.remessaRetornoService.getLotes(transacaoAg.pagador, headerArquivoDTO, isConference, dataPgto); + const cnab104 = this.remessaRetornoService.generateFile({ headerArquivoDTO, headerLoteDTOs, isTeste }); if (headerArquivoDTO && cnab104) { const [cnabStr, processedCnab104] = stringifyCnab104File(cnab104, true, 'CnabPgtoRem'); for (const processedLote of processedCnab104.lotes) { - const savedLote = lotes.filter((i) => i.formaLancamento === processedLote.headerLote.formaLancamento.value)[0]; + const savedLote = headerLoteDTOs.filter((i) => i.formaLancamento === processedLote.headerLote.formaLancamento.value)[0]; await this.remessaRetornoService.updateHeaderLoteDTOFrom104(savedLote, processedLote.headerLote, isConference); } if (!isConference) { @@ -523,7 +528,7 @@ export class CnabService { const headerArquivoDTO = await this.getHeaderArquivoCancelar(index); headerArquivoDTO.nsa = await this.headerArquivoService.getNextNSA(); const lotes = await this.getLotesCancelar(index); - const lotesDto: HeaderLoteDTO[] = []; + const headerLoteDTOs: HeaderLoteDTO[] = []; let detalhes: CnabRegistros104Pgto[] = []; for (const lote of lotes) { const headerLoteDTO = this.headerLoteService.convertHeaderLoteDTO(headerArquivoDTO, lote.pagador, lote.formaLancamento == '41' ? Cnab104FormaLancamento.TED : Cnab104FormaLancamento.CreditoContaCorrente); @@ -535,10 +540,10 @@ export class CnabService { } } headerLoteDTO.registros104 = detalhes; - lotesDto.push(headerLoteDTO); + headerLoteDTOs.push(headerLoteDTO); detalhes = []; } - const cnab104 = this.remessaRetornoService.generateFile(headerArquivoDTO, lotesDto, true, dataCancelamento); + const cnab104 = this.remessaRetornoService.generateFile({ headerArquivoDTO, headerLoteDTOs, isCancelamento: true, isTeste }); if (headerArquivoDTO && cnab104) { const [cnabStr] = stringifyCnab104File(cnab104, true, 'CnabPgtoRem'); if (!cnabStr) { diff --git a/src/cnab/service/pagamento/remessa-retorno.service.ts b/src/cnab/service/pagamento/remessa-retorno.service.ts index 46fb4e8a..30bcb604 100644 --- a/src/cnab/service/pagamento/remessa-retorno.service.ts +++ b/src/cnab/service/pagamento/remessa-retorno.service.ts @@ -45,6 +45,7 @@ import { ItemTransacaoService } from './item-transacao.service'; import { ClienteFavorecido } from 'src/cnab/entity/cliente-favorecido.entity'; import { LancamentoService } from 'src/lancamento/lancamento.service'; import { LancamentoStatus } from 'src/lancamento/enums/lancamento-status.enum'; +import { Cnab104AmbienteCliente } from 'src/cnab/enums/104/cnab-104-ambiente-cliente.enum'; const sc = structuredClone; const PgtoRegistros = Cnab104PgtoTemplates.file104.registros; @@ -222,8 +223,18 @@ export class RemessaRetornoService { /** * Montar Cnab104 a partir dos DTOs de tabelas */ - public generateFile(headerArquivo: HeaderArquivoDTO, headerLoteDTOs: HeaderLoteDTO[], isCancelamento = false, dataCancelamento = new Date()) { - const headerArquivo104 = this.getHeaderArquivo104FromDTO(headerArquivo); + public generateFile(args: { + headerArquivoDTO: HeaderArquivoDTO; // + headerLoteDTOs: HeaderLoteDTO[]; + isCancelamento?: boolean; + isTeste?: boolean; + dataCancelamento?: Date; + }) { + const { headerArquivoDTO: headerArquivo, headerLoteDTOs, isTeste } = args; + const isCancelamento = Boolean(args.isCancelamento); + const dataCancelamento = args?.dataCancelamento || new Date(); + + const headerArquivo104 = this.getHeaderArquivo104FromDTO(headerArquivo, isTeste); const trailerArquivo104 = sc(PgtoRegistros.trailerArquivo); return this.getCnabFilePgto(headerArquivo104, headerLoteDTOs, trailerArquivo104, isCancelamento, dataCancelamento); } @@ -279,7 +290,7 @@ export class RemessaRetornoService { return cnab104; } - private getHeaderArquivo104FromDTO(headerArquivoDTO: HeaderArquivoDTO): CnabHeaderArquivo104 { + private getHeaderArquivo104FromDTO(headerArquivoDTO: HeaderArquivoDTO, isTeste?: boolean): CnabHeaderArquivo104 { const headerArquivo104: CnabHeaderArquivo104 = sc(PgtoRegistros.headerArquivo); headerArquivo104.codigoBanco.value = headerArquivoDTO.codigoBanco; headerArquivo104.numeroInscricao.value = headerArquivoDTO.numeroInscricao; @@ -294,6 +305,7 @@ export class RemessaRetornoService { headerArquivo104.dataGeracaoArquivo.value = headerArquivoDTO.dataGeracao; headerArquivo104.horaGeracaoArquivo.value = headerArquivoDTO.horaGeracao; headerArquivo104.nsa.value = headerArquivoDTO.nsa; + headerArquivo104.ambienteCliente.value = isTeste ? Cnab104AmbienteCliente.Teste : Cnab104AmbienteCliente.Producao; return headerArquivo104; } diff --git a/src/cnab/templates/cnab-240/104/cnab-header-arquivo-104-template.const.ts b/src/cnab/templates/cnab-240/104/cnab-header-arquivo-104-template.const.ts index a69fd2e0..633da208 100644 --- a/src/cnab/templates/cnab-240/104/cnab-header-arquivo-104-template.const.ts +++ b/src/cnab/templates/cnab-240/104/cnab-header-arquivo-104-template.const.ts @@ -1,4 +1,5 @@ import { Cnab } from 'src/cnab/const/cnab.const'; +import { Cnab104AmbienteCliente } from 'src/cnab/enums/104/cnab-104-ambiente-cliente.enum'; import { CnabCodigoRegistro } from 'src/cnab/enums/all/cnab-codigo-registro.enum'; import { CnabHeaderArquivo104 } from 'src/cnab/interfaces/cnab-240/104/cnab-header-arquivo-104.interface'; @@ -70,7 +71,7 @@ export const CnabHeaderArquivo104Template: CnabHeaderArquivo104 = { ambienteCliente: { pos: [41, 41], picture: 'X(001)', - value: 'P', + value: Cnab104AmbienteCliente.Producao, ...Cnab.insert.d(), }, /** 0.10 */ diff --git a/src/cron-jobs/cron-jobs.service.ts b/src/cron-jobs/cron-jobs.service.ts index 0aef1f3a..35efe50b 100644 --- a/src/cron-jobs/cron-jobs.service.ts +++ b/src/cron-jobs/cron-jobs.service.ts @@ -288,6 +288,7 @@ export class CronJobsService { dataPgto: addDays(today, 1), isConference: false, isCancelamento: false, + isTeste: false, }); await this.cnabService.sendRemessa(listCnab); this.logger.log(`Tarefa finalizada - ${formatDateInterval(new Date(), startDate)}`, METHOD); @@ -316,6 +317,7 @@ export class CronJobsService { dataPgto: today, isConference: false, isCancelamento: false, + isTeste: false, }); await this.cnabService.sendRemessa(listCnab); this.logger.log(`Tarefa finalizada - ${formatDateInterval(new Date(), startDate)}`, METHOD); @@ -349,6 +351,7 @@ export class CronJobsService { dataPgto: new Date(), isConference: false, isCancelamento: false, + isTeste: false, }); await this.cnabService.sendRemessa(listCnab); this.logger.log(`Tarefa finalizada - ${formatDateInterval(new Date(), startDateLog)}`, METHOD); @@ -372,6 +375,7 @@ export class CronJobsService { dataPgto: undefined, // data programada no Lançamento isConference: false, isCancelamento: false, + isTeste: false, }); await this.cnabService.sendRemessa(listCnab); this.logger.log(`Tarefa finalizada - ${formatDateInterval(new Date(), startDateLog)}`, METHOD); @@ -398,6 +402,7 @@ export class CronJobsService { dataPgto, isConference, isCancelamento, + isTeste: false, nsaInicial, nsaFinal, dataCancelamento,