This commit is contained in:
Cunha 2026-06-23 16:25:55 -03:00
parent 230654836b
commit cdf5aad1c8
8 changed files with 20056 additions and 1206 deletions

10213
.vscode/.advpl/_binary_class.prw vendored Normal file

File diff suppressed because it is too large Load Diff

9808
.vscode/.advpl/_binary_functions.prw vendored Normal file

File diff suppressed because it is too large Load Diff

20
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,20 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "totvs_language_debug",
"request": "launch",
"name": "TOTVS Language Debug",
"program": "${command:AskForProgramName}",
"cwb": "${workspaceFolder}",
"smartclientBin": "../totvs/bin/smartclient/smartclient.exe",
"isMultiSession": true,
"enableTableSync": true,
"extendFeatures": {
"charDetails": false
}
}
],
"lastProgramExecuted": "<cancel>",
"lastProgramArguments": []
}

4
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"totvsLanguageServer.welcomePage": false,
"totvsLanguageServer.editor.linter.includes": "C:\\25-04-14-P12-SMARTCLIENT_BUILD 20.3.2.12_WINDOWS_X64\\include"
}

Binary file not shown.

View File

@ -1,152 +0,0 @@
"""
Backfill de paymentType para todos os Numero_Pedido em Grgb_vendas_report
que ainda não constam em Grgb_installment_paytype.
Pode ser interrompido e re-executado a qualquer momento retoma de onde parou.
"""
import re
import time
import requests
from typing import Optional
from installments_reader import Auth, get_installments_page
# ─── CONFIG ───────────────────────────────────────────────────────────────────
SQL_CONN = (
"DRIVER={ODBC Driver 17 for SQL Server};"
"SERVER=10.77.77.10;"
"DATABASE=GINSENG;"
"UID=andrey;"
"PWD=88253332;"
"TrustServerCertificate=yes;"
)
INSTALLMENT_GROUP_COL = "Numero_Pedido"
RATE_LIMIT_S = 1.5
PRINT_EVERY = 1
# ──────────────────────────────────────────────────────────────────────────────
def _conn_str() -> str:
s = SQL_CONN.rstrip(";")
if not re.search(r"(?i)\bEncrypt\b", s):
s += ";Encrypt=no"
return s + ";"
def _ensure_paytype_table(cur) -> None:
cur.execute("""
IF OBJECT_ID('dbo.Grgb_installment_paytype', 'U') IS NULL
BEGIN
CREATE TABLE dbo.Grgb_installment_paytype (
InstallmentGroupCode VARCHAR(50) NOT NULL PRIMARY KEY,
PaymentType VARCHAR(80) NULL,
ConsultadoEm DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME()
)
END
""")
def _load_pending(cur) -> list[str]:
cur.execute(f"""
SELECT DISTINCT [{INSTALLMENT_GROUP_COL}]
FROM dbo.Grgb_vendas_report
WHERE [{INSTALLMENT_GROUP_COL}] IS NOT NULL
AND [{INSTALLMENT_GROUP_COL}] <> ''
AND [{INSTALLMENT_GROUP_COL}] NOT IN (
SELECT InstallmentGroupCode FROM dbo.Grgb_installment_paytype
)
ORDER BY [{INSTALLMENT_GROUP_COL}]
""")
return [str(r[0]) for r in cur.fetchall()]
def _query_payment_type(
session: requests.Session,
auth: Auth,
group_code: str,
) -> Optional[str]:
"""Usa get_installments_page do installments_reader (headers + retry corretos)."""
try:
body = get_installments_page(
session=session,
auth=auth,
start_date=None,
end_date=None,
installment_change=None,
mediator_code=None,
page=1,
installment_group_code=group_code,
)
installments = body.get("data", {}).get("installments") or []
if installments:
return str(installments[0].get("paymentType") or "")
except Exception as exc:
print(f"[erro] groupCode={group_code}: {exc}")
return None
def _save(cur, group_code: str, payment_type: Optional[str]) -> None:
cur.execute(
"INSERT INTO dbo.Grgb_installment_paytype (InstallmentGroupCode, PaymentType) "
"VALUES (?, ?)",
group_code, payment_type,
)
def main() -> None:
import pyodbc
conn_str = _conn_str()
cn = pyodbc.connect(conn_str, timeout=60)
cn.autocommit = False
cur = cn.cursor()
_ensure_paytype_table(cur)
cn.commit()
pending = _load_pending(cur)
cur.close(); cn.close()
total = len(pending)
print(f"[backfill] {total} pedidos pendentes de paymentType")
if not total:
print("[backfill] nada a fazer.")
return
session = requests.Session()
session.trust_env = False
auth = Auth(session)
ok = erros = 0
for i, group_code in enumerate(pending, 1):
payment_type = _query_payment_type(session, auth, group_code)
cn = pyodbc.connect(conn_str, timeout=60)
cn.autocommit = False
cur = cn.cursor()
try:
_save(cur, group_code, payment_type)
cn.commit()
ok += 1
except Exception as exc:
cn.rollback()
print(f"[erro] sql groupCode={group_code}: {exc}")
erros += 1
finally:
cur.close(); cn.close()
if i % PRINT_EVERY == 0 or i == total:
pct = i / total * 100
print(
f"[backfill] {i}/{total} ({pct:.1f}%)"
f" ok={ok} erros={erros}"
f" ultimo={group_code} paymentType={payment_type}"
)
time.sleep(RATE_LIMIT_S)
print(f"\n[backfill] concluido: {ok} gravados, {erros} erros")
if __name__ == "__main__":
main()

View File

@ -43,9 +43,9 @@ ALL_MEDIATOR_CODES = [
"24293", "24447", "24451", "24457", "24458", "4494",
]
INCREMENTAL = True # True = modo diário incremental
START_DATE = "2026-01-01" # usado apenas se INCREMENTAL = False
END_DATE = "2026-01-31" # usado apenas se INCREMENTAL = False
INCREMENTAL = True # True = modo diário incremental
START_DATE = "2025-12-01" # usado apenas se INCREMENTAL = False
END_DATE = "2026-06-22" # usado apenas se INCREMENTAL = False
INCREMENTAL_DEFAULT_START = "2026-01-01" # data inicial no primeiro run incremental
DATA_TYPE = "VENDAS"
@ -58,7 +58,7 @@ _SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
WATERMARK_FILE = os.path.join(_SCRIPT_DIR, "vendas_watermark.json")
IMPORT_BATCH_SIZE = 500 # linhas por lote no SQL Server
ENRICH_PAYMENT_TYPES = True # True = consulta API de parcelas para preencher paymentType
ENRICH_PAYMENT_TYPES = False # True = consulta API de parcelas para preencher paymentType
# Nome da coluna em Grgb_vendas_report que contém o installmentGroupCode.
# Verifique rodando: SELECT TOP 1 * FROM dbo.Grgb_vendas_report
INSTALLMENT_GROUP_COL = "Numero_Pedido"
@ -621,11 +621,13 @@ def _build_chunks(start_date: str, end_date: str) -> list[tuple[str, str]]:
def main() -> None:
start_date, end_date = _resolve_date_range()
if not start_date:
print("[info] dados já estão atualizados até ontem, nada a importar.")
return
if INCREMENTAL:
start_date, end_date = _resolve_date_range()
if not start_date:
print("[info] dados já estão atualizados até ontem, nada a importar.")
return
else:
start_date, end_date = START_DATE, END_DATE
print(f"[info] período a importar: {start_date} .. {end_date}")

File diff suppressed because it is too large Load Diff