﻿#!/usr/bin/env python
# -*- coding: utf-8 -*-

from datetime import datetime
import csv, sqlite3, locale

locale.setlocale( locale.LC_ALL, 'Spanish_Argentina.1252')

INCISOS_A_IGNORAR = ('1')
PROGRAMA_A_IGNORAR = ('90', '00')

CODIGO_CORRALITO = '2016/0000099000'
CODIGO_RECORTE = '2016/0000098999'

ARCHIVO_ESTADOS = "raw_estados.csv"
ARCHIVO_CODIGOS = "raw_codigos.csv"
ARCHIVO_SALIDA_CSV = "salida.csv"
ARCHIVO_SALIDA_HTML = "salida.html"
BASE = "ep-py.db"

tabla = datetime.now().strftime('e_%d%m%Y')

db_conn = sqlite3.connect(BASE)
db_cur = db_conn.cursor()
db_cur.execute("DROP TABLE IF EXISTS " + tabla)
db_cur.execute("CREATE TABLE " + tabla + '''(da TEXT,
                                                           ca TEXT,
                                                           ju TEXT,
                                                           sj TEXT,
                                                           ent TEXT,
                                                           pg TEXT,
                                                           sp TEXT,
                                                           py TEXT,
                                                           ac TEXT,
                                                           ob TEXT,
                                                           fi TEXT,
                                                           fu TEXT,
                                                           fte TEXT,
                                                           sfte TEXT,
                                                           inciso TEXT,
                                                           principal TEXT,
                                                           parcial TEXT,
                                                           subparc TEXT,
                                                           dpto TEXT,
                                                           ug TEXT,
                                                           descripcion TEXT,
                                                           credito_original REAL,
                                                           variaciones REAL,
                                                           credito_actual REAL,
                                                           reservado REAL,
                                                           compromiso REAL,
                                                           devengado REAL,
                                                           pagado REAL,
                                                           disponible REAL,
                                                           pasivo REAL,
                                                           pendiente_liberacion REAL,
                                                           retenido REAL)''')
diradmin = (('954', 'Gobernación'),
            ('967', 'Secretaría Legal y Técnica de la Provincia'),
            ('977', 'Ministerio de Turismo'),
            ('978', 'Secretaría de Ambiente'),
            ('984', 'Ministerio de Cultura y Comunicación'),
            ('986', 'Secretaría de Cultura'),
            ('987', 'Instituto Provincial de Discapacidad'))

unidades=(('954','01','01',"Dirección General de Despacho de la Gobernación"),
          ('954','01','02',"Dirección General Servicio Administrativo Contable de la Gobernación"),
          ('954','02','01',"Secretaría General de la Gobernación"),
          ('954','02','02',"Secretaría de Ciencia, Tecnología e Innovación"),
          ('954','02','03',"Coordinación General de Políticas de Género"),
          ('954','03','01',"Dirección General de Informática"),
          ('954','16','01',"Gobernación"),
          ('954','16','02',"Dirección General de Ceremonial"),
          ('954','16','03',"Representación del Gobierno de Entre Ríos en Capital Federal"),
          ('954','16','04',"Vicegobernación"),
          ('954','16','05',"Comisión Fiscalizadora del I. O. S. P. E. R."),
          ('954','16','06',"Secretaría de Niñez, Familia y Discapacidad"),
          ('954','17','01',"Escribanía Mayor de Gobierno"),
          ('954','18','01',"Secretaría de la Juventud"),
          ('954','19','01',"Secretaría de Relaciones Institucionales e Internacionales"),
          ('954','20','01',"Ente Región Centro e Integración Regional"),
          ('954','21','01',"Subsecretaría de Gestión Administrativa"),
          ('954','21','02',"Dirección General de Subsidios"),
          ('954','28','01',"Unidad de Gestión Isla Puerto"),
          ('967','16','01',"Secretaría Legal y Técnica de la Provincia"),
          ('977','01','01',"Ministerio de Turismo"),
          ('977','16','01',"Secretaría de Turismo"),
          ('977','16','02',"Dirección de Turismo Social"),
          ('978','16','01',"Secretaría de Ambiente"),
          ('984','01','01',"Ministerio de Cultura y Comunicación"),
          ('984','01','02',"Subsecretaría de Gestión Administrativa y Asuntos Jurídicos"),
          ('984','02','01',"Secretaría de Telecomunicaciones"),
          ('984','16','01',"Secretaría de Comunicación"),
          ('984','16','02',"Consejo Provincial de Políticas Comunicacionales"),
          ('984','17','01',"Dirección de Comunicación y Sistemas Telefónicos"),
          ('984','18','01',"Ente de Control y Regulación de Telecomunicaciones"),
          ('986','01','01',"Secretaría de Cultura"),
          ('986','16','01',"Centro Cultural y de Convenciones \"La Vieja Usina\""),
          ('986','17','01',"Casa de la Cultura"),
          ('986','18','01',"Dirección del Archivo General de la Provincia"),
          ('986','19','01',"Museos de la Provincia"),
          ('986','19','02',"Museo de Ciencias Naturales y Antropológicas \"Profesor Antonio Serrano\""),
          ('986','20','01',"Bibliotecas de la Provincia"),
          ('986','21','01',"Orquesta Sinfónica"),
          ('986','22','01',"Editorial de Entre Ríos"),
          ('986','23','01',"Instituto Audiovisual de Entre Ríos"),
          ('986','24','01',"Centro Experimental de Industrias Culturales Entrerrianas"),
          ('987','27','01',"Instituto Provincial de Discapacidad"),
          ('987','27','03',"Complejo Recreativo de Integración - Ascona - Federación"),
          ('987','27','04',"Consejo Provincial Asesor para la Discapacidad"))

db_cur.execute('''CREATE TABLE IF NOT EXISTS diradmin(id_da TEXT NOT NULL PRIMARY KEY,
                                                      denominacion TEXT NOT NULL)''')

db_cur.execute('''CREATE TABLE IF NOT EXISTS uejecutoras(da TEXT NOT NULL,
														 pg TEXT NOT NULL,
														 ac TEXT NOT NULL,
														 den TEXT NOT NULL,
														 PRIMARY KEY (da, pg, ac))''')

db_cur.executemany("INSERT OR IGNORE INTO diradmin VALUES(?,?)", (diradmin))
db_cur.executemany("INSERT OR IGNORE INTO uejecutoras VALUES(?,?,?,?)", (unidades))

def denominacionDA(da):
    db_cur.execute('SELECT denominacion FROM diradmin WHERE id_da= ' + da)
    denominacion = db_cur.fetchone()
    if denominacion:
        denominacion = denominacion[0]
    else:
        denominacion = '***Dirección de Administración Desconocida***'

    return 'D. A. Nº ' + da + ' - ' + denominacion

def denominacionUE(da, pg, ac):
    query = "SELECT den FROM uejecutoras WHERE da='" + da + "' AND pg='" + pg + "' AND ac='" + ac + "'"
    db_cur.execute(query)
    denominacion = db_cur.fetchone()
    if denominacion:
        denominacion = denominacion[0]
    else:
        denominacion = '***Unidad Ejecutora Desconocida***'
    
    return 'PG ' + pg + ' - AC ' + ac + ': ' + denominacion

def query_totales(da="", pg="", ac="", inciso=""):
    db_conn=sqlite3.connect(BASE)
    db_cur=db_conn.cursor()
    
    filtro=""
    
    if da:
        filtro += ' AND da="' + da + '"'
    if pg:
        filtro += ' AND pg="' + pg + '"' 
    if ac:
        filtro += ' AND ac="' + ac + '"'
    if inciso:
        filtro += ' AND inciso="' + inciso + '"'

    query_t = '''SELECT 
                   PRINTF("_%.2f",TOTAL(credito_original)) AS 'Crédito Original',
                   PRINTF("_%.2f",TOTAL(variaciones)) AS 'Variaciones',
                   PRINTF("_%.2f",TOTAL(credito_actual)) AS 'Crédito Actual',
                   PRINTF("_%.2f",TOTAL(retenido)) AS 'Retenido',
                   PRINTF("_%.2f",TOTAL(pendiente_liberacion)) AS 'Pendiente Liberación',
                   PRINTF("_%.2f",TOTAL(disponible)) AS 'Disponible',
                   PRINTF("_%.2f",TOTAL((disponible + pendiente_liberacion))) AS 'Disponible Real'
               FROM ''' + tabla + ''' WHERE pg!="90" AND inciso!="1"''' + filtro
    db_cur.execute(query_t)
    r = db_cur.fetchall()
    
    resultado = []
    
    for rows in r:
        for f in rows:
            resultado.append(convertirMoneda(f.replace('_','')))
    db_conn.close() 
    return resultado

def salida_html(ARCHIVO_SALIDA_HTML):
    query = '''SELECT da AS 'DA',
                  pg || '-' || ac AS 'PG-AC',
                  fte || '-' || sfte AS 'F-SFTE',
                  inciso || '.' || principal || '.' ||
                  parcial || '.' || subparc || '-' ||
                  dpto || '.' || ug AS 'Partida',
                  descripcion AS 'Descripción',
                  PRINTF("_%.2f",credito_original) AS 'Crédito Original',
                  PRINTF("_%.2f",variaciones) AS 'Variaciones',
                  PRINTF("_%.2f",credito_actual) AS 'Crédito Actual',
                  PRINTF("_%.2f",retenido) AS 'Retenido',
                  PRINTF("_%.2f",pendiente_liberacion) AS 'Pendiente Liberación',
                  PRINTF("_%.2f",disponible) AS 'Disponible',
                  PRINTF("_%.2f",(disponible + pendiente_liberacion)) AS 'Disponible Real'
              FROM ''' + tabla + ''' WHERE pg!="90" AND inciso!="1" AND pg='01' AND ac='01'
              ORDER BY da ASC, pg ASC, ac ASC'''
    db_conn=sqlite3.connect(BASE)
    db_conn.row_factory = sqlite3.Row
    db_cur = db_conn.cursor()
    db_cur.execute(query)
    row = db_cur.fetchone()
    
    da_actual=row['da']
    pg_actual, ac_actual = row['PG-AC'].split('-')
    inciso_actual = row['Partida'][0]
    
    print(da_actual, pg_actual, ac_actual, inciso_actual)

    while row:
        for f in row:
            print(f)
        row = db_cur.fetchone()
    
    db_conn.close()
    

def convertirMoneda(valor):
    return locale.currency(float(valor), grouping=True).replace('+','')

def procesarEstados(archivocsv):
    with open(archivocsv, 'r') as estados_csv:
        reader = csv.reader(estados_csv, delimiter=';')
        next(reader) # Descarto los encabezados (nombres de columna) 
        
        diccionario_estados = {} # Diccionario en el que voy a guardar cada estado
        
        for registro in reader:
            tmp_registro = []
            for campo in registro:
                tmp_registro.append(campo.replace('_','').replace(',','.')) # Elimino guiones y cambio separadores de decimales
                
            clave = ''
            for i in range(0, 20):
                clave += tmp_registro[i] + ' '
            clave = clave.rstrip()
            
            tmp_registro.append('0') # agrego un cero en PENDIENTE LIBERACION
            tmp_registro.append('0') # agrego un cero en RETENIDO
            
            # acá está la magia, las claves del diccionario_estados son la
            # codificación de la partida y el estado es el valor asociado
            diccionario_estados[clave] = tmp_registro[20:]
        estados_csv.close()
    return diccionario_estados

def procesarCodigos(archivocsv):
    with open(archivocsv, 'r') as codigos_csv:
        reader = csv.reader(codigos_csv, delimiter=';')
        next(reader) # Descarto los encabezados
        
        lista_codigos = []
        
        for registro in reader:
            tmp_registro = []
            registro.pop(1), registro.pop() # elimino las fechas y las descripciones de los códigos
            tmp_registro.append(registro[0].replace('.', ' ').strip()) # codificación partida
            tmp_registro.append(registro.pop(1).replace(',','.')) # monto reserva
            tmp_registro.append(registro.pop(1)) # código reserva
            lista_codigos.append(tmp_registro)
        codigos_csv.close()
    return lista_codigos


# JUNTANDO TODO
diccionario_salida = procesarEstados(ARCHIVO_ESTADOS)

for i in procesarCodigos(ARCHIVO_CODIGOS):
    clave = i[0]
    valor = i[1]
    codigo = i[2]

    if codigo == CODIGO_CORRALITO:
        diccionario_salida[clave][-2] = valor # guardo el PENDIENTE_LIBERACION
    elif codigo == CODIGO_RECORTE:
        diccionario_salida[clave][-1] = valor # guardo el RETENIDO

for clave in sorted(diccionario_salida.keys()):
    registro = clave.split() + diccionario_salida[clave]
    db_cur.execute("INSERT INTO " + tabla + " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", (registro))

db_conn.commit()


query = '''SELECT da AS 'DA',
                  pg || '-' || ac AS 'PG-AC',
                  fte || '-' || sfte AS 'F-SFTE',
                  inciso || '.' || principal || '.' ||
                  parcial || '.' || subparc || '-' ||
                  dpto || '.' || ug AS 'Partida',
                  descripcion AS 'Descripción',
                  PRINTF("_%.2f",credito_original) AS 'Crédito Original',
                  PRINTF("_%.2f",variaciones) AS 'Variaciones',
                  PRINTF("_%.2f",credito_actual) AS 'Crédito Actual',
                  PRINTF("_%.2f",retenido) AS 'Retenido',
                  PRINTF("_%.2f",pendiente_liberacion) AS 'Pendiente Liberación',
                  PRINTF("_%.2f",disponible) AS 'Disponible',
                  PRINTF("_%.2f",(disponible + pendiente_liberacion)) AS 'Disponible Real'
           FROM ''' + tabla + ''' WHERE pg!="90" AND inciso!="1"
           ORDER BY da ASC, pg ASC, ac ASC'''

# row_factory
db_conn.row_factory = sqlite3.Row
c = db_conn.cursor()
c.execute(query)
r = c.fetchall()


def salidaCSV():
    # Saliendo en CSV
    with open(ARCHIVO_SALIDA_CSV, 'w', newline='') as salida: # Archivo CSV con consulta a la db
        writer = csv.writer(salida, delimiter=";")
        writer.writerow(r[0].keys()) # Nombres de las Columnas
                
        for reg in (r): # Registros
            writer.writerow(reg)
        
        salida.close()

def salidaHTML(archivo):
    # Saliendo en HTML row_factory
    with open(archivo, 'w', newline='') as salida:
        salida.write('''<!DOCTYPE html>\n<html>\n<style>
    table {
        width: 90%;
        margin-left: auto;
        margin-right: auto;
    }
    tr:hover { background-color: #f5f5ef; }
    
    table, th, td {
        border: 1px solid black;
        border-collapse: collapse;
        padding: 5px;
        vertical-align-middle;    
    }
    th { background-color: #e0e0d1; }
    .left { text-align: left; }
    .total_da { background-color: blue; 
                text-align: right;
              }    
    </style>\n<body>\n<table>\n<tr>''')
        for nombre_col in r[0].keys(): # Nombres de las Columnas
            salida.write("<th>" + nombre_col + "</th>")
        salida.write("</tr>\n")
        
        colspan = str(len(r[0].keys())-3)
        da_actual = r[0]['DA']
        pg_ac_actual = r[0]['PG-AC']
        
        salida.write("<tr class=\"left\"><th colspan=3></th><th colspan=" + colspan + ">" + denominacionDA(da_actual) + "</th></tr>\n")
        salida.write("<tr class=\"left\"><th colspan=3></th><th colspan=" + colspan + ">" + denominacionUE(da_actual, *pg_ac_actual.split('-')) + "</th></tr>\n")
        
        for reg in (r): # Registros
            da_tmp = reg['DA']
            pg_ac_tmp = reg['PG-AC']
            
            if da_tmp != da_actual:
                salida.write("<tr class=\"total_da\"><th colspan=5>TOTALES DA Nº "+ da_actual +"</th>")
                for t in query_totales(str(da_actual)):
                    salida.write("<th>" + t + "</th>")
                salida.write("</tr>\n")
                salida.write("<tr class=\"left\"><th colspan=3></th><th colspan=" + colspan + ">" + denominacionDA(da_tmp) + "</th></tr>\n")
                da_actual = da_tmp
                
            if pg_ac_tmp != pg_ac_actual:
                salida.write("<tr class=\"total_pg_ac\"><th colspan=5>TOTALES "+ denominacionUE(da_actual, *pg_ac_actual.split('-')) +"</th>")
                for t in query_totales(str(da_actual), *pg_ac_actual.split('-')):
                    salida.write("<th>" + t + "</th>")
                salida.write("</tr>\n")
                salida.write("<tr class=\"left\"><th colspan=3></th><th colspan=" + colspan + ">" + denominacionUE(da_actual, *pg_ac_tmp.split('-')) + "</th></tr>\n")
                pg_ac_actual = pg_ac_tmp
    
            salida.write("<tr>")
            for celda in reg:
                if '_' in celda:
                    salida.write("<td>" + convertirMoneda(celda.replace('_', '')) + "</td>")
                else:
                    salida.write("<td>" + celda + "</td>")
            salida.write("</tr>\n")
        # if da_tmp == da_actual:
                # salida.write("<tr class=\"total_da\"><th colspan=5>TOTALES DA Nº "+ da_actual +"</th>")
                # for t in query_totales(str(da_actual)):
                    # salida.write("<th>" + t + "</th>")
                # salida.write("</tr>\n")
        salida.write('</table></body></html>')
        salida.close()

# salidaHTML(ARCHIVO_SALIDA_HTML)

salidaHTML(ARCHIVO_SALIDA_HTML)

db_conn.close()
print("GRACIAS POR UTILIZAR EP-PY")