import { Injectable } from '@nestjs/common' import { HttpService } from '../http' import { ApiOmieGenericError } from './errors' import { GenerateContractParams, GenerateCustomerParams, GenerateServiceOrderParams } from './params' import { buildGenerateContractData, buildGenerateCustomerData, buildGenerateServiceOrderData } from './helpers' import { OmieConfigService } from './service' type ParamsRequest = { call: string param: Record app_key?: string app_secret?: string } type GenerateContractResult = { code: number customerCode: number } type GenerateServiceOrdertResult = { code: number customerCode: number status: string message: string } type InvoiceContractResult = { soCode: number status: string message: string } type CancelContractResult = { status: string message: string } @Injectable() export class OmieService { constructor(protected readonly httpService: HttpService, private omieConfigService: OmieConfigService) {} async generateCustomer({ patient, address }: GenerateCustomerParams): Promise { try { const result = await this.request('geral/clientes', { call: 'IncluirCliente', param: [ buildGenerateCustomerData({ patient, address: { ...address, cityCode: await this.getCityCode(address.city, address.state), number: address.number?.toString().slice(0, 10), }, }), ], }) return result?.codigo_cliente_omie } catch (error) { if (error instanceof ApiOmieGenericError) if (error.faultCode === 'SOAP-ENV:Client-102') return +error.faultString.match(/.*\[(.*)\].*\[(.*)\]/)[2] throw error } } async generateContract({ patient, subscription, plan, amount, address, }: GenerateContractParams): Promise { const config = await this.omieConfigService.getConfig() const customerCode = Number(patient.omie_code || (await this.generateCustomer({ patient, address }))) const result = await this.request('servicos/contrato', { call: 'IncluirContrato', param: [ buildGenerateContractData({ subscription, plan, amount, customerCode: customerCode, email: patient.email, checkingAccountCode: config.checking_account_code, categoryCode: config.category_code, }), ], }) return { code: result.nCodCtr, customerCode } } async generateServiceOrder({ patient, subscription, plan, amount, address, installment, totalInstallments, cardType, }: GenerateServiceOrderParams): Promise { const config = await this.omieConfigService.getConfig() const customerCode = Number(patient.omie_code || (await this.generateCustomer({ patient, address }))) const result = await this.request('servicos/os', { call: 'IncluirOS', param: [ buildGenerateServiceOrderData({ subscription, plan, amount, customerCode: customerCode, email: patient.email, installment, totalInstallments, cardType, config, }), ], }) return { code: result.nCodOS, customerCode, status: result.cCodStatus, message: result.cDescStatus } } async invoiceContract(contractCode: number): Promise { const result = await this.request('servicos/contratofat', { call: 'FaturarContrato', param: [{ nCodCtr: contractCode }], }) return { soCode: result.nCodOS, status: result.cCodStatus, message: result.cDescStatus } } async invoiceServiceOrder(soCode: number): Promise { const result = await this.request('servicos/osp', { call: 'FaturarOS', param: [{ nCodOS: soCode }], }) return { soCode: result.nCodOS, status: result.cCodStatus, message: result.cDescStatus } } async cancelContract(contractCode: number): Promise { const result = await this.request('servicos/contratofat', { call: 'CancelarContrato', param: [{ nCodCtr: contractCode }], }) return { status: result.cCodStatus, message: result.cDescStatus } } async cancelInvoice(contractCode: number): Promise { const result = await this.request('servicos/osp', { call: 'CancelarOS', param: [{ nCodOS: contractCode }], }) return { status: result.cCodStatus, message: result.cDescStatus } } private async getCityCode(cityName: string, state: string): Promise { const result = await this.request('geral/cidades', { call: 'PesquisarCidades', param: [ { pagina: 1, registros_por_pagina: 50, filtrar_por_UF: state, filtrar_por_cidade: cityName, }, ], }) return result?.lista_cidades?.shift()?.cCod } private async request(path: string, data: ParamsRequest): Promise { const config = await this.omieConfigService.getConfig() if (!config.enable) throw new Error('Omie service disabled') data.app_key = config.app_key data.app_secret = config.app_secret try { return await this.httpService.post(`${config.endpoint}/${path}/`, data, { errorMessage: `Erro ao realizar comunicação com Omie.`, headers: { 'Content-Type': 'application/json', }, name: this.constructor.name, }) } catch (err) { throw new ApiOmieGenericError(err.message, err.body?.faultcode, err.body?.faultstring) } } }