Cancelar CFDI de pago

This commit is contained in:
Mauricio Baeza 2018-09-07 00:08:16 -05:00
parent e5a389a9dd
commit 0ec7989c75
3 changed files with 112 additions and 2 deletions

View File

@ -1858,6 +1858,12 @@ class MovimientosBanco(BaseModel):
@classmethod
def add(cls, values):
ids = values.pop('ids', '')
if ids and not Facturas.validate_count_partners(util.loads(ids)):
msg = 'Facturas relacionadas a diferentes clientes'
data = {'ok': False, 'msg': msg}
return data
actualizar = False
if 'saldo' in values:
saldo = values['saldo']
@ -3220,6 +3226,17 @@ class Facturas(BaseModel):
class Meta:
order_by = ('fecha',)
@classmethod
def validate_count_partners(cls, ids):
filters = (Facturas.id.in_(tuple(ids.keys())))
partners = (Facturas.select(fn.COUNT(Facturas.cliente))
.where(filters)
.group_by(Facturas.cliente)
.order_by(Facturas.cliente).tuples())
if len(partners) > 1:
return False
return True
@classmethod
def cancel(cls, id):
obj = Facturas.get(Facturas.id==id)
@ -5279,6 +5296,7 @@ class CfdiPagos(BaseModel):
notas = TextField(default='')
error = TextField(default='')
cancelada = BooleanField(default=False)
fecha_cancelacion = DateTimeField(null=True)
class Meta:
order_by = ('movimiento',)
@ -5288,6 +5306,46 @@ class CfdiPagos(BaseModel):
opt = values.pop('opt')
return getattr(cls, '_{}'.format(opt))(cls, values)
def _cancel(self, values):
id_mov = int(values['id_mov'])
filters = (
(CfdiPagos.movimiento==id_mov) &
(CfdiPagos.cancelada==False)
)
last = CfdiPagos.select().where(filters)
if not last:
msg = 'El depósito no tiene facturas de pago activas'
data = {'ok': False, 'msg': msg}
return data
if len(last) > 1:
msg = 'Hay más de una factura activa para este depósito'
data = {'ok': False, 'msg': msg}
return data
last = last[0]
if not last.uuid:
msg = 'La factura no esta timbrada'
data = {'ok': False, 'msg': msg}
return data
auth = Emisor.get_auth()
cert = Certificado.get_cert()
data, result = util.cancel_xml(auth, last.uuid, cert)
if data['ok']:
last.estatus = 'Cancelada'
last.error = ''
last.cancelada = True
last.fecha_cancelacion = result['Fecha']
msg = 'Factura cancelada correctamente'
else:
last.error = msg = data['msg']
last.save()
return {'ok': data['ok'], 'msg': msg, 'id': last.id}
def _get_folio(self, serie):
folio = int(Configuracion.get_('txt_config_cfdipay_folio') or '0')
start = (CfdiPagos
@ -5341,9 +5399,19 @@ class CfdiPagos(BaseModel):
data = {'ok': True, 'new': False}
return data
fields = {}
filters = (
(CfdiPagos.movimiento==id_mov) &
(CfdiPagos.cancelada==True)
)
previous = CfdiPagos.select().where(filters).order_by(CfdiPagos.id.desc())
if previous:
previous = previous[0]
fields['tipo_relacion'] = DEFAULT_CFDIPAY['TYPE_RELATION']
fields['uuid_relacionado'] = previous.uuid
emisor = Emisor.select()[0]
serie = Configuracion.get_('txt_config_cfdipay_serie') or DEFAULT_CFDIPAY['SERIE']
fields = {}
fields['movimiento'] = id_mov
fields['socio'] = partner
fields['serie'] = serie
@ -5417,7 +5485,7 @@ class CfdiPagos(BaseModel):
if invoice.tipo_relacion:
related = {
'tipo': invoice.tipo_relacion,
'cfdis': (invoice.uuid_relacionado,),
'cfdis': (str(invoice.uuid_relacionado),),
}
emisor = {
@ -7958,6 +8026,10 @@ def _migrate_tables():
migrations.append(migrator.drop_column('cfdipagos', 'cancelado'))
migrations.append(migrator.add_column('cfdipagos', 'cancelada', cancelada))
if not 'fecha_cancelacion' in columns:
fecha_cancelacion = DateTimeField(null=True)
migrations.append(migrator.add_column('cfdipagos', 'fecha_cancelacion', fecha_cancelacion))
if migrations:
with database_proxy.atomic() as txn:
migrate(*migrations)

View File

@ -164,6 +164,7 @@ DEFAULT_CFDIPAY = {
'KEYSAT': '84111506',
'UNITKEY': 'ACT',
'DESCRIPTION': 'Pago',
'TYPE_RELATION': '04',
}
DIR_FACTURAS = 'facturas'
USAR_TOKEN = False

View File

@ -893,6 +893,43 @@ function cmd_pay_stamp_click(){
function cmd_pay_cancel_click(){
var form = $$('form_bank_pay')
var values = form.getValues()
var data = {'opt': 'cancel', 'id_mov': values.id_mov}
var grid = $$('grid_cfdi_pay')
if(grid.count() == 0){
msg_error('El depósito no tiene facturas de pago activas')
return
}
msg = '¿Estás seguro de cancelar esta factura?\n\nESTA 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){
webix.ajax().post('/cfdipay', data, {
error:function(text, data, XmlHttpRequest){
msg = 'Ocurrio un error, consulta a soporte técnico'
msg_error(msg)
},
success:function(text, data, XmlHttpRequest){
values = data.json();
if(values.ok){
grid.updateItem(values.id, {'estatus': 'Cancelada'})
msg_ok(values.msg)
}else{
msg_error(values.msg)
}
}
})
}
}
})
}