diff --git a/source/app/controllers/main.py b/source/app/controllers/main.py
index a0379d3..8146a19 100644
--- a/source/app/controllers/main.py
+++ b/source/app/controllers/main.py
@@ -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):
diff --git a/source/app/controllers/pacs/cfdi_cert.py b/source/app/controllers/pacs/cfdi_cert.py
index edb6455..4c3a0a2 100644
--- a/source/app/controllers/pacs/cfdi_cert.py
+++ b/source/app/controllers/pacs/cfdi_cert.py
@@ -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
diff --git a/source/app/controllers/pacs/comerciodigital/comercio.py b/source/app/controllers/pacs/comerciodigital/comercio.py
index 1c17607..08c4ed9 100644
--- a/source/app/controllers/pacs/comerciodigital/comercio.py
+++ b/source/app/controllers/pacs/comerciodigital/comercio.py
@@ -17,6 +17,7 @@
# ~ along with this program. If not, see .
+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 = {
diff --git a/source/app/controllers/pacs/finkok/finkok.py b/source/app/controllers/pacs/finkok/finkok.py
index a333650..1bb095b 100644
--- a/source/app/controllers/pacs/finkok/finkok.py
+++ b/source/app/controllers/pacs/finkok/finkok.py
@@ -16,7 +16,7 @@
# ~ You should have received a copy of the GNU General Public License
# ~ along with this program. If not, see .
-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'\n{xml}'
- # ~ xml = f'\n{xml}'
args = {
'xml': xml.encode(),
'username': auth['user'],
diff --git a/source/app/controllers/utils.py b/source/app/controllers/utils.py
index a698e6f..e5959dd 100644
--- a/source/app/controllers/utils.py
+++ b/source/app/controllers/utils.py
@@ -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:
diff --git a/source/app/models/db.py b/source/app/models/db.py
index e66ad23..371d006 100644
--- a/source/app/models/db.py
+++ b/source/app/models/db.py
@@ -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)
diff --git a/source/app/models/main.py b/source/app/models/main.py
index 3e77ff9..3304533 100644
--- a/source/app/models/main.py
+++ b/source/app/models/main.py
@@ -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(
diff --git a/source/app/settings.py b/source/app/settings.py
index 4005397..7b4a3ff 100644
--- a/source/app/settings.py
+++ b/source/app/settings.py
@@ -250,35 +250,6 @@ DEFAULT_GLOBAL = {
'clave_sat': '01010101',
}
-# ~ TEMPLATE_CANCEL = """
- # ~
- # ~ {uuid}
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
- # ~
-# ~
-# ~ """
-
TEMPLATE_CANCEL = """
{uuid}
diff --git a/source/static/js/controller/products.js b/source/static/js/controller/products.js
index c8b60a4..c7b31c5 100644
--- a/source/static/js/controller/products.js
+++ b/source/static/js/controller/products.js
@@ -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)
+ }
+ }
+ })
+}
diff --git a/source/static/js/ui/products.js b/source/static/js/ui/products.js
index d908b06..eeb3472 100644
--- a/source/static/js/ui/products.js
+++ b/source/static/js/ui/products.js
@@ -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)
}
}