forked from elmau/empresa-libre
Cancelar CFDI de pago
This commit is contained in:
parent
e5a389a9dd
commit
0ec7989c75
|
@ -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)
|
||||
|
|
|
@ -164,6 +164,7 @@ DEFAULT_CFDIPAY = {
|
|||
'KEYSAT': '84111506',
|
||||
'UNITKEY': 'ACT',
|
||||
'DESCRIPTION': 'Pago',
|
||||
'TYPE_RELATION': '04',
|
||||
}
|
||||
DIR_FACTURAS = 'facturas'
|
||||
USAR_TOKEN = False
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue