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

import datetime
import ftplib
import io
import os
import serial
import time
from Tkinter import *

mapa = list()
direccion_mapa = str()
direccion_mapa_procesado = str()
direccion_lecturas = str()
pantalla = str("________")

#################################
# FUNCIONES DE LA INTERFAZ
#################################


def mapa_simple():
    dato = "simple\n"
    mapa.append(dato)
    archivo_mapa = open(direccion_mapa, 'a')
    archivo_mapa.write(dato)
    archivo_mapa.close()
    return pantalla.set("SIMPLE")


def mapa_hueco():
    dato = "hueco\n"
    mapa.append(dato)
    archivo_mapa = open(direccion_mapa, 'a')
    archivo_mapa.write(dato)
    archivo_mapa.close()
    return pantalla.set("HUECO")


def mapa_bulto():
    dato = "bulto\n"
    mapa.append(dato)
    archivo_mapa = open(direccion_mapa, 'a')
    archivo_mapa.write(dato)
    archivo_mapa.close()
    return pantalla.set("BULTO")


def mapa_incidencia():
    dato = "incidencia\n"
    mapa.append(dato)
    archivo_mapa = open(direccion_mapa, 'a')
    archivo_mapa.write(dato)
    archivo_mapa.close()
    return pantalla.set("INCIDENCIA")


def mapa_multicapa_simple():
    dato = "multicapa-simple\n"
    mapa.append(dato)
    archivo_mapa = open(direccion_mapa, 'a')
    archivo_mapa.write(dato)
    archivo_mapa.close()
    return pantalla.set("MULTICAPA SIMPLE")


def mapa_multicapa_incidencia():
    dato = "multicapa-incidencia\n"
    mapa.append(dato)
    archivo_mapa = open(direccion_mapa, 'a')
    archivo_mapa.write(dato)
    archivo_mapa.close()
    return pantalla.set("MULTICAPA INCIDENCIA")


def borrar_ultima():
    mapa.pop()
    archivo_mapa = open(direccion_mapa, 'w')
    archivo_mapa.close()
    for dato in mapa:
        archivo_mapa = open(direccion_mapa, 'a')
        archivo_mapa.write(dato)
        archivo_mapa.close()
    ultimo_dato = mapa[-1][:-1]  # para eliminar /n
    return pantalla.set("LAST: " + ultimo_dato.upper())


def mapear():
    # CREAMOS UN ARCHIVO DONDE IREMOS GUARDANDO EL MAPA
    empresa = dato_empresa.get()
    pasillo = int(dato_pasillo.get())
    pasillo = str("{:03d}".format(pasillo))
    alturamax = int(dato_alturamax.get())
    piking = str(dato_piking.get())

    global direccion_mapa
    fecha = datetime.datetime.now()

    nombre_mapa = "mapa " + str(fecha.year) + str(fecha.month) + \
        str(fecha.day) + " " + empresa + " " + pasillo + ".txt"
    direccion_mapa = "mapas/" + str(nombre_mapa)

    existe_mapa = False
    if(os.path.exists(direccion_mapa) == False):
        archivo_mapa = open(direccion_mapa, "w")
        archivo_mapa.close()
    else:
        archivo_mapa = open(direccion_mapa, "r")
        existe_mapa = True
        # Actualizamos nuestra variable mapa. Podremos continuar el trabajo por donde lo dejamos,
        # pero actualmente no podemos especificar el punto exacto donde lo dejamos
        mapa = archivo_mapa.readlines()
        archivo_mapa.close()
        # Si el mapa se comenzó pero no tiene nigún registro se aconseja borrarlo.
        if(len(mapa) == 0):
            archivo_mapa = open(direccion_mapa, "w")
            archivo_mapa.close()
        # else:
            # TENEMOS QUE CREAR UN AVISO DE QUE EXISTE EL TRABAJO, CON UNA VENTANA EMERGENTE. Y QUE
            # LO VAMOS A CONTINUAR
    pantalla.set("** MAPEO ACTIVO **")


def fin_mapeo():
    global mapa
    global direccion_mapa
    global direccion_mapa_procesado

    pantalla.set("** MAPEO TERMINADO **")
    time.sleep(2)
    pantalla.set("** PROCESANDO MAPEO **")
    # Ahora tenemos que crear la matriz de datos de acuerdo con la altura máxima y la zona de piking
    alturamax = int(dato_alturamax.get())
    piking = str(dato_piking.get())
    if(piking == "True"):
        alturamin = 2
    if(piking == "False"):
        alturamin = 1
    altura = alturamin
    columna = 1
    subiendo = True
    anterior_multicapa = False
    archivo_mapa = open(direccion_mapa, "r")
    procesando_mapa = archivo_mapa.readlines()  # nuestra lista
    archivo_mapa.close()
    direccion_mapa_procesado = direccion_mapa.split("/")
    direccion_mapa_procesado = str(
        direccion_mapa_procesado[0]) + "/procesado " + str(direccion_mapa_procesado[1])
    archivo_mapa_procesado = open(direccion_mapa_procesado, "w")
    archivo_mapa_procesado.close()
    # Algoritmo para el procesamiento de los datos del mapa
    for dato in procesando_mapa:
        analisis_dato = dato.split("-")
        if(analisis_dato[0] == "multicapa"):
            aux2 = str(columna) + "|" + str(altura) + "|" + str(dato)
            archivo_mapa_procesado = open(direccion_mapa_procesado, "a")
            archivo_mapa_procesado.write(aux2)
            archivo_mapa_procesado.close()
            anterior_multicapa = True
        else:
            if(anterior_multicapa == True):
                if(subiendo == True):
                    altura = altura + 1
                    if(altura > alturamax):
                        altura = altura - 1
                        columna = columna + 1
                        subiendo = False
                else:
                    altura = altura - 1
                    if(altura < alturamin):
                        altura = altura + 1
                        columna = columna + 1
                        subiendo = True
                aux2 = str(columna) + "|" + str(altura) + "|" + str(dato)
                archivo_mapa_procesado = open(direccion_mapa_procesado, "a")
                archivo_mapa_procesado.write(aux2)
                archivo_mapa_procesado.close()
            else:
                aux2 = str(columna) + "|" + str(altura) + "|" + str(dato)
                archivo_mapa_procesado = open(direccion_mapa_procesado, "a")
                archivo_mapa_procesado.write(aux2)
                archivo_mapa_procesado.close()
            if(subiendo == True):
                altura = altura + 1
                if(altura > alturamax):
                    altura = altura - 1
                    columna = columna + 1
                    subiendo = False
            else:
                altura = altura - 1
                if(altura < alturamin):
                    altura = altura + 1
                    columna = columna + 1
                    subiendo = True
            anterior_multicapa = False

    pantalla.set("** MAPEO PROCESADO **")
    time.sleep(2)
    mapa.clear()
    direccion_mapa = str()
    pantalla.set("** CREE NUEVO MAPEO **")


def cargar_lecturas():
    global direccion_lecturas

    # Identificamos el nombre del archivo que vamos a capturar
    fecha = datetime.datetime.now()
    empresa = dato_empresa.get()
    pasillo = int(dato_pasillo.get())
    pasillo = str("{:03d}".format(pasillo))
    nombre_lecturas = "lecturas " + \
        str(fecha.year) + str(fecha.month) + str(fecha.day) + \
        " " + empresa + " " + pasillo + ".txt"
    direccion_lecturas = "lecturas/" + str(nombre_lecturas)

    # CAPTURAMOS POR FTP EL ARCHIVO lecturas

    # Datos FTP
    ftp_servidor = 'home662228864.1and1-data.host'
    ftp_usuario = 'u87707226'
    ftp_clave = 'airvant.1'
    # Carpeta del servidor donde queremos subir el fichero
    ftp_raiz = '/OPERATIVAS/Airvant_01/'

    # Datos del fichero a subir
    # Ruta al fichero en el servidor
    fichero_origen = nombre_lecturas
    # Nombre que tendra el fichero en el WBC
    fichero_destino = direccion_lecturas

    # Conectamos con el servidor
    try:
        s = ftplib.FTP(ftp_servidor, ftp_usuario, ftp_clave)
        # class FTP(host='', user='', passwd='', acct='', timeout=_GLOBAL_DEFAULT_TIMEOUT, source_address=None)
        try:
            # Vamos al directorio operativas en el FTP
            s.cwd(ftp_raiz)
            # Dentro del directorio descargamos por binario el archivo de las lecturas
            s.retrbinary('RETR ' + fichero_origen,
                         open(fichero_destino, 'wb').write)
            s.quit()
            print("\n PICAJE DESCARGADO CORRECTAMENTE\n")
        except:
            print("No se ha podido encontrar el fichero " + fichero_origen)
    except:
        print("No se ha podido conectar al servidor " + ftp_servidor)

##################################################################################################
# FUNCIONES ESPECÍFICAS DE ENVÍO Y PROCESADO DEL TRABAJO REALIZADO                               #
##################################################################################################


def crear_EXCEL(direccion_fusionado, direccion_excel):
    from openpyxl import Workbook
    # Creamos una lista con la informacion de archivo_trabajo el archivo tiene que existir
    archivo_fusionado = open(direccion_fusionado, "r")
    # lista creada, que tendremos que procesar
    fusionados = archivo_fusionado.readlines()
    archivo_fusionado.close()
    # Ahora vamos a reconocer si es una lectura Code128 o GS1 128
    aux1 = fusionados[0].split("|")
    # columna | altura | lectura
    aux2 = aux1[2].split(" ")
    # si es gs1 12345678901234 5 123456
    aux_gs1 = False
    if(len(aux2) > 1):
        aux_gs1 = True

    # Si no es gs1, hacemos un guardado normal
    if(aux_gs1 == False):
        items_procesado = list([])
        for lectura in fusionados:
            aux_lista = lectura.split("|")
            # columna, altura, lectura
            aux_lectura = list([aux_lista[0], aux_lista[1], aux_lista[2]])
            items_procesado.append(aux_lectura)
        # Tenemos que crear en memoria el contenido de nuestro archivo excel. Funciona distinto a *.txt
        # wb = openpyxl.workbook.Workbook()
        wb = Workbook()
        ws = wb.active
        ws.title = "Lecturas pasillo"
        # ws = openpyxl.workbook.Workbook.create_sheet("Lecturas pasillo")
        ws.cell(row=1, column=1, value="Columna")
        ws.cell(row=1, column=2, value="Altura")
        ws.cell(row=1, column=3, value="Contenido")
        r = 2
        for dato in items_procesado:
            ws.cell(row=r, column=1, value=dato[0])  # columna
            ws.cell(row=r, column=2, value=dato[1])  # altura
            ws.cell(row=r, column=3, value=dato[2])  # lectura
            r = r + 1
        wb.save(direccion_excel)

    # Si es un gs1, hacemos un guardado especial
    if(aux_gs1 == True):
        items_procesado = list([])
        for lectura in items:
            aux_columna_altura = lectura.split("|")
            aux_codigo = aux_columna_altura[2].split(" ")
            aux_lectura = list([aux_columna_altura[0], aux_columna_altura[1], aux_codigo[0], aux_codigo[1], aux_codigo[2],
                                aux_codigo[3], aux_codigo[4], aux_codigo[5], aux_codigo[6], aux_codigo[7], aux_codigo[8]])
            # columna, altura, 00, 01, 02, 37, 10, 11, 13, 15, 17
            items_procesado.append(aux_lectura)
        # Tenemos que crear en memoria el contenido de nuestro archivo excel. Funciona distinto a *.txt
        # wb = openpyxl.workbook.Workbook()
        wb = Workbook()
        ws = wb.active
        ws.title = "Lecturas pasillo"
        # ws = openpyxl.workbook.Workbook.create_sheet("Lecturas pasillo")
        ws.cell(row=1, column=1, value="Columna")
        ws.cell(row=1, column=2, value="Altura")
        ws.cell(row=1, column=3, value="(00)")
        ws.cell(row=1, column=4, value="(01)")
        ws.cell(row=1, column=5, value="(02)")
        ws.cell(row=1, column=6, value="(37)")
        ws.cell(row=1, column=7, value="(10)")
        ws.cell(row=1, column=8, value="(11)")
        ws.cell(row=1, column=9, value="(13)")
        ws.cell(row=1, column=10, value="(15)")
        ws.cell(row=1, column=11, value="(17)")
        r = 2
        for dato in items_procesado:
            ws.cell(row=r, column=1, value=dato[0])  # columna
            ws.cell(row=r, column=2, value=dato[1])  # altura
            ws.cell(row=r, column=3, value=dato[2])  # (00)
            ws.cell(row=r, column=4, value=dato[3])  # (01)
            ws.cell(row=r, column=5, value=dato[4])  # (02)
            ws.cell(row=r, column=6, value=dato[5])  # (37)
            ws.cell(row=r, column=7, value=dato[6])  # (10)
            ws.cell(row=r, column=8, value=dato[7])  # (11)
            ws.cell(row=r, column=9, value=dato[8])  # (13)
            ws.cell(row=r, column=10, value=dato[9])  # (15)
            ws.cell(row=r, column=11, value=dato[10])  # (17)
            r = r + 1
        wb.save(direccion_excel)


def envio_email(direccion_excel):
        import smtplib
        # Librerias para construir el mensaje
        from email.mime.multipart import MIMEMultipart
        from email.mime.text import MIMEText
        # Librerias para adjuntar archivos
        from email.MIMEBase import MIMEBase
        from email import encoders

        empresa = dato_empresa.get()
        pasillo = int(dato_pasillo.get())
        pasillo = str("{:03d}".format(pasillo))
        # Definimos remitente y receptor
        addr_to = "operativa.airvant@gmail.com"
        addr_from = "operativa.airvant@gmail.com"
        # Definimos SMTP del email
        smtp_server = "stmp.gmail.com"
        smtp_user = "operativa.airvant@gmail.com"
        smtp_pass = "#airvant.onw"
        # Construimos el email
        mensaje = MIMEMultipart()
        mensaje['From'] = addr_from
        mensaje['To'] = addr_to
        mensaje['Subject'] = "Airvant | Empresa: {0} Pasillo: {1}" .format(
            empresa, pasillo)
        # El cuerpo del mensaje se estructura en HTML
        mensaje.attach(MIMEText(
            '<h1>Trabajo de pasillo finalizado</h1><p>Descargue el archivo EXCEL adjunto.<p>Gracias por confiar en <b>Airvant</b>.', 'HTML'))
        # Adjuntamos el archivo de direccion_trabajo
        fp = open(direccion_excel, 'rb')
        adjunto = MIMEBase('multipart', 'encrypted')
        adjunto.set_payload(fp.read())
        fp.close()
        # Encriptamos archivo.
        encoders.encode_base64(adjunto)
        fecha = datetime.datetime.now()
        nombre_archivo = str(fecha.year) + str(fecha.month) + \
            str(fecha.day) + " " + empresa + " " + pasillo + ".xlsx"
        adjunto.add_header('Content-Disposition',
                           'attachment', filename=nombre_archivo)
        mensaje.attach(adjunto)

        # Script para el envío del correo electrónico a la dirección indicada
        mailServer = smtplib.SMTP('smtp.gmail.com', 587)
        mailServer.ehlo()
        mailServer.starttls()
        mailServer.ehlo()
        mailServer.login(smtp_user, smtp_pass)
        mailServer.sendmail(addr_from, addr_to, mensaje.as_string())
        mailServer.quit()


def fusionar_enviar():
    global direccion_lecturas
    global direccion_mapa_procesado

    fecha = datetime.datetime.now()
    empresa = dato_empresa.get()
    pasillo = int(dato_pasillo.get())
    pasillo = str("{:03d}".format(pasillo))
    nombre_fusionado = "fusionado " + \
        str(fecha.year) + str(fecha.month) + str(fecha.day) + \
        " " + empresa + " " + pasillo + ".txt"
    nombre_excel = str(fecha.year) + str(fecha.month) + \
        str(fecha.day) + " " + empresa + " " + pasillo + ".xlsx"
    direccion_fusionado = "terminado/" + nombre_fusionado
    direccion_excel = "terminado/" + nombre_excel

    # FUSION DE DATOS
    archivo_lecturas = open(direccion_lecturas, "r")
    lecturas = archivo_lecturas.readlines()
    archivo_lecturas.close()
    archivo_mapa_procesado = open(direccion_mapa_procesado, "r")
    mapa_procesado = archivo_mapa_procesado.readlines()
    archivo_mapa_procesado.close()
    # Creamos el archivo fusionado
    archivo_fusionado = open(direccion_fusionado, "w")
    archivo_fusionado.close()
    j = 0
    for i in range(len(mapa_procesado)):
        aux_mapa = mapa_procesado[i].split("|")
        if((aux_mapa[2] == "simple\n") or (aux_mapa[2] == "multicapa-simple\n")):
            fusionado = aux_mapa[0] + "|" + aux_mapa[1] + "|" + lecturas[j]
            archivo_fusionado = open(direccion_fusionado, "a")
            archivo_fusionado.write(fusionado)
            archivo_fusionado.close()
            j = j + 1
        else:
            fusionado = aux_mapa[0] + "|" + aux_mapa[1] + "|" + aux_mapa[2]
            archivo_fusionado = open(direccion_fusionado, "a")
            archivo_fusionado.write(fusionado)
            archivo_fusionado.close()
    pantalla.set("** FUSIONADO CORRECTO **")
    # Después del fusionado tenemos que crear el excel
    crear_EXCEL(direccion_fusionado, direccion_excel)
    pantalla.set("** EXCEL CREADO CORRECTO **")
    # Por último enviamos el EXCEL por correo electrónico
    envio_email(direccion_excel)
    pantalla.set("** EXCEL ENVIADO **")
    time.sleep(5)
    pantalla.set("** CREE NUEVO MAPEO **")

###############################
# INTERFAZ DE USUARIO PARA MAPEO
#################################


root = Tk()
root.title("Airvant Mapeo Manual")
root.geometry("480x320")
root.resizable(0, 0)

menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="Salir", command=root.quit)  # root.quit
menubar.add_cascade(label="Archivo", menu=filemenu)
root.config(menu=menubar)
# ESTARÍA BIEN CREAR ALGO QUE PONGA EL DESARROLLADOR DE LA TECNOLOGÍA
# img_airvant = PhotoImage(file="airvant_logo.png")

dato_empresa = StringVar()
dato_pasillo = IntVar()
dato_alturamax = IntVar()
dato_piking = StringVar()
# dato_email = StringVar()
pantalla = StringVar()

# PARTE DE CONFIGURACIÓN DEL MAPEO
Label(root, text="EMPRESA").grid(row=0, column=0)
Entry(root, textvariable=dato_empresa).grid(row=0, column=1)
Label(root, text="PASILLO").grid(row=1, column=0)
Label(root, text="ALTURA").grid(row=1, column=1)
Entry(root, textvariable=dato_pasillo, width=4).grid(row=2, column=0)
Entry(root, textvariable=dato_alturamax, width=2).grid(row=2, column=1)
Radiobutton(root, text="piking en 1", variable=dato_piking,
            value="True").grid(row=3, column=0)
Radiobutton(root, text="sin piking", variable=dato_piking,
            value="False").grid(row=3, column=1)

Label(root, bg="CadetBlue", textvariable=pantalla).grid(
    row=0, column=2, columnspan=2)
pantalla.set("** CREE MAPEO **")
Button(root, text="SIMPLE", command=mapa_simple).grid(row=1, column=2)
Button(root, text="MULT-SIMPLE",
       command=mapa_multicapa_simple).grid(row=1, column=3)
Button(root, text="HUECO", command=mapa_hueco).grid(row=2, column=2)
Button(root, text="BULTO", command=mapa_bulto).grid(row=2, column=3)
Button(root, text="INCIDENCIA", command=mapa_incidencia).grid(row=3, column=2)
Button(root, text="MULT-INCIDENCIA",
       command=mapa_multicapa_incidencia).grid(row=3, column=3)

Button(root, text="MAPEAR", command=mapear).grid(row=4, column=0)
Button(root, text="FINALIZAR MAPEO", command=fin_mapeo).grid(
    row=4, column=1, columnspan=2)
Button(root, text="BORRAR ÚLTIMA", command=borrar_ultima).grid(row=4, column=3)

Button(root, text="CARGAR LECTURAS",
       command=cargar_lecturas).grid(row=5, column=0)
Button(root, text="FUSIONAR Y ENVIAR",
       command=fusionar_enviar).grid(row=5, column=1)

root.mainloop()
