Enviar correo
This commit is contained in:
parent
28bb6a74d1
commit
8ff857ec73
|
@ -14,8 +14,15 @@
|
||||||
#~ https://github.com/kennethreitz/requests/blob/v1.2.3/requests/structures.py#L37
|
#~ https://github.com/kennethreitz/requests/blob/v1.2.3/requests/structures.py#L37
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import smtplib
|
||||||
import collections
|
import collections
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
from email.mime.base import MIMEBase
|
||||||
|
from email.mime.text import MIMEText
|
||||||
|
from email import encoders
|
||||||
|
from email.utils import formatdate
|
||||||
|
|
||||||
|
|
||||||
class CaseInsensitiveDict(collections.MutableMapping):
|
class CaseInsensitiveDict(collections.MutableMapping):
|
||||||
|
@ -223,3 +230,80 @@ class NumLet(object):
|
||||||
return re.sub('$', 's', palabra)
|
return re.sub('$', 's', palabra)
|
||||||
else:
|
else:
|
||||||
return palabra + 'es'
|
return palabra + 'es'
|
||||||
|
|
||||||
|
|
||||||
|
class SendMail(object):
|
||||||
|
|
||||||
|
def __init__(self, config):
|
||||||
|
self._config = config
|
||||||
|
self._server = None
|
||||||
|
self._error = ''
|
||||||
|
self._is_connect = self._login()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_connect(self):
|
||||||
|
return self._is_connect
|
||||||
|
|
||||||
|
@property
|
||||||
|
def error(self):
|
||||||
|
return self._error
|
||||||
|
|
||||||
|
def _login(self):
|
||||||
|
try:
|
||||||
|
if self._config['ssl']:
|
||||||
|
self._server = smtplib.SMTP_SSL(
|
||||||
|
self._config['servidor'],
|
||||||
|
self._config['puerto'], timeout=10)
|
||||||
|
else:
|
||||||
|
self._server = smtplib.SMTP(
|
||||||
|
self._config['servidor'],
|
||||||
|
self._config['puerto'], timeout=10)
|
||||||
|
self._server.login(self._config['usuario'], self._config['contra'])
|
||||||
|
return True
|
||||||
|
except smtplib.SMTPAuthenticationError as e:
|
||||||
|
if '535' in str(e):
|
||||||
|
self._error = 'Nombre de usuario o contraseña inválidos'
|
||||||
|
return False
|
||||||
|
if '534' in str(e) and 'gmail' in self._config['servidor']:
|
||||||
|
self._error = 'Necesitas activar el acceso a otras ' \
|
||||||
|
'aplicaciones en tu cuenta de GMail'
|
||||||
|
return False
|
||||||
|
except smtplib.SMTPException as e:
|
||||||
|
self._error = str(e)
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
self._error = str(e)
|
||||||
|
return False
|
||||||
|
return
|
||||||
|
|
||||||
|
def send(self, options):
|
||||||
|
try:
|
||||||
|
message = MIMEMultipart()
|
||||||
|
message['From'] = self._config['usuario']
|
||||||
|
message['To'] = options['para']
|
||||||
|
message['CC'] = options['copia']
|
||||||
|
message['Subject'] = options['asunto']
|
||||||
|
message['Date'] = formatdate(localtime=True)
|
||||||
|
message.attach(MIMEText(options['mensaje'], 'html'))
|
||||||
|
for f in options['files']:
|
||||||
|
part = MIMEBase('application', 'octet-stream')
|
||||||
|
part.set_payload(f[0])
|
||||||
|
encoders.encode_base64(part)
|
||||||
|
part.add_header(
|
||||||
|
'Content-Disposition',
|
||||||
|
"attachment; filename={}".format(f[1]))
|
||||||
|
message.attach(part)
|
||||||
|
|
||||||
|
receivers = options['para'].split(',') + options['copia'].split(',')
|
||||||
|
self._server.sendmail(
|
||||||
|
self._config['usuario'], receivers, message.as_string())
|
||||||
|
return ''
|
||||||
|
except Exception as e:
|
||||||
|
return str(e)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
try:
|
||||||
|
self._server.quit()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return
|
||||||
|
|
|
@ -76,12 +76,33 @@ class AppValues(object):
|
||||||
if file_object is None:
|
if file_object is None:
|
||||||
session = req.env['beaker.session']
|
session = req.env['beaker.session']
|
||||||
values = req.params
|
values = req.params
|
||||||
req.context['result'] = self._db.validate_cert(values, session)
|
if table == 'correo':
|
||||||
|
req.context['result'] = self._db.validate_email(values)
|
||||||
|
elif table == 'sendmail':
|
||||||
|
req.context['result'] = self._db.send_email(values, session)
|
||||||
|
else:
|
||||||
|
req.context['result'] = self._db.validate_cert(values, session)
|
||||||
else:
|
else:
|
||||||
req.context['result'] = self._db.add_cert(file_object)
|
req.context['result'] = self._db.add_cert(file_object)
|
||||||
resp.status = falcon.HTTP_200
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
|
||||||
|
class AppConfig(object):
|
||||||
|
|
||||||
|
def __init__(self, db):
|
||||||
|
self._db = db
|
||||||
|
|
||||||
|
def on_get(self, req, resp):
|
||||||
|
values = req.params
|
||||||
|
req.context['result'] = self._db.get_config(values)
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
def on_post(self, req, resp):
|
||||||
|
values = req.params
|
||||||
|
req.context['result'] = self._db.add_config(values)
|
||||||
|
resp.status = falcon.HTTP_200
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class AppPartners(object):
|
class AppPartners(object):
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,9 @@ import time
|
||||||
import unicodedata
|
import unicodedata
|
||||||
import uuid
|
import uuid
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from smtplib import SMTPException, SMTPAuthenticationError
|
||||||
from xml.etree import ElementTree as ET
|
from xml.etree import ElementTree as ET
|
||||||
|
|
||||||
import uno
|
import uno
|
||||||
|
@ -25,7 +27,7 @@ from com.sun.star.awt import Size
|
||||||
import pyqrcode
|
import pyqrcode
|
||||||
from dateutil import parser
|
from dateutil import parser
|
||||||
|
|
||||||
from .helper import CaseInsensitiveDict, NumLet
|
from .helper import CaseInsensitiveDict, NumLet, SendMail
|
||||||
from settings import DEBUG, log, template_lookup, COMPANIES, DB_SAT, \
|
from settings import DEBUG, log, template_lookup, COMPANIES, DB_SAT, \
|
||||||
PATH_XSLT, PATH_XSLTPROC, PATH_OPENSSL, PATH_TEMPLATES, PRE
|
PATH_XSLT, PATH_XSLTPROC, PATH_OPENSSL, PATH_TEMPLATES, PRE
|
||||||
|
|
||||||
|
@ -926,3 +928,33 @@ def to_zip(*files):
|
||||||
|
|
||||||
return zip_buffer.getvalue()
|
return zip_buffer.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
def make_fields(xml):
|
||||||
|
doc = ET.fromstring(xml)
|
||||||
|
data = CaseInsensitiveDict(doc.attrib.copy())
|
||||||
|
data.pop('certificado')
|
||||||
|
data.pop('sello')
|
||||||
|
version = data['version']
|
||||||
|
receptor = doc.find('{}Receptor'.format(PRE[version]))
|
||||||
|
receptor = CaseInsensitiveDict(receptor.attrib.copy())
|
||||||
|
data['receptor_nombre'] = receptor['nombre']
|
||||||
|
data['receptor_rfc'] = receptor['rfc']
|
||||||
|
data = {k.lower(): v for k, v in data.items()}
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
def make_info_mail(data, fields):
|
||||||
|
return data.format(**fields).replace('\n', '<br/>')
|
||||||
|
|
||||||
|
|
||||||
|
def send_mail(data):
|
||||||
|
msg = ''
|
||||||
|
server = SendMail(data['server'])
|
||||||
|
is_connect = server.is_connect
|
||||||
|
if is_connect:
|
||||||
|
msg = server.send(data['options'])
|
||||||
|
else:
|
||||||
|
msg = server.error
|
||||||
|
server.close()
|
||||||
|
return {'ok': is_connect, 'msg': msg}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ from middleware import (
|
||||||
)
|
)
|
||||||
from models.db import StorageEngine
|
from models.db import StorageEngine
|
||||||
from controllers.main import (
|
from controllers.main import (
|
||||||
AppLogin, AppLogout, AppAdmin, AppEmisor,
|
AppLogin, AppLogout, AppAdmin, AppEmisor, AppConfig,
|
||||||
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
|
AppMain, AppValues, AppPartners, AppProducts, AppInvoices, AppFolios,
|
||||||
AppDocumentos
|
AppDocumentos
|
||||||
)
|
)
|
||||||
|
@ -38,6 +38,7 @@ api.add_route('/emisor', AppEmisor(db))
|
||||||
api.add_route('/folios', AppFolios(db))
|
api.add_route('/folios', AppFolios(db))
|
||||||
api.add_route('/main', AppMain(db))
|
api.add_route('/main', AppMain(db))
|
||||||
api.add_route('/values/{table}', AppValues(db))
|
api.add_route('/values/{table}', AppValues(db))
|
||||||
|
api.add_route('/config', AppConfig(db))
|
||||||
api.add_route('/doc/{type_doc}/{id_doc}', AppDocumentos(db))
|
api.add_route('/doc/{type_doc}/{id_doc}', AppDocumentos(db))
|
||||||
api.add_route('/partners', AppPartners(db))
|
api.add_route('/partners', AppPartners(db))
|
||||||
api.add_route('/products', AppProducts(db))
|
api.add_route('/products', AppProducts(db))
|
||||||
|
|
|
@ -14,12 +14,24 @@ class StorageEngine(object):
|
||||||
def get_values(self, table, values=None):
|
def get_values(self, table, values=None):
|
||||||
return getattr(self, '_get_{}'.format(table))(values)
|
return getattr(self, '_get_{}'.format(table))(values)
|
||||||
|
|
||||||
|
def get_config(self, values):
|
||||||
|
return main.Configuracion.get_(values)
|
||||||
|
|
||||||
|
def add_config(self, values):
|
||||||
|
return main.Configuracion.add(values)
|
||||||
|
|
||||||
def add_cert(self, file_object):
|
def add_cert(self, file_object):
|
||||||
return main.Certificado.add(file_object)
|
return main.Certificado.add(file_object)
|
||||||
|
|
||||||
def validate_cert(self, values, session):
|
def validate_cert(self, values, session):
|
||||||
return main.Certificado.validate(values, session)
|
return main.Certificado.validate(values, session)
|
||||||
|
|
||||||
|
def validate_email(self, values):
|
||||||
|
return main.test_correo(values)
|
||||||
|
|
||||||
|
def send_email(self, values, session):
|
||||||
|
return main.Facturas.send(values['id'], session['rfc'])
|
||||||
|
|
||||||
def _get_cert(self, values):
|
def _get_cert(self, values):
|
||||||
return main.Certificado.get_data()
|
return main.Certificado.get_data()
|
||||||
|
|
||||||
|
|
|
@ -59,9 +59,34 @@ def desconectar():
|
||||||
|
|
||||||
|
|
||||||
class Configuracion(BaseModel):
|
class Configuracion(BaseModel):
|
||||||
clave = TextField()
|
clave = TextField(unique=True)
|
||||||
valor = TextField(default='')
|
valor = TextField(default='')
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_(cls, keys):
|
||||||
|
if keys['fields'] == 'correo':
|
||||||
|
fields = ('correo_servidor', 'correo_puerto', 'correo_ssl',
|
||||||
|
'correo_usuario', 'correo_contra', 'correo_copia',
|
||||||
|
'correo_asunto', 'correo_mensaje', 'correo_directo')
|
||||||
|
data = (Configuracion
|
||||||
|
.select()
|
||||||
|
.where(Configuracion.clave.in_(fields))
|
||||||
|
)
|
||||||
|
values = {r.clave: r.valor for r in data}
|
||||||
|
return values
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add(cls, values):
|
||||||
|
try:
|
||||||
|
for k, v in values.items():
|
||||||
|
obj, created = Configuracion.get_or_create(clave=k)
|
||||||
|
obj.valor = v
|
||||||
|
obj.save()
|
||||||
|
return {'ok': True}
|
||||||
|
except Exception as e:
|
||||||
|
log.error(str(e))
|
||||||
|
return {'ok': False, 'msg': str(e)}
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
order_by = ('clave',)
|
order_by = ('clave',)
|
||||||
indexes = (
|
indexes = (
|
||||||
|
@ -1059,6 +1084,47 @@ class Facturas(BaseModel):
|
||||||
|
|
||||||
return file_zip, name_zip
|
return file_zip, name_zip
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def send(cls, id, rfc):
|
||||||
|
values = Configuracion.get_({'fields': 'correo'})
|
||||||
|
#~ print (server)
|
||||||
|
obj = Facturas.get(Facturas.id==id)
|
||||||
|
if obj.uuid is None:
|
||||||
|
msg = 'La factura no esta timbrada'
|
||||||
|
return {'ok': False, 'msg': msg}
|
||||||
|
|
||||||
|
if not obj.cliente.correo_facturas:
|
||||||
|
msg = 'El cliente no tiene configurado el correo para facturas'
|
||||||
|
return {'ok': False, 'msg': msg}
|
||||||
|
|
||||||
|
files = (cls.get_zip(id, rfc),)
|
||||||
|
|
||||||
|
fields = util.make_fields(obj.xml)
|
||||||
|
server = {
|
||||||
|
'servidor': values['correo_servidor'],
|
||||||
|
'puerto': values['correo_puerto'],
|
||||||
|
'ssl': bool(int(values['correo_ssl'])),
|
||||||
|
'usuario': values['correo_usuario'],
|
||||||
|
'contra': values['correo_contra'],
|
||||||
|
}
|
||||||
|
options = {
|
||||||
|
'para': obj.cliente.correo_facturas,
|
||||||
|
'copia': values['correo_copia'],
|
||||||
|
'asunto': util.make_info_mail(values['correo_asunto'], fields),
|
||||||
|
'mensaje': util.make_info_mail(values['correo_mensaje'], fields),
|
||||||
|
'files': files,
|
||||||
|
}
|
||||||
|
data= {
|
||||||
|
'server': server,
|
||||||
|
'options': options,
|
||||||
|
}
|
||||||
|
result = util.send_mail(data)
|
||||||
|
if not result['ok'] or result['msg']:
|
||||||
|
return {'ok': False, 'msg': result['msg']}
|
||||||
|
|
||||||
|
msg = 'Factura enviada correctamente'
|
||||||
|
return {'ok': True, 'msg': msg}
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_(cls, values):
|
def get_(cls, values):
|
||||||
rows = tuple(Facturas
|
rows = tuple(Facturas
|
||||||
|
@ -1450,6 +1516,28 @@ def get_sat_key(key):
|
||||||
return util.get_sat_key('products', key)
|
return util.get_sat_key('products', key)
|
||||||
|
|
||||||
|
|
||||||
|
def test_correo(values):
|
||||||
|
server = {
|
||||||
|
'servidor': values['correo_servidor'],
|
||||||
|
'puerto': values['correo_puerto'],
|
||||||
|
'ssl': bool(values['correo_ssl'].replace('0', '')),
|
||||||
|
'usuario': values['correo_usuario'],
|
||||||
|
'contra': values['correo_contra'],
|
||||||
|
}
|
||||||
|
options = {
|
||||||
|
'para': values['correo_usuario'],
|
||||||
|
'copia': values['correo_copia'],
|
||||||
|
'asunto': values['correo_asunto'],
|
||||||
|
'mensaje': values['correo_mensaje'].replace('\n', '<br/>'),
|
||||||
|
'files': [],
|
||||||
|
}
|
||||||
|
data= {
|
||||||
|
'server': server,
|
||||||
|
'options': options,
|
||||||
|
}
|
||||||
|
return util.send_mail(data)
|
||||||
|
|
||||||
|
|
||||||
def _init_values():
|
def _init_values():
|
||||||
data = (
|
data = (
|
||||||
{'key': 'version', 'value': VERSION},
|
{'key': 'version', 'value': VERSION},
|
||||||
|
|
|
@ -16,6 +16,8 @@ var controllers = {
|
||||||
$$('up_cert').attachEvent('onUploadComplete', up_cert_upload_complete)
|
$$('up_cert').attachEvent('onUploadComplete', up_cert_upload_complete)
|
||||||
$$('cmd_agregar_serie').attachEvent('onItemClick', cmd_agregar_serie_click)
|
$$('cmd_agregar_serie').attachEvent('onItemClick', cmd_agregar_serie_click)
|
||||||
$$('grid_folios').attachEvent('onItemClick', grid_folios_click)
|
$$('grid_folios').attachEvent('onItemClick', grid_folios_click)
|
||||||
|
$$('cmd_probar_correo').attachEvent('onItemClick', cmd_probar_correo_click)
|
||||||
|
$$('cmd_guardar_correo').attachEvent('onItemClick', cmd_guardar_correo_click)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +177,24 @@ function get_table_folios(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function get_config_correo(){
|
||||||
|
var form = $$('form_correo')
|
||||||
|
var fields = form.getValues()
|
||||||
|
|
||||||
|
webix.ajax().get('/config', {'fields': 'correo'}, {
|
||||||
|
error: function(text, data, xhr) {
|
||||||
|
msg = 'Error al consultar'
|
||||||
|
msg_error(msg)
|
||||||
|
},
|
||||||
|
success: function(text, data, xhr) {
|
||||||
|
var values = data.json()
|
||||||
|
form.setValues(values)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function multi_admin_change(prevID, nextID){
|
function multi_admin_change(prevID, nextID){
|
||||||
//~ webix.message(nextID)
|
//~ webix.message(nextID)
|
||||||
if(nextID == 'app_emisor'){
|
if(nextID == 'app_emisor'){
|
||||||
|
@ -188,6 +208,11 @@ function multi_admin_change(prevID, nextID){
|
||||||
get_table_folios()
|
get_table_folios()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(nextID == 'app_correo'){
|
||||||
|
get_config_correo()
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -442,10 +467,120 @@ function grid_folios_click(id, e, node){
|
||||||
msg_error(msg)
|
msg_error(msg)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function validar_correo(values){
|
||||||
|
|
||||||
|
if(!values.correo_servidor.trim()){
|
||||||
|
msg = 'El servidor de salida no puede estar vacío'
|
||||||
|
msg_error(msg)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(!values.correo_puerto){
|
||||||
|
msg = 'El puerto no puede ser cero'
|
||||||
|
msg_error(msg)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(!values.correo_usuario.trim()){
|
||||||
|
msg = 'El nombre de usuario no puede estar vacío'
|
||||||
|
msg_error(msg)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(!values.correo_contra.trim()){
|
||||||
|
msg = 'La contraseña no puede estar vacía'
|
||||||
|
msg_error(msg)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(!values.correo_asunto.trim()){
|
||||||
|
msg = 'El asunto del correo no puede estar vacío'
|
||||||
|
msg_error(msg)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if(!values.correo_mensaje.trim()){
|
||||||
|
msg = 'El mensaje del correo no puede estar vacío'
|
||||||
|
msg_error(msg)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cmd_probar_correo_click(){
|
||||||
|
var form = $$('form_correo')
|
||||||
|
var values = form.getValues()
|
||||||
|
|
||||||
|
if(!validar_correo(values)){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
webix.ajax().sync().post('/values/correo', values, {
|
||||||
|
error: function(text, data, xhr) {
|
||||||
|
msg = 'Error al probar el correo'
|
||||||
|
msg_error(msg)
|
||||||
|
},
|
||||||
|
success: function(text, data, xhr) {
|
||||||
|
var values = data.json();
|
||||||
|
if (values.ok){
|
||||||
|
msg = 'Correo de prueba enviado correctamente. Ya puedes \
|
||||||
|
guardar esta configuración'
|
||||||
|
msg_sucess(msg)
|
||||||
|
}else{
|
||||||
|
msg_error(values.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function save_config_mail(values){
|
||||||
|
|
||||||
|
webix.ajax().sync().post('/config', values, {
|
||||||
|
error: function(text, data, xhr) {
|
||||||
|
msg = 'Error al guardar la configuración'
|
||||||
|
msg_error(msg)
|
||||||
|
},
|
||||||
|
success: function(text, data, xhr) {
|
||||||
|
var values = data.json();
|
||||||
|
if (values.ok){
|
||||||
|
msg = 'Configuración guardada correctamente'
|
||||||
|
msg_sucess(msg)
|
||||||
|
}else{
|
||||||
|
msg_error(values.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function cmd_guardar_correo_click(){
|
||||||
|
var form = $$('form_correo')
|
||||||
|
var values = form.getValues()
|
||||||
|
|
||||||
|
if(!validar_correo(values)){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = 'Asegurate de haber probado la configuración<BR><BR>\
|
||||||
|
¿Estás seguro de guardar estos datos?'
|
||||||
|
webix.confirm({
|
||||||
|
title: 'Configuración de correo',
|
||||||
|
ok: 'Si',
|
||||||
|
cancel: 'No',
|
||||||
|
type: 'confirm-error',
|
||||||
|
text: msg,
|
||||||
|
callback:function(result){
|
||||||
|
if(result){
|
||||||
|
save_config_mail(values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -642,6 +642,41 @@ function cmd_invoice_timbrar_click(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function enviar_correo(row){
|
||||||
|
if(!row.uuid){
|
||||||
|
msg_error('La factura no esta timbrada')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg = '¿Estás seguro de enviar por correo esta factura?'
|
||||||
|
webix.confirm({
|
||||||
|
title: 'Enviar Factura',
|
||||||
|
ok: 'Si',
|
||||||
|
cancel: 'No',
|
||||||
|
type: 'confirm-error',
|
||||||
|
text: msg,
|
||||||
|
callback:function(result){
|
||||||
|
if(result){
|
||||||
|
webix.ajax().post('/values/sendmail', {'id': row.id}, {
|
||||||
|
error:function(text, data, XmlHttpRequest){
|
||||||
|
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||||
|
msg_error(msg)
|
||||||
|
},
|
||||||
|
success:function(text, data, XmlHttpRequest){
|
||||||
|
values = data.json();
|
||||||
|
if(values.ok){
|
||||||
|
msg_sucess(values.msg)
|
||||||
|
}else{
|
||||||
|
msg_error(values.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function grid_invoices_click(id, e, node){
|
function grid_invoices_click(id, e, node){
|
||||||
var row = this.getItem(id)
|
var row = this.getItem(id)
|
||||||
|
|
||||||
|
@ -652,7 +687,7 @@ function grid_invoices_click(id, e, node){
|
||||||
}else if(id.column == 'zip'){
|
}else if(id.column == 'zip'){
|
||||||
location = '/doc/zip/' + row.id
|
location = '/doc/zip/' + row.id
|
||||||
}else if(id.column == 'email'){
|
}else if(id.column == 'email'){
|
||||||
show('Correo')
|
enviar_correo(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ var menu_data = [
|
||||||
{id: 'app_home', icon: 'dashboard', value: 'Inicio'},
|
{id: 'app_home', icon: 'dashboard', value: 'Inicio'},
|
||||||
{id: 'app_emisor', icon: 'user-circle', value: 'Emisor'},
|
{id: 'app_emisor', icon: 'user-circle', value: 'Emisor'},
|
||||||
{id: 'app_folios', icon: 'sort-numeric-asc', value: 'Folios'},
|
{id: 'app_folios', icon: 'sort-numeric-asc', value: 'Folios'},
|
||||||
|
{id: 'app_correo', icon: 'envelope-o', value: 'Correo'},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -205,6 +206,55 @@ var emisor_folios = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var emisor_correo = [
|
||||||
|
{template: 'Servidor de Salida', type: 'section'},
|
||||||
|
{cols: [
|
||||||
|
{view: 'text', id: 'correo_servidor', name: 'correo_servidor',
|
||||||
|
label: 'Servidor SMTP: '},
|
||||||
|
{}]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'counter', id: 'correo_puerto', name: 'correo_puerto',
|
||||||
|
label: 'Puerto: ', value: 26, step: 1},
|
||||||
|
{}]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'checkbox', id: 'correo_ssl', name: 'correo_ssl',
|
||||||
|
label: 'Usar TLS/SSL: '},
|
||||||
|
{}]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'text', id: 'correo_usuario', name: 'correo_usuario',
|
||||||
|
label: 'Usuario: '},
|
||||||
|
{}]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'text', id: 'correo_contra', name: 'correo_contra',
|
||||||
|
label: 'Contraseña: ', type: 'password'},
|
||||||
|
{}]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'text', id: 'correo_copia', name: 'correo_copia',
|
||||||
|
label: 'Con copia a: '}
|
||||||
|
]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'text', id: 'correo_asunto', name: 'correo_asunto',
|
||||||
|
label: 'Asunto del correo: '}
|
||||||
|
]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'textarea', id: 'correo_mensaje', name: 'correo_mensaje',
|
||||||
|
label: 'Mensaje del correo: ', height: 200}
|
||||||
|
]},
|
||||||
|
{cols: [
|
||||||
|
{view: 'checkbox', id: 'correo_directo', name: 'correo_directo',
|
||||||
|
label: 'Enviar directamente: '},
|
||||||
|
{}]},
|
||||||
|
{minHeight: 25},
|
||||||
|
{cols: [{},
|
||||||
|
{view: 'button', id: 'cmd_probar_correo', label: 'Probar Configuración',
|
||||||
|
autowidth: true, type: 'form'},
|
||||||
|
{maxWidth: 100},
|
||||||
|
{view: 'button', id: 'cmd_guardar_correo', label: 'Guardar Configuración',
|
||||||
|
autowidth: true, type: 'form'},
|
||||||
|
{}]}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
var controls_folios = [
|
var controls_folios = [
|
||||||
{
|
{
|
||||||
view: 'tabview',
|
view: 'tabview',
|
||||||
|
@ -219,6 +269,20 @@ var controls_folios = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
var controls_correo = [
|
||||||
|
{
|
||||||
|
view: 'tabview',
|
||||||
|
id: 'tab_correo',
|
||||||
|
tabbar: {options: ['Correo Electrónico']},
|
||||||
|
animate: true,
|
||||||
|
cells: [
|
||||||
|
{id: 'Correo Electrónico', rows: emisor_correo},
|
||||||
|
{},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
var form_folios = {
|
var form_folios = {
|
||||||
type: 'space',
|
type: 'space',
|
||||||
cols: [{
|
cols: [{
|
||||||
|
@ -239,6 +303,22 @@ var form_folios = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var form_correo = {
|
||||||
|
type: 'space',
|
||||||
|
cols: [{
|
||||||
|
view: 'form',
|
||||||
|
id: 'form_correo',
|
||||||
|
complexData: true,
|
||||||
|
elements: controls_correo,
|
||||||
|
elementsConfig: {
|
||||||
|
labelWidth: 150,
|
||||||
|
labelAlign: 'right'
|
||||||
|
},
|
||||||
|
autoheight: true
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var app_emisor = {
|
var app_emisor = {
|
||||||
id: 'app_emisor',
|
id: 'app_emisor',
|
||||||
rows:[
|
rows:[
|
||||||
|
@ -267,6 +347,17 @@ var app_folios = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var app_correo = {
|
||||||
|
id: 'app_correo',
|
||||||
|
rows:[
|
||||||
|
{view: 'template', id: 'th_correo', type: 'header',
|
||||||
|
template: 'Configuración de correo'},
|
||||||
|
form_correo,
|
||||||
|
{},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var multi_admin = {
|
var multi_admin = {
|
||||||
id: 'multi_admin',
|
id: 'multi_admin',
|
||||||
animate: true,
|
animate: true,
|
||||||
|
@ -278,6 +369,7 @@ var multi_admin = {
|
||||||
},
|
},
|
||||||
app_emisor,
|
app_emisor,
|
||||||
app_folios,
|
app_folios,
|
||||||
|
app_correo,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue