| Server IP : 189.126.111.107 / Your IP : 216.73.217.69 Web Server : Apache System : Linux www.gadotticar.com.br 5.4.0-135-generic #152-Ubuntu SMP Wed Nov 23 20:19:22 UTC 2022 x86_64 User : gadotticar ( 1000) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /home/gadotticar/frete-api/src/frete/transportadoras/ |
Upload File : |
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { HttpService } from '@nestjs/axios';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { ApiToken } from '../entities/api-token.entity';
import { lastValueFrom } from 'rxjs';
@Injectable()
export class MelhorEnvioService {
private readonly apiUrl: string;
constructor(
private readonly httpService: HttpService,
private readonly configService: ConfigService, // ConfigService para variáveis de ambiente
@InjectRepository(ApiToken)
private readonly apiTokenRepository: Repository<ApiToken>,
) {
// Definindo o URL da API com base na variável de ambiente
this.apiUrl = this.configService.get<string>('MELHOR_ENVIO_SANDBOX') === 'true'
? 'https://sandbox.melhorenvio.com.br'
: 'https://www.melhorenvio.com.br';
}
// Obter o token de acesso do banco de dados
private async getAccessToken(): Promise<string> {
//console.log('Buscando token no banco de dados...');
const tokenRecord = await this.apiTokenRepository.findOne({
where: { id: 5 },
order: { expires_at: 'DESC' },
});
if (!tokenRecord) {
console.error('Nenhum token encontrado no banco de dados!');
throw new HttpException('No access token found in database', HttpStatus.INTERNAL_SERVER_ERROR);
}
// console.log('Token encontrado:', tokenRecord);
// Verificar se o token expirou
if (new Date() >= new Date(tokenRecord.expires_at)) {
//console.log('Token expirado. Tentando renovar...');
const newAccessToken = await this.refreshAccessToken(tokenRecord.refresh_token);
tokenRecord.access_token = newAccessToken;
await this.apiTokenRepository.save(tokenRecord);
//console.log('Token renovado com sucesso.');
}
return tokenRecord.access_token;
}
// Atualizar o token de acesso usando o refresh token
private async refreshAccessToken(refreshToken: string): Promise<string> {
const clientId = this.configService.get<string>('MELHOR_ENVIO_CLIENT_ID');
const clientSecret = this.configService.get<string>('MELHOR_ENVIO_CLIENT_SECRET');
//console.log('Renovando token com refresh token...');
//console.log('Client ID:', clientId);
//console.log('Client Secret:', clientSecret);
//console.log('Refresh Token:', refreshToken);
try {
const response = await lastValueFrom(
this.httpService.post(`${this.apiUrl}/oauth/token`, {
grant_type: 'refresh_token',
client_id: clientId,
client_secret: clientSecret,
refresh_token: refreshToken,
}),
);
//console.log('Resposta da renovação do token:', response.data);
return response.data.access_token;
} catch (error) {
if (error.response) {
console.error('Erro ao renovar token - Status:', error.response.status);
console.error('Erro ao renovar token - Dados da resposta:', error.response.data);
} else {
console.error('Erro ao renovar token:', error.message);
}
throw new HttpException('Error refreshing access token', HttpStatus.INTERNAL_SERVER_ERROR);
}
}
// Calcular frete
public async calculateShipping(data: any): Promise<any> {
console.log('Iniciando cálculo de frete com o payload recebido:', data);
// Validação básica para garantir que os campos necessários existem
if (!data.Origem || !data.Origem.cep) {
throw new HttpException('Campo "Origem.cep" está ausente', HttpStatus.BAD_REQUEST);
}
if (!data.Destino || !data.Destino.cep) {
throw new HttpException('Campo "Destino.cep" está ausente', HttpStatus.BAD_REQUEST);
}
if (!data.Produtos || !Array.isArray(data.Produtos) || data.Produtos.length === 0) {
throw new HttpException('Campo "Produtos" está ausente ou vazio', HttpStatus.BAD_REQUEST);
}
// Preparar o payload no formato esperado pela API do Melhor Envio
const payload = {
from: {
postal_code: data.Origem.cep, // Campo Origem.cep
},
to: {
postal_code: data.Destino.cep, // Campo Destino.cep
},
products: data.Produtos.map((produto) => ({
weight: produto.peso,
width: produto.largura,
height: produto.altura,
length: produto.comprimento,
insurance_value: produto.valor,
})),
};
//console.log('Payload preparado para a API do Melhor Envio:', payload);
// Obter o token de acesso
const accessToken = await this.getAccessToken();
//console.log('Token de acesso obtido:', accessToken);
try {
const response = await lastValueFrom(
this.httpService.post(`${this.apiUrl}/api/v2/me/shipment/calculate`, payload, {
headers: {
Authorization: `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
}),
);
//console.log('Resposta da API do Melhor Envio:', response.data);
return response.data;
} catch (error) {
if (error.response) {
console.error('Erro ao calcular frete - Status:', error.response.status);
console.error('Erro ao calcular frete - Dados da resposta:', error.response.data);
} else {
console.error('Erro ao calcular frete:', error.message);
}
throw new HttpException('Error calculating shipping', HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}