Source code for satcfdi.transform.helpers

import logging
from decimal import Decimal

from lxml import etree
from lxml.etree import QName

from ..exceptions import CFDIError
from ..models import Code
from ..utils import iterate

logger = logging.getLogger(__name__)
TEXT_KEY = "_text"
_ = iterate


[docs] class SchemaCollector: def __init__(self): self.nsmap = {} self.schemas = [] self.base = set()
[docs] def add_schema(self, schema): if schema not in self.schemas: self.schemas.append(schema)
[docs] def add_map(self, tns_alias, tns): if tns_alias in self.nsmap: if not self.nsmap[tns_alias] == tns: raise CFDIError("TNS Alias already registered with a different alias") else: self.nsmap[tns_alias] = tns
[docs] def add_base(self, base): self.base.add(base)
[docs] class Xint(int): """ An int class that knows the original value that was used to create it """ def __new__(cls, value: str): self = int.__new__(cls, value) self.value = value return self def __str__(self): return self.value
[docs] def fmt_decimal(d): if isinstance(d, Decimal): return d.__format__("f") return str(d)
[docs] def simple_element(_tag, nsmap=None, text=None): el = etree.Element(_tag, nsmap=nsmap) el.text = text return el
[docs] def default_objectify(cls, node): self = cls() self.tag = node.tag def add_attributes(n, target): for k, v in n.attrib.items(): target[k] = v text = n.text if text: text = n.text.strip() if text: target[TEXT_KEY] = text def add_elements(n, target): for el in n: new = cls() name = QName(el.tag).localname add_attributes(el, target=new) add_elements(el, target=new) current = target.get(name) if current is None: target[name] = new elif isinstance(current, cls): target[name] = [current, new] else: current.append(new) add_attributes(node, target=self) add_elements(node, target=self) return self
[docs] def impuesto_index(attrib, attribute_name): impuesto = attrib[attribute_name] ext = attribute_name[8:] if tipo_factor := attrib.get('TipoFactor' + ext): impuesto += "|" + tipo_factor if tasa_cuota := attrib.get('TasaOCuota' + ext): impuesto += "|" + Decimal(tasa_cuota).__format__(".6f") return impuesto
[docs] def strcode(data): if isinstance(data, Code): return data.code return data