G-Scripts/extranet_notas_debito.py
daniel.rodrigues cdd4045970 att
2025-10-31 10:39:43 -03:00

179 lines
6.9 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import os
import requests
import pyodbc
from datetime import datetime, timedelta
OUTPUT_DIR_BASE = r"\\10.77.77.11\Contabilidade\AUTOMAÇÃO\NotadeDebito"
DB_CONN = (
"Driver={ODBC Driver 17 for SQL Server};"
"Server=10.77.77.10;"
"Database=GINSENG;"
"UID=andrey;"
"PWD=88253332Wa@;"
)
# 1⃣ Token
def get_token():
print("🔐 Obtendo token...")
r = requests.get("https://api.grupoginseng.com.br/api/tokens")
r.raise_for_status()
token = r.json()["data"][0]["token"]
print("✅ Token obtido com sucesso.")
return token
# 2⃣ Última data sincronizada
def get_last_invoice_date(cursor):
cursor.execute("SELECT MAX(invoiceDate) FROM dbo.DebitNotes WHERE invoiceDate IS NOT NULL")
result = cursor.fetchone()[0]
if result:
print(f"🕓 Última data sincronizada: {result}")
return result
else:
default = datetime.now() - timedelta(days=5)
print(f"⚙️ Nenhuma data encontrada, buscando últimos 30 dias ({default.date()})")
return default
# 3⃣ Busca com paginação
def get_all_documents(token):
print("📡 Consultando notas fiscais (paginado)...")
url_base = "https://sf-fiscal-api.grupoboticario.digital/v1/debit-notes/documents-list"
headers = {
"accept": "application/json, text/plain, */*",
"authorization": token,
"content-type": "application/json",
}
payload = {
"franchiseId": [
"4494", "12522", "12817", "12818", "12820", "12823", "12824", "12826", "12828", "12829",
"12830", "12838", "13427", "14617", "14668", "19103", "20005", "20006", "20009", "20056",
"20057", "20441", "20683", "20712", "20858", "20968", "20969", "20970", "20979", "20986",
"20988", "20989", "20991", "20992", "20993", "20994", "20995", "20996", "20997", "20998",
"20999", "21000", "21001", "21007", "21068", "21277", "21278", "21296", "21375", "21381",
"21383", "21495", "21624", "21647", "21737", "21738", "21739", "21740", "22448", "22475",
"22501", "22526", "22532", "22533", "22541", "22593", "22632", "23156", "23475", "23665",
"23701", "23702", "23703", "23704", "23705", "23706", "23707", "23708", "23709", "23711",
"23712", "23713", "3546", "4560", "5699", "910173", "910291", "911486", "911487", "911488",
"911489", "911490", "911491", "911492", "911509", "911510", "911511", "911512", "911513",
"911514", "911515", "911516", "911517", "911518", "911519", "911762", "911766", "911924",
"911940", "912242", "912273", "912856", "912857", "912858", "912859"
]
}
skip, take = 0, 2000
all_docs = []
while True:
url = f"{url_base}?cpId=10269&skip={skip}&take={take}"
print(f"➡️ Página {skip // take + 1} — buscando registros {skip}{skip + take}...")
r = requests.post(url, headers=headers, json=payload)
if r.status_code != 200:
print(f"❌ Erro {r.status_code}: {r.text}")
break
docs = r.json().get("documentsList", [])
if not docs:
print("✅ Nenhum novo documento encontrado.")
break
all_docs.extend(docs)
print(f"📦 Recebidos {len(docs)} registros (total: {len(all_docs)})")
if len(docs) < take:
break
skip += take
return all_docs
# 4⃣ Filtro local por data
def filter_documents_by_date(documents, start_date, end_date):
filtrados = []
for doc in documents:
try:
inv_date = datetime.strptime(doc.get("invoiceDate", ""), "%Y-%m-%d")
if start_date.date() <= inv_date.date() <= end_date.date():
filtrados.append(doc)
except Exception:
continue
print(f"📅 {len(filtrados)} documentos dentro do intervalo {start_date}{end_date}")
return filtrados
# 5⃣ Inserção e download
def record_exists(cursor, doc_id):
cursor.execute("SELECT 1 FROM dbo.DebitNotes WHERE id = ?", doc_id)
return cursor.fetchone() is not None
def insert_record(cursor, doc):
cursor.execute("""
INSERT INTO dbo.DebitNotes (
id, debitNoteOrigin, cnpj, cpId, franchiseId, debitNoteNumber,
invoiceNumber, invoiceItem, invoiceDate, invoiceDueDate, value,
serviceDescription, imageId, notificationRead, notificationReadDate,
acknowledged, acknowledgedDate, UUID, imageName, uploadedFile
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (
doc.get("id"),
doc.get("debitNoteOrigin") or "N/D",
doc.get("cnpj") or "",
doc.get("cpId"),
doc.get("franchiseId"),
doc.get("debitNoteNumber") or "",
doc.get("invoiceNumber") or "",
doc.get("invoiceItem") or "",
doc.get("invoiceDate"),
doc.get("invoiceDueDate"),
doc.get("value") or 0,
doc.get("serviceDescription") or "",
doc.get("imageId"),
1 if doc.get("notificationRead") else 0,
doc.get("notificationReadDate"),
1 if doc.get("acknowledged") else 0,
doc.get("acknowledgedDate"),
doc.get("UUID"),
doc.get("imageName"),
1 if doc.get("uploadedFile") else 0
))
def download_pdf(token, franchise_id, doc_id, image_name, invoice_date):
try:
url = f"https://sf-fiscal-api.grupoboticario.digital/v1/handle-images/NDEB/{franchise_id}/{doc_id}/{image_name}/download"
r = requests.get(url, headers={"authorization": token})
r.raise_for_status()
s3_url = r.text.strip()
pasta = os.path.join(OUTPUT_DIR_BASE, str(invoice_date))
os.makedirs(pasta, exist_ok=True)
file_path = os.path.join(pasta, image_name)
pdf = requests.get(s3_url, stream=True)
if pdf.status_code == 200:
with open(file_path, "wb") as f:
for chunk in pdf.iter_content(8192):
f.write(chunk)
print(f"📥 PDF salvo: {file_path}")
except Exception as e:
print(f"❌ Erro ao baixar {image_name}: {e}")
# 🚀 Main
def main():
token = get_token()
conn = pyodbc.connect(DB_CONN)
cursor = conn.cursor()
# Filtrar apenas notas do dia 29-10-2025
data_especifica = datetime(2025, 10, 29)
todos = get_all_documents(token)
documentos = filter_documents_by_date(todos, data_especifica, data_especifica)
novos, ignorados = 0, 0
for doc in documentos:
if record_exists(cursor, doc["id"]):
ignorados += 1
continue
insert_record(cursor, doc)
novos += 1
download_pdf(token, doc["franchiseId"], doc["id"], doc["imageName"], doc["invoiceDate"])
conn.commit()
conn.close()
print(f"\n✅ Finalizado. {novos} novos registros, {ignorados} já existiam.")
print(f"🕓 Execução concluída em {datetime.now().strftime('%H:%M:%S')}")
if __name__ == "__main__":
main()