|
|
@ -1,131 +1,131 @@ |
|
|
|
|
|
|
|
|
|
|
|
import smtplib |
|
|
|
# import smtplib |
|
|
|
from email.mime.multipart import MIMEMultipart |
|
|
|
# from email.mime.multipart import MIMEMultipart |
|
|
|
from email.mime.text import MIMEText |
|
|
|
# from email.mime.text import MIMEText |
|
|
|
import pyodbc |
|
|
|
# import pyodbc |
|
|
|
import json |
|
|
|
# import json |
|
|
|
import datetime |
|
|
|
# import datetime |
|
|
|
|
|
|
|
|
|
|
|
# Cargar la información de conexión desde el archivo JSON |
|
|
|
# # Cargar la información de conexión desde el archivo JSON |
|
|
|
with open('config.json', 'r') as config_file: |
|
|
|
# with open('config.json', 'r') as config_file: |
|
|
|
config = json.load(config_file) |
|
|
|
# config = json.load(config_file) |
|
|
|
|
|
|
|
|
|
|
|
# Crear una cadena de conexión usando la información del archivo JSON |
|
|
|
# # Crear una cadena de conexión usando la información del archivo JSON |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
conn_str = ( |
|
|
|
# conn_str = ( |
|
|
|
f"DRIVER=ODBC Driver 17 for SQL Server;" |
|
|
|
# f"DRIVER=ODBC Driver 17 for SQL Server;" |
|
|
|
f"SERVER={config['server']};" |
|
|
|
# f"SERVER={config['server']};" |
|
|
|
f"DATABASE={config['database']};" |
|
|
|
# f"DATABASE={config['database']};" |
|
|
|
f"UID={config['username']};" |
|
|
|
# f"UID={config['username']};" |
|
|
|
f"PWD={config['password']};" |
|
|
|
# f"PWD={config['password']};" |
|
|
|
) |
|
|
|
# ) |
|
|
|
|
|
|
|
|
|
|
|
# Conectar a la base de datos |
|
|
|
# # Conectar a la base de datos |
|
|
|
conn = pyodbc.connect(conn_str) |
|
|
|
# conn = pyodbc.connect(conn_str) |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
# try: |
|
|
|
cursor = conn.cursor() |
|
|
|
# cursor = conn.cursor() |
|
|
|
# fecha = '2023-09-05' # Ejemplo de fecha |
|
|
|
# fecha = '2023-09-11' # Ejemplo de fecha |
|
|
|
fecha = datetime.date.today() |
|
|
|
# # fecha = datetime.date.today() |
|
|
|
cursor.execute("{CALL NotificacionCruze(?)}", fecha) |
|
|
|
# cursor.execute("{CALL NotificacionCruze(?)}", fecha) |
|
|
|
|
|
|
|
|
|
|
|
# Recuperar los resultados del procedimiento almacenado |
|
|
|
# # Recuperar los resultados del procedimiento almacenado |
|
|
|
rows = cursor.fetchall() |
|
|
|
# rows = cursor.fetchall() |
|
|
|
|
|
|
|
|
|
|
|
# Configurar el servidor de correo electrónico saliente (SMTP) desde el archivo JSON |
|
|
|
# # Configurar el servidor de correo electrónico saliente (SMTP) desde el archivo JSON |
|
|
|
with open('config.json', 'r') as email_config_file: |
|
|
|
# with open('config.json', 'r') as email_config_file: |
|
|
|
email_config = json.load(email_config_file) |
|
|
|
# email_config = json.load(email_config_file) |
|
|
|
|
|
|
|
|
|
|
|
smtp_server = email_config['EmailServer'] |
|
|
|
# smtp_server = email_config['EmailServer'] |
|
|
|
smtp_port = email_config['EmailPort'] |
|
|
|
# smtp_port = email_config['EmailPort'] |
|
|
|
|
|
|
|
|
|
|
|
# Tus credenciales de correo electrónico desde el archivo JSON |
|
|
|
# # Tus credenciales de correo electrónico desde el archivo JSON |
|
|
|
sender_email = email_config['EmailUser'] |
|
|
|
# sender_email = email_config['EmailUser'] |
|
|
|
sender_password = email_config['EmailPassword'] |
|
|
|
# sender_password = email_config['EmailPassword'] |
|
|
|
|
|
|
|
|
|
|
|
factura_data = {} |
|
|
|
# factura_data = {} |
|
|
|
|
|
|
|
|
|
|
|
# Iterar a través de los resultados y agruparlos por factura |
|
|
|
# # Iterar a través de los resultados y agruparlos por factura |
|
|
|
for row in rows: |
|
|
|
# for row in rows: |
|
|
|
invoice = row.Invoice |
|
|
|
# invoice = row.Invoice |
|
|
|
if invoice not in factura_data: |
|
|
|
# if invoice not in factura_data: |
|
|
|
factura_data[invoice] = [] |
|
|
|
# factura_data[invoice] = [] |
|
|
|
factura_data[invoice].append(row) |
|
|
|
# factura_data[invoice].append(row) |
|
|
|
|
|
|
|
|
|
|
|
# Crear un diccionario para almacenar los correos de CorreosResponsables y NotificacionAA por factura |
|
|
|
# # Crear un diccionario para almacenar los correos de CorreosResponsables y NotificacionAA por factura |
|
|
|
correos_por_factura = {} |
|
|
|
# correos_por_factura = {} |
|
|
|
|
|
|
|
|
|
|
|
# Iterar a través de los resultados y agrupar los correos por factura |
|
|
|
# # Iterar a través de los resultados y agrupar los correos por factura |
|
|
|
for row in rows: |
|
|
|
# for row in rows: |
|
|
|
invoice = row.Invoice |
|
|
|
# invoice = row.Invoice |
|
|
|
if invoice not in correos_por_factura: |
|
|
|
# if invoice not in correos_por_factura: |
|
|
|
correos_por_factura[invoice] = {'CorreosResponsables': [], 'NotificacionAA': []} |
|
|
|
# correos_por_factura[invoice] = {'CorreosResponsables': [], 'NotificacionAA': []} |
|
|
|
|
|
|
|
|
|
|
|
correos_responsables = row.CorreosResponsables.split(',') if row.CorreosResponsables else [] |
|
|
|
# correos_responsables = row.CorreosResponsables.split(',') if row.CorreosResponsables else [] |
|
|
|
notificacion_aa = row.NotificacionAA.split(',') if row.NotificacionAA else [] |
|
|
|
# notificacion_aa = row.NotificacionAA.split(',') if row.NotificacionAA else [] |
|
|
|
|
|
|
|
|
|
|
|
correos_por_factura[invoice]['CorreosResponsables'].extend(correos_responsables) |
|
|
|
# correos_por_factura[invoice]['CorreosResponsables'].extend(correos_responsables) |
|
|
|
correos_por_factura[invoice]['NotificacionAA'].extend(notificacion_aa) |
|
|
|
# correos_por_factura[invoice]['NotificacionAA'].extend(notificacion_aa) |
|
|
|
|
|
|
|
|
|
|
|
# Iterar a través de las facturas y enviar correos |
|
|
|
# # Iterar a través de las facturas y enviar correos |
|
|
|
for invoice, correos_en_factura in correos_por_factura.items(): |
|
|
|
# for invoice, correos_en_factura in correos_por_factura.items(): |
|
|
|
correos_responsables = correos_en_factura['CorreosResponsables'] |
|
|
|
# correos_responsables = correos_en_factura['CorreosResponsables'] |
|
|
|
notificacion_aa = correos_en_factura['NotificacionAA'] |
|
|
|
# notificacion_aa = correos_en_factura['NotificacionAA'] |
|
|
|
|
|
|
|
|
|
|
|
# Obtener los datos comunes para la factura (fecha, invoice, caja, vigenciaDoda, notificacion) |
|
|
|
# # Obtener los datos comunes para la factura (fecha, invoice, caja, vigenciaDoda, notificacion) |
|
|
|
first_row = factura_data[invoice][0] |
|
|
|
# first_row = factura_data[invoice][0] |
|
|
|
fechaActual = first_row.FechaActual |
|
|
|
# fechaActual = first_row.FechaActual |
|
|
|
caja = first_row.Caja |
|
|
|
# caja = first_row.Caja |
|
|
|
vigenciaDoda = first_row.VigenciaDODA |
|
|
|
# vigenciaDoda = first_row.VigenciaDODA |
|
|
|
notificacion = first_row.Notificacion |
|
|
|
# notificacion = first_row.Notificacion |
|
|
|
|
|
|
|
|
|
|
|
# Crear el mensaje de correo electrónico |
|
|
|
# # Crear el mensaje de correo electrónico |
|
|
|
msg = MIMEMultipart() |
|
|
|
# msg = MIMEMultipart() |
|
|
|
msg['From'] = sender_email |
|
|
|
# msg['From'] = sender_email |
|
|
|
msg['Subject'] = f"Información de factura {invoice}" |
|
|
|
# msg['Subject'] = f"Información de factura {invoice}" |
|
|
|
|
|
|
|
|
|
|
|
# Crear el cuerpo del mensaje con los datos de la factura en una tabla |
|
|
|
# # Crear el cuerpo del mensaje con los datos de la factura en una tabla |
|
|
|
message = f"<html><body>" |
|
|
|
# message = f"<html><body>" |
|
|
|
message += f"<h2>Factura {invoice}</h2>" |
|
|
|
# message += f"<h2>Factura {invoice}</h2>" |
|
|
|
message += f"<table border='1'><tr><th>Fecha Actual</th><th>Invoice</th><th>Caja</th><th>VigenciaDODA</th><th>Notificacion</th></tr>" |
|
|
|
# message += f"<table border='1'><tr><th>Fecha Actual</th><th>Invoice</th><th>Caja</th><th>VigenciaDODA</th><th>Notificacion</th></tr>" |
|
|
|
message += f"<tr><td>{fechaActual}</td><td>{invoice}</td><td>{caja}</td><td>{vigenciaDoda}</td><td>{notificacion}</td></tr>" |
|
|
|
# message += f"<tr><td>{fechaActual}</td><td>{invoice}</td><td>{caja}</td><td>{vigenciaDoda}</td><td>{notificacion}</td></tr>" |
|
|
|
message += f"</table><br>" |
|
|
|
# message += f"</table><br>" |
|
|
|
|
|
|
|
|
|
|
|
# message += f"<h3>CorreosResponsables:</h3>" |
|
|
|
# # message += f"<h3>CorreosResponsables:</h3>" |
|
|
|
# message += "<ul>" |
|
|
|
# # message += "<ul>" |
|
|
|
# for destinatario in correos_responsables: |
|
|
|
# # for destinatario in correos_responsables: |
|
|
|
# message += f"<li>{destinatario}</li>" |
|
|
|
# # message += f"<li>{destinatario}</li>" |
|
|
|
# message += "</ul>" |
|
|
|
# # message += "</ul>" |
|
|
|
|
|
|
|
|
|
|
|
# message += f"<h3>NotificacionAA:</h3>" |
|
|
|
# # message += f"<h3>NotificacionAA:</h3>" |
|
|
|
# message += "<ul>" |
|
|
|
# # message += "<ul>" |
|
|
|
# for destinatario in notificacion_aa: |
|
|
|
# # for destinatario in notificacion_aa: |
|
|
|
# message += f"<li>{destinatario}</li>" |
|
|
|
# # message += f"<li>{destinatario}</li>" |
|
|
|
# message += "</ul>" |
|
|
|
# # message += "</ul>" |
|
|
|
|
|
|
|
|
|
|
|
message += "</body></html>" |
|
|
|
# message += "</body></html>" |
|
|
|
msg.attach(MIMEText(message, 'html')) |
|
|
|
# msg.attach(MIMEText(message, 'html')) |
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
# try: |
|
|
|
# Establecer la conexión al servidor SMTP |
|
|
|
# # Establecer la conexión al servidor SMTP |
|
|
|
server = smtplib.SMTP(smtp_server, smtp_port) |
|
|
|
# server = smtplib.SMTP(smtp_server, smtp_port) |
|
|
|
server.starttls() |
|
|
|
# server.starttls() |
|
|
|
server.login(sender_email, sender_password) |
|
|
|
# server.login(sender_email, sender_password) |
|
|
|
|
|
|
|
|
|
|
|
# Enviar el correo a todos los destinatarios de CorreosResponsables y NotificacionAA |
|
|
|
# # Enviar el correo a todos los destinatarios de CorreosResponsables y NotificacionAA |
|
|
|
destinatarios = correos_responsables + notificacion_aa |
|
|
|
# destinatarios = correos_responsables + notificacion_aa |
|
|
|
server.sendmail(sender_email, destinatarios, msg.as_string()) |
|
|
|
# server.sendmail(sender_email, destinatarios, msg.as_string()) |
|
|
|
print(f"Correo enviado a CorreosResponsables y NotificacionAA de factura {invoice}") |
|
|
|
# print(f"Correo enviado a CorreosResponsables y NotificacionAA de factura {invoice}") |
|
|
|
|
|
|
|
|
|
|
|
# Cerrar la conexión SMTP |
|
|
|
# # Cerrar la conexión SMTP |
|
|
|
server.quit() |
|
|
|
# server.quit() |
|
|
|
except Exception as e: |
|
|
|
# except Exception as e: |
|
|
|
print(f"Error al enviar correo de factura {invoice}: {e}") |
|
|
|
# print(f"Error al enviar correo de factura {invoice}: {e}") |
|
|
|
|
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
# except Exception as e: |
|
|
|
print("Error al conectarse:", e) |
|
|
|
# print("Error al conectarse:", e) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Codigo doode se mejora el envio de las notificaciones AA en ves de una por una un resumen de las Facturas Mejora a futuro. |
|
|
|
# Codigo doode se mejora el envio de las notificaciones AA en ves de una por una un resumen de las Facturas Mejora a futuro. |
|
|
@ -293,6 +293,148 @@ except Exception as e: |
|
|
|
# except Exception as e: |
|
|
|
# except Exception as e: |
|
|
|
# print("Error al conectarse:", e) |
|
|
|
# print("Error al conectarse:", e) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#codigo de se le agrego correo tipos viaje . |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import smtplib |
|
|
|
|
|
|
|
from email.mime.multipart import MIMEMultipart |
|
|
|
|
|
|
|
from email.mime.text import MIMEText |
|
|
|
|
|
|
|
import pyodbc |
|
|
|
|
|
|
|
import json |
|
|
|
|
|
|
|
import datetime |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Cargar la información de conexión desde el archivo JSON |
|
|
|
|
|
|
|
with open('config.json', 'r') as config_file: |
|
|
|
|
|
|
|
config = json.load(config_file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Crear una cadena de conexión usando la información del archivo JSON |
|
|
|
|
|
|
|
conn_str = ( |
|
|
|
|
|
|
|
f"DRIVER=ODBC Driver 17 for SQL Server;" |
|
|
|
|
|
|
|
f"SERVER={config['server']};" |
|
|
|
|
|
|
|
f"DATABASE={config['database']};" |
|
|
|
|
|
|
|
f"UID={config['username']};" |
|
|
|
|
|
|
|
f"PWD={config['password']};" |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Conectar a la base de datos |
|
|
|
|
|
|
|
conn = pyodbc.connect(conn_str) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
cursor = conn.cursor() |
|
|
|
|
|
|
|
fecha = '2023-09-13' # Ejemplo de fecha |
|
|
|
|
|
|
|
cursor.execute("{CALL NotificacionCruze(?)}", fecha) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Recuperar los resultados del procedimiento almacenado |
|
|
|
|
|
|
|
rows = cursor.fetchall() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Configurar el servidor de correo electrónico saliente (SMTP) desde el archivo JSON |
|
|
|
|
|
|
|
with open('config.json', 'r') as email_config_file: |
|
|
|
|
|
|
|
email_config = json.load(email_config_file) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
smtp_server = email_config['EmailServer'] |
|
|
|
|
|
|
|
smtp_port = email_config['EmailPort'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Tus credenciales de correo electrónico desde el archivo JSON |
|
|
|
|
|
|
|
sender_email = email_config['EmailUser'] |
|
|
|
|
|
|
|
sender_password = email_config['EmailPassword'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
factura_data = {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Iterar a través de los resultados y agruparlos por factura |
|
|
|
|
|
|
|
for row in rows: |
|
|
|
|
|
|
|
invoice = row.Invoice |
|
|
|
|
|
|
|
if invoice not in factura_data: |
|
|
|
|
|
|
|
factura_data[invoice] = [] |
|
|
|
|
|
|
|
factura_data[invoice].append(row) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Crear un diccionario para almacenar los correos de CorreosResponsables, NotificacionAA y CorreosTipoViaje por factura |
|
|
|
|
|
|
|
correos_por_factura = {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Iterar a través de los resultados y agrupar los correos por factura |
|
|
|
|
|
|
|
for row in rows: |
|
|
|
|
|
|
|
invoice = row.Invoice |
|
|
|
|
|
|
|
if invoice not in correos_por_factura: |
|
|
|
|
|
|
|
correos_por_factura[invoice] = {'CorreosResponsables': [], 'NotificacionAA': [], 'CorreoTipoViaje': []} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
correos_responsables = row.CorreosResponsables.split(',') if row.CorreosResponsables else [] |
|
|
|
|
|
|
|
notificacion_aa = row.NotificacionAA.split(',') if row.NotificacionAA else [] |
|
|
|
|
|
|
|
correos_tipo_viaje = row.CorreoTipoViaje.split(',') if row.CorreoTipoViaje else [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
correos_por_factura[invoice]['CorreosResponsables'].extend(correos_responsables) |
|
|
|
|
|
|
|
correos_por_factura[invoice]['NotificacionAA'].extend(notificacion_aa) |
|
|
|
|
|
|
|
correos_por_factura[invoice]['CorreoTipoViaje'].extend(correos_tipo_viaje) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Iterar a través de las facturas y enviar correos |
|
|
|
|
|
|
|
for invoice, correos_en_factura in correos_por_factura.items(): |
|
|
|
|
|
|
|
correos_responsables = correos_en_factura['CorreosResponsables'] |
|
|
|
|
|
|
|
notificacion_aa = correos_en_factura['NotificacionAA'] |
|
|
|
|
|
|
|
correos_tipo_viaje = correos_en_factura['CorreoTipoViaje'] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Obtener los datos comunes para la factura (fecha, invoice, caja, vigenciaDoda, notificacion) |
|
|
|
|
|
|
|
first_row = factura_data[invoice][0] |
|
|
|
|
|
|
|
fechaActual = first_row.FechaActual |
|
|
|
|
|
|
|
caja = first_row.Caja |
|
|
|
|
|
|
|
vigenciaDoda = first_row.VigenciaDODA |
|
|
|
|
|
|
|
notificacion = first_row.Notificacion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Crear el mensaje de correo electrónico |
|
|
|
|
|
|
|
msg = MIMEMultipart() |
|
|
|
|
|
|
|
msg['From'] = sender_email |
|
|
|
|
|
|
|
msg['Subject'] = f"Información de factura {invoice}" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Crear el cuerpo del mensaje con los datos de la factura en una tabla |
|
|
|
|
|
|
|
message = f"<html><body>" |
|
|
|
|
|
|
|
message += f"<h2>Factura {invoice}</h2>" |
|
|
|
|
|
|
|
message += f"<table border='1'><tr><th>Fecha Actual</th><th>Invoice</th><th>Caja</th><th>VigenciaDODA</th><th>Notificacion</th></tr>" |
|
|
|
|
|
|
|
message += f"<tr><td>{fechaActual}</td><td>{invoice}</td><td>{caja}</td><td>{vigenciaDoda}</td><td>{notificacion}</td></tr>" |
|
|
|
|
|
|
|
message += f"</table><br>" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# # Agregar correos de CorreosResponsables, NotificacionAA y CorreosTipoViaje al mensaje |
|
|
|
|
|
|
|
# message += "<h3>CorreosResponsables:</h3>" |
|
|
|
|
|
|
|
# message += "<ul>" |
|
|
|
|
|
|
|
# for destinatario in correos_responsables: |
|
|
|
|
|
|
|
# message += f"<li>{destinatario}</li>" |
|
|
|
|
|
|
|
# message += "</ul>" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# message += f"<h3>NotificacionAA:</h3>" |
|
|
|
|
|
|
|
# message += "<ul>"s |
|
|
|
|
|
|
|
# for destinatario in notificacion_aa: |
|
|
|
|
|
|
|
# message += f"<li>{destinatario}</li>" |
|
|
|
|
|
|
|
# message += "</ul>" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# message += f"<h3>CorreosTipoViaje:</h3>" |
|
|
|
|
|
|
|
# message += "<ul>" |
|
|
|
|
|
|
|
# for destinatario in correos_tipo_viaje: |
|
|
|
|
|
|
|
# message += f"<li>{destinatario}</li>" |
|
|
|
|
|
|
|
# message += "</ul>" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
message += "</body></html>" |
|
|
|
|
|
|
|
msg.attach(MIMEText(message, 'html')) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try: |
|
|
|
|
|
|
|
# Establecer la conexión al servidor SMTP |
|
|
|
|
|
|
|
server = smtplib.SMTP(smtp_server, smtp_port) |
|
|
|
|
|
|
|
server.starttls() |
|
|
|
|
|
|
|
server.login(sender_email, sender_password) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Enviar el correo a todos los destinatarios de CorreosResponsables, NotificacionAA y CorreosTipoViaje |
|
|
|
|
|
|
|
destinatarios = correos_responsables + notificacion_aa + correos_tipo_viaje |
|
|
|
|
|
|
|
server.sendmail(sender_email, destinatarios, msg.as_string()) |
|
|
|
|
|
|
|
print(f"Correo enviado a CorreosResponsables, NotificacionAA y CorreosTipoViaje de factura {invoice}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Cerrar la conexión SMTP |
|
|
|
|
|
|
|
server.quit() |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
|
|
|
|
print(f"Error al enviar correo de factura {invoice}: {e}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
|
|
|
|
print("Error al conectarse:", e) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|