Primera version funcional

This commit is contained in:
Marklogo 2026-02-17 21:57:44 +01:00
parent 6ec347f3f4
commit 240be1157b
4 changed files with 57 additions and 83 deletions

View File

@ -36,3 +36,18 @@ python main.py
``` ```
### Uso del script ### Uso del script
```bash
python main.py {ap,vacaciones} fecha --dias
{ap,vacaciones} Tipo de solicitud
fecha Fecha, rango o lista
--dias nDias en caso de vacaciones el nº de dias habiles (opcional, en caso de no especificarlo se le solicita por prompt)
Ejemplos:
python main.py ap 17/02/26
python main.py ap 17/02/26-19/02/26
python main.py ap 17/02/26,20/02/26,25/02/26
python main.py vacaciones 16/02/26-22/02/26 'Se solicitaran los dias habiles mediante el prompt'
python main.py vacaciones 16/02/26-22/02/26 --dias 5
```/

View File

@ -1,63 +0,0 @@
DNI
Nombre
Apellido 1
Apellido 2
Cuerpo o escala
Área
Primergrado
segundoGrado
ausencia1hJornada
ausencia1hFraccionada
reduccion1h
reducciónMediaHora
horasSindicales
diasSindicales
diasHabiles
PermisoParto
permisoadopcion
PermisoPaternidad
fallecimiento
trasladoSin
trasladoCon
examenesFinales
examenesPrenatales
Lactancia
NacimientoPrematuro
indispensable
moscoso
matrimonio
sindicales
CursoOrganismo
CursoAGE
CursoSindicatos
CursoPracticas
TomaProvision
TomaNuevoCuerpo
jubilacion
InteresParticular
FamiliarGrave
LicenciaEstudio
LicenciaPropios
LicenciaDesarrollo
TotalEnfermedadSin
TotalEnfermedadCon
ParcialEnfermedad
GestiónOficial
GestiónPersonal
ConisionServicio
viajeOficial
PorNocturnas
FueraHorario
refuerzos
noBeneficios
curso
decision
NumDiasHabiles
nmHorasSidicales
Otros
PERÍODO DE TIEMPO POR EL QUE SE SOLICITA
Imprimir
OposicionesInterna
numDiasSindicales
Fecha
guarda

13
docs/config.json Normal file
View File

@ -0,0 +1,13 @@
{
"datos_personales": {
"DNI": "33340763D",
"Nombre": "MARCOS",
"Apellido 1": "LOPEZ",
"Apellido 2": "GOMEZ",
"Cuerpo o escala": "C.TEC. AUX. DE INFORMATICA ADMON. ESTADO"
},
"rutas": {
"plantilla": "./docs/Plantilla.pdf",
"certificado": "./certificado/certificado.p12"
}
}

37
main.py
View File

@ -1,30 +1,38 @@
import argparse import argparse
import re import re
import os import os
import json
import warnings import warnings
warnings.filterwarnings("ignore", category=UserWarning, module="pyhanko")
import getpass import getpass
from pypdf import PdfReader, PdfWriter
from datetime import datetime from datetime import datetime
from pypdf import PdfReader, PdfWriter
from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter from pyhanko.pdf_utils.incremental_writer import IncrementalPdfFileWriter
from pyhanko.sign import signers, fields from pyhanko.sign import signers, fields
from pyhanko.stamp import TextStampStyle from pyhanko.stamp import TextStampStyle
from pyhanko.pdf_utils.layout import SimpleBoxLayoutRule, AxisAlignment from pyhanko.pdf_utils.layout import SimpleBoxLayoutRule, AxisAlignment
from pyhanko.pdf_utils.text import TextBoxStyle from pyhanko.pdf_utils.text import TextBoxStyle
# Ignorar avisos de pyhanko
warnings.filterwarnings("ignore", category=UserWarning, module="pyhanko")
class SolicitudRRHH: class SolicitudRRHH:
def __init__(self): def __init__(self):
self.cert_path = os.path.join(os.path.dirname(__file__), "certificado", "certificado.p12") self.base_path = os.path.dirname(os.path.abspath(__file__))
self.datos_personales = { self.config = self._cargar_configuracion()
"DNI": "33340763D",
"Nombre": "MARCOS", self.cert_path = os.path.join(self.base_path, self.config["rutas"]["certificado"])
"Apellido 1": "LOPEZ", self.datos_personales = self.config["datos_personales"]
"Apellido 2": "GOMEZ",
"Cuerpo o escala": "C.TEC. AUX. DE INFORMATICA ADMON. ESTADO"
}
self.args = self._parsear_argumentos() self.args = self._parsear_argumentos()
self.num_dias = self._obtener_num_dias() self.num_dias = self._obtener_num_dias()
def _cargar_configuracion(self):
config_path = os.path.join(self.base_path, "docs/config.json")
if not os.path.exists(config_path):
raise FileNotFoundError(f"No se encuentra el archivo de configuración: {config_path}")
with open(config_path, 'r', encoding='utf-8') as f:
return json.load(f)
def _validar_fecha(self, fecha_str): def _validar_fecha(self, fecha_str):
patron_fecha = r"\d{2}/\d{2}/\d{2}" patron_fecha = r"\d{2}/\d{2}/\d{2}"
patron_completo = rf"^{patron_fecha}((-{patron_fecha})|(,{patron_fecha})*)?$" patron_completo = rf"^{patron_fecha}((-{patron_fecha})|(,{patron_fecha})*)?$"
@ -53,7 +61,7 @@ class SolicitudRRHH:
def _firmar_pdf(self, archivo_entrada, archivo_salida): def _firmar_pdf(self, archivo_entrada, archivo_salida):
if not os.path.exists(self.cert_path): if not os.path.exists(self.cert_path):
print(f"⚠️ No se encontró el certificado.") print(f"⚠️ No se encontró el certificado en {self.cert_path}. Se guardará sin firmar.")
os.rename(archivo_entrada, archivo_salida) os.rename(archivo_entrada, archivo_salida)
return return
@ -61,7 +69,8 @@ class SolicitudRRHH:
w = IncrementalPdfFileWriter(inf) w = IncrementalPdfFileWriter(inf)
signer = signers.SimpleSigner.load_pkcs12( signer = signers.SimpleSigner.load_pkcs12(
pfx_file=self.cert_path, pfx_file=self.cert_path,
passphrase=self._obtener_passw_cert()) passphrase=self._obtener_passw_cert()
)
estilo = TextStampStyle( estilo = TextStampStyle(
border_width=0, border_width=0,
@ -84,7 +93,8 @@ class SolicitudRRHH:
with open(archivo_salida, 'wb') as outf: with open(archivo_salida, 'wb') as outf:
pdf_signer.sign_pdf(w, output=outf) pdf_signer.sign_pdf(w, output=outf)
def generar_pdf(self, path_plantilla="./docs/Plantilla.pdf"): def generar_pdf(self):
path_plantilla = os.path.join(self.base_path, self.config["rutas"]["plantilla"])
reader = PdfReader(path_plantilla) reader = PdfReader(path_plantilla)
writer = PdfWriter() writer = PdfWriter()
writer.clone_reader_document_root(reader) writer.clone_reader_document_root(reader)
@ -114,7 +124,6 @@ class SolicitudRRHH:
writer.set_need_appearances_writer() writer.set_need_appearances_writer()
# --- FLUJO DE GUARDADO Y FIRMA ---
nombre_final = self._generar_nombre_archivo() nombre_final = self._generar_nombre_archivo()
temp_file = "temp_solicitud.pdf" temp_file = "temp_solicitud.pdf"