Actualizar lista de cambios
This commit is contained in:
commit
6de30c3417
23
CHANGELOG.md
23
CHANGELOG.md
|
@ -1,4 +1,25 @@
|
|||
=======
|
||||
v 1.44.0 [10-Ene-2022]
|
||||
----------------------
|
||||
- Soporte para Carta Porte v2 con CFDI 3.3
|
||||
- Soporte para el nuevo esquema de cancelación del SAT
|
||||
|
||||
* IMPORTANTE:
|
||||
|
||||
Es necesario hacer una migración:
|
||||
|
||||
```
|
||||
cd /opt/empresa-libre
|
||||
|
||||
git pull origin master
|
||||
|
||||
cd source/app/models
|
||||
|
||||
python main.py -bk
|
||||
|
||||
python main.py -m -r RFC
|
||||
```
|
||||
|
||||
|
||||
v 1.43.0 [12-Dic-2021]
|
||||
----------------------
|
||||
- Soporte para entradas de almacen.
|
||||
|
|
|
@ -12,6 +12,7 @@ contratar: administracion ARROBA empresalibre.net
|
|||
|
||||
#### Ahora también puede aportar con criptomonedas:
|
||||
|
||||
G1: `A5DdXxCKPw3QKWVdDVs7CzkNugNUW1sHu5zDJFWxCU2h`
|
||||
BCH: `qztd3l00xle5tffdqvh2snvadkuau2ml0uqm4n875d`
|
||||
BTC: `3FhiXcXmAesmQzrNEngjHFnvaJRhU1AGWV`
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import datetime
|
|||
from xml.etree import ElementTree as ET
|
||||
from xml.dom.minidom import parseString
|
||||
|
||||
from dateutil import parser
|
||||
from logbook import Logger
|
||||
|
||||
|
||||
|
@ -96,6 +97,12 @@ SAT = {
|
|||
'xmlns': 'http://www.sat.gob.mx/leyendasFiscales',
|
||||
'schema': ' http://www.sat.gob.mx/leyendasFiscales http://www.sat.gob.mx/sitio_internet/cfd/leyendasFiscales/leyendasFisc.xsd',
|
||||
},
|
||||
'cartaporte': {
|
||||
'version': '2.0',
|
||||
'prefix': 'cartaporte20',
|
||||
'xmlns': 'http://www.sat.gob.mx/CartaPorte20',
|
||||
'schema': ' http://www.sat.gob.mx/CartaPorte20 http://www.sat.gob.mx/sitio_internet/cfd/CartaPorte/CartaPorte20.xsd',
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,6 +121,7 @@ class CFDI(object):
|
|||
self._pagos = False
|
||||
self._is_nomina = False
|
||||
self._leyendas = False
|
||||
self._carta_porte = False
|
||||
self._divisas = ''
|
||||
self.error = ''
|
||||
|
||||
|
@ -165,6 +173,7 @@ class CFDI(object):
|
|||
self._ine = True
|
||||
self._pagos = bool(datos['complementos'].get('pagos', False))
|
||||
self._leyendas = bool(datos['complementos'].get('leyendas', False))
|
||||
self._carta_porte = bool(datos['complementos'].get('cartaporte', False))
|
||||
|
||||
self._divisas = datos['comprobante'].pop('divisas', '')
|
||||
|
||||
|
@ -230,9 +239,16 @@ class CFDI(object):
|
|||
attributes[name] = SAT['leyendas']['xmlns']
|
||||
schema_leyendas = SAT['leyendas']['schema']
|
||||
|
||||
schema_carta_porte = ''
|
||||
if self._carta_porte:
|
||||
name = 'xmlns:{}'.format(SAT['cartaporte']['prefix'])
|
||||
attributes[name] = SAT['cartaporte']['xmlns']
|
||||
schema_carta_porte = SAT['cartaporte']['schema']
|
||||
|
||||
attributes['xsi:schemaLocation'] = self._sat_cfdi['schema'] + \
|
||||
schema_locales + schema_donativo + schema_ine + schema_edu + \
|
||||
schema_divisas + schema_nomina + schema_pagos + schema_leyendas
|
||||
schema_divisas + schema_nomina + schema_pagos + schema_leyendas + \
|
||||
schema_carta_porte
|
||||
attributes.update(datos)
|
||||
|
||||
if not 'Version' in attributes:
|
||||
|
@ -455,6 +471,44 @@ class CFDI(object):
|
|||
self._complemento = ET.SubElement(
|
||||
self._cfdi, '{}:Complemento'.format(self._pre))
|
||||
|
||||
if self._carta_porte:
|
||||
datos = datos['cartaporte']
|
||||
print('\nDatos', datos)
|
||||
ubicaciones = datos.pop('ubicaciones')
|
||||
mercancias = datos.pop('mercancias', ())
|
||||
tiposfigura = datos.pop('tiposfigura', ())
|
||||
|
||||
atributos = {'Version': SAT['cartaporte']['version']}
|
||||
atributos.update(datos)
|
||||
|
||||
prefix = SAT['cartaporte']['prefix']
|
||||
node_carta = ET.SubElement(self._complemento, f'{prefix}:CartaPorte', atributos)
|
||||
|
||||
node = ET.SubElement(node_carta, f'{prefix}:Ubicaciones')
|
||||
for ubicacion in ubicaciones:
|
||||
dt = parser.parse(ubicacion['FechaHoraSalidaLlegada'])
|
||||
ubicacion['FechaHoraSalidaLlegada'] = dt.isoformat()[:19]
|
||||
ET.SubElement(node, f'{prefix}:Ubicacion', ubicacion)
|
||||
|
||||
attr = mercancias
|
||||
mercancias = attr.pop('mercancias')
|
||||
autotransporte = attr.pop('autotransporte')
|
||||
identificacion = autotransporte.pop('identificacion')
|
||||
seguros = autotransporte.pop('seguros')
|
||||
|
||||
node = ET.SubElement(node_carta, f'{prefix}:Mercancias', attr)
|
||||
for mercancia in mercancias:
|
||||
ET.SubElement(node, f'{prefix}:Mercancia', mercancia)
|
||||
|
||||
sub_node = ET.SubElement(node, f'{prefix}:Autotransporte', autotransporte)
|
||||
ET.SubElement(sub_node, f'{prefix}:IdentificacionVehicular', identificacion)
|
||||
ET.SubElement(sub_node, f'{prefix}:Seguros', seguros)
|
||||
|
||||
if tiposfigura:
|
||||
sub_node = ET.SubElement(node_carta, f'{prefix}:FiguraTransporte')
|
||||
for figura in tiposfigura:
|
||||
ET.SubElement(sub_node, f'{prefix}:TiposFigura', figura)
|
||||
|
||||
if self._divisas:
|
||||
atributos = {
|
||||
'version': SAT['divisas']['version'],
|
||||
|
|
|
@ -769,3 +769,21 @@ class AppUsers(object):
|
|||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.users_post(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppSATUnidadesPeso(object):
|
||||
|
||||
def __init__(self, db):
|
||||
self._db = db
|
||||
|
||||
def on_get(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.sat_unidades_peso_get(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
def on_post(self, req, resp):
|
||||
values = req.params
|
||||
user = req.env['beaker.session']['userobj']
|
||||
req.context['result'] = self._db.sat_unidades_peso_post(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
|
|
@ -46,8 +46,8 @@ class PACComercioDigital(object):
|
|||
api = 'https://app2.comercio-digital.mx/{}'
|
||||
URL = {
|
||||
'timbra': ws.format('ws', 'timbre/timbrarV5.aspx'),
|
||||
'cancel': ws.format('cancela', 'cancela3/cancelarUuid'),
|
||||
'cancelxml': ws.format('cancela', 'cancela3/cancelarXml'),
|
||||
'cancel': ws.format('cancela', 'cancela4/cancelarUuid'),
|
||||
'cancelxml': ws.format('cancela', 'cancela4/cancelarXml'),
|
||||
'status': ws.format('cancela', 'arws/consultaEstatus'),
|
||||
'client': api.format('x3/altaEmpresa'),
|
||||
'saldo': api.format('x3/saldo'),
|
||||
|
@ -69,8 +69,8 @@ class PACComercioDigital(object):
|
|||
ws6 = 'https://pruebas6.comercio-digital.mx/arws/{}'
|
||||
URL = {
|
||||
'timbra': ws.format('timbre/timbrarV5.aspx'),
|
||||
'cancel': ws.format('cancela3/cancelarUuid'),
|
||||
'cancelxml': ws.format('cancela3/cancelarXml'),
|
||||
'cancel': ws.format('cancela4/cancelarUuid'),
|
||||
'cancelxml': ws.format('cancela4/cancelarXml'),
|
||||
'status': ws6.format('consultaEstatus'),
|
||||
'client': api.format('x3/altaEmpresa'),
|
||||
'saldo': api.format('x3/saldo'),
|
||||
|
@ -148,7 +148,7 @@ class PACComercioDigital(object):
|
|||
|
||||
def _get_data_cancel(self, cfdi, info, auth):
|
||||
info['pass'] = '12345678a'
|
||||
info['tipo'] = 'cfdi3.3'
|
||||
info['tipo'] = 'cfdi'
|
||||
info['key'] = base64.b64encode(info['key']).decode()
|
||||
info['cer'] = base64.b64encode(info['cer']).decode()
|
||||
|
||||
|
@ -180,16 +180,18 @@ class PACComercioDigital(object):
|
|||
f"PWDK={info['pass']}",
|
||||
f"KEYF={info['key']}",
|
||||
f"CERT={info['cer']}",
|
||||
f"TIPO={info['tipo']}",
|
||||
f"TIPO1={info['tipo']}",
|
||||
f"ACUS=SI",
|
||||
f"RFCR={rfc_receptor}",
|
||||
f"TIPOC={tipo}",
|
||||
f"TOTAL={total}",
|
||||
f"UUIDREL={info['args']['uuid']}",
|
||||
f"MOTIVO={info['args']['reason']}",
|
||||
)
|
||||
return '\n'.join(data)
|
||||
|
||||
def cancel(self, cfdi, info, auth={}):
|
||||
if not auth:
|
||||
if DEBUG or not auth:
|
||||
auth = AUTH
|
||||
url = self.URL['cancel']
|
||||
data = self._get_data_cancel(cfdi, info, auth)
|
||||
|
|
|
@ -47,7 +47,7 @@ logging.getLogger('zeep').setLevel(logging.ERROR)
|
|||
|
||||
|
||||
TIMEOUT = 10
|
||||
DEBUG_SOAP = False
|
||||
DEBUG_SOAP = True
|
||||
|
||||
|
||||
class DebugPlugin(Plugin):
|
||||
|
@ -58,6 +58,7 @@ class DebugPlugin(Plugin):
|
|||
path = f'/tmp/soap_{name}.xml'
|
||||
with open(path, 'w') as f:
|
||||
f.write(data)
|
||||
# ~ print(data)
|
||||
return
|
||||
|
||||
def egress(self, envelope, http_headers, operation, binding_options):
|
||||
|
@ -209,10 +210,16 @@ class PACFinkok(object):
|
|||
client = Client(self.URL[method],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
uuid_type = client.get_type('ns1:UUIDS')
|
||||
sa = client.get_type('ns0:stringArray')
|
||||
|
||||
# ~ sa = client.get_type('ns0:stringArray')
|
||||
ns1_uuid = client.get_type('ns1:UUID')
|
||||
data_uuid = {
|
||||
'UUID': cfdi_uuid,
|
||||
'FolioSustitucion': info['args']['uuid'],
|
||||
'Motivo': info['args']['reason'],
|
||||
}
|
||||
# ~ 'UUIDS': uuid_type(uuids=sa(string=cfdi_uuid)),
|
||||
args = {
|
||||
'UUIDS': uuid_type(uuids=sa(string=cfdi_uuid)),
|
||||
'UUIDS': uuid_type(ns1_uuid(**data_uuid)),
|
||||
'username': auth['user'],
|
||||
'password': auth['pass'],
|
||||
'taxpayer_id': rfc_emisor,
|
||||
|
|
|
@ -72,6 +72,7 @@ from settings import USAR_TOKEN, API, DECIMALES_TAX
|
|||
# ~ from .configpac import AUTH
|
||||
|
||||
|
||||
from .utils import get_qr
|
||||
# ~ v2
|
||||
import segno
|
||||
from .pacs.cfdi_cert import SATCertificate
|
||||
|
@ -250,6 +251,26 @@ def get_sat_unidades(key):
|
|||
return tuple(data)
|
||||
|
||||
|
||||
def get_sat_unidadespeso(key):
|
||||
con = sqlite3.connect(DB_SAT)
|
||||
con.row_factory = sqlite3.Row
|
||||
cursor = con.cursor()
|
||||
|
||||
filtro = '%{}%'.format(key)
|
||||
sql = "SELECT * FROM unidad_peso WHERE key LIKE ? OR name LIKE ?"
|
||||
|
||||
cursor.execute(sql, [filtro, filtro])
|
||||
data = cursor.fetchall()
|
||||
cursor.close()
|
||||
con.close()
|
||||
if data is None:
|
||||
return ()
|
||||
|
||||
data = tuple([dict(r) for r in data])
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def get_sat_productos(key):
|
||||
con = sqlite3.connect(DB_SAT)
|
||||
con.row_factory = sqlite3.Row
|
||||
|
@ -1606,22 +1627,22 @@ def to_letters(value, currency):
|
|||
return NumLet(value, currency).letras
|
||||
|
||||
|
||||
def get_qr(data, p=True):
|
||||
qr = pyqrcode.create(data, mode='binary')
|
||||
if p:
|
||||
path = get_path_temp('.qr')
|
||||
qr.png(path, scale=7)
|
||||
return path
|
||||
# ~ def get_qr(data, p=True):
|
||||
# ~ qr = pyqrcode.create(data, mode='binary')
|
||||
# ~ if p:
|
||||
# ~ path = get_path_temp('.qr')
|
||||
# ~ qr.png(path, scale=7)
|
||||
# ~ return path
|
||||
|
||||
buffer = io.BytesIO()
|
||||
qr.png(buffer, scale=8)
|
||||
return base64.b64encode(buffer.getvalue()).decode()
|
||||
# ~ buffer = io.BytesIO()
|
||||
# ~ qr.png(buffer, scale=8)
|
||||
# ~ return base64.b64encode(buffer.getvalue()).decode()
|
||||
|
||||
|
||||
def get_qr2(data, kind='svg'):
|
||||
buffer = io.BytesIO()
|
||||
segno.make(data).save(buffer, kind=kind, scale=8, border=2)
|
||||
return buffer
|
||||
# ~ def get_qr2(data, kind='svg'):
|
||||
# ~ buffer = io.BytesIO()
|
||||
# ~ segno.make(data).save(buffer, kind=kind, scale=8, border=2)
|
||||
# ~ return buffer
|
||||
|
||||
|
||||
def _get_relacionados(doc, version):
|
||||
|
@ -1877,10 +1898,12 @@ def _timbre(doc, version, values, pdf_from='1'):
|
|||
}
|
||||
qr_data = '{url}{uuid}{emisor}{receptor}{total}{sello}'.format(**qr_data)
|
||||
|
||||
if pdf_from == '1':
|
||||
data['cbb'] = get_qr2(qr_data)
|
||||
else:
|
||||
data['cbb'] = get_qr2(qr_data, 'png')
|
||||
data['cbb'] = get_qr(qr_data, 'png')
|
||||
|
||||
# ~ if pdf_from == '1':
|
||||
# ~ data['cbb'] = get_qr(qr_data, 'png')
|
||||
# ~ else:
|
||||
# ~ data['cbb'] = get_qr(qr_data)
|
||||
|
||||
data['cadenaoriginal'] = CADENA.format(**data)
|
||||
return data
|
||||
|
|
|
@ -665,10 +665,10 @@ def get_pac_by_rfc(cfdi):
|
|||
return RFCS[rfc_pac]
|
||||
|
||||
|
||||
def _cancel_with_cert(invoice, auth, certificado):
|
||||
def _cancel_with_cert(invoice, args, auth, certificado):
|
||||
cert = SATCertificate(certificado.cer, certificado.key_enc.encode())
|
||||
pac = PACS[auth['pac']]()
|
||||
info = {'cer': cert.cer_pem, 'key': cert.key_pem}
|
||||
info = {'cer': cert.cer_pem, 'key': cert.key_pem, 'args': args}
|
||||
|
||||
result = pac.cancel(invoice.xml, info, auth)
|
||||
if pac.error:
|
||||
|
@ -681,9 +681,9 @@ def _cancel_with_cert(invoice, auth, certificado):
|
|||
return data
|
||||
|
||||
|
||||
def cancel_xml_sign(invoice, auth, certificado):
|
||||
if DEBUG:
|
||||
return _cancel_with_cert(invoice, auth, certificado)
|
||||
def cancel_xml_sign(invoice, args, auth, certificado):
|
||||
# ~ if DEBUG:
|
||||
return _cancel_with_cert(invoice, args, auth, certificado)
|
||||
|
||||
cert = SATCertificate(certificado.cer, certificado.key_enc.encode())
|
||||
pac = PACS[auth['pac']]()
|
||||
|
@ -824,13 +824,44 @@ def _products_from_xml(rfc, data):
|
|||
return result
|
||||
|
||||
|
||||
def upload_file(rfc, opt, file_obj):
|
||||
if opt == 'productsadd':
|
||||
result = _products_from_xml(rfc, file_obj.file.read())
|
||||
def save_file(path, data, modo='wb'):
|
||||
try:
|
||||
with open(path, modo) as f:
|
||||
f.write(data)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
def _save_template(rfc, name, file_obj):
|
||||
result = {'status': 'server', 'ok': False}
|
||||
|
||||
ext1 = name[-3:]
|
||||
ext2 = file_obj.filename.split('.')[-1].lower()
|
||||
if ext1 != ext2:
|
||||
msg = f'Extensión incorrecta del archivo: {ext2}'
|
||||
result['error'] = msg
|
||||
return result
|
||||
|
||||
rfc = rfc.lower()
|
||||
path = _join(PATHS['USER'], f'{rfc}{name}')
|
||||
if save_file(path, file_obj.file.read()):
|
||||
result['ok'] = True
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def get_qr(data):
|
||||
def upload_file(rfc, name, file_obj):
|
||||
if name == 'productsadd':
|
||||
return _products_from_xml(rfc, file_obj.file.read())
|
||||
|
||||
return _save_template(rfc, name, file_obj)
|
||||
|
||||
|
||||
def get_qr(data, kind='svg', in_base64=False):
|
||||
buffer = io.BytesIO()
|
||||
segno.make(data).save(buffer, kind='svg', scale=8, border=2)
|
||||
return buffer.getvalue()
|
||||
segno.make(data).save(buffer, kind=kind, scale=8, border=2)
|
||||
qr = buffer
|
||||
if in_base64:
|
||||
qr = base64.b64encode(qr.getvalue()).decode()
|
||||
return qr
|
||||
|
|
|
@ -24,6 +24,7 @@ from controllers.main import (AppEmpresas,
|
|||
AppUsers,
|
||||
AppWareHouse,
|
||||
AppWareHouseProduct,
|
||||
AppSATUnidadesPeso,
|
||||
)
|
||||
|
||||
|
||||
|
@ -76,6 +77,7 @@ api.add_route('/warehouse', AppWareHouse(db))
|
|||
api.add_route('/warehouseproduct', AppWareHouseProduct(db))
|
||||
api.add_route('/ticketsdetails', AppTicketsDetails(db))
|
||||
api.add_route('/users', AppUsers(db))
|
||||
api.add_route('/satunidadespeso', AppSATUnidadesPeso(db))
|
||||
|
||||
|
||||
session_options = {
|
||||
|
|
|
@ -236,6 +236,9 @@ class StorageEngine(object):
|
|||
def _get_satunidades(self, values):
|
||||
return main.get_sat_unidades(values['key'])
|
||||
|
||||
def _get_satunidadespeso(self, values):
|
||||
return main.get_sat_unidadespeso(values['key'])
|
||||
|
||||
def _get_satproductos(self, values):
|
||||
return main.get_sat_productos(values['key'])
|
||||
|
||||
|
@ -514,6 +517,12 @@ class StorageEngine(object):
|
|||
def nomina_get(self, filters, user):
|
||||
return main.CfdiNomina.get_data(filters, user)
|
||||
|
||||
def sat_unidades_peso_get(self, filters, user):
|
||||
return main.SATUnidadesPeso.get_data(filters, user)
|
||||
|
||||
def sat_unidades_peso_post(self, args, user):
|
||||
return main.SATUnidadesPeso.post(args, user)
|
||||
|
||||
# Companies only in MV
|
||||
def _get_empresas(self, values):
|
||||
return main.companies_get()
|
||||
|
|
|
@ -43,6 +43,7 @@ from controllers import utils
|
|||
from settings import (
|
||||
DEBUG,
|
||||
CANCEL_VERSION,
|
||||
CARTA_PORTE,
|
||||
DEFAULT_GLOBAL,
|
||||
DB_COMPANIES,
|
||||
EXT,
|
||||
|
@ -128,6 +129,7 @@ class UploadFile(object):
|
|||
method = f'_read_{opt}'
|
||||
if hasattr(cls, method):
|
||||
return getattr(cls, method)(cls, result)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
@ -145,7 +147,7 @@ def upload_file(rfc, opt, file_obj):
|
|||
return Emisor.save_logo(file_obj)
|
||||
|
||||
# ~ v2
|
||||
names = ('productsadd',)
|
||||
names = ('productsadd', '_3.3_cp_2.0.ods')
|
||||
if opt in names:
|
||||
result = UploadFile.read(rfc, opt, file_obj)
|
||||
return result
|
||||
|
@ -341,6 +343,7 @@ def config_timbrar():
|
|||
'cfdi_anticipo': Configuracion.get_('chk_config_anticipo'),
|
||||
'cfdi_ine': Configuracion.get_bool('chk_config_ine'),
|
||||
'cfdi_edu': Configuracion.get_bool('chk_config_edu'),
|
||||
'cfdi_carta_porte': Configuracion.get_bool('chk_config_carta_porte'),
|
||||
'cfdi_divisas': Configuracion.get_bool('chk_config_divisas'),
|
||||
'cfdi_metodo_pago': Configuracion.get_bool('chk_config_ocultar_metodo_pago'),
|
||||
'cfdi_condicion_pago': Configuracion.get_bool('chk_config_ocultar_condiciones_pago'),
|
||||
|
@ -478,6 +481,7 @@ class Configuracion(BaseModel):
|
|||
fields = (
|
||||
'chk_config_ine',
|
||||
'chk_config_edu',
|
||||
'chk_config_carta_porte',
|
||||
'chk_config_pagos',
|
||||
'chk_config_divisas',
|
||||
'chk_cfg_pays_data_bank',
|
||||
|
@ -1356,6 +1360,77 @@ class CondicionesPago(BaseModel):
|
|||
return obj
|
||||
|
||||
|
||||
class SATUnidadesPeso(BaseModel):
|
||||
key = TextField(unique=True, index=True)
|
||||
name = TextField(default='', index=True)
|
||||
activo = BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
order_by = ('name',)
|
||||
indexes = (
|
||||
(('key', 'name'), True),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return '{} ({})'.format(self.name, self.key)
|
||||
|
||||
@classmethod
|
||||
def _get_all(cls, values, user):
|
||||
rows = tuple(SATUnidadesPeso.select().dicts())
|
||||
return rows
|
||||
|
||||
@classmethod
|
||||
def _get_active(cls, values, user):
|
||||
fields = (
|
||||
SATUnidadesPeso.key.alias('id'),
|
||||
SATUnidadesPeso.name.alias('value'),
|
||||
)
|
||||
where = (SATUnidadesPeso.activo==True)
|
||||
rows = tuple(
|
||||
SATUnidadesPeso.select(*fields).where(where).dicts()
|
||||
)
|
||||
return rows
|
||||
|
||||
@classmethod
|
||||
def get_data(cls, values, user):
|
||||
opt = values.pop('opt')
|
||||
return getattr(cls, f'_get_{opt}')(values, user)
|
||||
|
||||
@classmethod
|
||||
def _add(cls, values, user):
|
||||
result = True
|
||||
try:
|
||||
SATUnidadesPeso.create(**values)
|
||||
except:
|
||||
result = False
|
||||
|
||||
return {'ok': result}
|
||||
|
||||
@classmethod
|
||||
def _delete(cls, values, user):
|
||||
id = values['id']
|
||||
q = SATUnidadesPeso.delete().where(SATUnidadesPeso.id==id)
|
||||
result = bool(q.execute())
|
||||
response = {'ok': result}
|
||||
return response
|
||||
|
||||
@classmethod
|
||||
def _update_active(cls, values, user):
|
||||
id = values['id']
|
||||
update = {'activo': bool(values['activo'])}
|
||||
where = (SATUnidadesPeso.id==id)
|
||||
q = SATUnidadesPeso.update(**update).where(where)
|
||||
result = bool(q.execute())
|
||||
response = {'ok': result}
|
||||
return response
|
||||
|
||||
@classmethod
|
||||
def post(cls, values, user):
|
||||
opt = values['opt']
|
||||
args = utils.loads(values['values'])
|
||||
return getattr(cls, f'_{opt}')(args, user)
|
||||
|
||||
|
||||
class SATUnidades(BaseModel):
|
||||
key = TextField(unique=True, index=True)
|
||||
name = TextField(default='', index=True)
|
||||
|
@ -1378,6 +1453,11 @@ class SATUnidades(BaseModel):
|
|||
except:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_key_by_id(self, id):
|
||||
obj = SATUnidades.get(SATUnidades.id==id)
|
||||
return obj.key
|
||||
|
||||
@classmethod
|
||||
def get_(self):
|
||||
rows = SATUnidades.select().dicts()
|
||||
|
@ -4305,8 +4385,8 @@ class Facturas(BaseModel):
|
|||
return True
|
||||
|
||||
@classmethod
|
||||
def cancel(cls, id):
|
||||
obj = Facturas.get(Facturas.id==id)
|
||||
def cancel(cls, args):
|
||||
obj = Facturas.get(Facturas.id==args['id'])
|
||||
if obj.uuid is None:
|
||||
obj.estatus = 'Cancelada'
|
||||
obj.cancelada = True
|
||||
|
@ -4315,10 +4395,10 @@ class Facturas(BaseModel):
|
|||
msg = 'Factura cancelada correctamente'
|
||||
return {'ok': True, 'msg': msg, 'row': {'estatus': obj.estatus}}
|
||||
|
||||
return cls._cancel_xml_sign(obj)
|
||||
return cls._cancel_xml_sign(obj, args)
|
||||
|
||||
@classmethod
|
||||
def _cancel_xml_sign(cls, invoice):
|
||||
def _cancel_xml_sign(cls, invoice, args):
|
||||
if not invoice.version in CANCEL_VERSION:
|
||||
msg = 'Solo es posible cancelar CFDI >= 3.3'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
@ -4327,7 +4407,7 @@ class Facturas(BaseModel):
|
|||
auth = Configuracion.get_({'fields': 'auth_by_pac', 'pac': pac})
|
||||
|
||||
certificado = Certificado.get(Certificado.es_fiel==False)
|
||||
result = utils.cancel_xml_sign(invoice, auth, certificado)
|
||||
result = utils.cancel_xml_sign(invoice, args, auth, certificado)
|
||||
|
||||
if result['ok']:
|
||||
invoice.estatus = 'Cancelada'
|
||||
|
@ -4668,9 +4748,8 @@ class Facturas(BaseModel):
|
|||
f"&rr={data['receptor_rfc']}&tt={data['cfdi_total']}"
|
||||
f"&fe={data['cfdi_sello'][-8:]}"
|
||||
)
|
||||
cbb = util.get_qr(qr_data, False)
|
||||
cbb = utils.get_qr(qr_data, 'png', True)
|
||||
data['cbb'] = f'data:image/png;base64,{cbb}'
|
||||
# ~ data['cbb'] = utils.get_qr(qr_data)
|
||||
|
||||
return data
|
||||
|
||||
|
@ -5245,6 +5324,23 @@ class Facturas(BaseModel):
|
|||
FacturasComplementos.create(**data)
|
||||
return
|
||||
|
||||
def _save_cartaporte(self, invoice, valores):
|
||||
if not valores:
|
||||
return
|
||||
|
||||
values = utils.loads(valores)
|
||||
mercancias = values['mercancias']
|
||||
for mercancia in mercancias['mercancias']:
|
||||
mercancia['ClaveUnidad'] = SATUnidades.get_key_by_id(mercancia['ClaveUnidad'])
|
||||
|
||||
data = {
|
||||
'factura': invoice,
|
||||
'nombre': 'cartaporte',
|
||||
'valores': utils.dumps(values),
|
||||
}
|
||||
FacturasComplementos.create(**data)
|
||||
return
|
||||
|
||||
def _get_serie(self, user, default_serie):
|
||||
if user.sucursal is None:
|
||||
return default_serie
|
||||
|
@ -5256,6 +5352,7 @@ class Facturas(BaseModel):
|
|||
productos = util.loads(values.pop('productos'))
|
||||
relacionados = util.loads(values.pop('relacionados'))
|
||||
ine = values.pop('ine', {})
|
||||
cartaporte = values.pop('cartaporte', {})
|
||||
tipo_comprobante = values['tipo_comprobante']
|
||||
folio_custom = values.pop('folio_custom', '')
|
||||
divisas = values.pop('divisas', '')
|
||||
|
@ -5282,9 +5379,14 @@ class Facturas(BaseModel):
|
|||
values['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
||||
values['anticipo'] = util.get_bool(values['anticipo'])
|
||||
values['donativo'] = util.get_bool(values['donativo'])
|
||||
|
||||
if tipo_comprobante == 'T':
|
||||
values['metodo_pago'] = ''
|
||||
values['forma_pago'] = ''
|
||||
values['moneda'] = CARTA_PORTE['MONEDA']
|
||||
self_client = Socios.get(Socios.rfc==emisor.rfc)
|
||||
if values['cliente'] != self_client.id:
|
||||
values['cliente'] = self_client
|
||||
|
||||
with database_proxy.atomic() as txn:
|
||||
# ~ print('VALUES\n\n', values)
|
||||
|
@ -5293,6 +5395,7 @@ class Facturas(BaseModel):
|
|||
cls, obj, productos, tipo_comprobante, user)
|
||||
cls._guardar_relacionados(cls, obj, relacionados)
|
||||
cls._guardar_ine(cls, obj, ine)
|
||||
cls._save_cartaporte(cls, obj, cartaporte)
|
||||
cls._save_leyendas_fiscales(cls, obj, leyendas_fiscales)
|
||||
obj.subtotal = totals['subtotal']
|
||||
obj.descuento = totals['descuento']
|
||||
|
@ -5377,7 +5480,6 @@ class Facturas(BaseModel):
|
|||
comprobante['Fecha'] = invoice.fecha.isoformat()[:19]
|
||||
comprobante['FormaPago'] = invoice.forma_pago
|
||||
comprobante['NoCertificado'] = certificado.serie
|
||||
# ~ comprobante['Certificado'] = certificado.cer_txt
|
||||
comprobante['SubTotal'] = FORMAT.format(invoice.subtotal)
|
||||
comprobante['Moneda'] = invoice.moneda
|
||||
comprobante['TipoCambio'] = '1'
|
||||
|
@ -5392,9 +5494,10 @@ class Facturas(BaseModel):
|
|||
comprobante['Descuento'] = FORMAT.format(invoice.descuento)
|
||||
|
||||
if invoice.tipo_comprobante == 'T':
|
||||
comprobante['SubTotal'] = '0.00'
|
||||
comprobante['Total'] = '0.00'
|
||||
comprobante['SubTotal'] = '0'
|
||||
comprobante['Total'] = '0'
|
||||
del comprobante['FormaPago']
|
||||
del comprobante['TipoCambio']
|
||||
|
||||
if invoice.tipo_relacion:
|
||||
relacionados = {
|
||||
|
@ -5996,9 +6099,10 @@ class Facturas(BaseModel):
|
|||
result = {'ok': False, 'msg': msg, 'row': {}}
|
||||
return result
|
||||
|
||||
result = cls.cancel(args['id'])
|
||||
values = utils.loads(args['values'])
|
||||
result = cls.cancel(values)
|
||||
if result['ok']:
|
||||
m = 'C {}'.format(args['id'])
|
||||
m = 'C {}'.format(values['id'])
|
||||
_save_log(user.usuario, m, 'F')
|
||||
return result
|
||||
|
||||
|
@ -10249,6 +10353,10 @@ def get_sat_unidades(key):
|
|||
return util.get_sat_unidades(key)
|
||||
|
||||
|
||||
def get_sat_unidadespeso(key):
|
||||
return util.get_sat_unidadespeso(key)
|
||||
|
||||
|
||||
def get_sat_productos(key):
|
||||
return util.get_sat_productos(key)
|
||||
|
||||
|
@ -10345,6 +10453,7 @@ def _crear_tablas(rfc):
|
|||
InventoryEntries,
|
||||
PartnerInvoices,
|
||||
WareHouseProduct,
|
||||
SATUnidadesPeso,
|
||||
]
|
||||
log.info('Creando tablas...')
|
||||
database_proxy.create_tables(tablas, True)
|
||||
|
@ -10402,6 +10511,7 @@ def _migrate_tables(rfc=''):
|
|||
InventoryEntries,
|
||||
PartnerInvoices,
|
||||
WareHouseProduct,
|
||||
SATUnidadesPeso,
|
||||
]
|
||||
log.info('Creando tablas nuevas...')
|
||||
database_proxy.create_tables(tablas, True)
|
||||
|
|
|
@ -42,7 +42,7 @@ except ImportError:
|
|||
|
||||
|
||||
DEBUG = DEBUG
|
||||
VERSION = '1.43.0'
|
||||
VERSION = '1.44.0'
|
||||
EMAIL_SUPPORT = ('soporte@empresalibre.mx',)
|
||||
TITLE_APP = '{} v{}'.format(TITLE_APP, VERSION)
|
||||
|
||||
|
@ -209,6 +209,10 @@ EXT = {
|
|||
}
|
||||
MXN = 'MXN'
|
||||
|
||||
CARTA_PORTE = {
|
||||
'MONEDA': 'XXX',
|
||||
}
|
||||
|
||||
PATHS = {
|
||||
'STATIC': path_static,
|
||||
'CSS': path_css,
|
||||
|
|
BIN
source/db/sat.db
BIN
source/db/sat.db
Binary file not shown.
|
@ -0,0 +1,473 @@
|
|||
id key name
|
||||
1 Tu Contenedor externo
|
||||
2 X1A Tambor de acero
|
||||
3 X1B Tambor de aluminio
|
||||
4 X1D Tambor contrachapado
|
||||
5 X1F Contenedor flexible
|
||||
6 X1G Tambor de fibra
|
||||
7 X1w Tambor de madera
|
||||
8 X2C Barril de madera
|
||||
9 X3A Bidón de acero
|
||||
10 X3H Bidón de plástico
|
||||
11 X43 Bolsa de gran tamaño
|
||||
12 X44 Bolsa de plástico
|
||||
13 X4A Caja de acero
|
||||
14 X4B Caja de aluminio
|
||||
15 X4C Caja de madera natural
|
||||
16 X4D Caja de contrachapado
|
||||
17 X4F Caja de madera reconstituida
|
||||
18 X4G Caja de cartón
|
||||
19 X4H Caja de plástico
|
||||
20 X5H Bolsa de plástico tejido
|
||||
21 X5L Bolsa textil
|
||||
22 X5M Bolsa de papel
|
||||
23 X6H Recipiente de plástico, Contenedor compuesto.
|
||||
24 X6P Recipiente de vidrio, Contenedor compuesto.
|
||||
25 X7A Estuche para carro
|
||||
26 X7B Estuche de madera
|
||||
27 X8A Pallet de madera
|
||||
28 X8B Cajón de madera
|
||||
29 X8C Madera flejada
|
||||
30 XAA Contenedor intermedio para gráneles de plástico rígido
|
||||
31 XAB Contenedor de fibra
|
||||
32 XAC Contenedor de papel
|
||||
33 XAD Contenedor de madera
|
||||
34 XAE Aerosol
|
||||
35 XAF Pallet modular con collares, 80cms * 60cms
|
||||
36 XAG Pallet o empaquetado
|
||||
37 XAH Pallet, 100cms X 110cms
|
||||
38 XAI Contenedor tipo concha
|
||||
39 XAJ Cono
|
||||
40 XAL Esfera
|
||||
41 XAM Ampolleta no protegida
|
||||
42 XAP Ampolleta protegida
|
||||
43 XAT Atomizador
|
||||
44 XAV Cápsula
|
||||
45 XB4 Cinturón
|
||||
46 XBA Barril
|
||||
47 XBB Bobina
|
||||
48 XBC Cajón para botellas / Estante para botellas
|
||||
49 XBD Tablero
|
||||
50 XBE Flejado
|
||||
51 XBF Globo no protegido
|
||||
52 XBG Bolso
|
||||
53 XBH Manojo
|
||||
54 XBI Compartimiento
|
||||
55 XBJ Cubeta
|
||||
56 XBK Cesta
|
||||
57 XBL Paca comprimida
|
||||
58 XBM Cuenco
|
||||
59 XBN Paca no comprimida
|
||||
60 XBO Botella no-protegida y cilíndrica
|
||||
61 XBP Globo protegido
|
||||
62 XBQ Botella cilíndrica protegida
|
||||
63 XBR Barra
|
||||
64 XBS Botella, no-protegida en forma de bulbo
|
||||
65 XBT Rollo de tela
|
||||
66 XBU Butt
|
||||
67 XBV Botella de bulbo protegido
|
||||
68 XBW Caja para líquidos
|
||||
69 XBX Caja
|
||||
70 XBY Tablero, con fleje/ agrupados/ armados
|
||||
71 XBZ Barras, con fleje/ agrupados/ armados
|
||||
72 XCA Lata rectangular
|
||||
73 XCB Cajón para cerveza
|
||||
74 XCC Mantequera
|
||||
75 XCD Lata con mango y boquilla
|
||||
76 XCE Cesto tejido
|
||||
77 XCF Cofre
|
||||
78 XCG Contenedor tipo Jaula
|
||||
79 XCH Cajonera
|
||||
80 XCI Frasco
|
||||
81 XCJ Ataúd
|
||||
82 XCK Barrica
|
||||
83 XCL Espiral
|
||||
84 XCM Paquete de tarjetas
|
||||
85 XCN Contenedor, no especificado como equipo de transporte
|
||||
86 XCO Garrafón no protegido
|
||||
87 XCP Garrafón protegido
|
||||
88 XCQ Cartucho
|
||||
89 XCR Cajón
|
||||
90 XCS Estuche
|
||||
91 XCT Cartón
|
||||
92 XCU Vaso
|
||||
93 XCV Cubierta
|
||||
94 XCW Jaula estilo rodillo
|
||||
95 XCX Lata cilíndrica
|
||||
96 XCY Cilindro
|
||||
97 XCZ Lona
|
||||
98 XDA Cajón multicapa de plástico
|
||||
99 XDB Cajón de varias capas de madera
|
||||
100 XDC Cajón multicapa de cartón
|
||||
101 XDG Jaula, Según la clasificación de la compañía (Commonwealth Handling Equipment Pool (CHEP))
|
||||
102 XDH Caja, Según la clasificación de la compañía (CHEP), Eurobox
|
||||
103 XDI Tambor de hierro
|
||||
104 XDJ damajuana o garrafa, no protegido
|
||||
105 XDK Cajón a granel, cartón
|
||||
106 XDL Cajas de plástico
|
||||
107 XDM Cajones a granel de madera
|
||||
108 XDN Dispensador
|
||||
109 XDP damajuana o garrafa, protegido
|
||||
110 XDR Tambor
|
||||
111 XDS Bandeja de una capa sin cubierta y de plástico
|
||||
112 XDT Bandeja de una capa sin cubierta y de madera
|
||||
113 XDU Bandeja de una capa sin cubierta y poliestireno
|
||||
114 XDV Bandeja de una capa sin cubierta y de cartón
|
||||
115 XDW Bandeja de dos capas sin tapa y con bandeja de plástico
|
||||
116 XDX Bandeja de dos capas sin cubierta y de madera
|
||||
117 XDY Bandeja de dos capas sin cubierta y de cartón
|
||||
118 XEC Bolsa de plástico
|
||||
119 XED Estuche, con pallet de base
|
||||
120 XEE Estuche, con pallet base de madera
|
||||
121 XEF Estuche, con pallet base de cartón
|
||||
122 XEG Estuche, con pallet base de plástico
|
||||
123 XEH Estuche, con pallet base de metal
|
||||
124 XEI Estuche isotérmico
|
||||
125 XEN Sobre
|
||||
126 XFB Bolsa flexible
|
||||
127 XFC Cajón para fruta
|
||||
128 XFD Cajón enmarcado
|
||||
129 XFE Tanque flexible
|
||||
130 XFI Firkin
|
||||
131 XFL Matraz
|
||||
132 XFO Cajón para zapatos
|
||||
133 XFP Caja auxiliar para película fotográfica
|
||||
134 XFR Marco
|
||||
135 XFT Contenedor para alimentos
|
||||
136 XFW Carro de cama plana
|
||||
137 XFX Bolsa flexible tipo contenedor
|
||||
138 XGB Botella para gas
|
||||
139 XGI Viga
|
||||
140 XGL Contenedor tipo galón
|
||||
141 XGR Recipiente de vidrio
|
||||
142 XGU Bandeja contenedor para apilar horizontalmente objetos planos
|
||||
143 XGY Costal de Yute
|
||||
144 XGZ Vigas con correas o agrupadas
|
||||
145 XHA Cesta con mango y de plástico
|
||||
146 XHB Cesta con mango y de madera
|
||||
147 XHC Cesta con asa y de cartón
|
||||
148 XHG Hogshead
|
||||
149 XHN Gancho
|
||||
150 XHR Cesto
|
||||
151 XIA Paquete con pantalla y de madera
|
||||
152 XIB Paquete con pantalla y de cartón
|
||||
153 XIC Paquete con pantalla y de plástico
|
||||
154 XID Paquete con pantalla y de metal
|
||||
155 XIE Paquete de mostrador.
|
||||
156 XIF Envase para alimentos
|
||||
157 XIG Paquete envuelto en papel
|
||||
158 XIH Tambor de plástico
|
||||
159 XIK Paquete de cartón con los agujeros para botellas
|
||||
160 XIL Bandeja rígida con tapa y apilable (CEN TS 14482: 2002)
|
||||
161 XIN Lingote
|
||||
162 XIZ Lingotes con correas/ agrupados
|
||||
163 XJB Bolsa jumbo
|
||||
164 XJC Bidón rectangular
|
||||
165 XJG Jarra
|
||||
166 XJR Tarro
|
||||
167 XJT Bolsa de yute
|
||||
168 XJY Bidón, cilíndrico
|
||||
169 XKG Barrilete
|
||||
170 XKI Kit (Conjunto de piezas)
|
||||
171 XLE Valijas
|
||||
172 XLG Bitácora
|
||||
173 XLT Lote
|
||||
174 XLU Caja de arrastre
|
||||
175 XLV Contenedor pequeño
|
||||
176 XLZ Registros con fleje/ agrupados/ armados
|
||||
177 XMA Cajón metálico
|
||||
178 XMB Múltiplo de bolsas
|
||||
179 XMC Cajón para leche
|
||||
180 XME Contenedor de metal
|
||||
181 XMR Recipiente de metal
|
||||
182 XMS Saco milti-pared
|
||||
183 XMT Tapete
|
||||
184 XMW Contenedor envuelto en plástico
|
||||
185 XMX Caja pequeña de cerillos
|
||||
186 XNA No disponible
|
||||
187 XNE Sin empaque o no empaquetado
|
||||
188 XNF Sin empaque o no empaquetado, unidad simple
|
||||
189 XNG Sin empaque o no empaquetado, unidades múltiples
|
||||
190 XNS Caja nido
|
||||
191 XNT Red
|
||||
192 XNU Red de plástico con tubo
|
||||
193 XNV Red textil con tubo
|
||||
194 XOA Pallet, Según la clasificación de la compañía (Commonwealth Handling Equipment Pool (CHEP) 40 cm x 60 cm
|
||||
195 XOB Pallet, Según la clasificación de la compañía (Commonwealth Handling Equipment Pool (CHEP) 80 cm x 120 cm
|
||||
196 XOC Pallet, Según la clasificación de la compañía (Commonwealth Handling Equipment Pool (CHEP) 100 cm x 120 cm
|
||||
197 XOD Pallet, AS 4068-1993
|
||||
198 XOE Pallet, ISO T11
|
||||
199 XOF Plataforma, peso o dimensión no especificada
|
||||
200 XOK Bloque
|
||||
201 XOT Octabin
|
||||
202 XP2 Charola
|
||||
203 XPA Cajetilla
|
||||
204 XPB Pallet, Caja combinada y abierta con caja y pallet.
|
||||
205 XPC Paquete postal
|
||||
206 XPD Pallet modular con collares (80cms * 100cms)
|
||||
207 XPE Pallet modular con collares (80cms * 120cms)
|
||||
208 XPF Corral
|
||||
209 XPG Placa
|
||||
210 XPH Cantaro
|
||||
211 XPI Pleca
|
||||
212 XPJ Canastilla
|
||||
213 XPK Paquete
|
||||
214 XPL Balde
|
||||
215 XPN Tablón
|
||||
216 XPO Bolsa pequeña
|
||||
217 XPR Contenedor de plástico
|
||||
218 XPT Maceta
|
||||
219 XPU Cacerola
|
||||
220 XPV Tubos, con fleje/ agrupados/ armados
|
||||
221 XPX Pallet
|
||||
222 XPY Placas con fleje/ agrupados/ armados
|
||||
223 XPZ Tablones con fleje/ agrupados/ armados
|
||||
224 XQA Tambor de acero con cabeza no desmontable
|
||||
225 XQB Tambor de acero con cabeza extraíble
|
||||
226 XQC Tambor de aluminio con cabeza no extraíble
|
||||
227 XQD Tambor de aluminio con cabeza extraíble
|
||||
228 XQF Tambor, plástico con cabeza no desmontable
|
||||
229 XQG Tambor, plástico, cabeza extraíble
|
||||
230 XQH Barril de madera con tapón
|
||||
231 XQJ Barril de madera con cabeza desprendible
|
||||
232 XQK Bidón de acero con cabeza no desmontable
|
||||
233 XQL Bidón de acero con cabeza desmontable
|
||||
234 XQM Bidón de plástico con cabeza no desmontable
|
||||
235 XQN Bidón de plástico con cabeza extraíble
|
||||
236 XQP Caja de madera natural estándar
|
||||
237 XQQ Caja de madera natural con muros a prueba de filtraciones
|
||||
238 XQR Caja de plástico expandida
|
||||
239 XQS Caja de plástico sólida
|
||||
240 XRD Rod
|
||||
241 XRG Anillo
|
||||
242 XRJ Estante, Perchero para ropa
|
||||
243 XRK Estante
|
||||
244 XRL Carrete
|
||||
245 XRO Rollo
|
||||
246 XRT Red Roja
|
||||
247 XRZ Varillas con fleje/ agrupados/ armados
|
||||
248 XSA Saco
|
||||
249 XSB Losa
|
||||
250 XSC Cajón poco profundo
|
||||
251 XSD Huso
|
||||
252 XSE Baúl
|
||||
253 XSH Bolsa pequeña hermética
|
||||
254 XSI Patín
|
||||
255 XSK Carcasa esqueleto
|
||||
256 XSL Hoja de deslizamiento
|
||||
257 XSM Hoja de metal
|
||||
258 XSO Carrete pequeño
|
||||
259 XSP Hoja de empaque de plástico
|
||||
260 XSS Cajón de acero
|
||||
261 XSU Maleta
|
||||
262 XSV Sobre de acero
|
||||
263 XSW Envoltorio
|
||||
264 XSY Manga
|
||||
265 XSZ Hojas con fleje/ agrupados/ armados
|
||||
266 XT1 Tableta
|
||||
267 XTB Tina
|
||||
268 XTC Caja para té
|
||||
269 XTD Tubo plegable
|
||||
270 XTG Contenedor de tanque genérico
|
||||
271 XTI Tierce
|
||||
272 XTK Tanque rectangular
|
||||
273 XTL Tina con tapa
|
||||
274 XTN Hojalata
|
||||
275 XTO Tonel
|
||||
276 XTR Maletero
|
||||
277 XTS Estructura
|
||||
278 XTT Bolsa de mano
|
||||
279 XTU Tubo
|
||||
280 XTV Tubo con boquilla
|
||||
281 XTW Pallet tricapa
|
||||
282 XTY Tanque cilíndrico
|
||||
283 XTZ Tubos con fleje/ agrupados/ armados
|
||||
284 XUC Sin empaque
|
||||
285 XUN Unidad
|
||||
286 XVA Tanque
|
||||
287 XVG Tanque de gas (a 1,031 mbar y 15° C)
|
||||
288 XVI Frasco pequeño
|
||||
289 XVK Paquete transportable
|
||||
290 XVL Contenedor para líquidos a granel
|
||||
291 XVN Vehículo
|
||||
292 XVO "Contenedor para sólido de partículas grandes a granel (""nódulos"")"
|
||||
293 XVP Envasado al vacío
|
||||
294 XVQ Tanque para Gas licuado (a temperatura / presión anormal)
|
||||
295 XVR Contenedor para sólidos de partículas granulares a granel (Granos)
|
||||
296 XVS Contenedor de chatarra a granel
|
||||
297 XVY "Contenedor para sólido de partículas finas a granel (""polvos"")"
|
||||
298 XWA Contenedor de granel intermedio
|
||||
299 XWB Botella de mimbre
|
||||
300 XWC Contenedor intermedio para gráneles y de acero
|
||||
301 XWD Contenedor intermedio para gráneles y de aluminio
|
||||
302 XWF Contenedor intermedio para gráneles y de metal
|
||||
303 XWG Contenedor intermedio para gráneles y de acero presurizado menor a 10 kpa
|
||||
304 XWH Contenedor intermedio para gráneles y de aluminio, presurizado menor a 10 kpa
|
||||
305 XWJ Contenedor intermedio para gráneles y de metal con una presión de 10 kpa
|
||||
306 XWK Contenedor intermedio para gráneles y de acero para líquido
|
||||
307 XWL Contenedor intermedio para gráneles y de aluminio para líquido
|
||||
308 XWM Contenedor intermedio para gráneles y de metal para líquido
|
||||
309 XWN Contenedor intermedio para gráneles con tejido plástico sin capa con revestimiento
|
||||
310 XWP Contenedor intermedio para gráneles con tejido plástico y recubierto
|
||||
311 XWQ Contenedor intermedio para gráneles con tejido plástico con revestimiento
|
||||
312 XWR Contenedor intermedio para gráneles con tejido plástico, revestido y con forro
|
||||
313 XWS Contenedor intermedio para gráneles con película de plástico
|
||||
314 XWT Contenedor intermedio para gráneles textil sin capa / forro
|
||||
315 XWU Contenedor intermedio para gráneles de madera natural con forro interior
|
||||
316 XWV Contenedor intermedio para gráneles textil recubierto
|
||||
317 XWW Contenedor intermedio para gráneles textil con revestimiento
|
||||
318 XWX Contenedor intermedio para gráneles textil recubierto y con forro
|
||||
319 XWY Contenedor intermedio para gráneles contrachapado con revestimiento interior
|
||||
320 XWZ Contenedor intermedio para gráneles de madera reconstituida con revestimiento interior
|
||||
321 XXA Bolsa de tejido plástico, sin abrigo interior ni forro
|
||||
322 XXB Bolsa de tejido plástico a prueba de filtraciones
|
||||
323 XXC Bolsa de tejido plástico resistente al agua
|
||||
324 XXD Bolsa con película de plástico
|
||||
325 XXF Bolsa textil sin capa ni forro interior
|
||||
326 XXG Bolsa textil a prueba de filtraciones
|
||||
327 XXH Bolsa textil resistente al agua
|
||||
328 XXJ Bolsa de papel multi-pared
|
||||
329 XXK Bolsa de papel multi-pared, resistente al agua
|
||||
330 XYA Empaque compuesto, recipiente de plástico en tambor de acero
|
||||
331 XYB Empaque compuesto, recipiente de plástico en cajas de acero
|
||||
332 XYC Empaque compuesto, recipiente de plástico en tambor de aluminio
|
||||
333 XYD Empaque compuesto, recipiente de plástico en cajón de aluminio
|
||||
334 XYF Empaque compuesto, recipiente de plástico en caja de madera
|
||||
335 XYG Empaque compuesto, recipiente de plástico en tambor de madera contrachapada
|
||||
336 XYH Empaque compuesto, recipiente de plástico en caja de madera contrachapada
|
||||
337 XYJ Empaque compuesto, recipiente de plástico en tambor de fibra
|
||||
338 XYK Empaque compuesto, recipiente de plástico en caja de cartón
|
||||
339 XYL Empaque compuesto, recipiente de plástico en el tambor de plástico
|
||||
340 XYM Empaque compuesto, recipiente de plástico en caja de plástico sólido
|
||||
341 XYN Empaque compuesto, receptáculo de vidrio en tambor de acero
|
||||
342 XYP Empaque compuesto, receptáculo de vidrio en caja de cajas de acero
|
||||
343 XYQ Empaque compuesto, recipiente de vidrio en tambor de aluminio
|
||||
344 XYR Empaque compuesto, receptáculo de vidrio en caja de aluminio
|
||||
345 XYS Empaque compuesto, recipiente de vidrio en caja de madera
|
||||
346 XYT Empaque compuesto, recipiente de vidrio en tambor de madera contrachapada
|
||||
347 Xyv Empaque compuesto, recipiente de vidrio en el cesto de mimbre
|
||||
348 XYW Empaque compuesto, recipiente de vidrio en tambor de fibra
|
||||
349 XYX Empaque compuesto, recipiente de vidrio en caja de cartón
|
||||
350 XYY Empaque compuesto, recipiente de vidrio en paquete de plástico expandible
|
||||
351 XYZ Empaque compuesto, recipiente de vidrio en paquete de plástico sólido
|
||||
352 XZA Contenedor de granel intermedio, papel, multi-pared
|
||||
353 XZB Bolsa grande
|
||||
354 XZC Contenedor intermedio para gráneles de papel, multi-pared y resistente al agua
|
||||
355 XZD Contenedor intermedio para gráneles de plástico rígido, con equipo estructural para sólidos
|
||||
356 XZF Contenedor intermedio para gráneles de plástico rígido, autoportante para sólidos
|
||||
357 XZG Contenedor intermedio para gráneles de plástico rígido, con equipo estructural, presurizado
|
||||
358 XZH Contenedor intermedio para gráneles de plástico rígido, autoportante y presurizado
|
||||
359 XZJ Contenedor intermedio para gráneles de plástico rígido, con equipo estructural para líquidos
|
||||
360 XZK Contenedor intermedio para gráneles de plástico rígido, autoportante, líquidos
|
||||
361 XZL Contenedor intermedio para gráneles, compuesto y de plástico rígido, sólidos
|
||||
362 XZM Contenedor intermedio para gráneles, compuesto y de plástico flexible, sólidos
|
||||
363 XZN Contenedor intermedio para gráneles, compuesto y de plástico rígido, presurizado
|
||||
364 XZP Contenedor intermedio para gráneles, compuesto y de plástico flexible, presurizado
|
||||
365 XZQ Contenedor intermedio para gráneles, compuesto y de plástico rígido, líquidos
|
||||
366 XZR Contenedor intermedio para gráneles, compuesto y de plástico flexible para líquidos
|
||||
367 XZS Contenedor intermedio para gráneles, compuesto
|
||||
368 XZT Contenedor intermedio para gráneles con tablero de fibras
|
||||
369 XZU Contenedor intermedio para gráneles flexible
|
||||
370 XZV Contenedor intermedio para gráneles de metal, distinto del acero
|
||||
371 XZW Contenedor intermedio para gráneles, de madera natural
|
||||
372 XZX Contenedor intermedio para gráneles, de contrachapado
|
||||
373 XZY Contenedor intermedio para gráneles, de madera reconstituida
|
||||
374 KGM Kilogramo
|
||||
375 MC Microgramo
|
||||
376 DJ Decagramo
|
||||
377 DG Decigramo
|
||||
378 GRM Gramo
|
||||
379 CGM Centigramo
|
||||
380 TNE Tonelada (tonelada métrica)
|
||||
381 DTN Decitonelada métrica
|
||||
382 MGM Miligramo
|
||||
383 HGM Hectogramo
|
||||
384 KTN Kilotonelada Métrica
|
||||
385 2U Megagramo
|
||||
386 LBR Libra
|
||||
387 GRN Grano
|
||||
388 ONZ Onza (avoirdupois)
|
||||
389 CWI Hundredweight
|
||||
390 CWA Hundred pound
|
||||
391 LTN Tonelada (UK) o tonelada larga (estados unidos)
|
||||
392 STI Estone (UK)
|
||||
393 STN Tonelada (estados unidos) o tonelada corta (UK y estados unidos)
|
||||
394 APZ Onza troy u onza farmacéutica
|
||||
395 F13 Slug
|
||||
396 K64 Libra (avoirdupois) por grado fahrenheit
|
||||
397 L69 Tonelada por kelvin
|
||||
398 L87 Tonelada corta por grado fahrenheit
|
||||
399 M85 Tonelada, ensayo
|
||||
400 M86 Libra Alemana
|
||||
401 J33 Microgramo por kilogramo
|
||||
402 L32 Nanogramo por kilogramo
|
||||
403 NA Miligramo por kilogramo
|
||||
404 M29 Kilogramo por kilogramo
|
||||
405 M91 Libra por libra
|
||||
406 Q29 Microgramo por hectogramo
|
||||
407 MTQ Metro cúbico
|
||||
408 MAL Megalitro
|
||||
409 LTR Litro
|
||||
410 MMQ Milímetro cúbico
|
||||
411 CMQ Centímetro cúbico
|
||||
412 DMQ Decímetro cúbico
|
||||
413 MLT Mililitro
|
||||
414 HLT Hectolitro
|
||||
415 CLT Centilitro
|
||||
416 DMA Decámetro cúbico
|
||||
417 H19 Hectómetro cúbico
|
||||
418 H20 Kilómetro cúbico
|
||||
419 M71 Metro cúbico por pascal (joules)
|
||||
420 DLT Decilitro
|
||||
421 4G Microlitro
|
||||
422 K6 Kilolitro
|
||||
423 A44 Decalitro
|
||||
424 G94 Centímetro cúbico por bar
|
||||
425 G95 Litro por bar
|
||||
426 G96 Metro cúbico por bar
|
||||
427 G97 Mililitro por bar
|
||||
428 5I Pies cúbicos estándar
|
||||
429 INQ Pulgada cúbica
|
||||
430 FTQ Pie cúbico
|
||||
431 YDQ Yarda cúbica
|
||||
432 GLI Galón (UK)
|
||||
433 GLL Galón (EUA)
|
||||
434 PT Pinta (US)
|
||||
435 PTI Pint (uk)
|
||||
436 QTI Cuarto (UK)
|
||||
437 PTL Pinta líquida (estados unidos)
|
||||
438 QTL Cuarto de líquido (estadis unidos)
|
||||
439 PTD Pinta seca (estados unidos)
|
||||
440 OZI Onza líquida (UK)
|
||||
441 QT Cuarto (EUA)
|
||||
442 J57 Barril (uk petróleo)
|
||||
443 K21 Pie cúbico por grado fahrenheit
|
||||
444 K23 Pie cúbico por psi (libra por pulgada cuadrada)
|
||||
445 L43 Peck (UK)
|
||||
446 L61 Pinta (US seco)
|
||||
447 L62 Cuarto de galón (seco de los EUA)
|
||||
448 L84 Tonelada (flota UK)
|
||||
449 L86 Tonelada (flota estados unidos)
|
||||
450 M11 Yarda cúbica por grado fahrenheit
|
||||
451 M14 Yarda cúbica por psi (libra por pulgada cuadrada)
|
||||
452 OZA Onza líquida (estados unidos)
|
||||
453 BUI Bushel (UK)
|
||||
454 BUA Bushel (EUA)
|
||||
455 BLL Barril (EUA)
|
||||
456 BLD Barril seco (EUA)
|
||||
457 GLD Galón seco (EUA)
|
||||
458 QTD Cuarto seco (estados unidos)
|
||||
459 G26 Estere
|
||||
460 G21 Taza (unidad de volumen)
|
||||
461 G24 Cucharada (estados unidos)
|
||||
462 G25 Cucharilla (estados unidos)
|
||||
463 G23 Peck
|
||||
464 M67 Acre-pie
|
||||
465 M68 Cordón
|
||||
466 M69 Milla cúbica (reino unido)
|
||||
467 M70 Unidad tradicional de capacidad de carga
|
||||
468 Q32 Femtolitro
|
||||
469 Q33 Picolitro
|
||||
470 Q34 Nanolitro
|
||||
471 NM3 Metro cúbico normalizado
|
||||
472 SM3 Metro cúbico estándar
|
|
|
@ -114,7 +114,9 @@
|
|||
{"key": "607", "name": "Régimen de Enajenación o Adquisición de Bienes", "moral": true, "activo": false},
|
||||
{"key": "629", "name": "De los Regímenes Fiscales Preferentes y de las Empresas Multinacionales", "fisica": true, "activo": false},
|
||||
{"key": "630", "name": "Enajenación de acciones en bolsa de valores", "fisica": true, "activo": false},
|
||||
{"key": "615", "name": "Régimen de los ingresos por obtención de premios", "fisica": true, "activo": false}
|
||||
{"key": "615", "name": "Régimen de los ingresos por obtención de premios", "fisica": true, "activo": false},
|
||||
{"key": "625", "name": "Régimen de las Actividades Empresariales con ingresos a través de Plataformas Tecnológicas", "fisica": true, "activo": true},
|
||||
{"key": "626", "name": "Régimen Simplificado de Confianza", "moral": true, "fisica": true, "activo": true}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -86,6 +86,7 @@ var controllers = {
|
|||
$$('txt_plantilla_nomina1233').attachEvent('onItemClick', txt_plantilla_nomina1233_click)
|
||||
$$('txt_plantilla_pagos10').attachEvent('onItemClick', txt_plantilla_pagos10_click)
|
||||
$$('make_pdf_from').attachEvent('onChange', opt_make_pdf_from_on_change)
|
||||
$$('cmd_template_upload').attachEvent('onItemClick', cmd_template_upload_click)
|
||||
|
||||
//~ Partners
|
||||
$$('chk_config_change_balance_partner').attachEvent('onItemClick', chk_config_item_click)
|
||||
|
@ -113,6 +114,7 @@ var controllers = {
|
|||
$$('chk_config_divisas').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_ine').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_edu').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('chk_config_carta_porte').attachEvent('onItemClick', chk_config_item_click)
|
||||
|
||||
$$('chk_config_leyendas_fiscales').attachEvent('onItemClick', chk_config_item_click)
|
||||
$$('cmd_admin_leyendas_fiscales').attachEvent('onItemClick', cmd_admin_leyendas_fiscales_click)
|
||||
|
@ -159,6 +161,10 @@ var controllers = {
|
|||
$$('cmd_add_sucursal').attachEvent('onItemClick', cmd_add_sucursal_click)
|
||||
$$('grid_sucursales').attachEvent('onItemClick', grid_sucursales_click)
|
||||
|
||||
//~ Carta Porte
|
||||
$$('grid_unidadpeso_found').attachEvent('onValueSuggest', grid_unidadpeso_found_click)
|
||||
$$('grid_carta_unidades_peso').attachEvent('onItemClick', grid_carta_unidades_peso_click)
|
||||
$$('grid_carta_unidades_peso').attachEvent('onCheck', grid_carta_unidades_peso_on_check)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1567,6 +1573,27 @@ function agregar_nueva_unidad(obj){
|
|||
}
|
||||
|
||||
|
||||
function agregar_nueva_unidadpeso(obj){
|
||||
var grid = $$('grid_carta_unidades_peso')
|
||||
var args = {
|
||||
opt: 'add',
|
||||
values: {key: obj.key, name: obj.name},
|
||||
}
|
||||
|
||||
webix.ajax().post('/satunidadespeso', args, {
|
||||
error: function(text, data, xhr) {
|
||||
webix.message({type: 'error', text: 'Error al agregar'})
|
||||
},
|
||||
success: function(text, data, xhr){
|
||||
var values = data.json()
|
||||
if (values.ok){
|
||||
grid.add(obj)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function grid_unidad_found_click(obj){
|
||||
msg = '¿Estás seguro de agregar la siguiente unidad?'
|
||||
msg += '(' + obj.key + ')<BR>'
|
||||
|
@ -1588,6 +1615,27 @@ function grid_unidad_found_click(obj){
|
|||
}
|
||||
|
||||
|
||||
function grid_unidadpeso_found_click(obj){
|
||||
msg = '¿Estás seguro de agregar la siguiente unidad?'
|
||||
msg += '(' + obj.key + ')<BR>'
|
||||
msg += obj.name
|
||||
|
||||
webix.confirm({
|
||||
title: 'Agregar Unidad',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
agregar_nueva_unidadpeso(obj)
|
||||
}
|
||||
}
|
||||
})
|
||||
$$('buscar_carta_unidades_peso').setValue('')
|
||||
}
|
||||
|
||||
|
||||
function agregar_impuesto(impuesto, tasa){
|
||||
var grid = $$('grid_admin_taxes')
|
||||
var values = {impuesto: impuesto, tasa: tasa}
|
||||
|
@ -2129,8 +2177,7 @@ function grid_usuarios_on_check(row, column, state){
|
|||
value: state,
|
||||
}
|
||||
|
||||
|
||||
if(column='in_branch'){
|
||||
if(column=='in_branch'){
|
||||
set_user_branch(row, state)
|
||||
return
|
||||
}
|
||||
|
@ -2808,6 +2855,17 @@ function cmd_subir_certificado_click(){
|
|||
|
||||
var values = form.getValues()
|
||||
|
||||
if(!file_cer){
|
||||
msg = 'Selecciona el archivo CER del certificado'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
if(!file_key){
|
||||
msg = 'Selecciona el archivo KEY del certificado'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
if(!values.contra.trim()){
|
||||
msg = 'La contraseña no puede estar vacía'
|
||||
msg_error(msg)
|
||||
|
@ -2838,6 +2896,8 @@ function cmd_subir_certificado_click(){
|
|||
|
||||
$$('form_upload').setValues({})
|
||||
$$('up_cert').files.data.clearAll()
|
||||
file_cer = null
|
||||
file_key = null
|
||||
}
|
||||
|
||||
|
||||
|
@ -3165,3 +3225,118 @@ function grid_warehouse_click(id, e, node){
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function delete_unit_weight(id){
|
||||
var grid = $$('grid_carta_unidades_peso')
|
||||
|
||||
var values = {
|
||||
opt: 'delete',
|
||||
values: {id: id},
|
||||
}
|
||||
|
||||
webix.ajax().post('/satunidadespeso', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json()
|
||||
if(values.ok){
|
||||
grid.remove(id)
|
||||
msg_ok('Unidad de Peso eliminada correctamente')
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function grid_carta_unidades_peso_click(id, e, node){
|
||||
if(id.column != 'delete'){
|
||||
return
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de borrar la Unidad de Peso seleccionada?'
|
||||
webix.confirm({
|
||||
title: 'Borrar Unidad',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
delete_unit_weight(id.row)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function grid_carta_unidades_peso_on_check(row, column, state){
|
||||
var values = {
|
||||
opt: 'update_active',
|
||||
values: {id: row, activo: state},
|
||||
}
|
||||
webix.ajax().post('/satunidadespeso', values, {
|
||||
error:function(text, data, XmlHttpRequest){
|
||||
msg = 'Ocurrio un error, consulta a soporte técnico'
|
||||
msg_error(msg)
|
||||
},
|
||||
success:function(text, data, XmlHttpRequest){
|
||||
var values = data.json()
|
||||
if(!values.ok){
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_template_upload_click(e){
|
||||
|
||||
var template = $$('lst_templates_cfdi')
|
||||
|
||||
if(!template.getValue()){
|
||||
msg = 'Selecciona una plantilla'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
var body_elements = [
|
||||
{cols: [{width: 100}, {view: 'uploader', id: 'up_templates', autosend: true, link: 'lst_files',
|
||||
value: 'Seleccionar archivo', upload: '/files/' + template.getValue(),
|
||||
width: 200}, {width: 100}]},
|
||||
{view: 'list', id: 'lst_files', type: 'uploader', autoheight:true,
|
||||
borderless: true},
|
||||
{},
|
||||
{cols: [{}, {view: 'button', label: 'Cerrar', autowidth: true,
|
||||
click:("$$('win_templates').close();")}, {}]}
|
||||
]
|
||||
|
||||
var w = webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_templates',
|
||||
modal: true,
|
||||
position: 'center',
|
||||
head: template.getText(),
|
||||
body: {
|
||||
view: 'form',
|
||||
elements: body_elements,
|
||||
}
|
||||
})
|
||||
|
||||
w.show()
|
||||
|
||||
$$('up_templates').attachEvent('onUploadComplete', function(response){
|
||||
if(response.ok){
|
||||
w.close()
|
||||
msg_ok('Plantilla cargada correctamente')
|
||||
}else{
|
||||
$$("lst_files").clearAll()
|
||||
msg_error(response.error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ var invoices_controllers = {
|
|||
$$('cmd_invoice_timbrar').attachEvent('onItemClick', cmd_invoice_timbrar_click)
|
||||
$$('cmd_invoice_sat').attachEvent('onItemClick', cmd_invoice_sat_click)
|
||||
$$('cmd_invoice_verify_sat').attachEvent('onItemClick', cmd_invoice_verify_sat_click)
|
||||
$$('cmd_invoice_cancelar').attachEvent('onItemClick', cmd_invoice_cancelar_click)
|
||||
$$('cmd_invoice_ask_cancel').attachEvent('onItemClick', cmd_invoice_ask_cancel_click)
|
||||
$$('grid_invoices').attachEvent('onItemClick', grid_invoices_click)
|
||||
$$('grid_invoices').attachEvent('onSelectChange', grid_invoices_on_select_change)
|
||||
$$('grid_invoices').attachEvent('onHeaderClick', grid_invoices_on_header_click)
|
||||
|
@ -86,6 +86,9 @@ var invoices_controllers = {
|
|||
$$('search_by').attachEvent('onKeyPress', search_by_key_press)
|
||||
$$('search_by').attachEvent('onItemClick', search_by_click)
|
||||
|
||||
tv_invoice = $$('tv_invoice').getTabbar()
|
||||
tv_invoice.attachEvent('onChange', tv_invoice_change)
|
||||
|
||||
webix.extend($$('grid_invoices'), webix.ProgressBar)
|
||||
|
||||
init_config_invoices()
|
||||
|
@ -212,8 +215,15 @@ function default_config(){
|
|||
get_leyendas_fiscales()
|
||||
$$('tv_invoice').getTabbar().showOption('Leyendas Fiscales')
|
||||
}
|
||||
if(!values.cfdi_carta_porte){
|
||||
$$('tv_invoice').getTabbar().hideOption('Carta Porte')
|
||||
}else{
|
||||
get_leyendas_fiscales()
|
||||
$$('tv_invoice').getTabbar().showOption('Carta Porte')
|
||||
}
|
||||
cfg_invoice['leyendasfiscales'] = values.cfdi_leyendasfiscales
|
||||
cfg_invoice['edu'] = values.cfdi_edu
|
||||
cfg_invoice['carta_porte'] = values.cfdi_carta_porte
|
||||
cfg_invoice['open_pdf'] = values.cfdi_open_pdf
|
||||
cfg_invoice['tax_locales'] = values.cfdi_tax_locales
|
||||
cfg_invoice['tax_decimals'] = values.cfdi_tax_decimals
|
||||
|
@ -332,11 +342,25 @@ function cmd_delete_invoice_click(id, e, node){
|
|||
|
||||
function validate_invoice(values){
|
||||
|
||||
if(values.id_partner == 0){
|
||||
webix.UIManager.setFocus('search_client_name')
|
||||
msg = 'Selecciona un cliente'
|
||||
msg_error(msg)
|
||||
return false
|
||||
var usar_cartaporte = $$('chk_cfdi_usar_cartaporte').getValue()
|
||||
if(usar_cartaporte){
|
||||
value = $$('lst_carta_UnidadPeso').getValue()
|
||||
if(!value){
|
||||
msg = 'Es necesario seleccionar una Unidad de Peso'
|
||||
msg_error(msg)
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var tipo_comprobante = $$('lst_tipo_comprobante').getValue()
|
||||
if(tipo_comprobante != 'T'){
|
||||
if(values.id_partner == 0){
|
||||
webix.UIManager.setFocus('search_client_name')
|
||||
msg = 'Selecciona un cliente'
|
||||
msg_error(msg)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if(!grid.count()){
|
||||
|
@ -461,11 +485,6 @@ function validate_invoice(values){
|
|||
|
||||
}
|
||||
|
||||
var tipo_comprobante = $$('lst_tipo_comprobante').getValue()
|
||||
if(tipo_comprobante == 'T'){
|
||||
msg_ok('El CFDI es de tipo Traslado')
|
||||
}
|
||||
|
||||
var rows = grid.data.getRange()
|
||||
for (i = 0; i < rows.length; i++) {
|
||||
var importe = rows[i]['importe']
|
||||
|
@ -678,6 +697,67 @@ function guardar_y_timbrar(values){
|
|||
data['ine'] = valores
|
||||
}
|
||||
|
||||
var usar_cartaporte = $$('chk_cfdi_usar_cartaporte').getValue()
|
||||
if(usar_cartaporte){
|
||||
var total_distance = 0.00
|
||||
var total_weight = 0.00
|
||||
var cartaporte = {
|
||||
TranspInternac: $$('lst_carta_TranspInternac').getValue(),
|
||||
TotalDistRec: total_distance,
|
||||
}
|
||||
var ubicaciones = $$('grid_carta_ubicaciones').data.getRange()
|
||||
ubicaciones.forEach(function(row, index){
|
||||
delete row['id']
|
||||
delete row['delete']
|
||||
if(row['DistanciaRecorrida']){
|
||||
total_distance += parseFloat(row['DistanciaRecorrida'])
|
||||
}
|
||||
})
|
||||
cartaporte['TotalDistRec'] = String(total_distance)
|
||||
cartaporte['ubicaciones'] = ubicaciones
|
||||
|
||||
var row = $$('grid_carta_autotransporte').data.getRange()[0]
|
||||
var autotransporte = {
|
||||
PermSCT: row['PermSCT'],
|
||||
NumPermisoSCT: row['NumPermisoSCT'],
|
||||
identificacion: {
|
||||
ConfigVehicular: row['ConfigVehicular'],
|
||||
PlacaVM: row['PlacaVM'],
|
||||
AnioModeloVM: row['AnioModeloVM'],
|
||||
},
|
||||
seguros: {
|
||||
AseguraRespCivil: row['AseguraRespCivil'],
|
||||
PolizaRespCivil: row['PolizaRespCivil'],
|
||||
}
|
||||
}
|
||||
|
||||
var mercancias = $$('grid_carta_mercancias').data.getRange()
|
||||
mercancias.forEach(function(row, index){
|
||||
delete row['id']
|
||||
row['Cantidad'] = String(row['Cantidad'])
|
||||
//~ row['ValorMercancia'] = String(row['ValorMercancia'])
|
||||
if(row['PesoEnKg']){
|
||||
total_weight += parseFloat(row['PesoEnKg'])
|
||||
}
|
||||
})
|
||||
var mercancias = {
|
||||
'PesoBrutoTotal': String(total_weight),
|
||||
'UnidadPeso': $$('lst_carta_UnidadPeso').getValue(),
|
||||
'NumTotalMercancias': String(mercancias.length),
|
||||
mercancias: mercancias,
|
||||
autotransporte: autotransporte,
|
||||
}
|
||||
cartaporte['mercancias'] = mercancias
|
||||
|
||||
var tiposfigura = $$('grid_carta_tipos_figuras').data.getRange()
|
||||
tiposfigura.forEach(function(row, index){
|
||||
delete row['id']
|
||||
})
|
||||
cartaporte['tiposfigura'] = tiposfigura
|
||||
|
||||
data['cartaporte'] = cartaporte
|
||||
}
|
||||
|
||||
if(!save_invoice(data)){
|
||||
return
|
||||
}
|
||||
|
@ -1412,67 +1492,6 @@ function grid_invoices_click(id, e, node){
|
|||
}
|
||||
|
||||
|
||||
function send_cancel(id){
|
||||
webix.ajax().post('invoices', {opt: 'cancel', id: id}, function(text, data){
|
||||
var values = data.json()
|
||||
if(values.ok){
|
||||
msg_ok(values.msg)
|
||||
gi.updateItem(id, values.row)
|
||||
}else{
|
||||
msg_error('No fue posible cancelar')
|
||||
webix.alert({
|
||||
title: 'Error al Cancelar',
|
||||
text: values.msg,
|
||||
type: 'alert-error'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_invoice_cancelar_click(){
|
||||
if(gi.count() == 0){
|
||||
return
|
||||
}
|
||||
|
||||
var row = gi.getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona una factura')
|
||||
return
|
||||
}
|
||||
|
||||
if (row instanceof Array){
|
||||
msg_error('Selecciona solo una factura')
|
||||
return
|
||||
}
|
||||
|
||||
if(row.estatus == 'Cancelada'){
|
||||
msg_error('La factura ya esta cancelada')
|
||||
return
|
||||
}
|
||||
|
||||
msg = ''
|
||||
if(!row.uuid){
|
||||
msg = 'La factura NO esta timbrada, asegurate de que efectivamente NO este timbrada.<BR><BR>'
|
||||
}
|
||||
|
||||
msg += '¿Estás seguro de enviar a cancelar esta factura?<BR><BR> \
|
||||
ESTA ACCIÓN NO SE PUEDE DESHACER'
|
||||
webix.confirm({
|
||||
title: 'Cancelar Factura',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
send_cancel(row.id)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function get_filters_invoices(){
|
||||
var filters = $$('filter_dates').getValue()
|
||||
|
||||
|
@ -2462,3 +2481,137 @@ function get_leyendas_fiscales(){
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function _tab_carta_porte(){
|
||||
var g1 = $$('grid_details')
|
||||
var g2 = $$('grid_carta_mercancias')
|
||||
|
||||
if(!g1.count()){
|
||||
msg = 'Agrega primero "todos" los productos a trasladar'
|
||||
msg_error(msg)
|
||||
activate_tab('tv_invoice', 'Generar')
|
||||
return
|
||||
}
|
||||
|
||||
g2.clearAll()
|
||||
|
||||
g1.eachRow(function(row){
|
||||
const r = g1.getItem(row)
|
||||
var data = new Object()
|
||||
data['BienesTransp'] = r.clave_sat
|
||||
data['Descripcion'] = r.descripcion
|
||||
data['Cantidad'] = r.cantidad
|
||||
data['ClaveUnidad'] = r.unidad
|
||||
//~ data['ValorMercancia'] = r.importe
|
||||
g2.add(data)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
function tv_invoice_change(nv, ov){
|
||||
if(nv=='Carta Porte'){
|
||||
_tab_carta_porte()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function send_invoice_cancel(id, reason='', uuid=''){
|
||||
var args = {
|
||||
opt: 'cancel',
|
||||
values: {
|
||||
id: id,
|
||||
reason: reason,
|
||||
uuid: uuid,
|
||||
}
|
||||
}
|
||||
webix.ajax().post('invoices', args, function(text, data){
|
||||
var values = data.json()
|
||||
if(values.ok){
|
||||
msg_ok(values.msg)
|
||||
gi.updateItem(id, values.row)
|
||||
}else{
|
||||
msg_error('No fue posible cancelar')
|
||||
webix.alert({
|
||||
title: 'Error al Cancelar',
|
||||
text: values.msg,
|
||||
type: 'alert-error'
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_invoice_cancel_click(){
|
||||
var row = $$('grid_invoices').getSelectedItem()
|
||||
var reason = $$('lst_reasons_cancel').getValue()
|
||||
var uuid = $$('txt_cancel_uuid').getValue()
|
||||
|
||||
if(!reason){
|
||||
msg = 'Selecciona un motivo para esta cancelación'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
if(reason=='01' & !uuid){
|
||||
msg = 'Debes de capturar el UUID que reemplaza a este CFDI'
|
||||
msg_error(msg)
|
||||
return
|
||||
}
|
||||
|
||||
send_invoice_cancel(row.id, reason, uuid)
|
||||
$$('win_invoice_cancel').close()
|
||||
}
|
||||
|
||||
|
||||
function cmd_win_cancel_close_click(){
|
||||
$$('win_invoice_cancel').close()
|
||||
}
|
||||
|
||||
|
||||
function cmd_invoice_ask_cancel_click(){
|
||||
var g = $$('grid_invoices')
|
||||
|
||||
if(g.count() == 0){
|
||||
return
|
||||
}
|
||||
|
||||
var row = g.getSelectedItem()
|
||||
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona una factura')
|
||||
return
|
||||
}
|
||||
|
||||
if (row instanceof Array){
|
||||
msg_error('Selecciona solo una factura')
|
||||
return
|
||||
}
|
||||
|
||||
if(row.estatus == 'Cancelada'){
|
||||
msg_error('La factura ya esta cancelada')
|
||||
return
|
||||
}
|
||||
|
||||
msg = ''
|
||||
if(row.uuid){
|
||||
win_invoice_cancel.init()
|
||||
$$('win_invoice_cancel').show()
|
||||
}else{
|
||||
msg = 'La factura NO esta timbrada, asegurate de que efectivamente NO este timbrada.<BR><BR>'
|
||||
msg += '¿Estás seguro de enviar a cancelar esta factura?<BR><BR> \
|
||||
ESTA ACCIÓN NO SE PUEDE DESHACER'
|
||||
webix.confirm({
|
||||
title: 'Cancelar Factura',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
send_invoice_cancel(row.id)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -624,3 +624,6 @@ function grid_parse(grid_name, values){
|
|||
}
|
||||
|
||||
|
||||
function activate_tab(parent, name){
|
||||
$$(parent).getTabbar().setValue(name)
|
||||
}
|
||||
|
|
|
@ -594,8 +594,20 @@ var type_make_pdf = [
|
|||
]
|
||||
|
||||
|
||||
var opt_templates_cfdi = [
|
||||
{id: '_3.3_cp_2.0.ods', value: 'CFDI v3.3 - Carta Porte 2.0'},
|
||||
]
|
||||
|
||||
|
||||
var options_templates = [
|
||||
{maxHeight: 15},
|
||||
{maxHeight: 25},
|
||||
{cols: [{maxWidth: 20},
|
||||
{view: 'richselect', id: 'lst_templates_cfdi', label: 'Plantillas CFDI: ', labelWidth: 100, options: opt_templates_cfdi},
|
||||
{maxWidth: 10},
|
||||
{view: 'button', id: 'cmd_template_upload', type: 'iconButton', icon: 'file', width: 35},
|
||||
{},
|
||||
{maxWidth: 20} ]},
|
||||
{maxHeight: 50},
|
||||
{cols: [{maxWidth: 20},
|
||||
{view: 'search', id: 'txt_plantilla_factura_32', name: 'plantilla_factura_32',
|
||||
label: 'Plantilla Factura v3.2 (ODS): ', labelPosition: 'top',
|
||||
|
@ -867,6 +879,12 @@ var options_admin_complements = [
|
|||
type: 'form', align: 'center', autowidth: true, disabled: true},
|
||||
{}, {maxWidth: 15}
|
||||
]},
|
||||
{maxHeight: 20},
|
||||
{template: 'Complemento para Carta Porte', type: 'section'},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_config_carta_porte', labelWidth: 0,
|
||||
labelRight: 'Usar el complemento Carta Porte'},
|
||||
{maxWidth: 15}]},
|
||||
]
|
||||
|
||||
|
||||
|
@ -1297,6 +1315,91 @@ var sat_usos_cfdi = [
|
|||
]
|
||||
|
||||
|
||||
var suggest_sat_unidades_peso = {
|
||||
view: 'gridsuggest',
|
||||
id: 'grid_unidadpeso_found',
|
||||
name: 'grid_unidadpeso_found',
|
||||
body: {
|
||||
autoConfig: false,
|
||||
scroll:true,
|
||||
autoheight:false,
|
||||
header: true,
|
||||
yCount: 10,
|
||||
columns: [
|
||||
{id: 'id', hidden: true},
|
||||
{id: 'key', adjust: 'data', header: 'Clave'},
|
||||
{id: 'name', adjust: 'data', header: 'Unidad'},
|
||||
],
|
||||
dataFeed:function(text){
|
||||
if (text.length > 1){
|
||||
this.load('/values/satunidadespeso?key=' + text)
|
||||
}else{
|
||||
this.hide()
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var buscar_carta_unidades_peso = {
|
||||
view: 'search',
|
||||
id: 'buscar_carta_unidades_peso',
|
||||
label: 'Buscar Unidad de Peso en el catálogo del SAT',
|
||||
labelPosition: 'top',
|
||||
suggest: suggest_sat_unidades_peso,
|
||||
placeholder: 'Por clave o descripción. Captura al menos tres letras',
|
||||
}
|
||||
|
||||
|
||||
var columns_carta_unidades_peso = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'delete', header: '', width: 30, css: 'delete'},
|
||||
{id: 'key', header: 'Clave'},
|
||||
{id: 'name', header: 'Nombre', adjust: 'data'},
|
||||
{id: 'activo', header: 'Activo', template: '{common.checkbox()}',
|
||||
editor: 'checkbox'},
|
||||
]
|
||||
|
||||
|
||||
var grid_carta_unidades_peso = {
|
||||
view: 'datatable',
|
||||
id: 'grid_carta_unidades_peso',
|
||||
url: 'satunidadespeso?opt=all',
|
||||
select: 'cell',
|
||||
adjust: true,
|
||||
autowidth: true,
|
||||
headermenu: true,
|
||||
columns: columns_carta_unidades_peso,
|
||||
on:{
|
||||
'data->onStoreUpdated':function(){
|
||||
this.data.each(function(obj, i){
|
||||
obj.delete = '-'
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
var carta_porte_unidades_peso = [
|
||||
{maxHeight: 20},
|
||||
{cols: [{maxWidth: 15}, buscar_carta_unidades_peso, {}]},
|
||||
{maxHeight: 20},
|
||||
{cols: [{maxWidth: 15}, grid_carta_unidades_peso, {}]},
|
||||
{maxHeight: 20},
|
||||
]
|
||||
|
||||
|
||||
var tab_sat_carta_porte = [{
|
||||
view: 'tabview',
|
||||
id: 'tab_sat_carta_porte',
|
||||
multiview: true,
|
||||
animate: true,
|
||||
cells: [
|
||||
{id: 'Unidades de Peso', rows: carta_porte_unidades_peso},
|
||||
]
|
||||
}]
|
||||
|
||||
|
||||
var tab_sat = {
|
||||
view: 'tabview',
|
||||
id: 'tab_sat',
|
||||
|
@ -1309,6 +1412,7 @@ var tab_sat = {
|
|||
{id: 'Unidades', rows: sat_unidades},
|
||||
{id: 'Formas de Pago', rows: sat_formasdepago},
|
||||
{id: 'Usos de CFDI', rows: sat_usos_cfdi},
|
||||
{id: 'Carta Porte', rows: tab_sat_carta_porte},
|
||||
],
|
||||
}
|
||||
|
||||
|
|
|
@ -208,7 +208,7 @@ var toolbar_invoices_util = [
|
|||
{view: 'button', id: 'cmd_invoice_verify_sat', label: 'SAT',
|
||||
type: 'iconButton', autowidth: true, icon: 'firefox'},
|
||||
{},
|
||||
{view: 'button', id: 'cmd_invoice_cancelar', label: 'Cancelar',
|
||||
{view: 'button', id: 'cmd_invoice_ask_cancel', label: 'Cancelar',
|
||||
type: 'iconButton', autowidth: true, icon: 'ban'},
|
||||
]
|
||||
|
||||
|
@ -820,6 +820,7 @@ var grid_leyendas_fiscales = {
|
|||
columns: grid_cols_leyendas_fiscales,
|
||||
}
|
||||
|
||||
|
||||
var controls_leyendas_fiscales = [
|
||||
{maxHeight: 15},
|
||||
{cols: [{maxWidth: 15},
|
||||
|
@ -830,6 +831,233 @@ var controls_leyendas_fiscales = [
|
|||
]
|
||||
|
||||
|
||||
var opt_transporte_internacional = [
|
||||
{id: 'Sí', value: 'Sí'},
|
||||
{id: 'No', value: 'No'},
|
||||
]
|
||||
|
||||
|
||||
var opt_entrada_salida = [
|
||||
{id: '', value: ''},
|
||||
{id: 'Entrada', value: 'Entrada'},
|
||||
{id: 'Salida', value: 'Salida'},
|
||||
]
|
||||
|
||||
|
||||
var opt_origen_destino = [
|
||||
{id: 'Origen', value: 'Origen'},
|
||||
{id: 'Destino', value: 'Destino'},
|
||||
]
|
||||
|
||||
|
||||
var date_suggest = {
|
||||
type: 'calendar',
|
||||
body:{
|
||||
timepicker: true,
|
||||
icons: true,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var opt_countries = [
|
||||
{id: 'MXN', value: 'México'},
|
||||
]
|
||||
|
||||
|
||||
var grid_cols_carta_ubicaciones = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'delete', header: '', hidden: true, width: 30, css: 'delete'},
|
||||
{id: 'TipoUbicacion', header: 'Tipo de Ubicación', editor: 'select', options: opt_origen_destino, fillspace: 1},
|
||||
{id: 'RFCRemitenteDestinatario', header: 'RFC Rem/Des', editor: 'text', fillspace: 1},
|
||||
{id: 'NombreRemitenteDestinatario', header: 'Nombre Rem/Des', editor: 'text', fillspace: 1},
|
||||
{id: 'FechaHoraSalidaLlegada', header: 'Fecha/Hora', editor: 'date', suggest: date_suggest, format: webix.Date.dateToStr("%D, %d-%M-%Y %h:%i"), footer: 'Total distancia:', fillspace: 1},
|
||||
{id: 'DistanciaRecorrida', header: 'Distancia (KM)', editor: 'text', css: 'right', footer: {content: 'summColumn', css: 'right'}, fillspace: 1},
|
||||
{id: 'Municipio', headerd: 'Municipio', editor: 'text', fillspace: 1},
|
||||
{id: 'Estado', headerd: 'Estado', editor: 'text', fillspace: 1},
|
||||
{id: 'Pais', headerd: 'Pais', editor: 'select', options: opt_countries, fillspace: 1},
|
||||
{id: 'CodigoPostal', headerd: 'C.P.', editor: 'text', fillspace: 1},
|
||||
]
|
||||
//~ Calle
|
||||
//~ NumeroExterior
|
||||
//~ NumeroInterior
|
||||
//~ Colonia
|
||||
//~ Localidad
|
||||
//~ Referencia
|
||||
|
||||
|
||||
|
||||
var grid_cols_carta_mercancias = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'BienesTransp', header: 'Clave SAT', fillspace: 1},
|
||||
{id: 'Descripcion', header: 'Descripción', fillspace: 1},
|
||||
{id: 'Cantidad', header: 'Cantidad', format: webix.i18n.numberFormat, css: 'right', fillspace: 1},
|
||||
{id: 'ClaveUnidad', header: 'Unidad', options: 'values/unidades', fillspace: 1},
|
||||
//~ {id: 'ValorMercancia', header: 'Valor Mercancia', format: webix.i18n.priceFormat, css: 'right', footer: 'Total peso:', fillspace: 1},
|
||||
{id: 'PesoEnKg', header: 'Peso (Kg)', format: webix.i18n.numberFormat, css: 'right', editor: 'text', footer: {content: 'summColumn', css: 'right'}, fillspace: 1},
|
||||
]
|
||||
|
||||
|
||||
var opt_config_auto = [
|
||||
{id: '', value: ''},
|
||||
{id: 'VL', value: '[VL] Vehículo ligero de carga (2 llantas en el eje delantero y 2 llantas en el eje trasero)'},
|
||||
{id: 'C2', value: '[C2] Camión Unitario (2 llantas en el eje delantero y 4 llantas en el eje trasero)'},
|
||||
{id: 'C3', value: '[C3] Camión Unitario (2 llantas en el eje delantero y 6 o 8 llantas en los dos ejes traseros)'},
|
||||
]
|
||||
|
||||
|
||||
var grid_cols_carta_autotransporte = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'PermSCT', header: 'Tipo Permiso SCT', editor: 'text', fillspace: 1},
|
||||
{id: 'NumPermisoSCT', header: 'Número Permiso SCT', editor: 'text', fillspace: 1},
|
||||
{id: 'ConfigVehicular', header: 'Clave Autotransporte', editor: 'select', options: opt_config_auto, fillspace: 1},
|
||||
{id: 'PlacaVM', header: 'Placa', editor: 'text', fillspace: 1},
|
||||
{id: 'AnioModeloVM', header: 'Modelo (Año)', editor: 'text', fillspace: 1},
|
||||
{id: 'AseguraRespCivil', header: 'Aseguradora', editor: 'text', fillspace: 1},
|
||||
{id: 'PolizaRespCivil', header: 'Póliza', editor: 'text', fillspace: 1},
|
||||
]
|
||||
|
||||
|
||||
var opt_tipos_figura = [
|
||||
{id: '', value: ''},
|
||||
{id: '01', value: '[01] Operador'},
|
||||
{id: '02', value: '[02] Propietario'},
|
||||
{id: '03', value: '[03] Arrendador'},
|
||||
{id: '04', value: '[04] Notificado'},
|
||||
]
|
||||
|
||||
|
||||
var grid_cols_carta_tipos_figuras = [
|
||||
{id: 'id', header: 'ID', hidden: true},
|
||||
{id: 'TipoFigura', header: 'Tipo Figura', editor: 'select', options: opt_tipos_figura, fillspace: 1},
|
||||
{id: 'RFCFigura', header: 'RFC Figura', editor: 'text', fillspace: 1},
|
||||
{id: 'NombreFigura', header: 'Nombre Figura', editor: 'text', fillspace: 1},
|
||||
{id: 'NumLicencia', header: 'Número de Licencia', editor: 'text', fillspace: 1},
|
||||
|
||||
]
|
||||
|
||||
|
||||
var grid_carta_ubicaciones = {
|
||||
view: 'datatable',
|
||||
id: 'grid_carta_ubicaciones',
|
||||
multiselect: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
editable: true,
|
||||
footer: true,
|
||||
columns: grid_cols_carta_ubicaciones,
|
||||
//~ data: data_tmp1,
|
||||
data: [
|
||||
{delete: '-', TipoUbicacion: 'Origen', Pais: 'MXN'},
|
||||
{delete: '-', TipoUbicacion: 'Destino', Pais: 'MXN'},
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
var grid_carta_mercancias = {
|
||||
view: 'datatable',
|
||||
id: 'grid_carta_mercancias',
|
||||
multiselect: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
editable: true,
|
||||
footer: true,
|
||||
columns: grid_cols_carta_mercancias,
|
||||
}
|
||||
|
||||
|
||||
var grid_carta_autotransporte = {
|
||||
view: 'datatable',
|
||||
id: 'grid_carta_autotransporte',
|
||||
multiselect: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
editable: true,
|
||||
columns: grid_cols_carta_autotransporte,
|
||||
data: [{id: 0}],
|
||||
//~ data: data_tmp2,
|
||||
}
|
||||
|
||||
|
||||
var grid_carta_tipos_figuras = {
|
||||
view: 'datatable',
|
||||
id: 'grid_carta_tipos_figuras',
|
||||
multiselect: false,
|
||||
adjust: true,
|
||||
autoheight: true,
|
||||
headermenu: true,
|
||||
editable: true,
|
||||
columns: grid_cols_carta_tipos_figuras,
|
||||
data: [{id: 0}],
|
||||
//~ data: data_tmp3,
|
||||
}
|
||||
|
||||
|
||||
var body_carta_mercancias = {rows:[
|
||||
{cols: [{view: 'richselect', id: 'lst_carta_UnidadPeso', labelPosition: 'top',
|
||||
label: 'Unidad de Peso', maxWidth: 300, options: '/satunidadespeso?opt=active'}, {}
|
||||
]},
|
||||
{maxHeight: 10},
|
||||
grid_carta_mercancias,
|
||||
]}
|
||||
|
||||
|
||||
var body_carta_ubicaciones = {rows:[
|
||||
grid_carta_ubicaciones,
|
||||
]}
|
||||
|
||||
|
||||
var body_carta_autotransporte = {rows:[
|
||||
grid_carta_autotransporte,
|
||||
]}
|
||||
|
||||
|
||||
var body_carta_tipos_figuras = {rows:[
|
||||
grid_carta_tipos_figuras,
|
||||
]}
|
||||
|
||||
|
||||
var controls_carta_porte = [
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'checkbox', id: 'chk_cfdi_usar_cartaporte', labelWidth: 0,
|
||||
labelRight: 'Usar el complemento Carta Porte'},
|
||||
{}]},
|
||||
{view: 'fieldset', label: 'Mercancias', body: body_carta_mercancias},
|
||||
{cols: [{maxWidth: 15},
|
||||
{view: 'richselect', id: 'lst_carta_TranspInternac', labelPosition: 'top',
|
||||
label: 'Transporte Internacional', options: opt_transporte_internacional,
|
||||
value: 'No', readonly: true},
|
||||
{view: 'richselect', id: 'lst_carta_EntradaSalidaMerc', labelPosition: 'top',
|
||||
label: 'Entrada o Salida', options: opt_entrada_salida,
|
||||
value: '', disabled: true},
|
||||
{view: 'richselect', id: 'lst_carta_PaisOrigenDestino', labelPosition: 'top',
|
||||
label: 'País Origen/Destino', options: [],
|
||||
value: '', disabled: true},
|
||||
{view: 'richselect', id: 'lst_carta_ViaEntradaSalida', labelPosition: 'top',
|
||||
label: 'Vía de Entrada o Salida', options: [],
|
||||
value: '', disabled: true},
|
||||
]},
|
||||
{view: 'fieldset', label: 'Ubicaciones', body: body_carta_ubicaciones},
|
||||
{view: 'fieldset', label: 'Autotransporte', body: body_carta_autotransporte},
|
||||
{view: 'fieldset', label: 'Tipos Figura', body: body_carta_tipos_figuras},
|
||||
]
|
||||
|
||||
|
||||
var form_carta_porte = {
|
||||
type: 'space',
|
||||
responsive: true,
|
||||
cols: [{
|
||||
view: 'form',
|
||||
id: 'form_carta_porte',
|
||||
complexData: true,
|
||||
scroll: true,
|
||||
elements: controls_carta_porte,
|
||||
}]
|
||||
}
|
||||
|
||||
|
||||
var controls_invoices = [
|
||||
{
|
||||
view: 'tabview',
|
||||
|
@ -840,6 +1068,7 @@ var controls_invoices = [
|
|||
{id: 'PreFacturas', rows: controls_prefactura},
|
||||
{id: 'INE', rows: controls_ine},
|
||||
{id: 'Leyendas Fiscales', rows: controls_leyendas_fiscales},
|
||||
{id: 'Carta Porte', rows: [form_carta_porte]},
|
||||
]
|
||||
},
|
||||
]
|
||||
|
@ -913,3 +1142,44 @@ var win_import_invoice = {
|
|||
$$('up_invoice').attachEvent('onUploadComplete', up_invoice_upload_complete)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var opt_reasons_cancel = [
|
||||
{id: '', value: ''},
|
||||
{id: '01', value: '[01] Comprobante emitido con errores con relación'},
|
||||
{id: '02', value: '[02] Comprobante emitido con errores sin relación'},
|
||||
{id: '03', value: '[03] No se llevó acabo la operación'},
|
||||
{id: '04', value: '[04] Operación nominativa relacionada en una factura global'},
|
||||
]
|
||||
|
||||
|
||||
var body_invoice_cancel = {rows: [{minHeight: 15},
|
||||
{view: 'richselect', id: 'lst_reasons_cancel', labelPosition: 'top', label: 'Razón de cancelación', options: opt_reasons_cancel, value: '', width: 400},
|
||||
{view: 'text', id: 'txt_cancel_uuid', labelPosition: 'top', label: 'UUID que sustituye', width: 400},
|
||||
{view: 'label', label: 'Esta acción no se puede deshacer', autowidth: true, align: 'center'},
|
||||
{view: 'label', label: '¿Estás segura de continuar?', autowidth: true, align: 'center'},
|
||||
{cols: [{},
|
||||
{view: 'button', id: 'cmd_invoice_cancel', width: 100, label: 'Cancelar', type: 'danger', icon: 'ban'},
|
||||
{maxWidth: 25},
|
||||
{view: 'button', id: 'cmd_win_cancel_close', width: 100, label: 'Cerrar'},
|
||||
{}
|
||||
]},
|
||||
{minHeight: 20},
|
||||
]}
|
||||
|
||||
|
||||
var win_invoice_cancel = {
|
||||
init: function(){
|
||||
webix.ui({
|
||||
view: 'window',
|
||||
id: 'win_invoice_cancel',
|
||||
modal: true,
|
||||
width: 400,
|
||||
position: 'center',
|
||||
head: 'Cancelar CFDI',
|
||||
body: body_invoice_cancel,
|
||||
})
|
||||
$$('cmd_invoice_cancel').attachEvent('onItemClick', cmd_invoice_cancel_click)
|
||||
$$('cmd_win_cancel_close').attachEvent('onItemClick', cmd_win_cancel_close_click)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue