842 lines
42 KiB
Python
842 lines
42 KiB
Python
import json
|
|
import logging
|
|
import os
|
|
|
|
import requests
|
|
|
|
from src.models.erro_holmes import ErroHolmes
|
|
from src.models.estoque_homes import EstoqueHolmes
|
|
from src.models.proposta import Proposta
|
|
from src.models.resultado import Resultado
|
|
from src.repositories.estoque_repository import EstoqueRepository
|
|
from src.utils.utils import extrair_proposta
|
|
|
|
class HolmesAPI:
|
|
|
|
def __init__(self):
|
|
self.headers = {
|
|
# "authorization": self._token_usuario(),
|
|
"api_token": 'eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNmE4MzBjMzcwNDdlNzI1MTVlMDU1ZDFhIiwiaWF0IjoxNzg2OTczMjM5fQ.K-R2E6v7JjCJDJJfDhyZ8nwQwMiaVfbF2BtUvW-sNwQ',
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
def _somente_digitos(self, valor) -> str:
|
|
return ''.join(c for c in str(valor or '') if c.isdigit())
|
|
|
|
def _token_usuario(self) -> str:
|
|
url = "https://app-api.holmesdoc.io/v1/session"
|
|
body = {"email": os.getenv('HOLMES_USER'), "password": os.getenv('HOLMES_PASS')}
|
|
headers = {"Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36"}
|
|
response = requests.post(url, json=body, headers=headers)
|
|
response.raise_for_status()
|
|
dados = response.json()
|
|
if "token" not in dados:
|
|
logging.error(
|
|
f"Login Holmes sem token (HTTP {response.status_code}): {str(dados)[:500]}"
|
|
)
|
|
raise RuntimeError("Login Holmes não retornou token")
|
|
|
|
return dados["token"]
|
|
|
|
def _build_payload_novos(self, proposta: Proposta) -> dict:
|
|
start_event = 'StartEvent_1'
|
|
|
|
campos = [
|
|
("e88ea290-8ce4-11f1-9f28-e51e49945850", proposta.empresa_holmes),
|
|
("ed2d30f0-8ce4-11f1-9f28-e51e49945850", proposta.tipo_pessoa),
|
|
("f2fe24d0-8ce4-11f1-9f28-e51e49945850", proposta.usado_na_troca),
|
|
("2aafcff0-8cf4-11f1-9f28-e51e49945850", proposta.forma_pagamento),
|
|
("fad87d40-8ce4-11f1-9f28-e51e49945850", proposta.proposta_apollo),
|
|
("fdfd63f0-8ce4-11f1-9f28-e51e49945850", proposta.veiculo),
|
|
("01109760-8ce5-11f1-9f28-e51e49945850", proposta.chassi),
|
|
("04ab7160-8ce5-11f1-9f28-e51e49945850", proposta.des_modelo),
|
|
("1b0974c0-8ce5-11f1-9f28-e51e49945850", proposta.valor_proposta),
|
|
("23914b40-8ce5-11f1-9f28-e51e49945850", proposta.nome),
|
|
("27b419f0-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.cpfcnpj)),
|
|
("398ac070-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.celular)),
|
|
("3e7bb490-8ce5-11f1-9f28-e51e49945850", proposta.email),
|
|
("6873d880-9ccc-11f1-b919-f777409ec14c", proposta.vendedor_holmes),
|
|
]
|
|
|
|
payload = {
|
|
"workflow": {
|
|
"start_event": start_event,
|
|
"property_values": [
|
|
{"id": prop_id, "value": valor}
|
|
for prop_id, valor in campos
|
|
if valor is not None and str(valor).strip() != ''
|
|
],
|
|
"whats": "",
|
|
"documents": [],
|
|
"test": False
|
|
}
|
|
}
|
|
logging.debug("Payload proposta %s: %s", proposta.proposta_apollo, payload)
|
|
return payload
|
|
|
|
def _build_payload_usados(self, proposta: Proposta) -> dict:
|
|
start_event = 'StartEvent_1'
|
|
|
|
campos = [
|
|
("e88ea290-8ce4-11f1-9f28-e51e49945850", proposta.empresa_holmes),
|
|
("ed2d30f0-8ce4-11f1-9f28-e51e49945850", proposta.tipo_pessoa),
|
|
("2aafcff0-8cf4-11f1-9f28-e51e49945850", proposta.forma_pagamento),
|
|
("f2fe24d0-8ce4-11f1-9f28-e51e49945850", proposta.usado_na_troca),
|
|
("fad87d40-8ce4-11f1-9f28-e51e49945850", proposta.proposta_apollo),
|
|
("fdfd63f0-8ce4-11f1-9f28-e51e49945850", proposta.veiculo),
|
|
("01109760-8ce5-11f1-9f28-e51e49945850", proposta.chassi),
|
|
("04ab7160-8ce5-11f1-9f28-e51e49945850", proposta.des_modelo),
|
|
("08b38c20-8ce5-11f1-9f28-e51e49945850", proposta.placa),
|
|
("1b0974c0-8ce5-11f1-9f28-e51e49945850", proposta.valor_proposta),
|
|
("23914b40-8ce5-11f1-9f28-e51e49945850", proposta.nome),
|
|
("27b419f0-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.cpfcnpj)),
|
|
("398ac070-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.celular)),
|
|
("3e7bb490-8ce5-11f1-9f28-e51e49945850", proposta.email),
|
|
("19c78c10-9d92-11f1-ad38-41765eab56e3", proposta.vendedor_holmes),
|
|
]
|
|
|
|
payload = {
|
|
"workflow": {
|
|
"start_event": start_event,
|
|
"property_values": [
|
|
{"id": prop_id, "value": valor}
|
|
for prop_id, valor in campos
|
|
if valor is not None and str(valor).strip() != ''
|
|
],
|
|
"whats": "",
|
|
"documents": [],
|
|
"test": False
|
|
}
|
|
}
|
|
logging.debug("Payload proposta %s: %s", proposta.proposta_apollo, payload)
|
|
return payload
|
|
|
|
def _build_payload_imobilizado(self, proposta: Proposta) -> dict:
|
|
start_event = 'StartEvent_1'
|
|
|
|
campos = [
|
|
("e88ea290-8ce4-11f1-9f28-e51e49945850", proposta.empresa_holmes),
|
|
("ed2d30f0-8ce4-11f1-9f28-e51e49945850", proposta.tipo_pessoa),
|
|
("f2fe24d0-8ce4-11f1-9f28-e51e49945850", proposta.usado_na_troca),
|
|
("2aafcff0-8cf4-11f1-9f28-e51e49945850", proposta.forma_pagamento),
|
|
("fad87d40-8ce4-11f1-9f28-e51e49945850", proposta.proposta_apollo),
|
|
("fdfd63f0-8ce4-11f1-9f28-e51e49945850", proposta.veiculo),
|
|
("01109760-8ce5-11f1-9f28-e51e49945850", proposta.chassi),
|
|
("04ab7160-8ce5-11f1-9f28-e51e49945850", proposta.des_modelo),
|
|
("08b38c20-8ce5-11f1-9f28-e51e49945850", proposta.placa),
|
|
("1b0974c0-8ce5-11f1-9f28-e51e49945850", proposta.valor_proposta),
|
|
("23914b40-8ce5-11f1-9f28-e51e49945850", proposta.nome),
|
|
("27b419f0-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.cpfcnpj)),
|
|
("398ac070-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.celular)),
|
|
("3e7bb490-8ce5-11f1-9f28-e51e49945850", proposta.email),
|
|
("d1b18d20-9d98-11f1-8298-cb4f6a31d606", proposta.vendedor_holmes),
|
|
]
|
|
|
|
payload = {
|
|
"workflow": {
|
|
"start_event": start_event,
|
|
"property_values": [
|
|
{"id": prop_id, "value": valor}
|
|
for prop_id, valor in campos
|
|
if valor is not None and str(valor).strip() != ''
|
|
],
|
|
"whats": "",
|
|
"documents": [],
|
|
"test": False
|
|
}
|
|
}
|
|
logging.debug("Payload proposta %s: %s", proposta.proposta_apollo, payload)
|
|
return payload
|
|
|
|
def _build_payload_venda_direta(self, proposta: Proposta) -> dict:
|
|
# Esse formulario tem IDs proprios (nao reaproveita os dos outros tres),
|
|
# nao tem Placa e traz a Observacao da proposta.
|
|
start_event = 'StartEvent_1'
|
|
|
|
campos = [
|
|
("37897690-8d03-11f1-9f28-e51e49945850", proposta.empresa_holmes),
|
|
("420c59c0-8d03-11f1-9f28-e51e49945850", proposta.tipo_pessoa),
|
|
("46da1900-8d04-11f1-9f28-e51e49945850", proposta.forma_pagamento),
|
|
("48ee6f80-8d03-11f1-9f28-e51e49945850", proposta.usado_na_troca),
|
|
("53933290-8d03-11f1-9f28-e51e49945850", proposta.proposta_apollo),
|
|
("58d81310-8d03-11f1-9f28-e51e49945850", proposta.veiculo),
|
|
("5b19c5b0-8d03-11f1-9f28-e51e49945850", proposta.chassi),
|
|
("5f92a3a0-8d03-11f1-9f28-e51e49945850", proposta.des_modelo),
|
|
("6b95e540-8d03-11f1-9f28-e51e49945850", proposta.valor_proposta),
|
|
("73c56290-8d03-11f1-9f28-e51e49945850", proposta.nome),
|
|
("79635f90-8d03-11f1-9f28-e51e49945850", self._somente_digitos(proposta.cpfcnpj)),
|
|
("85ea9e40-8d03-11f1-9f28-e51e49945850", self._somente_digitos(proposta.celular)),
|
|
("8f16f220-8d03-11f1-9f28-e51e49945850", proposta.email),
|
|
("cbe61910-a2de-11f1-aff4-4f1f04587741", proposta.vendedor_holmes),
|
|
("e7610290-a2de-11f1-aff4-4f1f04587741", proposta.observacao),
|
|
]
|
|
|
|
payload = {
|
|
"workflow": {
|
|
"start_event": start_event,
|
|
"property_values": [
|
|
{"id": prop_id, "value": valor}
|
|
for prop_id, valor in campos
|
|
if valor is not None and str(valor).strip() != ''
|
|
],
|
|
"whats": "",
|
|
"documents": [],
|
|
"test": False
|
|
}
|
|
}
|
|
logging.debug("Payload proposta %s: %s", proposta.proposta_apollo, payload)
|
|
return payload
|
|
|
|
def existe_holmes(self, chassi: str, proposta: str) -> bool:
|
|
"""Confere se o chassi já está lançado no holmes e caso tenha o mesmo chassi ele bate a proposta
|
|
|
|
Args:
|
|
chassi (str): Chassi do veiculo vendido
|
|
proposta (str): Proposta do veiculo
|
|
|
|
Returns:
|
|
bool: True caso existir e False caso não exista no holmes
|
|
"""
|
|
|
|
logging.info("Verificando se chassi %s (proposta %s) já existe no Holmes", chassi, proposta)
|
|
url = 'https://app-api.holmesdoc.io/v2/search'
|
|
body = {
|
|
"query": {
|
|
"from": 0,
|
|
"size": 50,
|
|
"context": "process",
|
|
"sort": "updated_at",
|
|
"order": "desc",
|
|
"groups": [
|
|
{
|
|
"match_all": True,
|
|
"terms": [
|
|
{
|
|
"value": f"{chassi}",
|
|
"type": "match_phrase",
|
|
"field": "_content"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"trash": False,
|
|
"deleted_by_me": False
|
|
}
|
|
|
|
resposta = requests.post(url, json=body, headers=self.headers)
|
|
resposta.raise_for_status()
|
|
dados = resposta.json()
|
|
|
|
if dados['total'] == 0:
|
|
logging.info("Chassi %s não encontrado no Holmes", chassi)
|
|
return False
|
|
|
|
PROCESSOS_VALIDOS = {
|
|
'Faturamento de Novos',
|
|
'Faturamento de Venda Direta',
|
|
'Faturamento de Test Drive',
|
|
'Faturamento de Usados',
|
|
}
|
|
|
|
docs_validos = [
|
|
doc for doc in dados.get('docs', [])
|
|
if doc.get('name') in PROCESSOS_VALIDOS
|
|
and doc.get('status') != 'canceled'
|
|
]
|
|
|
|
if not docs_validos:
|
|
logging.info("Chassi %s encontrado mas sem processos válidos (todos cancelados ou de outro template)", chassi)
|
|
return False
|
|
|
|
# proposta_holmes = extrair_proposta(docs_validos[0]['identifier'])
|
|
# if str(proposta_holmes) != str(proposta):
|
|
# logging.info("Chassi %s encontrado mas proposta diferente (Holmes: %s, Apollo: %s)", chassi, proposta_holmes, proposta)
|
|
# return False
|
|
|
|
logging.info("Chassi %s já existe no Holmes %s", chassi, proposta)
|
|
return True
|
|
|
|
def envia_fat_estoque_usado(self, proposta: Proposta, estoque_repo: EstoqueRepository) -> Resultado:
|
|
logging.info("Enviando proposta %s para Holmes (empresa=%s, revenda=%s)", proposta.proposta_apollo, proposta.empresa, proposta.revenda)
|
|
url = 'https://app-api.holmesdoc.io/v1/workflows/6a6cc58744c4ba86a63aebc1/start'
|
|
payload = self._build_payload_usados(proposta)
|
|
logging.debug("Payload montado para proposta %s", proposta.proposta_apollo)
|
|
response = requests.post(url, headers=self.headers, data=json.dumps(payload))
|
|
logging.debug("Holmes respondeu com status %s para proposta %s", response.status_code, proposta.proposta_apollo)
|
|
|
|
try:
|
|
if response.status_code != 200:
|
|
err_msg = f"Erro ao enviar para Holmes: {response.status_code} - {response.text or ''}"
|
|
err_msg = (err_msg[:3900] + "...") if len(err_msg) > 3900 else err_msg
|
|
logging.error("Falha ao enviar proposta %s: %s", proposta.proposta_apollo, err_msg)
|
|
estoque_repo.insere_erro(
|
|
ErroHolmes(
|
|
empresa = proposta.empresa,
|
|
revenda = proposta.revenda,
|
|
proposta_apollo = proposta.proposta_apollo,
|
|
motivo_erro= err_msg
|
|
)
|
|
)
|
|
return Resultado(sucesso=False, mensagem=err_msg)
|
|
|
|
else:
|
|
resposta = response.json()
|
|
logging.info("Proposta %s enviada com sucesso - processo Holmes: %s", proposta.proposta_apollo, resposta['id'])
|
|
estoque_repo.insere_estoque(
|
|
EstoqueHolmes(
|
|
empresa= proposta.empresa,
|
|
revenda= proposta.revenda,
|
|
proposta_apollo= proposta.proposta_apollo,
|
|
proesso_id= resposta['id'],
|
|
usuario_criou= 'SUPORTE SISTEMAS',
|
|
nome_processo= '[FAT] Faturamento de Estoque'
|
|
)
|
|
)
|
|
return Resultado(sucesso=True, mensagem=resposta['id'])
|
|
|
|
except Exception as e:
|
|
logging.error("Erro inesperado ao processar proposta %s: %s", proposta.proposta_apollo, e, exc_info=True)
|
|
return Resultado(sucesso=False, mensagem=str(e))
|
|
|
|
def envia_fat_estoque_novos(self, proposta: Proposta, estoque_repo: EstoqueRepository) -> Resultado:
|
|
logging.info("Enviando proposta %s para Holmes (empresa=%s, revenda=%s)", proposta.proposta_apollo, proposta.empresa, proposta.revenda)
|
|
url = 'https://app-api.holmesdoc.io/v1/workflows/6a6cbe67aff519bb6aa4b2d8/start'
|
|
payload = self._build_payload_novos(proposta)
|
|
logging.debug("Payload montado para proposta %s", proposta.proposta_apollo)
|
|
response = requests.post(url, headers=self.headers, data=json.dumps(payload))
|
|
logging.debug("Holmes respondeu com status %s para proposta %s", response.status_code, proposta.proposta_apollo)
|
|
|
|
try:
|
|
if response.status_code != 200:
|
|
err_msg = f"Erro ao enviar para Holmes: {response.status_code} - {response.text or ''}"
|
|
err_msg = (err_msg[:3900] + "...") if len(err_msg) > 3900 else err_msg
|
|
logging.error("Falha ao enviar proposta %s: %s", proposta.proposta_apollo, err_msg)
|
|
estoque_repo.insere_erro(
|
|
ErroHolmes(
|
|
empresa = proposta.empresa,
|
|
revenda = proposta.revenda,
|
|
proposta_apollo = proposta.proposta_apollo,
|
|
motivo_erro= err_msg
|
|
)
|
|
)
|
|
return Resultado(sucesso=False, mensagem=err_msg)
|
|
|
|
else:
|
|
resposta = response.json()
|
|
logging.info("Proposta %s enviada com sucesso - processo Holmes: %s", proposta.proposta_apollo, resposta['id'])
|
|
estoque_repo.insere_estoque(
|
|
EstoqueHolmes(
|
|
empresa= proposta.empresa,
|
|
revenda= proposta.revenda,
|
|
proposta_apollo= proposta.proposta_apollo,
|
|
proesso_id= resposta['id'],
|
|
usuario_criou= 'SUPORTE SISTEMAS',
|
|
nome_processo= '[FAT] Faturamento de Estoque'
|
|
)
|
|
)
|
|
return Resultado(sucesso=True, mensagem=resposta['id'])
|
|
|
|
except Exception as e:
|
|
logging.error("Erro inesperado ao processar proposta %s: %s", proposta.proposta_apollo, e, exc_info=True)
|
|
return Resultado(sucesso=False, mensagem=str(e))
|
|
|
|
def envia_fat_estoque_imobilizado(self, proposta: Proposta, estoque_repo: EstoqueRepository) -> Resultado:
|
|
logging.info("Enviando proposta %s para Holmes (empresa=%s, revenda=%s)", proposta.proposta_apollo, proposta.empresa, proposta.revenda)
|
|
url = 'https://app-api.holmesdoc.io/v1/workflows/6a6cc2a3dbf5173588777520/start'
|
|
payload = self._build_payload_imobilizado(proposta)
|
|
logging.debug("Payload montado para proposta %s", proposta.proposta_apollo)
|
|
response = requests.post(url, headers=self.headers, data=json.dumps(payload))
|
|
logging.debug("Holmes respondeu com status %s para proposta %s", response.status_code, proposta.proposta_apollo)
|
|
|
|
try:
|
|
if response.status_code != 200:
|
|
err_msg = f"Erro ao enviar para Holmes: {response.status_code} - {response.text or ''}"
|
|
err_msg = (err_msg[:3900] + "...") if len(err_msg) > 3900 else err_msg
|
|
logging.error("Falha ao enviar proposta %s: %s", proposta.proposta_apollo, err_msg)
|
|
estoque_repo.insere_erro(
|
|
ErroHolmes(
|
|
empresa = proposta.empresa,
|
|
revenda = proposta.revenda,
|
|
proposta_apollo = proposta.proposta_apollo,
|
|
motivo_erro= err_msg
|
|
)
|
|
)
|
|
return Resultado(sucesso=False, mensagem=err_msg)
|
|
|
|
else:
|
|
resposta = response.json()
|
|
logging.info("Proposta %s enviada com sucesso - processo Holmes: %s", proposta.proposta_apollo, resposta['id'])
|
|
estoque_repo.insere_estoque(
|
|
EstoqueHolmes(
|
|
empresa= proposta.empresa,
|
|
revenda= proposta.revenda,
|
|
proposta_apollo= proposta.proposta_apollo,
|
|
proesso_id= resposta['id'],
|
|
usuario_criou= 'SUPORTE SISTEMAS',
|
|
nome_processo= '[FAT] Faturamento de Estoque'
|
|
)
|
|
)
|
|
return Resultado(sucesso=True, mensagem=resposta['id'])
|
|
|
|
except Exception as e:
|
|
logging.error("Erro inesperado ao processar proposta %s: %s", proposta.proposta_apollo, e, exc_info=True)
|
|
return Resultado(sucesso=False, mensagem=str(e))
|
|
def envia_fat_estoque_venda_direta(self, proposta: Proposta, estoque_repo: EstoqueRepository) -> Resultado:
|
|
logging.info("Enviando proposta %s para Holmes (empresa=%s, revenda=%s)", proposta.proposta_apollo, proposta.empresa, proposta.revenda)
|
|
url = 'https://app-api.holmesdoc.io/v1/workflows/6a6cd6449341bbc7e45f29cf/start'
|
|
payload = self._build_payload_venda_direta(proposta)
|
|
logging.debug("Payload montado para proposta %s", proposta.proposta_apollo)
|
|
response = requests.post(url, headers=self.headers, data=json.dumps(payload))
|
|
logging.debug("Holmes respondeu com status %s para proposta %s", response.status_code, proposta.proposta_apollo)
|
|
|
|
try:
|
|
if response.status_code != 200:
|
|
err_msg = f"Erro ao enviar para Holmes: {response.status_code} - {response.text or ''}"
|
|
err_msg = (err_msg[:3900] + "...") if len(err_msg) > 3900 else err_msg
|
|
logging.error("Falha ao enviar proposta %s: %s", proposta.proposta_apollo, err_msg)
|
|
estoque_repo.insere_erro(
|
|
ErroHolmes(
|
|
empresa = proposta.empresa,
|
|
revenda = proposta.revenda,
|
|
proposta_apollo = proposta.proposta_apollo,
|
|
motivo_erro= err_msg
|
|
)
|
|
)
|
|
return Resultado(sucesso=False, mensagem=err_msg)
|
|
|
|
else:
|
|
resposta = response.json()
|
|
logging.info("Proposta %s enviada com sucesso - processo Holmes: %s", proposta.proposta_apollo, resposta['id'])
|
|
estoque_repo.insere_estoque(
|
|
EstoqueHolmes(
|
|
empresa= proposta.empresa,
|
|
revenda= proposta.revenda,
|
|
proposta_apollo= proposta.proposta_apollo,
|
|
proesso_id= resposta['id'],
|
|
usuario_criou= 'SUPORTE SISTEMAS',
|
|
nome_processo= '[FAT] Faturamento de Estoque'
|
|
)
|
|
)
|
|
return Resultado(sucesso=True, mensagem=resposta['id'])
|
|
|
|
except Exception as e:
|
|
logging.error("Erro inesperado ao processar proposta %s: %s", proposta.proposta_apollo, e, exc_info=True)
|
|
return Resultado(sucesso=False, mensagem=str(e))
|
|
# import json
|
|
# import logging
|
|
# import os
|
|
|
|
# import requests
|
|
|
|
# from src.models.erro_holmes import ErroHolmes
|
|
# from src.models.estoque_homes import EstoqueHolmes
|
|
# from src.models.proposta import Proposta
|
|
# from src.models.resultado import Resultado
|
|
# from src.repositories.estoque_repository import EstoqueRepository
|
|
# from src.utils.utils import extrair_proposta
|
|
|
|
# class HolmesAPI:
|
|
|
|
# def __init__(self):
|
|
# self.headers = {
|
|
# "authorization": self._token_usuario(),
|
|
# "Content-Type": "application/json"
|
|
# }
|
|
|
|
# def _somente_digitos(self, valor) -> str:
|
|
# return ''.join(c for c in str(valor or '') if c.isdigit())
|
|
|
|
# def _token_usuario(self) -> str:
|
|
# url = "https://app-api.holmesdoc.io/v1/session"
|
|
# body = {"email": os.getenv('HOLMES_USER'), "password": os.getenv('HOLMES_PASS')}
|
|
# headers = {"Content-Type": "application/json", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/151.0.0.0 Safari/537.36"}
|
|
# response = requests.post(url, json=body, headers=headers)
|
|
# response.raise_for_status()
|
|
# dados = response.json()
|
|
# if "token" not in dados:
|
|
# logging.error(
|
|
# f"Login Holmes sem token (HTTP {response.status_code}): {str(dados)[:500]}"
|
|
# )
|
|
# raise RuntimeError("Login Holmes não retornou token")
|
|
|
|
# return dados["token"]
|
|
|
|
# def _build_payload_novos(self, proposta: Proposta) -> dict:
|
|
# start_event = 'StartEvent_1'
|
|
|
|
# campos = [
|
|
# ("e88ea290-8ce4-11f1-9f28-e51e49945850", proposta.empresa_holmes),
|
|
# ("ed2d30f0-8ce4-11f1-9f28-e51e49945850", proposta.tipo_pessoa),
|
|
# ("f2fe24d0-8ce4-11f1-9f28-e51e49945850", proposta.usado_na_troca),
|
|
# ("2aafcff0-8cf4-11f1-9f28-e51e49945850", proposta.forma_pagamento),
|
|
# ("fad87d40-8ce4-11f1-9f28-e51e49945850", proposta.proposta_apollo),
|
|
# ("fdfd63f0-8ce4-11f1-9f28-e51e49945850", proposta.veiculo),
|
|
# ("01109760-8ce5-11f1-9f28-e51e49945850", proposta.chassi),
|
|
# ("04ab7160-8ce5-11f1-9f28-e51e49945850", proposta.des_modelo),
|
|
# ("1b0974c0-8ce5-11f1-9f28-e51e49945850", proposta.valor_proposta),
|
|
# ("23914b40-8ce5-11f1-9f28-e51e49945850", proposta.nome),
|
|
# ("27b419f0-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.cpfcnpj)),
|
|
# ("398ac070-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.celular)),
|
|
# ("3e7bb490-8ce5-11f1-9f28-e51e49945850", proposta.email),
|
|
# ("6873d880-9ccc-11f1-b919-f777409ec14c", proposta.vendedor_holmes),
|
|
# ]
|
|
|
|
# payload = {
|
|
# "workflow": {
|
|
# "start_event": start_event,
|
|
# "property_values": [
|
|
# {"id": prop_id, "value": valor}
|
|
# for prop_id, valor in campos
|
|
# if valor is not None and str(valor).strip() != ''
|
|
# ],
|
|
# "whats": "",
|
|
# "documents": [],
|
|
# "test": False
|
|
# }
|
|
# }
|
|
# logging.debug("Payload proposta %s: %s", proposta.proposta_apollo, payload)
|
|
# return payload
|
|
|
|
# def _build_payload_usados(self, proposta: Proposta) -> dict:
|
|
# start_event = 'StartEvent_1'
|
|
|
|
# campos = [
|
|
# ("e88ea290-8ce4-11f1-9f28-e51e49945850", proposta.empresa_holmes),
|
|
# ("ed2d30f0-8ce4-11f1-9f28-e51e49945850", proposta.tipo_pessoa),
|
|
# ("2aafcff0-8cf4-11f1-9f28-e51e49945850", proposta.forma_pagamento),
|
|
# ("f2fe24d0-8ce4-11f1-9f28-e51e49945850", proposta.usado_na_troca),
|
|
# ("fad87d40-8ce4-11f1-9f28-e51e49945850", proposta.proposta_apollo),
|
|
# ("fdfd63f0-8ce4-11f1-9f28-e51e49945850", proposta.veiculo),
|
|
# ("01109760-8ce5-11f1-9f28-e51e49945850", proposta.chassi),
|
|
# ("04ab7160-8ce5-11f1-9f28-e51e49945850", proposta.des_modelo),
|
|
# ("08b38c20-8ce5-11f1-9f28-e51e49945850", proposta.placa),
|
|
# ("1b0974c0-8ce5-11f1-9f28-e51e49945850", proposta.valor_proposta),
|
|
# ("23914b40-8ce5-11f1-9f28-e51e49945850", proposta.nome),
|
|
# ("27b419f0-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.cpfcnpj)),
|
|
# ("398ac070-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.celular)),
|
|
# ("3e7bb490-8ce5-11f1-9f28-e51e49945850", proposta.email),
|
|
# ("19c78c10-9d92-11f1-ad38-41765eab56e3", proposta.vendedor_holmes),
|
|
# ]
|
|
|
|
# payload = {
|
|
# "workflow": {
|
|
# "start_event": start_event,
|
|
# "property_values": [
|
|
# {"id": prop_id, "value": valor}
|
|
# for prop_id, valor in campos
|
|
# if valor is not None and str(valor).strip() != ''
|
|
# ],
|
|
# "whats": "",
|
|
# "documents": [],
|
|
# "test": False
|
|
# }
|
|
# }
|
|
# logging.debug("Payload proposta %s: %s", proposta.proposta_apollo, payload)
|
|
# return payload
|
|
|
|
# def _build_payload_imobilizado(self, proposta: Proposta) -> dict:
|
|
# start_event = 'StartEvent_1'
|
|
|
|
# campos = [
|
|
# ("e88ea290-8ce4-11f1-9f28-e51e49945850", proposta.empresa_holmes),
|
|
# ("ed2d30f0-8ce4-11f1-9f28-e51e49945850", proposta.tipo_pessoa),
|
|
# ("f2fe24d0-8ce4-11f1-9f28-e51e49945850", proposta.usado_na_troca),
|
|
# ("2aafcff0-8cf4-11f1-9f28-e51e49945850", proposta.forma_pagamento),
|
|
# ("fad87d40-8ce4-11f1-9f28-e51e49945850", proposta.proposta_apollo),
|
|
# ("fdfd63f0-8ce4-11f1-9f28-e51e49945850", proposta.veiculo),
|
|
# ("01109760-8ce5-11f1-9f28-e51e49945850", proposta.chassi),
|
|
# ("04ab7160-8ce5-11f1-9f28-e51e49945850", proposta.des_modelo),
|
|
# ("08b38c20-8ce5-11f1-9f28-e51e49945850", proposta.placa),
|
|
# ("1b0974c0-8ce5-11f1-9f28-e51e49945850", proposta.valor_proposta),
|
|
# ("23914b40-8ce5-11f1-9f28-e51e49945850", proposta.nome),
|
|
# ("27b419f0-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.cpfcnpj)),
|
|
# ("398ac070-8ce5-11f1-9f28-e51e49945850", self._somente_digitos(proposta.celular)),
|
|
# ("3e7bb490-8ce5-11f1-9f28-e51e49945850", proposta.email),
|
|
# ("d1b18d20-9d98-11f1-8298-cb4f6a31d606", proposta.vendedor_holmes),
|
|
# ]
|
|
|
|
# payload = {
|
|
# "workflow": {
|
|
# "start_event": start_event,
|
|
# "property_values": [
|
|
# {"id": prop_id, "value": valor}
|
|
# for prop_id, valor in campos
|
|
# if valor is not None and str(valor).strip() != ''
|
|
# ],
|
|
# "whats": "",
|
|
# "documents": [],
|
|
# "test": False
|
|
# }
|
|
# }
|
|
# logging.debug("Payload proposta %s: %s", proposta.proposta_apollo, payload)
|
|
# return payload
|
|
|
|
# def _build_payload_venda_direta(self, proposta: Proposta) -> dict:
|
|
# # Esse formulario tem IDs proprios (nao reaproveita os dos outros tres),
|
|
# # nao tem Placa e traz a Observacao da proposta.
|
|
# start_event = 'StartEvent_1'
|
|
|
|
# campos = [
|
|
# ("37897690-8d03-11f1-9f28-e51e49945850", proposta.empresa_holmes),
|
|
# ("420c59c0-8d03-11f1-9f28-e51e49945850", proposta.tipo_pessoa),
|
|
# ("46da1900-8d04-11f1-9f28-e51e49945850", proposta.forma_pagamento),
|
|
# ("48ee6f80-8d03-11f1-9f28-e51e49945850", proposta.usado_na_troca),
|
|
# ("53933290-8d03-11f1-9f28-e51e49945850", proposta.proposta_apollo),
|
|
# ("58d81310-8d03-11f1-9f28-e51e49945850", proposta.veiculo),
|
|
# ("5b19c5b0-8d03-11f1-9f28-e51e49945850", proposta.chassi),
|
|
# ("5f92a3a0-8d03-11f1-9f28-e51e49945850", proposta.des_modelo),
|
|
# ("6b95e540-8d03-11f1-9f28-e51e49945850", proposta.valor_proposta),
|
|
# ("73c56290-8d03-11f1-9f28-e51e49945850", proposta.nome),
|
|
# ("79635f90-8d03-11f1-9f28-e51e49945850", self._somente_digitos(proposta.cpfcnpj)),
|
|
# ("85ea9e40-8d03-11f1-9f28-e51e49945850", self._somente_digitos(proposta.celular)),
|
|
# ("8f16f220-8d03-11f1-9f28-e51e49945850", proposta.email),
|
|
# ("cbe61910-a2de-11f1-aff4-4f1f04587741", proposta.vendedor_holmes),
|
|
# ("e7610290-a2de-11f1-aff4-4f1f04587741", proposta.observacao),
|
|
# ]
|
|
|
|
# payload = {
|
|
# "workflow": {
|
|
# "start_event": start_event,
|
|
# "property_values": [
|
|
# {"id": prop_id, "value": valor}
|
|
# for prop_id, valor in campos
|
|
# if valor is not None and str(valor).strip() != ''
|
|
# ],
|
|
# "whats": "",
|
|
# "documents": [],
|
|
# "test": False
|
|
# }
|
|
# }
|
|
# logging.debug("Payload proposta %s: %s", proposta.proposta_apollo, payload)
|
|
# return payload
|
|
|
|
# def existe_holmes(self, chassi: str, proposta: str) -> bool:
|
|
# """Confere se o chassi já está lançado no holmes e caso tenha o mesmo chassi ele bate a proposta
|
|
|
|
# Args:
|
|
# chassi (str): Chassi do veiculo vendido
|
|
# proposta (str): Proposta do veiculo
|
|
|
|
# Returns:
|
|
# bool: True caso existir e False caso não exista no holmes
|
|
# """
|
|
|
|
# logging.info("Verificando se chassi %s (proposta %s) já existe no Holmes", chassi, proposta)
|
|
# url = 'https://app-api.holmesdoc.io/v2/search'
|
|
# body = {
|
|
# "query": {
|
|
# "from": 0,
|
|
# "size": 50,
|
|
# "context": "process",
|
|
# "sort": "updated_at",
|
|
# "order": "desc",
|
|
# "groups": [
|
|
# {
|
|
# "match_all": True,
|
|
# "terms": [
|
|
# {
|
|
# "value": f"{chassi}",
|
|
# "type": "match_phrase",
|
|
# "field": "_content"
|
|
# }
|
|
# ]
|
|
# }
|
|
# ]
|
|
# },
|
|
# "trash": False,
|
|
# "deleted_by_me": False
|
|
# }
|
|
|
|
# resposta = requests.post(url, json=body, headers=self.headers)
|
|
# resposta.raise_for_status()
|
|
# dados = resposta.json()
|
|
|
|
# if dados['total'] == 0:
|
|
# logging.info("Chassi %s não encontrado no Holmes", chassi)
|
|
# return False
|
|
|
|
# docs_validos = [
|
|
# doc for doc in dados['docs']
|
|
# if doc.get('name') == '[FAT] Faturamento de Estoque'
|
|
# and doc.get('status') != 'canceled'
|
|
# ]
|
|
|
|
# if not docs_validos:
|
|
# logging.info("Chassi %s encontrado mas sem processos válidos (todos cancelados ou de outro template)", chassi)
|
|
# return False
|
|
|
|
# proposta_holmes = extrair_proposta(docs_validos[0]['identifier'])
|
|
# if str(proposta_holmes) != str(proposta):
|
|
# logging.info("Chassi %s encontrado mas proposta diferente (Holmes: %s, Apollo: %s)", chassi, proposta_holmes, proposta)
|
|
# return False
|
|
|
|
# logging.info("Chassi %s já existe no Holmes com mesma proposta %s", chassi, proposta)
|
|
# return True
|
|
|
|
# def envia_fat_estoque_usado(self, proposta: Proposta, estoque_repo: EstoqueRepository) -> Resultado:
|
|
# logging.info("Enviando proposta %s para Holmes (empresa=%s, revenda=%s)", proposta.proposta_apollo, proposta.empresa, proposta.revenda)
|
|
# url = 'https://app-api.holmesdoc.io/v1/workflows/6a6cc58744c4ba86a63aebc1/start'
|
|
# payload = self._build_payload_usados(proposta)
|
|
# logging.debug("Payload montado para proposta %s", proposta.proposta_apollo)
|
|
# response = requests.post(url, headers=self.headers, data=json.dumps(payload))
|
|
# logging.debug("Holmes respondeu com status %s para proposta %s", response.status_code, proposta.proposta_apollo)
|
|
|
|
# try:
|
|
# if response.status_code != 200:
|
|
# err_msg = f"Erro ao enviar para Holmes: {response.status_code} - {response.text or ''}"
|
|
# err_msg = (err_msg[:3900] + "...") if len(err_msg) > 3900 else err_msg
|
|
# logging.error("Falha ao enviar proposta %s: %s", proposta.proposta_apollo, err_msg)
|
|
# estoque_repo.insere_erro(
|
|
# ErroHolmes(
|
|
# empresa = proposta.empresa,
|
|
# revenda = proposta.revenda,
|
|
# proposta_apollo = proposta.proposta_apollo,
|
|
# motivo_erro= err_msg
|
|
# )
|
|
# )
|
|
# return Resultado(sucesso=False, mensagem=err_msg)
|
|
|
|
# else:
|
|
# resposta = response.json()
|
|
# logging.info("Proposta %s enviada com sucesso - processo Holmes: %s", proposta.proposta_apollo, resposta['id'])
|
|
# estoque_repo.insere_estoque(
|
|
# EstoqueHolmes(
|
|
# empresa= proposta.empresa,
|
|
# revenda= proposta.revenda,
|
|
# proposta_apollo= proposta.proposta_apollo,
|
|
# proesso_id= resposta['id'],
|
|
# usuario_criou= 'SUPORTE SISTEMAS',
|
|
# nome_processo= '[FAT] Faturamento de Estoque'
|
|
# )
|
|
# )
|
|
# return Resultado(sucesso=True, mensagem=resposta['id'])
|
|
|
|
# except Exception as e:
|
|
# logging.error("Erro inesperado ao processar proposta %s: %s", proposta.proposta_apollo, e, exc_info=True)
|
|
# return Resultado(sucesso=False, mensagem=str(e))
|
|
|
|
# def envia_fat_estoque_novos(self, proposta: Proposta, estoque_repo: EstoqueRepository) -> Resultado:
|
|
# logging.info("Enviando proposta %s para Holmes (empresa=%s, revenda=%s)", proposta.proposta_apollo, proposta.empresa, proposta.revenda)
|
|
# url = 'https://app-api.holmesdoc.io/v1/workflows/6a6cbe67aff519bb6aa4b2d8/start'
|
|
# payload = self._build_payload_novos(proposta)
|
|
# logging.debug("Payload montado para proposta %s", proposta.proposta_apollo)
|
|
# response = requests.post(url, headers=self.headers, data=json.dumps(payload))
|
|
# logging.debug("Holmes respondeu com status %s para proposta %s", response.status_code, proposta.proposta_apollo)
|
|
|
|
# try:
|
|
# if response.status_code != 200:
|
|
# err_msg = f"Erro ao enviar para Holmes: {response.status_code} - {response.text or ''}"
|
|
# err_msg = (err_msg[:3900] + "...") if len(err_msg) > 3900 else err_msg
|
|
# logging.error("Falha ao enviar proposta %s: %s", proposta.proposta_apollo, err_msg)
|
|
# estoque_repo.insere_erro(
|
|
# ErroHolmes(
|
|
# empresa = proposta.empresa,
|
|
# revenda = proposta.revenda,
|
|
# proposta_apollo = proposta.proposta_apollo,
|
|
# motivo_erro= err_msg
|
|
# )
|
|
# )
|
|
# return Resultado(sucesso=False, mensagem=err_msg)
|
|
|
|
# else:
|
|
# resposta = response.json()
|
|
# logging.info("Proposta %s enviada com sucesso - processo Holmes: %s", proposta.proposta_apollo, resposta['id'])
|
|
# estoque_repo.insere_estoque(
|
|
# EstoqueHolmes(
|
|
# empresa= proposta.empresa,
|
|
# revenda= proposta.revenda,
|
|
# proposta_apollo= proposta.proposta_apollo,
|
|
# proesso_id= resposta['id'],
|
|
# usuario_criou= 'SUPORTE SISTEMAS',
|
|
# nome_processo= '[FAT] Faturamento de Estoque'
|
|
# )
|
|
# )
|
|
# return Resultado(sucesso=True, mensagem=resposta['id'])
|
|
|
|
# except Exception as e:
|
|
# logging.error("Erro inesperado ao processar proposta %s: %s", proposta.proposta_apollo, e, exc_info=True)
|
|
# return Resultado(sucesso=False, mensagem=str(e))
|
|
|
|
# def envia_fat_estoque_imobilizado(self, proposta: Proposta, estoque_repo: EstoqueRepository) -> Resultado:
|
|
# logging.info("Enviando proposta %s para Holmes (empresa=%s, revenda=%s)", proposta.proposta_apollo, proposta.empresa, proposta.revenda)
|
|
# url = 'https://app-api.holmesdoc.io/v1/workflows/6a6cc2a3dbf5173588777520/start'
|
|
# payload = self._build_payload_imobilizado(proposta)
|
|
# logging.debug("Payload montado para proposta %s", proposta.proposta_apollo)
|
|
# response = requests.post(url, headers=self.headers, data=json.dumps(payload))
|
|
# logging.debug("Holmes respondeu com status %s para proposta %s", response.status_code, proposta.proposta_apollo)
|
|
|
|
# try:
|
|
# if response.status_code != 200:
|
|
# err_msg = f"Erro ao enviar para Holmes: {response.status_code} - {response.text or ''}"
|
|
# err_msg = (err_msg[:3900] + "...") if len(err_msg) > 3900 else err_msg
|
|
# logging.error("Falha ao enviar proposta %s: %s", proposta.proposta_apollo, err_msg)
|
|
# estoque_repo.insere_erro(
|
|
# ErroHolmes(
|
|
# empresa = proposta.empresa,
|
|
# revenda = proposta.revenda,
|
|
# proposta_apollo = proposta.proposta_apollo,
|
|
# motivo_erro= err_msg
|
|
# )
|
|
# )
|
|
# return Resultado(sucesso=False, mensagem=err_msg)
|
|
|
|
# else:
|
|
# resposta = response.json()
|
|
# logging.info("Proposta %s enviada com sucesso - processo Holmes: %s", proposta.proposta_apollo, resposta['id'])
|
|
# estoque_repo.insere_estoque(
|
|
# EstoqueHolmes(
|
|
# empresa= proposta.empresa,
|
|
# revenda= proposta.revenda,
|
|
# proposta_apollo= proposta.proposta_apollo,
|
|
# proesso_id= resposta['id'],
|
|
# usuario_criou= 'SUPORTE SISTEMAS',
|
|
# nome_processo= '[FAT] Faturamento de Estoque'
|
|
# )
|
|
# )
|
|
# return Resultado(sucesso=True, mensagem=resposta['id'])
|
|
|
|
# except Exception as e:
|
|
# logging.error("Erro inesperado ao processar proposta %s: %s", proposta.proposta_apollo, e, exc_info=True)
|
|
# return Resultado(sucesso=False, mensagem=str(e))
|
|
# def envia_fat_estoque_venda_direta(self, proposta: Proposta, estoque_repo: EstoqueRepository) -> Resultado:
|
|
# logging.info("Enviando proposta %s para Holmes (empresa=%s, revenda=%s)", proposta.proposta_apollo, proposta.empresa, proposta.revenda)
|
|
# url = 'https://app-api.holmesdoc.io/v1/workflows/6a6cd6449341bbc7e45f29cf/start'
|
|
# payload = self._build_payload_venda_direta(proposta)
|
|
# logging.debug("Payload montado para proposta %s", proposta.proposta_apollo)
|
|
# response = requests.post(url, headers=self.headers, data=json.dumps(payload))
|
|
# logging.debug("Holmes respondeu com status %s para proposta %s", response.status_code, proposta.proposta_apollo)
|
|
|
|
# try:
|
|
# if response.status_code != 200:
|
|
# err_msg = f"Erro ao enviar para Holmes: {response.status_code} - {response.text or ''}"
|
|
# err_msg = (err_msg[:3900] + "...") if len(err_msg) > 3900 else err_msg
|
|
# logging.error("Falha ao enviar proposta %s: %s", proposta.proposta_apollo, err_msg)
|
|
# estoque_repo.insere_erro(
|
|
# ErroHolmes(
|
|
# empresa = proposta.empresa,
|
|
# revenda = proposta.revenda,
|
|
# proposta_apollo = proposta.proposta_apollo,
|
|
# motivo_erro= err_msg
|
|
# )
|
|
# )
|
|
# return Resultado(sucesso=False, mensagem=err_msg)
|
|
|
|
# else:
|
|
# resposta = response.json()
|
|
# logging.info("Proposta %s enviada com sucesso - processo Holmes: %s", proposta.proposta_apollo, resposta['id'])
|
|
# estoque_repo.insere_estoque(
|
|
# EstoqueHolmes(
|
|
# empresa= proposta.empresa,
|
|
# revenda= proposta.revenda,
|
|
# proposta_apollo= proposta.proposta_apollo,
|
|
# proesso_id= resposta['id'],
|
|
# usuario_criou= 'SUPORTE SISTEMAS',
|
|
# nome_processo= '[FAT] Faturamento de Estoque'
|
|
# )
|
|
# )
|
|
# return Resultado(sucesso=True, mensagem=resposta['id'])
|
|
|
|
# except Exception as e:
|
|
# logging.error("Erro inesperado ao processar proposta %s: %s", proposta.proposta_apollo, e, exc_info=True)
|
|
# return Resultado(sucesso=False, mensagem=str(e))
|