martes, 20 de febrero de 2024

Python (II) Web Services Client (II) . Sedipualba & Castilla. Tablas importantes de Castilla

 Vamos a ver como mejoreamos el programa anterior para que también pueda ejecutar WS de Sedipualba.

1. Fichero de configuración YAML

Separamos la información de Castilla y la de Sedipualba. Los campos marcados con varias "x" son campos que cada uno debe de rellenar en base a su personalización. Este fichero lo he llamado x02_Config.yml


#----------------------------------------------------------------------------------------
# 01. SEDIPUALBA
#----------------------------------------------------------------------------------------
sedipualba:
demo:
username: xxxx
key: xxxxxxxxxx
api:
sefycu: https://pre-46xxx.sedipualba.es/sefycu/wssefycu.asmx?wsdl
segra: https://pre-46xxx.sedipualba.es/sefycu/wssegra.asmx?wsdl
segex: https://pre-46xxx.sedipualba.es/segex/wssegex.asmx?wsdl
seres_registro: https://pre-46xxx.sedipualba.es/seres/Servicios/wsseresregistro.asmx?wsdl
seres_ciudadano: https://pre-46xxx.sedipualba.es/seres/Servicios/wsseresregistro.asmx?wsdl
directorio: https://pre-46xxx.sedipualba.es/wsdirectorio.asmx?wsdl
sello: https://pre-46xxx.sedipualba.es/firma/wsselloelectronico.asmx?wsdl
notificaciones: https://pre-46xxx.sedipualba.es/sefycu/wsnotificaciones.asmx
entidad: 46xxx
dir3: L0146xxx
destino_registro: 16517
destino_factures: 18847
prod:
username: xxxx
key: xxxxxxxxxx
api:
sefycu: https://46xxx.sedipualba.es/sefycu/wssefycu.asmx?wsdl
segra: https://46xxx.sedipualba.es/sefycu/wssegra.asmx?wsdl
segex: https://46xxx.sedipualba.es/segex/wssegex.asmx?wsdl
seres_registro: https://46xxx.sedipualba.es/seres/Servicios/wsseresregistro.asmx?wsdl
seres_ciudadano: https://46xxx.sedipualba.es/seres/Servicios/wsseresregistro.asmx?wsdl
directorio: https://46xxx.sedipualba.es/wsdirectorio.asmx?wsdl
sello: https://46xxx.sedipualba.es/firma/wsselloelectronico.asmx?wsdl
notificaciones: https://46xxx.sedipualba.es/sefycu/wsnotificaciones.asmx
entidad: 46xxx
dir3: L0146xxx
destino_registro: 26265
destino_factures: 24180

xml: >
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<$FUNCTION$ xmlns="$XMLNS$">
<wsSegUser>$USERNAME$</wsSegUser>
<wsSegPass>$KEY$</wsSegPass>
<idEntidad>$ENTIDAD$</idEntidad>
$PARAMETERS$
</$FUNCTION$>
</soap:Body>
</soap:Envelope>
headers :
#Content-Type: application/soap+xml; charset=utf-8
Content-Type: text/xml; charset=utf-8

xmlns :
sefycu: https://eadmin.dipualba.es/sefycu/wssefycu.asmx
segra: https://eadmin.dipualba.es/sefycu/wssegra.asmx
segex: https://eadmin.dipualba.es/segex/wssegex.asmx
seres_registro: http://sedipualba.es/wsSeresV1.2
seres_ciudadano: http://sedipualba.es/wsSeresV1
directorio: https://sedipualba.es/wsdirectorio.asmx
sello: http://www.sedipualba.es/firma/WSSelloElectronico.asmx
notificaciones: /admin/
#----------------------------------------------------------------------------------------
# 02. CASTILLA
#----------------------------------------------------------------------------------------
castilla:
api_url: https://rrhh-xxxxxxxx.grupocastilla.es/epsilonnetws/WSEmpleado.asmx?wsdl
headers :
Content-Type: application/soap+xml; charset=utf-8
token: >
&lt;TOKEN&gt;
&lt;AppName&gt;$APPNAME$&lt;/AppName&gt;
&lt;AppToken&gt;xxxxxxx&lt;/AppToken&gt;
&lt;/TOKEN&gt;
appName: xxxx_APPS
nombreTabla: PERSONAS
xml: >
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<ConsultaGenericaBD_XML xmlns="http://www.grupocastilla.es/epsilonnetws">
<sToken>$TOKEN$</sToken>
<nombreTabla>$TABLA$</nombreTabla>
<condicion>$CONDICION$</condicion>
</ConsultaGenericaBD_XML>
</soap:Body>
</soap:Envelope>


2. Clases de utilidad para trabajar con ficheros yXML

La primera clase es simple y es para escribir datos a un fichero ya sea en ruta absoluta o relativa

La segunda es para hacer unas pocas cosas con XML

Veamos el primer fichero u02_File.py 

import sys

'''
File Utils
'''

class FileUtils:
#------------------------------------------------------
# 01. Create the XML for making the WS call
# params:
# 1. condicion for instance "APELLIDO1 LIKE '%PEREZ%'"
#------------------------------------------------------
@staticmethod
def writeDataToFileAbsolute(absoluteFileNamePath, data):
fileOut=open(absoluteFileNamePath,"w") # Rewrite
fileOut.write(data)
fileOut.close

@staticmethod
def writeDataToFileRelativeFile(relativeFileNamePath, data):
#fileName = sys.path[0] + "/../my-python-programs-output/p01-request-01.output.xml"
fileName = sys.path[0] + "/" + relativeFileNamePath
print ('fileName:',fileName)
fileOut=open(fileName,"w") # Rewrite
fileOut.write(data)
fileOut.close


Veamos el segundo fichero u02_XML.py 

import xml.etree.ElementTree as ET

'''
XML Utils
'''
class XMLUtils:
#------------------------------------------------------
# Get a XML by tab
# params:
# 1. firstElem: xml string to read
#------------------------------------------------------
@staticmethod
def getElementByTag(xmlString, tagString):
elem=ET.fromstring(xmlString)
tabla=elem.tag
level=0
while tabla!=tagString and level<10:
elem=elem[0]
tabla=elem.tag
level+=1
return elem

#------------------------------------------------------
# Get an array of records as an array of dictionaries
# params:
# 1. firstElem: xml string to read
#------------------------------------------------------
@staticmethod
def getRecordsCastilla(firstElem):
records=[]
for secondElem in firstElem: # REGISTRO
#print('100 ',secondElem.tag, secondElem.attrib, secondElem.text)
dictio={}
for thirdElem in secondElem: # CAMPO
#print('200 ',thirdElem.tag, '--', thirdElem.attrib,'----', thirdElem.text)
att = thirdElem.attrib['NOMBRE']
value = thirdElem.text
dictio[att]=value
#print ('dictio=',dictio)
records.append(dictio)
return records


Tablas importantes

PUES_TRAB

    - id_trabajador: ('00075'???)

    -id_nivel ('00068')

    -id_secuencia ('004')


NIV_ORB

    -id_nivel ('00068')

    -d_nivel ("Tecnic nivell xx informatica")

    -id_puesto ('00013')


TRABAJADORES

    -id_empresa

    -id_trabajador

    -id_secuencia

Y ya buscamos en PERSONAS para obtener el resto de dtos

miércoles, 14 de febrero de 2024

Python (I) Web Services Client (I) . Castilla. Python environment. Dependencias Odoo

0. Instalar última versión de python

Seguimos las instrucciones de HowToGeek 

#1. Actualizamos
sudo apt update

#2. Instalamos dependencias
sudo apt install build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libreadline-dev libffi-dev

#3.Descargar la ultima version de Python de https://www.python.org/downloads/source/

#4. Ir a la crpeta donde se ha descargado por ejemplo Downloads 
cd ~Downloads

#5. Desempaquetar el fichero ".tgz"
tar zxvf Python-3.13.0.tgz

#6.Nos situamos en la carpeta generada
cd Python-3.13.0

#7. Compilamos el código
./configure --enable-optimizations

#8. Hacemos un build del Makefile generado. Este proceso es muuuuuy lento
sudo make install

#9. Verificamos que se ha instalado bien
python3 -V

1. Instalar la librería "request", y otras más en un entrono virtual

Si tenemos uina versión avanzada de Ubuntu, necesitamos instalar python en un entorno virtual.

Dicho entorno virtual se crea en una carpeta.

Cuando se instala python en dicha carpeta, crea 4 subcarpetas (bin, include, lib, lib64 y pyvenv.cfg)

Ahora para instalar el paquete request, hay que indicarle la ruta donde está instalado el python en dicho entorno virtual (dentro de la subcarpeta bin) , sinó no deja instalar.

OJO: Cuando se abra VStudio, hay que decirle que abra la carpeta donde se ha instalado el entorno virtual, de lo contrario no reconocerá las librerías instaladas. en mi caso es ~/MyOdoo/Control-Presencia

En una ventana de comandos ejecutar:

#0.Instalar dependencias necesarias
sudo apt install libpq-dev python3-dev

#1.Instalar Python3.11 en un entrono virtual
sudo apt install python3.11-venv

#2.Crear entrono virtual en ~/MyOdoo/Control-Presencia
#  OJO: Este directorio és el que tenemos que elegir en VS para que reconozca el 
#       el entorno donde se instralaran o se han instalado las librerias.
#       Para ello, una vez instaladas las librerias, se abrirá VStudio y se le dirá
#       File -> Open Folder y se indicara la carpeta ~/MyOdoo/Control-Presencia          

python3 -m venv ~/MyOdoo/Control-Presencia #3.Cambiamos de directorio.

cd ~/MyOdoo/Control-Presencia #4.Instalamos el paquete request indicando la ruta del ejecutable python en
#  el entorno virtual 
./bin/python -m pip install requests

#5.Instalamos la libreria para tratar XML
./bin/python -m pip install elementpath

#6.Instalamos la libreria para tratar YML
./bin/python -m pip install pyyaml

#7.Instalamos la libreria para conectase con Oracle
./bin/python -m pip install oracledb

#8.Instalamos la libreria para conectase con Postgres
./bin/python -m pip install psycopg2

#8.Instalamos la libreria para trabajar con arrays
./bin/python -m pip install numpy

#9.Instalamos la libreria para trabajar con pdf
./bin/python -m pip install -U pypdfium2

#10.Instalamos la libreria para trabajar con ocr
sudo apt install tesseract-ocr
./bin/python -m pip install pytesseract

./bin/python -m pip install opencv-contrib-python
./bin/python -m pip install imutils
./bin/python -m pip install matplotlib

sudo apt install libmagickwand-dev
./bin/python -m pip install Wand

./bin/python -m pip install deskew

./bin/python -m pip install easyocr

./bin/python -m pip install Filetype
./bin/python -m pip install pandas
./bin/python -m pip install openpyxl
./bin/python -m pip install xlrd
./bin/python -m pip install matplotlib

./bin/python -m pip install py7zr
./bin/python -m pip install python-magic

./bin/python -m pip install cmislib

./bin/python -m pip install tk
./bin/python -m pip install tkinter-tooltip

./bin/python -m pip install unidecode

./bin/python -m pip install nox

./bin/python -m pip install secure-smtplib

OJO: Para que funcione tkinter (tk) en Ubuntu hay que hacer

sudo apt-get install python3-tk

En Pycharm hacemos

- Ir a Python Packages 

- Dar el nombre del paquete e instalar (requests, elementpath, pyyaml, oracledb, psycopg2)



Si queremos instalar las dependencias de Odoo 16

#1.Cambiamos de directorio.
cd ~/MyOdoo/Control-Presencia

#2.Creamos un directorio para Odoo 16 y nos situamos en el
mkdir ~/MyOdoo/odoo-16.0
cd ~/MyOdoo/odoo-16.0

#3.Descargamos Odoo 16 dentro
mkdir ~/MyOdoo/odoo-16.0
git clone https://github.com/odoo/odoo.git -b 16.0 --depth=1

#4.Cambiamos de directorio del entorno
cd ~/MyOdoo/Control-Presencia

#4.Instalamos las dependencias que requiere Odoo
/bin/python -m pip install -r ~/MyOdoo/odoo-16.0/requirements.txt

#5.Instalamos las dependencia Odoo
/bin/python -m pip install -e ~/MyOdoo/odoo-16.0

#6.A veces falla si hacemos odoo --version. par tanto instalamos también
./bin/python -m pip install lxml_html_clean




2 Activar y desactivar un entorno virtual python


#1. Ya hemos visto como crear un entrono virtual
#  en ~/MyOdoo/Control-Presencia
#  OJO: Este directorio és el que tenemos que elegir en VS para que reconozca el 
#       el entorno donde se instralaran o se han instalado las librerias.
#       Para ello, una vez instaladas las librerias, se abrirá VStudio y se le dirá
#       File -> Open Folder y se indicara la carpeta ~/MyOdoo/Control-Presencia          

python3 -m venv ~/MyOdoo/Control-Presencia
#2. Mostrar la versión de python istalada
~/MyOdoo/Control-Presencia/bin/python -V

#3. Activar el entorno virtual
source ~/MyOdoo/Control-Presencia/bin/activate

#4. Ver donde se ha instalado el python
which python

#5. DESACTIVAR el entorno virtual
deactivate




3. Crear un programa sencillo y ejecutarlo

Ahora creamos este programita ejemplo de RealPython 


import requests
api_url = "https://jsonplaceholder.typicode.com/todos/1"
response = requests.get(api_url)
print(response.json())

Lo ejecutamos y nos dice Visual Studio 

Y le contestamos que instale

y nos contesta: 

{'userId': 1, 'id': 1, 'title': 'delectus aut autem', 'completed': False}

4. Crear un programa sencillo pero real

Llenemos este código


import requests
import xml.etree.ElementTree as ET

#Definimos la URL, el conteniodo y el tipo de consulta application/soap+xml
#1. URL
api_url="https://rrhh-xxxxxx.grupocastilla.es/epsilonnetws/WSEmpleado.asmx?wsdl"

#2. Contenido
xml="""<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<ConsultaGenericaBD_XML xmlns="http://www.grupocastilla.es/epsilonnetws">
<sToken>
&lt;TOKEN&gt;
&lt;AppName&gt;AYTOXXXX_APPS&lt;/AppName&gt;
&lt;AppToken&gt;XXXXXXXXXXXXXXX&lt;/AppToken&gt;
&lt;/TOKEN&gt;
</sToken>
<nombreTabla>PERSONAS</nombreTabla>
<condicion>APELLIDO2 LIKE '%PLA%'</condicion>
</ConsultaGenericaBD_XML>
</soap:Body>
</soap:Envelope>"""
#3. Tipo de petición
headers = {'Content-Type': 'application/soap+xml; charset=utf-8'}

#--EJECUTAMOS LA PETICIÓN
print (requests.post(api_url, data=xml, headers=headers).text)


Lo ejecutamos y nos dice 


<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ConsultaGenericaBD_XMLResponse xmlns="http://www.grupocastilla.es/epsilonnetws">
<ConsultaGenericaBD_XMLResult>
<TABLA xmlns="">
<REGISTRO>
<CAMPO NOMBRE="NIF">
<![CDATA[73XXXXXXX]]>
</CAMPO>
<CAMPO NOMBRE="ID_PF">
<![CDATA[0]]>
</CAMPO>
<CAMPO NOMBRE="APELLIDO1">
<![CDATA[XXXRIXXX]]>
</CAMPO>
<CAMPO NOMBRE="APELLIDO2">
<![CDATA[PLAXX]]>
</CAMPO>
<CAMPO NOMBRE="NOMBRE">
<![CDATA[XXXAXXX]]>
</CAMPO>
</REGISTRO>
<REGISTRO>
<CAMPO NOMBRE="NIF">
<![CDATA[XXXXXXXXX]]>
</CAMPO>
<CAMPO NOMBRE="ID_PF">
<![CDATA[0]]>
</CAMPO>
<CAMPO NOMBRE="APELLIDO1">
<![CDATA[MXXXXXX]]>
</CAMPO>
<CAMPO NOMBRE="APELLIDO2">
<![CDATA[PLAXXX]]>
</CAMPO>
<CAMPO NOMBRE="NOMBRE">
<![CDATA[JOSE]]>
</CAMPO>
</REGISTRO>
</TABLA>
</ConsultaGenericaBD_XMLResult>
</ConsultaGenericaBD_XMLResponse>
</soap:Body>
</soap:Envelope>




5. Crear un programa con un fichero de propiedades en YAML

Para simplificar trabajaremos en la misma carpeta

1. Veamos el fichero de configuración en formato YAML (c01_config.yml)


castilla:
api_url: https://rrhh-tavernes.grupocastilla.es/epsilonnetws/WSEmpleado.asmx?wsdl
headers :
Content-Type: application/soap+xml; charset=utf-8
token: >
&lt;TOKEN&gt;
&lt;AppName&gt;$APPNAME$&lt;/AppName&gt;
&lt;AppToken&gt;xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx&lt;/AppToken&gt;
&lt;/TOKEN&gt;
appName: AYTOxxxx_APPS
nombreTabla: PERSONAS
xml: >
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<ConsultaGenericaBD_XML xmlns="http://www.grupocastilla.es/epsilonnetws">
<sToken>$TOKEN$</sToken>
<nombreTabla>$TABLA$</nombreTabla>
<condicion>$CONDICION$</condicion>
</ConsultaGenericaBD_XML>
</soap:Body>
</soap:Envelope>


2. Veamos una clase de utilidades para trabajar con XML (u03_XML.py)

import xml.etree.ElementTree as ET

'''
XML Utils
'''
class XMLUtils:
@staticmethod
def getElement(xmlString, tagString):
elem=ET.fromstring(xmlString)
tabla=elem.tag
level=0
while tabla!=tagString and level<10:
elem=elem[0]
tabla=elem.tag
level+=1
return elem

#Get an array of records as an array of dictionaries
@staticmethod
def getRecordsCastilla(firstElem):
records=[]
for secondElem in firstElem: # REGISTRO
#print('100 ',secondElem.tag, secondElem.attrib, secondElem.text)
dictio={}
for thirdElem in secondElem: # CAMPO
#print('200 ',thirdElem.tag, '--', thirdElem.attrib,'----', thirdElem.text)
att = thirdElem.attrib['NOMBRE']
value = thirdElem.text
dictio[att]=value
#print ('dictio=',dictio)
records.append(dictio)
return records


3. Veamos el programa principal (p03_request.py)

import sys
import requests
import yaml
import xml.etree.ElementTree as ET
from u03_XML import XMLUtils

#--------------------------------------
#1. Get properties from config file
#--------------------------------------
configFile = sys.path[0] + "/c01_config.yml"
print ('configFile:', configFile)
with open(configFile, 'r') as f:
configData = yaml.full_load(f)['castilla']
print('confiData:',configData)
#------------------------------------------------------------
#2. Define request
#------------------------------------------------------------
condicion="" # All !!!
xml=configData['xml'] \
.replace('$TOKEN$' , configData['token']) \
.replace('$APPNAME$' , configData['appName']) \
.replace('$TABLA$' , configData['nombreTabla'])\
.replace('$CONDICION$', condicion)
#------------------------------------------------------------
#3. Execute and print output to console
#------------------------------------------------------------
output=requests.post(configData['api_url'], data = xml, headers = configData['headers']).text

#------------------------------------------------------------
#3. Write output to file
#------------------------------------------------------------
fileName = sys.path[0] + "/../my-python-programs-output/p01-request-01.output.xml"
print ('fileName:',fileName)
fileOut=open(fileName,"w") # Rewrite
fileOut.write(output)
fileOut.close

#------------------------------------------------------------
#4. Extract XML info
#------------------------------------------------------------
tabla=XMLUtils.getElement(output,"TABLA")
records=XMLUtils.getRecordsCastilla(tabla)

#------------------------------------------------------------
#5. Print the records
#------------------------------------------------------------
i=0
for myrecord in records: # myrecord is a dictionary
i+=1
print(i,'--------------------------------------')
print ('myrecord=', myrecord)










martes, 13 de febrero de 2024

AGM (12) Migración de expedientes y documentos a un REPOSITORIO LOCAL

Migración a un repositorio local


1. Archivo de los documentos

Para ello se pueden crear una carpeta por cada año, y dentro de cada año se puede crear una carpeta por cada expediente. Dentro de cada expediente se crearan los documentos (pero no se descarta que pueda haver subcarpetas para organizar mejor la información.

2. Metadatos

Los metadatos a crear son de varios tipos:

2.1 Metadatos de configuración:

Afectarán a todos el conjunto y son

  1. Ruta de la carpeta padre que va a contener todo el conjunto
  2. Tipo de compresión de los ficheros (zip, ninguno,etc)
  3. Contraseña de acceso (si es que los protegemos con contraseña)

2.2 Metadatos específicos del expediente

  1. Código del expediente en GTT
  2. Código del expediente en Sedipualba
  3. Código del expediente en Gexflow
  4. Código del expediente propio del Ayuntamiento. Este nombre será .....
  5. Año o fecha
  6. Tipo de expediente (pase a ejecutiva, contrato mayor..)
  7. Descripción
  8. Lista de departamentos autorizados con su tipo de permiso (inicial,consulta, modificación). De ellos uno y solo uno será el departamento que inició la gestión y se indicará la nomenclatura.
  9. Persona tramitadora
  10. Fecha de creación
  11. Fecha de cierre
  12. Estado actual (abierto, en tramitación, cerrado)
  13. Observaciones
  14. Lista de interesados

2.3 Metadatos específicos del documento

  1. URL relativa del documento respecto a la carpeta padre (incluyendo carpeta y nombre del documento). Esta URL será .....
  2. Lista de expedientes que contienen el documento. De ellos uno y solo uno es el principal  y la mayoría de casos será único.
  3. CSV
  4. Lista de firmas (firmante, fecha, hash a firmar, hash de firma). Se debería crear una entidad (tabla) a parte para gestionar las firmas ....
  5. Lista de interesados o afectados
  6. Tipo de documento (resolución, notificación, pliego, diligencia, informe, plano (según documento de normalización)
  7. Descripción o resumen
  8. Lista de palabras clave para buscar (passar posteriormente OCR)
  9. Fecha de alta
  10. Formato (ENI, pdf, xml, tiff....)
  11. Autor

3. Contenido del documento

  1. Referencia al documento (id) documento
  2. Texto extraido directamente del documento (BLOB..)
  3. Texto obtenido al passar el OCR a las imágenes contenidas en el documento (BLOB)

AGM (11) Migración de expedientes a SEDIPUALBA

 La idea es poder asociar los documentos a los expedientes por medio de sus actuaciones.


En Sedipualba, parece ser que no se puede consultar por persona un expediente, o lo que es lo mismo, buscar los expedientes que tiene una persona, por tanto se plantea a la hora de crear un expediente por WS, llenar los campos del expediente de Sedipualba de la siguiente manera.

1. Campo DESCRIPCION

Dar esta información estructurada de esta manera:

MIGRACION GTT
PROCEDIMIENTO: Declaración IIVTNU
PERSONA: DANTE ALIGIERI XIMO
NIF:  12345678C
FECHA: 2017-12-21 
REF-GTT: 107584773
SECCION: TRIBUTARIA
OTRAS PERSONAS: BUONAROTI MIGUEL ANGEL, BRUNELLESCHI FILIPPO
OTROS NIFS: 11111111H , 22222222J
REFERENCIA CATASTRAL: 
RELACION DE RECIBOS: 231345
OBSERVACIONES: Prueba

Y como se puede buscar por palabras en este campo, ya podemos al menos localizar un expediente por persona.


2. Campo COMENTARIO

Parece ser que una vez creado el expediente, se le puede asignar un campo de comentario, pero no cuando se crea.

Ese campo puede contener cualquier información que permita ajustar mas los parámetros de búsqueda o consulta

3. Mapeo de tipos de expediente y negociados


4.Nombrar documentos


Para el nombre de los documentos, se puede incluir el CSV tambien en el nombre del documento para poderlo buscar. ????'








viernes, 9 de febrero de 2024

AGM (10) Fraccionamientos.

 1. Valores fraccionados (VALOR.xls)

Parece ser que en un expediente, se acumulan recibos, y sobre esta acumulación de recibos, se hace un fraccionamiento del total de pagos. Los farccionamientos son la tabla FRRE y la aplicación de cada recibo a ese fracionamiento es la tabla FRAV. En consecuencia, un mismo plazo de fraccionamiento FREE (que tiene una referencia de cobro (REFERNCIA_REEM) se desglosa en las fracciones de cada recibo que lo forman (tabla FRAV de aplicacion de fracciones a los recibos)
Por tanto tenemos que :
 - Para saber el recibo FRAV.ID_EPER
 - Para saber eL número de fraccionamiento del conjunto donde se menten las fracciones del recibo FRAV.NUM_FRAC_FRRE = FRRE.NUM_FRAC_FRRE
 - Pero necesitamos que enlacen además con la actuación  FRAV.ID_ACTU=FRRE.ID_ACTU 

--------------------------------------

-- 5.1 VALORES FRACCIONADOS

--------------------------------------

SELECT DISTINCT --VALO.FRACC_VALO,

VALO.ID_EPER AS ID,

VALO.IMPORTE_VALO AS PRINCIPAL,

SUM(NVL(FRAV.RECARGO_FRAV,0)) AS RECARGO,

SUM(NVL(FRAV.INTERESES_FRAV,0)+ NVL(FRAV.INTERESES_FRAC_FRAV,0) ) AS INTERES,

SUM(NVL(FRAV.PRINCIPAL_FRAV,0) + NVL(FRAV.RECARGO_FRAV,0) + NVL(FRAV.INTERESES_FRAV,0)+NVL(FRAV.INTERESES_FRAC_FRAV,0) ) AS IMPORT,

CORG.COD_CONC,

APFR.NUMPLAZOS AS PLAZOS,

--VALO.ID_EPER AS RECIBO,

VALO.NUMERO_VALO AS RECIBO,

VALO.FECHA_INI_VALO AS F_INI_VOL,

VALO.FECHA_FIN_PERIODO_VALO AS F_FIN_VOL,

VALO.NIF_SP_VALO AS NIF,

VALO.NOMBRE_SP_VALO AS NOMBRE,

EPER.ID_PERS AS ID_SUJETO,

--ACTU.ID_ACTU AS ID_FRAC,

APFR.ID_PROP AS ID_FRAC, --ID de la pruesta

ACTU.ID_ACTU AS CALVE_PRIMARIA,

VALO.EJERCICIO_VALO AS EJERCICIO,

ACTU.ENTIDAD_CCC_ACTU AS DOM_ENTIDAD,

ACTU.OFICINA_CCC_ACTU AS DOM_OFICINA,

ACTU.DC_CCC_ACTU AS DOM_DC,

ACTU.NUMERO_CCC_ACTU AS DOM_CUENTA,

ACTU.IBAN_ACTU AS COM_IBAN,

VAAC.COSTAS_VAAC AS COSTAS

FROM "OPS$GTTORA".VALO_VALORES VALO

LEFT JOIN "OPS$GTTORA".EPER_ELEMENTOS_PERSONA EPER ON EPER.ID_EPER =VALO.ID_EPER

JOIN "OPS$GTTORA".FRAV_FRACC_APLICACION_VALOR FRAV ON FRAV.ID_EPER=VALO.ID_EPER

JOIN "OPS$GTTORA".APFR_APLAZ_FRACC APFR ON APFR.ID_ACTU =FRAV.ID_ACTU

JOIN "OPS$GTTORA".ACTU_ACTUACIONES ACTU ON ACTU.ID_ACTU =FRAV.ID_ACTU -- ACTU.ID_ACTU =APFR.ID_ACTU --- EFR.ID_ACTU

LEFT JOIN "OPS$GTTORA".VAAC_VALORES_ACTUACION VAAC ON VAAC.ID_ACTU =FRAV.ID_ACTU AND VAAC.ID_EPER =VALO.ID_EPER

--JOIN "OPS$GTTORA".REFR_REGISTRO_FRACCIONAMIENTOS REFR ON REFR.ID_EPER=VALO.ID_EPER

--LEFT JOIN "OPS$GTTORA".FRRE_FRACCIONES_REFERENCIAS FRRE ON FRRE.ID_ACTU=REFR.ID_ACTU

LEFT JOIN "OPS$GTTORA".CSUB_CONCEPTOS_SUBORGANISMO CSUB ON CSUB.ID_CSUB = VALO.ID_CSUB

LEFT JOIN "OPS$GTTORA".CORG_CONCEPTOS_ORGANISMO CORG ON CORG.ID_CORG =CSUB.ID_CORG

GROUP BY --VALO.FRACC_VALO,

VALO.ID_EPER , VALO.IMPORTE_VALO , CORG.COD_CONC, APFR.NUMPLAZOS,

VALO.NUMERO_VALO, VALO.FECHA_INI_VALO, VALO.FECHA_FIN_PERIODO_VALO, VALO.NIF_SP_VALO,

VALO.NOMBRE_SP_VALO, EPER.ID_PERS, APFR.ID_PROP, ACTU.ID_ACTU,

VALO.EJERCICIO_VALO, ACTU.ENTIDAD_CCC_ACTU, ACTU.OFICINA_CCC_ACTU, ACTU.DC_CCC_ACTU,

ACTU.NUMERO_CCC_ACTU, ACTU.IBAN_ACTU, VAAC.COSTAS_VAAC

ORDER BY VALO.ID_EPER;


2. Detalle de las fracciones de cada recibo (FRACCIONES.xls)

------------------------------------------

-- 5.2 DETALLE DE LOS VALORES FRACCIONADOS

------------------------------------------

SELECT --frav.ID_REGE, FRAV.ID_EPER, FRAV.NUM_FRAC_FRRE,'-----------------------',

--100*FRAV.ID_ACTU + FRAV.NUM_FRAC_FRRE AS ID,

100*APFR.ID_PROP + FRAV.NUM_FRAC_FRRE AS ID,

FRAV.PRINCIPAL_FRAV AS PRINCIPAL,

COBR.FECHA_COBR AS F_PAGO,

FRAV.INTERESES_FRAC_FRAV AS INTERESSOS,

FRAV.COSTAS_FRAV AS COSTAS,

--PORC_RECARGO_FRAV,

FRAV.RECARGO_FRAV AS RECARGO,

FRAV.TOTAL_FRAV AS IMPORT,

CSUB.ID_CORG AS CONCEPTO,

FRAV.NUM_FRAC_FRRE AS PLAZOS,

--FRAV.ID_EPER AS RECIBO,

VALO.NUMERO_VALO AS RECIBO,

--VALO.FECHA_INI_VALO AS F_INI_VOL,

FRRE.FECHA_CONFIRMACION_FRRE AS F_INI_VOL,

--VALO.FECHA_FIN_PERIODO_VALO AS F_FIN_VOL,

FRRE.FECHA_VENCIMIENTO_FRRE AS F_FIN_VOL,

VALO.NIF_SP_VALO AS NIF,

VALO.NOMBRE_SP_VALO AS NOMBRE,

APFR.ID_ACTU AS CLAVE_PRIMARIA,

APFR.ID_PROP AS ID_FRAC --ID de la pruesta

FROM "OPS$GTTORA".VALO_VALORES VALO

JOIN "OPS$GTTORA".FRAV_FRACC_APLICACION_VALOR FRAV ON FRAV.ID_EPER=VALO.ID_EPER --FRAV.ID_ACTU=VAAC.ID_ACTU AND FRAV.ID_EPER=VALO.ID_EPER --AND FRAV.NUM_FRAC_FRRE = FRRE.NUM_FRAC_FRRE

--LEFT JOIN "OPS$GTTORA".EPER_ELEMENTOS_PERSONA EPER ON EPER.ID_EPER =VALO.ID_EPER

--JOIN "OPS$GTTORA".VAAC_VALORES_ACTUACION VAAC ON VAAC.ID_EPER =VALO.ID_EPER

JOIN "OPS$GTTORA".APFR_APLAZ_FRACC APFR ON APFR.ID_ACTU=FRAV.ID_ACTU

JOIN "OPS$GTTORA".FRRE_FRACCIONES_REFERENCIAS FRRE ON FRRE.ID_ACTU=FRAV.ID_ACTU AND FRRE.NUM_FRAC_FRRE =FRAV.NUM_FRAC_FRRE

LEFT JOIN "OPS$GTTORA".COBR_COBROS COBR ON COBR.REF_COBR=FRRE.REFERENCIA_REEM

LEFT JOIN "OPS$GTTORA".CSUB_CONCEPTOS_SUBORGANISMO CSUB ON CSUB.ID_CSUB = VALO.ID_CSUB

ORDER BY FRAV.ID_REGE, FRAV.NUM_FRAC_FRRE

;