diff --git a/source/app/controllers/pacs/finkok/finkok.py b/source/app/controllers/pacs/finkok/finkok.py
index 1bb095b..93efd30 100644
--- a/source/app/controllers/pacs/finkok/finkok.py
+++ b/source/app/controllers/pacs/finkok/finkok.py
@@ -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,
diff --git a/source/app/controllers/utils.py b/source/app/controllers/utils.py
index 3e142f1..0b4a6a4 100644
--- a/source/app/controllers/utils.py
+++ b/source/app/controllers/utils.py
@@ -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']]()
diff --git a/source/app/models/main.py b/source/app/models/main.py
index 5d47532..7884aa8 100644
--- a/source/app/models/main.py
+++ b/source/app/models/main.py
@@ -4379,8 +4379,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
@@ -4389,10 +4389,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}
@@ -4401,7 +4401,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'
@@ -6087,9 +6087,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
diff --git a/source/static/js/controller/invoices.js b/source/static/js/controller/invoices.js
index 26d5362..c5a1abe 100644
--- a/source/static/js/controller/invoices.js
+++ b/source/static/js/controller/invoices.js
@@ -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)
@@ -1469,67 +1469,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.
'
- }
-
- msg += '¿Estás seguro de enviar a cancelar esta factura?
\
- 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()
@@ -2553,3 +2492,92 @@ function tv_invoice_change(nv, ov){
_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()
+
+ 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.
'
+ msg += '¿Estás seguro de enviar a cancelar esta factura?
\
+ 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)
+ }
+ }
+ })
+ }
+}
diff --git a/source/static/js/ui/invoices.js b/source/static/js/ui/invoices.js
index 72710c7..a16cb9f 100644
--- a/source/static/js/ui/invoices.js
+++ b/source/static/js/ui/invoices.js
@@ -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'},
]
@@ -1118,3 +1118,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)
+ }
+}