oc-facho/facho/fe/nomina/__init__.py
bit4bit 4b11f6b06d nueva estructura de directorios para nomina
FossilOrigin-Name: f3a95167abace679098bac9daffda6f17a8c819b92a5d096558f20dfce3acbbe
2021-11-05 02:34:45 +00:00

87 lines
2.4 KiB
Python

#
# Para esta implementacion se usa BDD
# ver **test_nomina.py**.
#
# La idea en general es validar comportamiento desde el XML,
# creando las estructuras minimas necesaras.
from dataclasses import dataclass
from .. import fe
from .. import form
from .devengado import *
from .deduccion import *
from .amount import Amount
class DIANNominaIndividualError(Exception):
pass
class DIANNominaIndividual:
def __init__(self):
self.fexml = fe.FeXML('NominaIndividual', 'http://www.dian.gov.co/contratos/facturaelectronica/v1')
# layout, la dian requiere que los elementos
# esten ordenados segun el anexo tecnico
self.fexml.placeholder_for('./Devengados/Basico')
self.fexml.placeholder_for('./Devengados/Transporte', optional=True)
self.devengados = self.fexml.fragment('./Devengados')
self.deducciones = self.fexml.fragment('./Deducciones')
def adicionar_devengado(self, devengado):
if not isinstance(devengado, Devengado):
raise ValueError('se espera tipo Devengado')
devengado.apply(self.devengados)
def adicionar_deduccion(self, deduccion):
if not isinstance(deduccion, Deduccion):
raise ValueError('se espera tipo Devengado')
deduccion.apply(self.deducciones)
def validate(self):
"""
Valida requisitos segun anexo tecnico
"""
errors = []
def check_element(xpath, msg):
if not self.fexml.exist_element(xpath):
errors.append(DIANNominaIndividualError(msg))
def check_attribute(xpath, key, msg):
err = DIANNominaIndividualError(msg)
elem = self.fexml.get_element(xpath)
if elem is None:
return errors.append(err)
if elem.get(key, None) is None:
return errors.append(err)
check_attribute('/fe:NominaIndividual/Periodo', 'FechaIngreso', 'se requiere Periodo')
check_element(
'/fe:NominaIndividual/Devengados/Basico',
'se requiere DevengadoBasico'
)
check_element(
'/fe:NominaIndividual/Deducciones/Salud',
'se requiere DeduccionSalud'
)
check_element(
'/fe:NominaIndividual/Deducciones/FondoPension',
'se requiere DeduccionFondoPension'
)
return errors
def toFachoXML(self):
return self.fexml