Importar nómina
This commit is contained in:
parent
776c90a467
commit
6a66b15f56
|
@ -1054,26 +1054,126 @@ class LIBO(object):
|
||||||
msg = 'Empleados importados correctamente'
|
msg = 'Empleados importados correctamente'
|
||||||
return rows, msg
|
return rows, msg
|
||||||
|
|
||||||
|
def _get_nomina(self, doc):
|
||||||
|
rows, msg = self._get_data(doc, 'Nomina')
|
||||||
|
if len(rows) == 2:
|
||||||
|
msg = 'Sin datos para importar'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
fields = (
|
||||||
|
'rfc',
|
||||||
|
'tipo_nomina',
|
||||||
|
'fecha_pago',
|
||||||
|
'fecha_inicial_pago',
|
||||||
|
'fecha_final_pago',
|
||||||
|
)
|
||||||
|
data = tuple([dict(zip(fields, r[1:])) for r in rows[2:]])
|
||||||
|
return data, ''
|
||||||
|
|
||||||
|
def _get_percepciones(self, doc, count):
|
||||||
|
rows, msg = self._get_data(doc, 'Percepciones')
|
||||||
|
if len(rows) == 2:
|
||||||
|
msg = 'Sin Percepciones'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
if len(rows[0][2:]) % 2:
|
||||||
|
msg = 'Las Percepciones deben ir en pares: Gravado y Exento'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
data = tuple([r[2:] for r in rows[:count+2]])
|
||||||
|
return data, ''
|
||||||
|
|
||||||
|
def _get_deducciones(self, doc, count):
|
||||||
|
rows, msg = self._get_data(doc, 'Deducciones')
|
||||||
|
if len(rows) == 2:
|
||||||
|
msg = 'Sin Deducciones'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
data = tuple([r[2:] for r in rows[:count+2]])
|
||||||
|
return data, ''
|
||||||
|
|
||||||
|
def _get_otros_pagos(self, doc, count):
|
||||||
|
rows, msg = self._get_data(doc, 'OtrosPagos')
|
||||||
|
if len(rows) == 2:
|
||||||
|
msg = 'Sin Otros Pagos'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
data = tuple([r[2:] for r in rows[:count+2]])
|
||||||
|
return data, ''
|
||||||
|
|
||||||
|
def _get_horas_extras(self, doc, count):
|
||||||
|
rows, msg = self._get_data(doc, 'HorasExtras')
|
||||||
|
if len(rows) == 2:
|
||||||
|
msg = 'Sin Horas Extras'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
if len(rows[1][1:]) % 4:
|
||||||
|
msg = 'Las Horas Extras deben ir grupos de 4 columnas'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
data = tuple([r[1:] for r in rows[:count+2]])
|
||||||
|
return data, ''
|
||||||
|
|
||||||
|
def _get_incapacidades(self, doc, count):
|
||||||
|
rows, msg = self._get_data(doc, 'Incapacidades')
|
||||||
|
if len(rows) == 2:
|
||||||
|
msg = 'Sin Incapacidades'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
if len(rows[1][1:]) % 3:
|
||||||
|
msg = 'Las Incapacidades deben ir grupos de 3 columnas'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
data = tuple([r[1:] for r in rows[:count+2]])
|
||||||
|
return data, ''
|
||||||
|
|
||||||
def nomina(self, path):
|
def nomina(self, path):
|
||||||
options = {'AsTemplate': True, 'Hidden': True}
|
options = {'AsTemplate': True, 'Hidden': True}
|
||||||
doc = self._doc_open(path, options)
|
doc = self._doc_open(path, options)
|
||||||
if doc is None:
|
if doc is None:
|
||||||
return ()
|
msg = 'No se pudo abrir la plantilla'
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
data, msg = self._get_data(doc, 'Nomina')
|
data = {}
|
||||||
|
nomina, msg = self._get_nomina(doc)
|
||||||
|
if msg:
|
||||||
doc.close(True)
|
doc.close(True)
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
if len(data) == 1:
|
percepciones, msg = self._get_percepciones(doc, len(nomina))
|
||||||
msg = 'Sin datos para importar'
|
if msg:
|
||||||
return (), msg
|
doc.close(True)
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
fields = (
|
deducciones, msg = self._get_deducciones(doc, len(nomina))
|
||||||
'num_empleado',
|
if msg:
|
||||||
'rfc',
|
doc.close(True)
|
||||||
)
|
return {}, msg
|
||||||
rows = tuple([dict(zip(fields, r)) for r in data[1:]])
|
|
||||||
msg = 'Nomina importada correctamente'
|
otros_pagos, msg = self._get_otros_pagos(doc, len(nomina))
|
||||||
return rows, msg
|
if msg:
|
||||||
|
doc.close(True)
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
horas_extras, msg = self._get_horas_extras(doc, len(nomina))
|
||||||
|
if msg:
|
||||||
|
doc.close(True)
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
incapacidades, msg = self._get_incapacidades(doc, len(nomina))
|
||||||
|
if msg:
|
||||||
|
doc.close(True)
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
doc.close(True)
|
||||||
|
data['nomina'] = nomina
|
||||||
|
data['percepciones'] = percepciones
|
||||||
|
data['deducciones'] = deducciones
|
||||||
|
data['otros_pagos'] = otros_pagos
|
||||||
|
data['horas_extras'] = horas_extras
|
||||||
|
data['incapacidades'] = incapacidades
|
||||||
|
|
||||||
|
return data, ''
|
||||||
|
|
||||||
def invoice(self, path):
|
def invoice(self, path):
|
||||||
options = {'AsTemplate': True, 'Hidden': True}
|
options = {'AsTemplate': True, 'Hidden': True}
|
||||||
|
@ -2846,3 +2946,20 @@ def import_invoice(rfc):
|
||||||
|
|
||||||
def calc_to_date(value):
|
def calc_to_date(value):
|
||||||
return datetime.date.fromordinal(int(value) + 693594)
|
return datetime.date.fromordinal(int(value) + 693594)
|
||||||
|
|
||||||
|
|
||||||
|
def get_days(start, end):
|
||||||
|
return (end - start).days + 1
|
||||||
|
|
||||||
|
|
||||||
|
def log_file(name, msg='', kill=False):
|
||||||
|
path = _join(PATH_MEDIA, 'tmp', '{}.log'.format(name))
|
||||||
|
|
||||||
|
if kill:
|
||||||
|
_kill(path)
|
||||||
|
return
|
||||||
|
|
||||||
|
with open(path, 'a') as fh:
|
||||||
|
line = '{} : {}'.format(str(now()), msg)
|
||||||
|
fh.write(line)
|
||||||
|
return
|
||||||
|
|
|
@ -5421,6 +5421,8 @@ class Empleados(BaseModel):
|
||||||
en = 0
|
en = 0
|
||||||
ea = 0
|
ea = 0
|
||||||
for row in rows:
|
for row in rows:
|
||||||
|
# ~ if row['rfc'] == 'BASM740115RW0':
|
||||||
|
# ~ continue
|
||||||
data = self._validate_import(self, row)
|
data = self._validate_import(self, row)
|
||||||
w = (Empleados.rfc==row['rfc'])
|
w = (Empleados.rfc==row['rfc'])
|
||||||
with database_proxy.transaction():
|
with database_proxy.transaction():
|
||||||
|
@ -5471,7 +5473,7 @@ class Empleados(BaseModel):
|
||||||
class CfdiNomina(BaseModel):
|
class CfdiNomina(BaseModel):
|
||||||
empleado = ForeignKeyField(Empleados)
|
empleado = ForeignKeyField(Empleados)
|
||||||
version = TextField(default=CURRENT_CFDI)
|
version = TextField(default=CURRENT_CFDI)
|
||||||
serie = TextField(default='')
|
serie = TextField(default='N')
|
||||||
folio = IntegerField(default=0)
|
folio = IntegerField(default=0)
|
||||||
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
fecha = DateTimeField(default=util.now, formats=['%Y-%m-%d %H:%M:%S'])
|
||||||
fecha_timbrado = DateTimeField(null=True)
|
fecha_timbrado = DateTimeField(null=True)
|
||||||
|
@ -5488,7 +5490,7 @@ class CfdiNomina(BaseModel):
|
||||||
auto_round=True)
|
auto_round=True)
|
||||||
total_mn = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
total_mn = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||||
auto_round=True)
|
auto_round=True)
|
||||||
tipo_comprobante = TextField(default='I')
|
tipo_comprobante = TextField(default='N')
|
||||||
metodo_pago = TextField(default='PUE')
|
metodo_pago = TextField(default='PUE')
|
||||||
lugar_expedicion = TextField(default='')
|
lugar_expedicion = TextField(default='')
|
||||||
confirmacion = TextField(default='')
|
confirmacion = TextField(default='')
|
||||||
|
@ -5511,7 +5513,7 @@ class CfdiNomina(BaseModel):
|
||||||
acuse = TextField(default='')
|
acuse = TextField(default='')
|
||||||
tipo_relacion = TextField(default='')
|
tipo_relacion = TextField(default='')
|
||||||
error = TextField(default='')
|
error = TextField(default='')
|
||||||
version = TextField(default=CURRENT_CFDI_NOMINA)
|
version_nomina = TextField(default=CURRENT_CFDI_NOMINA)
|
||||||
registro_patronal = TextField(default='')
|
registro_patronal = TextField(default='')
|
||||||
rfc_patron_origen = TextField(default='')
|
rfc_patron_origen = TextField(default='')
|
||||||
tipo_nomina = ForeignKeyField(SATTipoNomina)
|
tipo_nomina = ForeignKeyField(SATTipoNomina)
|
||||||
|
@ -5527,27 +5529,304 @@ class CfdiNomina(BaseModel):
|
||||||
class Meta:
|
class Meta:
|
||||||
order_by = ('fecha',)
|
order_by = ('fecha',)
|
||||||
|
|
||||||
def _validate_import(self, row):
|
def _get_serie(self):
|
||||||
|
serie = Configuracion.get_('chk_config_serie_nomina')
|
||||||
|
if not serie:
|
||||||
|
serie = DEFAULT_SAT_NOMINA['SERIE']
|
||||||
|
return serie
|
||||||
|
|
||||||
|
def _get_folio(self, serie):
|
||||||
|
folio = int(Configuracion.get_('chk_config_folio_nomina') or '0')
|
||||||
|
inicio = (CfdiNomina
|
||||||
|
.select(fn.Max(CfdiNomina.folio).alias('mf'))
|
||||||
|
.where(CfdiNomina.serie==serie)
|
||||||
|
.order_by(SQL('mf'))
|
||||||
|
.scalar())
|
||||||
|
|
||||||
|
if inicio is None:
|
||||||
|
new = 1
|
||||||
|
else:
|
||||||
|
new += 1
|
||||||
|
|
||||||
|
if folio > new:
|
||||||
|
new = folio
|
||||||
|
|
||||||
|
return new
|
||||||
|
|
||||||
|
def _validate_nomina(self, row):
|
||||||
sn = {'si': True, 'no': False}
|
sn = {'si': True, 'no': False}
|
||||||
data = row.copy()
|
data = row.copy()
|
||||||
return data
|
rfc = data.pop('rfc')
|
||||||
|
try:
|
||||||
|
data['empleado'] = Empleados.get(Empleados.rfc==rfc)
|
||||||
|
except Empleados.DoesNotExist:
|
||||||
|
msg = 'No existe el Empleado con RFC: {}'.format(rfc)
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
tipo_nomina = SATTipoNomina.get_by_key(row['tipo_nomina'])
|
||||||
|
if tipo_nomina is None:
|
||||||
|
msg = 'RFC: {}, Tipo de Nómina no existe: {}'.format(row['tipo_nomina'])
|
||||||
|
return {}, msg
|
||||||
|
|
||||||
|
data['serie'] = self._get_serie(self)
|
||||||
|
data['folio'] = self._get_folio(self, data['serie'])
|
||||||
|
data['forma_pago'] = DEFAULT_SAT_NOMINA['FORMA_PAGO']
|
||||||
|
data['uso_cfdi'] = DEFAULT_SAT_NOMINA['USO_CFDI']
|
||||||
|
data['tipo_nomina'] = tipo_nomina
|
||||||
|
data['fecha_pago'] = util.calc_to_date(row['fecha_pago'])
|
||||||
|
data['fecha_inicial_pago'] = util.calc_to_date(row['fecha_inicial_pago'])
|
||||||
|
data['fecha_final_pago'] = util.calc_to_date(row['fecha_final_pago'])
|
||||||
|
data['dias_pagados'] = util.get_days(data['fecha_inicial_pago'], data['fecha_final_pago'])
|
||||||
|
|
||||||
|
return data, ''
|
||||||
|
|
||||||
|
def _validate_percepciones(self, headers, row):
|
||||||
|
total_gravado = 0.0
|
||||||
|
total_exento = 0.0
|
||||||
|
total_jubilacion = 0.0
|
||||||
|
total_separacion = 0.0
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for i, key in enumerate(headers[::2]):
|
||||||
|
gravado = round(row[i * 2], DECIMALES)
|
||||||
|
exento = round(row[i * 2 + 1], DECIMALES)
|
||||||
|
if not gravado and not exento:
|
||||||
|
continue
|
||||||
|
tp = SATTipoPercepcion.get_by_key(key)
|
||||||
|
if tp is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
total_gravado += gravado
|
||||||
|
total_exento += exento
|
||||||
|
if key in ('039', '044'):
|
||||||
|
total_jubilacion += gravado + exento
|
||||||
|
elif key in ('022', '023', '025'):
|
||||||
|
total_separacion += gravado + exento
|
||||||
|
new = {
|
||||||
|
'tipo_percepcion': tp,
|
||||||
|
'importe_gravado': gravado,
|
||||||
|
'importe_exento': exento,
|
||||||
|
}
|
||||||
|
data.append(new)
|
||||||
|
|
||||||
|
total_sueldos = round(total_gravado + total_exento, DECIMALES)
|
||||||
|
totals = {
|
||||||
|
'total_gravado': total_gravado,
|
||||||
|
'total_exento': total_exento,
|
||||||
|
'total_jubilacion': total_jubilacion,
|
||||||
|
'total_separacion': total_separacion,
|
||||||
|
'total_sueldos': total_sueldos,
|
||||||
|
'total_percepciones': round(
|
||||||
|
total_sueldos + total_jubilacion + total_separacion, DECIMALES)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, totals, ''
|
||||||
|
|
||||||
|
def _validate_deducciones(self, headers, row):
|
||||||
|
total_retenciones = 0.0
|
||||||
|
total_otras_deducciones = 0.0
|
||||||
|
|
||||||
|
data = []
|
||||||
|
for i, value in enumerate(row):
|
||||||
|
key = headers[0][i]
|
||||||
|
importe = round(value, DECIMALES)
|
||||||
|
if not importe:
|
||||||
|
continue
|
||||||
|
|
||||||
|
td = SATTipoDeduccion.get_by_key(key)
|
||||||
|
if td is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if key == '002':
|
||||||
|
total_retenciones += importe
|
||||||
|
else:
|
||||||
|
total_otras_deducciones += importe
|
||||||
|
|
||||||
|
new = {
|
||||||
|
'tipo_deduccion': td,
|
||||||
|
'importe': importe,
|
||||||
|
}
|
||||||
|
data.append(new)
|
||||||
|
|
||||||
|
totals = {
|
||||||
|
'total_retenciones': total_retenciones,
|
||||||
|
'total_otras_deducciones': total_otras_deducciones,
|
||||||
|
'total_deducciones': round(
|
||||||
|
total_retenciones + total_otras_deducciones, DECIMALES)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, totals, ''
|
||||||
|
|
||||||
|
def _validate_otros_pagos(self, headers, row):
|
||||||
|
total_otros_pagos = 0.0
|
||||||
|
|
||||||
|
data = []
|
||||||
|
subsidio_causado = round(row[0], DECIMALES)
|
||||||
|
for i, value in enumerate(row):
|
||||||
|
if not i:
|
||||||
|
continue
|
||||||
|
|
||||||
|
key = headers[0][i]
|
||||||
|
importe = round(value, DECIMALES)
|
||||||
|
if not importe:
|
||||||
|
continue
|
||||||
|
|
||||||
|
td = SATTipoOtroPago.get_by_key(key)
|
||||||
|
if td is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
total_otros_pagos += importe
|
||||||
|
|
||||||
|
new = {
|
||||||
|
'tipo_otro_pago': td,
|
||||||
|
'importe': importe,
|
||||||
|
}
|
||||||
|
if key == '002':
|
||||||
|
new['subsidio_causado'] = subsidio_causado
|
||||||
|
data.append(new)
|
||||||
|
|
||||||
|
totals = {'total_otros_pagos': total_otros_pagos}
|
||||||
|
|
||||||
|
return data, totals, ''
|
||||||
|
|
||||||
|
def _validate_horas_extras(self, row):
|
||||||
|
data = []
|
||||||
|
for i, key in enumerate(row[::4]):
|
||||||
|
days = int(row[i * 4])
|
||||||
|
key = row[i * 4 + 1]
|
||||||
|
the = SATTipoHoras.get_by_key(key)
|
||||||
|
if the is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
hours = int(row[i * 4 + 2])
|
||||||
|
importe = round(row[i * 4 + 3], DECIMALES)
|
||||||
|
if not hours or not importe:
|
||||||
|
continue
|
||||||
|
|
||||||
|
new = {
|
||||||
|
'dias': days,
|
||||||
|
'tipos_horas': the,
|
||||||
|
'horas_extra': hours,
|
||||||
|
'importe_pagado': importe,
|
||||||
|
}
|
||||||
|
data.append(new)
|
||||||
|
|
||||||
|
return data, ''
|
||||||
|
|
||||||
|
def _validate_incapacidades(self, row):
|
||||||
|
data = []
|
||||||
|
for i, key in enumerate(row[::3]):
|
||||||
|
key = row[i * 3]
|
||||||
|
ti = SATTipoIncapacidad.get_by_key(key)
|
||||||
|
if ti is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
days = int(row[i * 4 + 1])
|
||||||
|
importe = round(row[i * 4 + 2], DECIMALES)
|
||||||
|
if not days or not importe:
|
||||||
|
continue
|
||||||
|
|
||||||
|
new = {
|
||||||
|
'dias': ti,
|
||||||
|
'tipo': days,
|
||||||
|
'importe': importe,
|
||||||
|
}
|
||||||
|
data.append(new)
|
||||||
|
|
||||||
|
return data, ''
|
||||||
|
|
||||||
def _import(self):
|
def _import(self):
|
||||||
|
util.log_file('nomina', kill=True)
|
||||||
emisor = Emisor.select()[0]
|
emisor = Emisor.select()[0]
|
||||||
rows, msg = util.import_nomina(emisor.rfc)
|
data, msg = util.import_nomina(emisor.rfc)
|
||||||
if not rows:
|
if not data:
|
||||||
return {'ok': False, 'msg': msg}
|
return {'ok': False, 'msg': msg}
|
||||||
|
|
||||||
for row in rows:
|
hp = data['percepciones'][0]
|
||||||
data = self._validate_import(self, row)
|
percepciones = data['percepciones'][2:]
|
||||||
# ~ w = (Nomina.empleado.rfc==row['rfc'])
|
hd = data['deducciones'][:1]
|
||||||
|
deducciones = data['deducciones'][2:]
|
||||||
|
ho = data['otros_pagos'][:1]
|
||||||
|
otros_pagos = data['otros_pagos'][2:]
|
||||||
|
horas_extras = data['horas_extras'][2:]
|
||||||
|
incapacidades = data['incapacidades'][2:]
|
||||||
|
|
||||||
|
for i, row in enumerate(data['nomina']):
|
||||||
|
row['lugar_expedicion'] = emisor.cp_expedicion or emisor.codigo_postal
|
||||||
|
row['regimen_fiscal'] = emisor.regimenes[0].key
|
||||||
|
row['registro_patronal'] = emisor.registro_patronal
|
||||||
|
new_nomina, msg = self._validate_nomina(self, row)
|
||||||
|
if msg:
|
||||||
|
util.log_file('nomina', msg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
new_percepciones, total_percepciones, msg = \
|
||||||
|
self._validate_percepciones(self, hp, percepciones[i])
|
||||||
|
if msg:
|
||||||
|
util.log_file('nomina', msg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
new_deducciones, total_deducciones, msg = \
|
||||||
|
self._validate_deducciones(self, hd, deducciones[i])
|
||||||
|
if msg:
|
||||||
|
util.log_file('nomina', msg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
new_otros_pagos, total_otros_pagos, msg = \
|
||||||
|
self._validate_otros_pagos(self, ho, otros_pagos[i])
|
||||||
|
if msg:
|
||||||
|
util.log_file('nomina', msg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
new_horas_extras, msg = self._validate_horas_extras(self, horas_extras[i])
|
||||||
|
if msg:
|
||||||
|
util.log_file('nomina', msg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
new_incapacidades, msg = self._validate_incapacidades(self, incapacidades[i])
|
||||||
|
if msg:
|
||||||
|
util.log_file('nomina', msg)
|
||||||
|
continue
|
||||||
|
|
||||||
|
totals = total_percepciones.copy()
|
||||||
|
totals.update(total_deducciones)
|
||||||
|
totals.update(total_otros_pagos)
|
||||||
|
totals['subtotal'] = round(totals['total_percepciones'] +
|
||||||
|
totals['total_otros_pagos'], DECIMALES)
|
||||||
|
totals['descuento'] = totals['total_deducciones']
|
||||||
|
totals['total'] = round(totals['subtotal'] -
|
||||||
|
totals['descuento'], DECIMALES)
|
||||||
|
|
||||||
with database_proxy.transaction():
|
with database_proxy.transaction():
|
||||||
pass
|
obj = CfdiNomina.create(**new_nomina)
|
||||||
# ~ if Empleados.select().where(w).exists():
|
for row in new_percepciones:
|
||||||
# ~ q = Empleados.update(**data).where(w)
|
row['cfdi'] = obj
|
||||||
# ~ q.execute()
|
CfdiNominaPercepciones.create(**row)
|
||||||
# ~ else:
|
for row in new_deducciones:
|
||||||
# ~ obj = Empleados.create(**data)
|
row['cfdi'] = obj
|
||||||
|
CfdiNominaDeducciones.create(**row)
|
||||||
|
for row in new_otros_pagos:
|
||||||
|
row['cfdi'] = obj
|
||||||
|
CfdiNominaOtroPago.create(**row)
|
||||||
|
for row in new_horas_extras:
|
||||||
|
row['cfdi'] = obj
|
||||||
|
CfdiNominaHorasExtra.create(**row)
|
||||||
|
for row in new_incapacidades:
|
||||||
|
row['cfdi'] = obj
|
||||||
|
CfdiNominaIncapacidad.create(**row)
|
||||||
|
|
||||||
|
concepto = {
|
||||||
|
'cfdi': obj,
|
||||||
|
'valor_unitario': totals['subtotal'],
|
||||||
|
'importe': totals['subtotal'],
|
||||||
|
'descuento': totals['total_deducciones'],
|
||||||
|
}
|
||||||
|
CfdiNominaDetalle.create(**concepto)
|
||||||
|
|
||||||
|
totals['cfdi'] = obj
|
||||||
|
CfdiNominaTotales.create(**totals)
|
||||||
|
|
||||||
|
msg = 'Nómina importada correctamente'
|
||||||
return {'ok': True, 'msg': msg}
|
return {'ok': True, 'msg': msg}
|
||||||
|
|
||||||
def _get(self):
|
def _get(self):
|
||||||
|
@ -5653,6 +5932,7 @@ class CfdiNominaSeparacion(BaseModel):
|
||||||
class CfdiNominaPercepciones(BaseModel):
|
class CfdiNominaPercepciones(BaseModel):
|
||||||
cfdi = ForeignKeyField(CfdiNomina)
|
cfdi = ForeignKeyField(CfdiNomina)
|
||||||
tipo_percepcion = ForeignKeyField(SATTipoPercepcion)
|
tipo_percepcion = ForeignKeyField(SATTipoPercepcion)
|
||||||
|
concepto = TextField(default='')
|
||||||
importe_gravado = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
importe_gravado = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||||
auto_round=True)
|
auto_round=True)
|
||||||
importe_exento = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
importe_exento = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||||
|
@ -5666,6 +5946,7 @@ class CfdiNominaPercepciones(BaseModel):
|
||||||
class CfdiNominaDeducciones(BaseModel):
|
class CfdiNominaDeducciones(BaseModel):
|
||||||
cfdi = ForeignKeyField(CfdiNomina)
|
cfdi = ForeignKeyField(CfdiNomina)
|
||||||
tipo_deduccion = ForeignKeyField(SATTipoDeduccion)
|
tipo_deduccion = ForeignKeyField(SATTipoDeduccion)
|
||||||
|
concepto = TextField(default='')
|
||||||
importe = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
importe = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||||
auto_round=True)
|
auto_round=True)
|
||||||
|
|
||||||
|
@ -5673,6 +5954,7 @@ class CfdiNominaDeducciones(BaseModel):
|
||||||
class CfdiNominaOtroPago(BaseModel):
|
class CfdiNominaOtroPago(BaseModel):
|
||||||
cfdi = ForeignKeyField(CfdiNomina)
|
cfdi = ForeignKeyField(CfdiNomina)
|
||||||
tipo_otro_pago = ForeignKeyField(SATTipoOtroPago)
|
tipo_otro_pago = ForeignKeyField(SATTipoOtroPago)
|
||||||
|
concepto = TextField(default='')
|
||||||
importe = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
importe = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||||
auto_round=True)
|
auto_round=True)
|
||||||
subsidio_causado = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
subsidio_causado = DecimalField(default=0.0, max_digits=20, decimal_places=6,
|
||||||
|
|
|
@ -137,6 +137,9 @@ USAR_TOKEN = False
|
||||||
CANCEL_SIGNATURE = False
|
CANCEL_SIGNATURE = False
|
||||||
PUBLIC = 'Público en general'
|
PUBLIC = 'Público en general'
|
||||||
DEFAULT_SAT_NOMINA = {
|
DEFAULT_SAT_NOMINA = {
|
||||||
|
'SERIE': 'N',
|
||||||
|
'FORMA_PAGO': '99',
|
||||||
|
'USO_CFDI': 'P01',
|
||||||
'CLAVE': '84111505',
|
'CLAVE': '84111505',
|
||||||
'UNIDAD': 'ACT',
|
'UNIDAD': 'ACT',
|
||||||
'DESCRIPCION': 'Pago de nómina',
|
'DESCRIPCION': 'Pago de nómina',
|
||||||
|
|
Loading…
Reference in New Issue