feat: empaquetado .exe con instalador y fix conexion SCAII

- launcher.py reescrito para PyInstaller (Voila in-process, kernel router)
- build_exe.bat: script PyInstaller (onedir + collect-all dependencias Jupyter)
- build_installer.bat + installer.iss: instalador Inno Setup
- schema_registro_sqlite.sql: schema DataStage en SQLite
- _make_conn_str ahora respeta SCAII_TRUSTED (Windows Auth)
- .env.example: quitar variables DB_* (Postgres ya no usado por DataStage)
- requirements.txt: quitar psycopg2-binary

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-22 15:57:25 -05:00
parent a65f34d852
commit 71ef0b390a
8 changed files with 20935 additions and 4787 deletions

View File

@@ -1,12 +1,8 @@
# Copia este archivo como .env y completa los valores reales.
# NO subas el .env al repositorio (esta en .gitignore).
# Configuracion de conexion a PostgreSQL (DataStage)
DB_HOST=localhost
DB_PORT=5432
DB_NAME=dbSat
DB_USER=servicemanager
DB_PASSWORD=cambia_esto
# DataStage corre embebido en SQLite (archivo datastage.db junto al .exe).
# No requiere configuracion. Para cambiar la ruta usa: DATASTAGE_DB=ruta\completa\datastage.db
# Configuracion de conexion a SQL Server (SCAII)
# SCAII_TRUSTED=yes -> usa Windows Authentication (ignora SCAII_USER/PASSWORD)

File diff suppressed because it is too large Load Diff

131
app/build_exe.bat Executable file
View File

@@ -0,0 +1,131 @@
@echo off
REM ============================================================
REM Build .exe de Utilerias RECON 2 con PyInstaller (modo onedir)
REM Usa un conda env limpio para empaquetado reproducible.
REM ============================================================
setlocal
cd /d "%~dp0"
set ENV_NAME=utilerias-recon-build
set PY_VERSION=3.11
REM ------------------------------------------------------------
REM 1) Verificar conda
REM ------------------------------------------------------------
where conda >nul 2>nul
if errorlevel 1 (
echo [ERROR] Conda no esta en PATH. Abre "Anaconda Prompt" y vuelve a ejecutar.
goto :end
)
REM ------------------------------------------------------------
REM 2) Crear env si no existe
REM ------------------------------------------------------------
call conda env list | findstr /B "%ENV_NAME% " >nul
if errorlevel 1 (
echo [INFO] Creando env conda "%ENV_NAME%" con Python %PY_VERSION%...
call conda create -y -n %ENV_NAME% python=%PY_VERSION%
if errorlevel 1 (
echo [ERROR] No se pudo crear el env.
goto :end
)
)
REM ------------------------------------------------------------
REM 3) Activar env e instalar dependencias
REM ------------------------------------------------------------
call conda activate %ENV_NAME%
if errorlevel 1 (
echo [ERROR] No se pudo activar el env.
goto :end
)
echo [INFO] Instalando dependencias...
call pip install --upgrade pip
call pip install -r requirements.txt
if errorlevel 1 (
echo [ERROR] Fallo la instalacion de dependencias.
goto :end
)
REM ------------------------------------------------------------
REM 4) Limpiar builds previos
REM ------------------------------------------------------------
if exist build rmdir /s /q build
if exist dist rmdir /s /q dist
if exist UtileriasReconV2.spec del /q UtileriasReconV2.spec
REM ------------------------------------------------------------
REM 5) Ejecutar PyInstaller (onedir, noconsole)
REM ------------------------------------------------------------
echo [INFO] Construyendo .exe (esto tarda 3-8 minutos)...
pyinstaller launcher.py ^
--name UtileriasReconV2 ^
--onedir ^
--noconsole ^
--noconfirm ^
--collect-all voila ^
--collect-all jupyter_server ^
--collect-all jupyter_client ^
--collect-all jupyter_core ^
--collect-all nbformat ^
--collect-all nbconvert ^
--collect-all ipykernel ^
--collect-all ipywidgets ^
--collect-all jupyterlab_pygments ^
--collect-all notebook ^
--collect-all rfc3987_syntax ^
--collect-all jsonschema_specifications ^
--collect-all jsonschema ^
--collect-all jupyter_events ^
--collect-all nbclient ^
--collect-all terminado ^
--collect-all debugpy ^
--collect-all matplotlib_inline ^
--collect-all matplotlib ^
--collect-all dotenv ^
--collect-all sklearn ^
--collect-all scipy ^
--collect-all pandas ^
--collect-all numpy ^
--collect-all sqlalchemy ^
--collect-all openpyxl ^
--hidden-import pyodbc ^
--hidden-import sqlalchemy.dialects.sqlite ^
--hidden-import sqlalchemy.dialects.mssql ^
--hidden-import sklearn.utils._typedefs ^
--hidden-import sklearn.neighbors._partition_nodes
if errorlevel 1 (
echo.
echo [ERROR] PyInstaller fallo. Revisa el log arriba.
goto :end
)
REM ------------------------------------------------------------
REM 6) Copiar app.ipynb y .env.example al lado del .exe
REM ------------------------------------------------------------
copy /Y app.ipynb dist\UtileriasReconV2\app.ipynb >nul
echo [INFO] app.ipynb copiado a dist\UtileriasReconV2\
if exist ..\.env.example (
copy /Y ..\.env.example dist\UtileriasReconV2\.env.example >nul
echo [INFO] .env.example copiado a dist\UtileriasReconV2\
)
echo.
echo ============================================================
echo BUILD EXITOSO (--onedir)
echo Carpeta lista: dist\UtileriasReconV2\
echo Ejecutable: dist\UtileriasReconV2\UtileriasReconV2.exe
echo.
echo Siguiente paso: empaquetar como instalador con Inno Setup
echo .\build_installer.bat
echo ============================================================
:end
echo.
pause
endlocal

72
app/build_installer.bat Executable file
View File

@@ -0,0 +1,72 @@
@echo off
REM ============================================================
REM Build completo: PyInstaller (onedir) + Inno Setup
REM Genera installer_output\UtileriasReconV2_Setup_X.X.X.exe
REM ============================================================
setlocal
cd /d "%~dp0"
REM ------------------------------------------------------------
REM 1) Localizar el compilador de Inno Setup (ISCC.exe)
REM ------------------------------------------------------------
set "ISCC="
if exist "%ProgramFiles(x86)%\Inno Setup 6\ISCC.exe" set "ISCC=%ProgramFiles(x86)%\Inno Setup 6\ISCC.exe"
if exist "%ProgramFiles%\Inno Setup 6\ISCC.exe" set "ISCC=%ProgramFiles%\Inno Setup 6\ISCC.exe"
if "%ISCC%"=="" (
echo [ERROR] No se encontro Inno Setup 6.
echo Descargalo de: https://jrsoftware.org/isdl.php
echo Instala la version "Stable Release", luego vuelve a ejecutar este script.
goto :end
)
echo [INFO] Inno Setup encontrado en: %ISCC%
REM ------------------------------------------------------------
REM 2) Construir el .exe con PyInstaller (onedir)
REM ------------------------------------------------------------
echo.
echo [INFO] Paso 1/2: PyInstaller...
call build_exe.bat
if errorlevel 1 (
echo [ERROR] PyInstaller fallo. Revisa el log arriba.
goto :end
)
if not exist "dist\UtileriasReconV2\UtileriasReconV2.exe" (
echo [ERROR] No se genero dist\UtileriasReconV2\UtileriasReconV2.exe
goto :end
)
REM ------------------------------------------------------------
REM 3) Limpiar build previo del instalador
REM ------------------------------------------------------------
if exist installer_output rmdir /s /q installer_output
REM ------------------------------------------------------------
REM 4) Compilar el instalador
REM ------------------------------------------------------------
echo.
echo [INFO] Paso 2/2: Inno Setup...
"%ISCC%" installer.iss
if errorlevel 1 (
echo [ERROR] Inno Setup fallo.
goto :end
)
echo.
echo ============================================================
echo INSTALADOR LISTO
echo Archivo: installer_output\UtileriasReconV2_Setup_1.0.0.exe
echo.
echo Distribuye SOLO ese .exe. El usuario:
echo 1. Ejecuta el instalador (1 vez, ~30 seg)
echo 2. Edita .env desde el menu Inicio (acceso directo)
echo 3. Doble clic en el icono del escritorio
echo 4. La app arranca en ~3 seg (sin re-extraer)
echo ============================================================
:end
echo.
pause
endlocal

67
app/installer.iss Executable file
View File

@@ -0,0 +1,67 @@
; ============================================================
; Instalador de Utilerias RECON 2
; Empaqueta dist\UtileriasReconV2\ en un instalador .exe unico.
; Requiere Inno Setup 6+: https://jrsoftware.org/isdl.php
; ============================================================
#define MyAppName "Utilerias RECON 2"
#define MyAppVersion "1.0.0"
#define MyAppPublisher "Tecma / CurtManufacturing"
#define MyAppExeName "UtileriasReconV2.exe"
[Setup]
AppId={{B3F1A7A8-4D2E-4A6B-9C5A-2C0D1F8E9A11}
AppName={#MyAppName}
AppVersion={#MyAppVersion}
AppPublisher={#MyAppPublisher}
DefaultDirName={autopf}\UtileriasReconV2
DefaultGroupName={#MyAppName}
DisableProgramGroupPage=yes
OutputDir=installer_output
OutputBaseFilename=UtileriasReconV2_Setup_{#MyAppVersion}
Compression=lzma2/ultra64
SolidCompression=yes
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
PrivilegesRequired=lowest
PrivilegesRequiredOverridesAllowed=dialog
WizardStyle=modern
UninstallDisplayIcon={app}\{#MyAppExeName}
[Languages]
Name: "spanish"; MessagesFile: "compiler:Languages\Spanish.isl"
[Tasks]
Name: "desktopicon"; Description: "Crear acceso directo en el escritorio"; GroupDescription: "Iconos adicionales:"
[Files]
; Empaqueta TODA la carpeta dist\UtileriasReconV2\ generada por PyInstaller.
; Excluimos *.map (source maps de JS, solo para debug del browser, no se usan)
; porque tienen nombres absurdamente largos y rompen la compresion.
Source: "dist\UtileriasReconV2\*"; DestDir: "{app}"; Excludes: "*.map"; Flags: ignoreversion recursesubdirs createallsubdirs
; Plantilla .env (el usuario la copia como .env y edita)
Source: "..\.env.example"; DestDir: "{app}"; Flags: ignoreversion
[Icons]
Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
Name: "{group}\Editar configuracion (.env)"; Filename: "notepad.exe"; Parameters: """{app}\.env"""
Name: "{group}\Desinstalar {#MyAppName}"; Filename: "{uninstallexe}"
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
[Run]
Filename: "{app}\{#MyAppExeName}"; Description: "Ejecutar {#MyAppName} ahora"; Flags: nowait postinstall skipifsilent
[Code]
// Si no existe .env, copia .env.example como .env tras instalar
procedure CurStepChanged(CurStep: TSetupStep);
var
EnvFile, EnvExample: string;
begin
if CurStep = ssPostInstall then
begin
EnvFile := ExpandConstant('{app}\.env');
EnvExample := ExpandConstant('{app}\.env.example');
if (not FileExists(EnvFile)) and FileExists(EnvExample) then
CopyFile(EnvExample, EnvFile, False);
end;
end;

View File

@@ -1,10 +1,9 @@
"""
Launcher de la app GENPACT V2.
Launcher de la app GENPACT V2 - Utilerias RECON 2.
Arranca un servidor Voila local en background y abre el browser apuntando al app.ipynb.
Cuando se cierra la consola, el servidor de Voila se mata.
Funciona tanto desde Python directo como empaquetado con PyInstaller.
Arranca Voila in-process (sin subprocess) para que funcione empaquetado con
PyInstaller. Si el .exe es invocado como kernel de IPython, enruta al
ipykernel_launcher en vez de relanzar Voila (evita el bucle infinito).
"""
import os
import sys
@@ -12,36 +11,113 @@ import time
import socket
import threading
import webbrowser
import subprocess
from pathlib import Path
# ------------------------------------------------------------------
# Localizar app.ipynb y .env
# ------------------------------------------------------------------
def base_dir() -> Path:
"""Carpeta donde estan los recursos de la app.
- En modo PyInstaller (--onedir), sys._MEIPASS apunta a la carpeta temporal.
- En modo dev, es la carpeta del script.
"""
# ============================================================
# Diagnostico: escribir log al disco apenas arranque el launcher.
# Si este archivo no aparece, el problema es PyInstaller / antivirus
# bloqueando la extraccion antes de que Python siquiera empiece.
# ============================================================
def _diag_log(msg):
try:
log_path = os.path.join(os.path.expanduser('~'), 'utilerias_recon_boot.log')
with open(log_path, 'a', encoding='utf-8') as f:
f.write(f'{time.strftime("%Y-%m-%d %H:%M:%S")} | {msg}\n')
except Exception:
pass
_diag_log(f'=== LAUNCHER START ===')
_diag_log(f'sys.executable={sys.executable}')
_diag_log(f'sys.argv={sys.argv}')
_diag_log(f'cwd={os.getcwd()}')
_diag_log(f'frozen={getattr(sys, "frozen", False)}')
try:
if sys.stdout is not None:
print(f'[boot] launcher iniciando, sys.executable={sys.executable}', flush=True)
print(f'[boot] argv={sys.argv}', flush=True)
print(f'[boot] cwd={os.getcwd()}', flush=True)
except Exception:
pass
# ============================================================
# Cargar .env ANTES de cualquier cosa para que las variables
# queden en os.environ y se hereden a Voila + kernels subprocess.
# (En --onefile el cwd del kernel apunta al temp de PyInstaller,
# no a la carpeta del .exe, asi que load_dotenv relativo falla.)
# ============================================================
def _exe_dir() -> Path:
if getattr(sys, 'frozen', False):
return Path(sys.executable).parent
return Path(__file__).resolve().parent
_env_file = _exe_dir() / '.env'
if _env_file.exists():
try:
from dotenv import load_dotenv
load_dotenv(_env_file, override=True)
except ImportError:
pass
# ============================================================
# Router de modo: detectar invocacion como kernel de Jupyter
# jupyter_client spawnea: sys.executable -m ipykernel_launcher -f conn.json
# En el .exe eso seria: UtileriasReconV2.exe -m ipykernel_launcher -f conn.json
# ============================================================
if 'ipykernel_launcher' in sys.argv:
# En modo empaquetado, sys.stdout/stderr heredados del padre (Voila)
# pueden ser invalidos para flush() y romper ipykernel.init_io.
# ipykernel los reemplaza por canales ZMQ despues, asi que devnull es seguro.
if getattr(sys, 'frozen', False):
try:
_devnull = open(os.devnull, 'w')
sys.stdout = _devnull
sys.stderr = _devnull
except Exception:
pass
sys.argv = [a for a in sys.argv if a not in ('-m', 'ipykernel_launcher')]
from ipykernel import kernelapp
kernelapp.launch_new_instance()
sys.exit(0)
# ============================================================
# Localizar app.ipynb y .env
# ============================================================
def resources_dir() -> Path:
"""Recursos embebidos (app.ipynb bundleado). En PyInstaller usa _MEIPASS."""
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
return Path(sys._MEIPASS)
return Path(sys.executable).parent if getattr(sys, 'frozen', False) \
else Path(__file__).resolve().parent
def user_dir() -> Path:
"""Archivos del usuario (.env). Siempre al lado del .exe."""
if getattr(sys, 'frozen', False):
# PyInstaller --onedir: los datos quedan al lado del .exe
return Path(sys.executable).parent
return Path(__file__).resolve().parent
BASE = base_dir()
APP_NB = BASE / 'app.ipynb'
RES = resources_dir()
USR = user_dir()
# Si el .env esta un nivel arriba (proyecto), copialo o setea el cwd
if not (BASE / '.env').exists() and (BASE.parent / '.env').exists():
os.chdir(BASE.parent)
# Buscar app.ipynb: primero al lado del .exe (override), luego en recursos
APP_NB = USR / 'app.ipynb'
if not APP_NB.exists():
APP_NB = RES / 'app.ipynb'
# cwd donde este el .env (para que python-dotenv lo encuentre)
if (USR / '.env').exists():
os.chdir(USR)
elif (USR.parent / '.env').exists():
os.chdir(USR.parent)
else:
os.chdir(BASE)
os.chdir(USR)
# ------------------------------------------------------------------
# Buscar puerto libre
# ------------------------------------------------------------------
def find_free_port(preferido: int = 8866) -> int:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
@@ -50,7 +126,6 @@ def find_free_port(preferido: int = 8866) -> int:
return preferido
except OSError:
sock.close()
# Si el preferido esta ocupado, deja que el SO asigne uno
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind(('127.0.0.1', 0))
p = s.getsockname()[1]
@@ -58,63 +133,66 @@ def find_free_port(preferido: int = 8866) -> int:
return p
# ------------------------------------------------------------------
# Arrancar Voila
# ------------------------------------------------------------------
def main():
if not APP_NB.exists():
print(f'ERROR: no se encuentra {APP_NB}')
def fatal(msg: str):
"""Muestra error y sale. Si no hay consola, usa MessageBox de Windows."""
try:
if sys.stdout is not None:
print(f'ERROR: {msg}')
except Exception:
pass
try:
import tkinter
from tkinter import messagebox
root = tkinter.Tk()
root.withdraw()
messagebox.showerror('Utilerias RECON 2', msg)
except Exception:
pass
sys.exit(1)
def main():
if not APP_NB.exists():
fatal(f'No se encuentra app.ipynb en {APP_NB}')
port = find_free_port(8866)
# Cuando Voila apunta a un notebook especifico, lo sirve en la raiz "/"
url = f'http://127.0.0.1:{port}/'
if sys.stdout is not None:
print('=' * 60)
print(' GENPACT V2 - Sistema de Descargas SCAII')
print('=' * 60)
print(f' Iniciando servidor Voila en puerto {port}...')
print(f' URL: {url}')
print(' Cierra esta ventana para detener la app.')
print('=' * 60)
# Construir comando de Voila
if getattr(sys, 'frozen', False):
# En modo empaquetado, llamamos al binario de python integrado
cmd = [sys.executable, '-m', 'voila',
str(APP_NB),
f'--port={port}',
'--no-browser',
'--Voila.ip=127.0.0.1',
'--strip_sources=True']
else:
cmd = [sys.executable, '-m', 'voila',
str(APP_NB),
f'--port={port}',
'--no-browser',
'--Voila.ip=127.0.0.1',
'--strip_sources=True']
# Lanzar proceso
proc = subprocess.Popen(cmd, stdout=sys.stdout, stderr=sys.stderr)
# Abrir browser cuando el server este listo
# Abrir browser cuando Voila acepte conexiones
def _open():
for _ in range(60):
for _ in range(120):
try:
with socket.create_connection(('127.0.0.1', port), timeout=0.5):
break
except OSError:
time.sleep(0.5)
webbrowser.open(url)
threading.Thread(target=_open, daemon=True).start()
# Lanzar Voila in-process (sin subprocess)
sys.argv = [
'voila',
str(APP_NB),
f'--port={port}',
'--no-browser',
'--Voila.ip=127.0.0.1',
'--strip_sources=True',
]
try:
proc.wait()
except KeyboardInterrupt:
print('\nDeteniendo Voila...')
proc.terminate()
from voila.app import Voila
Voila.launch_instance()
except SystemExit:
pass
except Exception as e:
fatal(f'Voila fallo al iniciar: {e}')
if __name__ == '__main__':

View File

@@ -11,5 +11,4 @@ jupyter_server>=2.0
notebook>=7.0
scikit-learn>=1.3
pyinstaller>=6.0
psycopg2-binary>=2.9
sqlalchemy>=2.0

384
app/schema_registro_sqlite.sql Executable file
View File

@@ -0,0 +1,384 @@
CREATE TABLE IF NOT EXISTS "Registro501" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"TipoOperacion" TEXT,
"ClaveDocumento" TEXT,
"SeccionAduaneraEntrada" TEXT,
"CurpContribuyente" TEXT,
"Rfc" TEXT,
"CurpAgenteA" TEXT,
"TipoCambio" NUMERIC,
"TotalFletes" NUMERIC,
"TotalSeguros" NUMERIC,
"TotalEmbalajes" NUMERIC,
"TotalIncrementables" NUMERIC,
"TotalDeducibles" NUMERIC,
"PesoBrutoMercancia" NUMERIC,
"MedioTransporteSalida" TEXT,
"MedioTransporteArribo" TEXT,
"MedioTransporteEntrada_Salida" TEXT,
"DestinoMercancia" TEXT,
"NombreContribuyente" TEXT,
"CalleContribuyente" TEXT,
"NumInteriorContribuyente" TEXT,
"NumExteriorContribuyente" TEXT,
"CPContribuyente" TEXT,
"MunicipioContribuyente" TEXT,
"EntidadFedContribuyente" TEXT,
"PaisContribuyente" TEXT,
"TipoPedimento" TEXT,
"FechaRecepcionPedimento" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro502" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"RfcTransportista" TEXT,
"CurpTransportista" TEXT,
"NombreTransportista" TEXT,
"PaisTransporte" TEXT,
"IdentificadorTransporte" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro503" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"NumeroGuia" TEXT,
"TipoGuia" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro504" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"NumContenedor" TEXT,
"TipoContenedor" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro505" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"FechaFacturacion" TEXT,
"NumeroFactura" TEXT,
"TerminoFacturacion" TEXT,
"MonedaFacturacion" TEXT,
"ValorDolares" NUMERIC,
"ValorMonedaExtranjera" NUMERIC,
"PaisFacturacion" TEXT,
"EntidadFedFacturacion" TEXT,
"IndentFiscalProveedor" TEXT,
"ProveedorMercancia" TEXT,
"CalleProveedor" TEXT,
"NumInteriorProveedor" TEXT,
"NumExteriorProveedor" TEXT,
"CpProveedor" TEXT,
"MunicipioProveedor" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro506" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"TipoFecha" TEXT,
"FechaOperacion" TEXT,
"FechaValidacionPagoR" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro507" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"ClaveCaso" TEXT,
"IdentificadorCaso" TEXT,
"TipoPedimento" TEXT,
"ComplementoCaso" TEXT,
"FechaValidacionPagoR" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro508" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"InstitucionEmisora" TEXT,
"NumeroCuenta" TEXT,
"FolioConstancia" TEXT,
"FechaConstancia" TEXT,
"TipoCuenta" TEXT,
"ClaveGarantia" TEXT,
"ValorUnitarioTitulo" NUMERIC,
"TotalGarantia" NUMERIC,
"CantidadUnidades" NUMERIC,
"TitulosAsignados" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro509" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"ClaveContribucion" TEXT,
"TasaContribucion" NUMERIC,
"TipoTasa" TEXT,
"TipoPedimento" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro510" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"ClaveContribucion" TEXT,
"FormaPago" TEXT,
"ImportePago" NUMERIC,
"TipoPedimento" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro511" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"SecuenciaObservacion" TEXT,
"Observaciones" TEXT,
"TipoPedimento" TEXT,
"FechaValidacionPagoR" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro512" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"PatenteAduanalOrig" TEXT,
"PedimentoOriginal" TEXT,
"SeccionAduaneraDespOrig" TEXT,
"DocumentoOriginal" TEXT,
"FechaOperacionOrig" TEXT,
"FraccionOriginal" TEXT,
"UnidadMedida" TEXT,
"MercanciaDescargada" NUMERIC,
"TipoPedimento" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro520" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"IndentFiscalDestinatario" TEXT,
"NombreDestinatarioMercancia" TEXT,
"CalleDestinatario" TEXT,
"NumInteriorDestinatario" TEXT,
"NumExteriorDestinatario" TEXT,
"CpDestinatario" TEXT,
"MunicpioDestinatario" TEXT,
"PaisDestinatario" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro551" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"Fraccion" TEXT,
"SecuenciaFraccion" TEXT,
"SubdivisionFraccion" TEXT,
"DescripcionMercancia" TEXT,
"PrecioUnitario" NUMERIC,
"ValorAduana" NUMERIC,
"ValorComercial" NUMERIC,
"ValorDolares" NUMERIC,
"CantidadUMComercial" NUMERIC,
"UnidadMedidaComercial" TEXT,
"CantidadUMTarifa" NUMERIC,
"UnidadMedidaTarifa" TEXT,
"ValorAgregado" NUMERIC,
"ClaveVinculacion" TEXT,
"MetodoValorizacion" TEXT,
"CodigoMercanciaProducto" TEXT,
"MarcaMercanciaProducto" TEXT,
"ModeloMercanciaProducto" TEXT,
"PaisOrigenDestino" TEXT,
"PaisCompradorVendedor" TEXT,
"EntidadFedOrigen" TEXT,
"EntidadFedDestino" TEXT,
"EntidadFedComprador" TEXT,
"EntidadFedVendedor" TEXT,
"TipoOperacion" TEXT,
"ClaveDocumento" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro552" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"Fraccion" TEXT,
"SecuenciaFraccion" TEXT,
"VinNumeroSerie" TEXT,
"KilometrajeVehiculo" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro553" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"Fraccion" TEXT,
"SecuenciaFraccion" TEXT,
"ClavePermiso" TEXT,
"FirmaDescargo" TEXT,
"NumeroPermiso" TEXT,
"ValorComercialDolares" NUMERIC,
"CantidadMUMTarifa" NUMERIC,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro554" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"Fraccion" TEXT,
"SecuenciaFraccion" TEXT,
"ClaveCaso" TEXT,
"IdentificadorCaso" TEXT,
"ComplementoCaso" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro555" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"Fraccion" TEXT,
"SecuenciaFraccion" TEXT,
"InstitucionEmisora" TEXT,
"NumeroCuenta" TEXT,
"FolioConstancia" TEXT,
"FechaConstancia" TEXT,
"ClaveGarantia" TEXT,
"ValorUnitarioTitulo" NUMERIC,
"TotalGarantia" NUMERIC,
"CantidadUnidadesMedida" NUMERIC,
"TitulosAsignados" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro556" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"Fraccion" TEXT,
"SecuenciaFraccion" TEXT,
"ClaveContribucion" TEXT,
"TasaContribucion" NUMERIC,
"TipoTasa" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro557" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"Fraccion" TEXT,
"SecuenciaFraccion" TEXT,
"ClaveContribucion" TEXT,
"FormaPago" TEXT,
"ImportePago" NUMERIC,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro558" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"Fraccion" TEXT,
"SecuenciaFraccion" TEXT,
"SecuenciaObservacion" TEXT,
"Observaciones" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro701" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"ClaveDocumento" TEXT,
"FechaPago" TEXT,
"PedimentoAnterior" TEXT,
"PatenteAnterior" TEXT,
"SeccionAduaneraAnterior" TEXT,
"DocumentoAnterior" TEXT,
"FechaOperacionAnterior" TEXT,
"PedimentoOriginal" TEXT,
"PatenteAduanalOrig" TEXT,
"SeccionAduaneraDespOrig" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "Registro702" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"ClaveContribucion" TEXT,
"FormaPago" TEXT,
"ImportePago" NUMERIC,
"TipoPedimento" TEXT,
"FechaPagoReal" TEXT
);
CREATE TABLE IF NOT EXISTS "RegistroInci" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"ConsecutivoRemesa" TEXT,
"NumeroSeleccion" TEXT,
"FechaInicioReconocimiento" TEXT,
"HoraInicioReconocimiento" TEXT,
"FechaFinReconocimiento" TEXT,
"HoraFinReconocimiento" TEXT,
"Fraccion" TEXT,
"SecuenciaFraccion" TEXT,
"ClaveDocumento" TEXT,
"TipoOperacion" TEXT,
"GradoIncidencia" TEXT,
"FechaSeleccion" TEXT
);
CREATE TABLE IF NOT EXISTS "RegistroResumen" (
"Folio" TEXT,
"RFCoPatenteAduanal" TEXT,
"Fecha_Inicial" TEXT,
"Fecha_Final" TEXT,
"Fecha_Ejecucion" TEXT,
"Total_Fracciones" INTEGER,
"Total_Contribuciones" INTEGER
);
CREATE TABLE IF NOT EXISTS "RegistroSel" (
"Patente" TEXT,
"Pedimento" TEXT,
"SeccionAduanera" TEXT,
"ConsecutivoRemesa" TEXT,
"NumeroSeleccion" TEXT,
"FechaSeleccion" TEXT,
"HoraSeleccion" TEXT,
"SemaforoFiscal" TEXT,
"ClaveDocumento" TEXT,
"TipoOperacion" TEXT
);
CREATE TABLE IF NOT EXISTS base_numpartes (
numparte TEXT PRIMARY KEY,
descripcion TEXT,
unimed TEXT,
fraccion TEXT
);