Agregar cancelación con certificados con el pac CD
This commit is contained in:
parent
e372f064b4
commit
28ef107949
|
@ -725,6 +725,12 @@ class AppWareHouseProduct(object):
|
|||
req.context['result'] = self._db.warehouseproduct_get(values)
|
||||
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.warehouseproduct_post(values, user)
|
||||
resp.status = falcon.HTTP_200
|
||||
|
||||
|
||||
class AppTicketsDetails(object):
|
||||
|
||||
|
|
|
@ -173,8 +173,6 @@ class SATCertificate(object):
|
|||
tree, encoding='utf-8', xml_declaration=True).decode()
|
||||
# ~ xml_signed = xml_signed.replace("'", '"').replace('utf', 'UTF')
|
||||
|
||||
print(xml_signed)
|
||||
|
||||
return xml_signed
|
||||
|
||||
@property
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import base64
|
||||
import logging
|
||||
|
||||
import lxml.etree as ET
|
||||
|
@ -146,6 +147,11 @@ class PACComercioDigital(object):
|
|||
return data
|
||||
|
||||
def _get_data_cancel(self, cfdi, info, auth):
|
||||
info['pass'] = '12345678a'
|
||||
info['tipo'] = 'cfdi3.3'
|
||||
info['key'] = base64.b64encode(info['key']).decode()
|
||||
info['cer'] = base64.b64encode(info['cer']).decode()
|
||||
|
||||
NS_CFDI = {
|
||||
'cfdi': 'http://www.sat.gob.mx/cfd/3',
|
||||
'tdf': 'http://www.sat.gob.mx/TimbreFiscalDigital',
|
||||
|
@ -200,7 +206,15 @@ class PACComercioDigital(object):
|
|||
self._error(result.headers['errmsg'])
|
||||
return ''
|
||||
|
||||
return result.text
|
||||
tree = ET.fromstring(result.text)
|
||||
date_cancel = tree.xpath('string(//Acuse/@Fecha)')[:19]
|
||||
|
||||
data = {
|
||||
'acuse': result.text,
|
||||
'date': date_cancel,
|
||||
}
|
||||
|
||||
return data
|
||||
|
||||
def _get_headers_cancel_xml(self, cfdi, info, auth):
|
||||
NS_CFDI = {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
# ~ You should have received a copy of the GNU General Public License
|
||||
# ~ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import base64
|
||||
# ~ import base64
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
|
@ -129,7 +129,9 @@ class PACFinkok(object):
|
|||
return {}
|
||||
|
||||
if self.CODE['200'] != ce:
|
||||
log.error('CodEstatus', type(ce), ce)
|
||||
self._error = ce
|
||||
return {}
|
||||
|
||||
return result
|
||||
|
||||
return result
|
||||
|
@ -243,8 +245,6 @@ class PACFinkok(object):
|
|||
client = Client(self.URL[method],
|
||||
transport=self._transport, plugins=self._plugins)
|
||||
client.set_ns_prefix('can', 'http://facturacion.finkok.com/cancel')
|
||||
# ~ xml = f'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\n{xml}'
|
||||
# ~ xml = f'<?xml version="1.0" encoding="UTF-8" standalone="true"?>\n{xml}'
|
||||
args = {
|
||||
'xml': xml.encode(),
|
||||
'username': auth['user'],
|
||||
|
|
|
@ -665,7 +665,7 @@ def get_pac_by_rfc(cfdi):
|
|||
return RFCS[rfc_pac]
|
||||
|
||||
|
||||
def _cancel_finkok(invoice, auth, certificado):
|
||||
def _cancel_with_cert(invoice, auth, certificado):
|
||||
cert = SATCertificate(certificado.cer, certificado.key_enc.encode())
|
||||
pac = PACS[auth['pac']]()
|
||||
info = {'cer': cert.cer_pem, 'key': cert.key_pem}
|
||||
|
@ -682,8 +682,9 @@ def _cancel_finkok(invoice, auth, certificado):
|
|||
|
||||
|
||||
def cancel_xml_sign(invoice, auth, certificado):
|
||||
if auth['pac'] == 'finkok':
|
||||
return _cancel_finkok(invoice, auth, certificado)
|
||||
# ~ if auth['pac'] == 'finkok':
|
||||
# ~ return _cancel_finkok(invoice, auth, certificado)
|
||||
return _cancel_with_cert(invoice, auth, certificado)
|
||||
|
||||
cert = SATCertificate(certificado.cer, certificado.key_enc.encode())
|
||||
pac = PACS[auth['pac']]()
|
||||
|
@ -695,6 +696,7 @@ def cancel_xml_sign(invoice, auth, certificado):
|
|||
template = TEMPLATE_CANCEL.format(**data)
|
||||
tree = ET.fromstring(template.encode())
|
||||
sign_xml = cert.sign_xml(tree)
|
||||
|
||||
result = pac.cancel_xml(sign_xml, auth, invoice.xml)
|
||||
|
||||
if pac.error:
|
||||
|
|
|
@ -496,6 +496,9 @@ class StorageEngine(object):
|
|||
def warehouseproduct_get(self, filters):
|
||||
return main.WareHouseProduct.get_data(filters)
|
||||
|
||||
def warehouseproduct_post(self, filters, user):
|
||||
return main.WareHouseProduct.post(filters, user)
|
||||
|
||||
def users_get(self, filters, user):
|
||||
return main.Usuarios.get_data(filters, user)
|
||||
|
||||
|
|
|
@ -4088,6 +4088,39 @@ class WareHouseProduct(BaseModel):
|
|||
obj.save()
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def _adjust_stock(cls, args, user):
|
||||
cant = args['cant']
|
||||
fields = dict(
|
||||
warehouse = args['storage'],
|
||||
product = args['id_product'],
|
||||
)
|
||||
obj = WareHouseProduct.get(**fields)
|
||||
obj.exists += cant
|
||||
obj.save()
|
||||
|
||||
total = (WareHouseProduct
|
||||
.select(fn.Sum(WareHouseProduct.exists)).alias('total')
|
||||
.where(WareHouseProduct.product==fields['product'])
|
||||
.limit(1)
|
||||
.scalar()
|
||||
)
|
||||
query = (Productos
|
||||
.update(existencia=total)
|
||||
.where(Productos.id==fields['product'])
|
||||
)
|
||||
query.execute()
|
||||
|
||||
result = {'ok': True, 'row': {'existencia': total}}
|
||||
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def post(cls, values, user):
|
||||
opt = values['opt']
|
||||
args = utils.loads(values['values'])
|
||||
return getattr(cls, f'_{opt}')(args, user)
|
||||
|
||||
|
||||
class RangosPrecios(BaseModel):
|
||||
producto = ForeignKeyField(Productos)
|
||||
|
@ -4221,10 +4254,6 @@ class Facturas(BaseModel):
|
|||
msg = 'No es posible cancelar CFDI 3.2'
|
||||
return {'ok': False, 'msg': msg}
|
||||
|
||||
# ~ pac = Configuracion.get_('lst_pac').lower()
|
||||
# ~ if pac:
|
||||
# ~ data, result = utils.xml_cancel(obj.xml, auth, certificado, pac)
|
||||
# ~ else:
|
||||
data, result = util.cancel_xml(auth, obj.uuid, certificado)
|
||||
|
||||
if data['ok']:
|
||||
|
@ -9915,8 +9944,6 @@ class InventoryEntries(BaseModel):
|
|||
result = {'ok': False, 'msg': msg}
|
||||
return result
|
||||
|
||||
print(0, args)
|
||||
|
||||
storage = args['target']
|
||||
cant = Decimal(args['cant'])
|
||||
values = dict(
|
||||
|
|
|
@ -250,35 +250,6 @@ DEFAULT_GLOBAL = {
|
|||
'clave_sat': '01010101',
|
||||
}
|
||||
|
||||
# ~ TEMPLATE_CANCEL = """<Cancelacion RfcEmisor="{rfc}" Fecha="{fecha}" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://cancelacfd.sat.gob.mx">
|
||||
# ~ <Folios>
|
||||
# ~ <UUID>{uuid}</UUID>
|
||||
# ~ </Folios>
|
||||
# ~ <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
# ~ <SignedInfo>
|
||||
# ~ <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
|
||||
# ~ <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
|
||||
# ~ <Reference URI="">
|
||||
# ~ <Transforms>
|
||||
# ~ <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
|
||||
# ~ </Transforms>
|
||||
# ~ <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
|
||||
# ~ <DigestValue />
|
||||
# ~ </Reference>
|
||||
# ~ </SignedInfo>
|
||||
# ~ <SignatureValue />
|
||||
# ~ <KeyInfo>
|
||||
# ~ <X509Data>
|
||||
# ~ <X509SubjectName />
|
||||
# ~ <X509IssuerSerial />
|
||||
# ~ <X509Certificate />
|
||||
# ~ </X509Data>
|
||||
# ~ <KeyValue />
|
||||
# ~ </KeyInfo>
|
||||
# ~ </Signature>
|
||||
# ~ </Cancelacion>
|
||||
# ~ """
|
||||
|
||||
TEMPLATE_CANCEL = """<Cancelacion xmlns="http://cancelacfd.sat.gob.mx" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Fecha="{fecha}" RfcEmisor="{rfc}">
|
||||
<Folios>
|
||||
<UUID>{uuid}</UUID>
|
||||
|
|
|
@ -910,3 +910,77 @@ function _add_entries_inventory_manual(row_id, data){
|
|||
})
|
||||
}
|
||||
|
||||
|
||||
function cmd_adjust_stock_click(id, e, node){
|
||||
var id_product = $$('txt_id_product').getValue()
|
||||
var row = $$('grid_warehouse_exists').getSelectedItem()
|
||||
if (row == undefined){
|
||||
msg_error('Selecciona un Almacen origen')
|
||||
return
|
||||
}
|
||||
var warehouse_source = row.id
|
||||
var cant_to_adjust = $$('txt_cant_to_adjust').getValue()
|
||||
|
||||
if(cant_to_adjust == 0){
|
||||
msg_error('La cantidad a ajustar no puede ser cero')
|
||||
return
|
||||
}
|
||||
|
||||
if(cant_to_adjust > row.exists){
|
||||
msg_error('La cantidad a ajustar no puede ser mayor a la existencia')
|
||||
return
|
||||
}
|
||||
|
||||
var values = {
|
||||
id_product: id_product,
|
||||
cant: cant_to_adjust,
|
||||
storage: warehouse_source,
|
||||
}
|
||||
|
||||
msg = '¿Estás seguro de hacer este ajuste?'
|
||||
webix.confirm({
|
||||
title: 'Ajuste de Almacen',
|
||||
ok: 'Si',
|
||||
cancel: 'No',
|
||||
type: 'confirm-error',
|
||||
text: msg,
|
||||
callback:function(result){
|
||||
if(result){
|
||||
_adjust_stock(values)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function _adjust_stock(args){
|
||||
var grid = $$('grid_products')
|
||||
var row = grid.getSelectedItem()
|
||||
|
||||
var values = {
|
||||
opt: 'adjust_stock',
|
||||
values: args,
|
||||
}
|
||||
|
||||
webix.ajax().sync().post('warehouseproduct', 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) {
|
||||
$$('txt_cant_to_adjust').setValue(0)
|
||||
$$('grid_warehouse_exists').load('warehouseproduct?opt=by_product&id=' + args.id_product)
|
||||
$$('grid_warehouse_exists').clearSelection()
|
||||
|
||||
grid.updateItem(row['id'], values.row)
|
||||
grid.refresh()
|
||||
|
||||
msg_ok('Ajuste realizado correctamente')
|
||||
}else{
|
||||
msg_error(values.msg)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
@ -502,6 +502,13 @@ var body_win_show_exists = {rows: [{maxHeight: 10, minHeight: 10},
|
|||
labelPosition: 'top', required: false, options: []}, {maxWidth: 10},
|
||||
{view: 'button', id: 'cmd_warehouse_move', label: 'Mover', maxWidth: 100},
|
||||
{maxWidth: 10}]},
|
||||
{minHeight: 25, maxHeight: 25},
|
||||
{template: 'Ajuste de almacen', type: 'section'},
|
||||
{cols: [{maxWidth: 10},
|
||||
{view: 'counter', id: 'txt_cant_to_adjust', label: 'Cantidad a ajustar:',
|
||||
labelPosition: 'top', step: 1, value: 0, min: -1000000},
|
||||
{view: 'button', id: 'cmd_adjust_stock', label: 'Ajustar', maxWidth: 100},
|
||||
{maxWidth: 10}]},
|
||||
{maxHeight: 20, minHeight: 20},
|
||||
{cols: [{},
|
||||
{view: 'button', id: 'cmd_win_show_exists_close', label: 'Cerrar', type: 'danger'},
|
||||
|
@ -523,5 +530,6 @@ var win_show_exists = {
|
|||
})
|
||||
$$('cmd_win_show_exists_close').attachEvent('onItemClick', cmd_win_show_exists_close_click)
|
||||
$$('cmd_warehouse_move').attachEvent('onItemClick', cmd_warehouse_move_click)
|
||||
$$('cmd_adjust_stock').attachEvent('onItemClick', cmd_adjust_stock_click)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue