Addenda Boveda y cliente 02
This commit is contained in:
parent
70986b923b
commit
a55a5eb1c4
|
@ -10,6 +10,9 @@ from settings import DEBUG, log, PATH_XSLT, DELETE_FILES, PAC_AUTH
|
||||||
from helper.comercio import PACComercioDigital as PAC
|
from helper.comercio import PACComercioDigital as PAC
|
||||||
|
|
||||||
|
|
||||||
|
from . import util2
|
||||||
|
|
||||||
|
|
||||||
def _call(args):
|
def _call(args):
|
||||||
return subprocess.check_output(args, shell=True).decode()
|
return subprocess.check_output(args, shell=True).decode()
|
||||||
|
|
||||||
|
@ -80,6 +83,7 @@ class DictToCfdi():
|
||||||
self._cfdi = None
|
self._cfdi = None
|
||||||
self._root = None
|
self._root = None
|
||||||
self._attr_complementos = {}
|
self._attr_complementos = {}
|
||||||
|
self._node_addenda = None
|
||||||
self._make_cfdi()
|
self._make_cfdi()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -95,6 +99,7 @@ class DictToCfdi():
|
||||||
self._conceptos()
|
self._conceptos()
|
||||||
self._impuestos()
|
self._impuestos()
|
||||||
self._complementos()
|
self._complementos()
|
||||||
|
self._addenda()
|
||||||
|
|
||||||
xml = ET.tostring(self._root,
|
xml = ET.tostring(self._root,
|
||||||
pretty_print=True, xml_declaration=True, encoding='utf-8')
|
pretty_print=True, xml_declaration=True, encoding='utf-8')
|
||||||
|
@ -233,6 +238,74 @@ class DictToCfdi():
|
||||||
ET.SubElement(node_leyendas, node_name, leyenda)
|
ET.SubElement(node_leyendas, node_name, leyenda)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _addenda(self):
|
||||||
|
type_addenda = self._data['addenda'].get('type', '')
|
||||||
|
data = self._data['addenda'].get('boveda', False)
|
||||||
|
self._boveda(data)
|
||||||
|
if type_addenda:
|
||||||
|
data = self._data['addenda'].get('cliente', False)
|
||||||
|
partes = self._data['addenda']['partes']
|
||||||
|
getattr(self, f'_addenda_{type_addenda}')(data, partes)
|
||||||
|
return
|
||||||
|
|
||||||
|
def _boveda(self, data):
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
|
||||||
|
XMLNS = 'http://kontender.mx/namespace/boveda'
|
||||||
|
NSMAP = {
|
||||||
|
'bovadd': 'http://kontender.mx/namespace/boveda',
|
||||||
|
'kon': 'http://kontender.mx/namespace',
|
||||||
|
}
|
||||||
|
|
||||||
|
node_name = f'{{{self._XMLNS}}}Addenda'
|
||||||
|
self._node_addenda = ET.SubElement(self._root, node_name)
|
||||||
|
|
||||||
|
schema = 'http://kontender.mx/namespace/boveda http://kontender.mx/namespace/boveda/BOVEDAFISCAL.xsd http://kontender.mx/namespace http://kontender.mx/namespace/AddendaK.xsd'
|
||||||
|
attr_qname = ET.QName(
|
||||||
|
'http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation')
|
||||||
|
schema = {attr_qname: schema}
|
||||||
|
|
||||||
|
node_name = f'{{{XMLNS}}}BOVEDAFISCAL'
|
||||||
|
node = ET.SubElement(self._node_addenda, node_name, schema, nsmap=NSMAP)
|
||||||
|
|
||||||
|
for k, v in data.items():
|
||||||
|
node_name = f'{{{XMLNS}}}{k}'
|
||||||
|
n = ET.SubElement(node, node_name)
|
||||||
|
n.text = v
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def _addenda_02(self, data, partes):
|
||||||
|
if not data:
|
||||||
|
return
|
||||||
|
|
||||||
|
XMLNS = 'http://www.sas-automative/en/locations/local-offices-and-plants/mexico/plant-puebla.html'
|
||||||
|
NSMAP = {'PMT': XMLNS}
|
||||||
|
version = data.pop('version')
|
||||||
|
attr = {'version': version}
|
||||||
|
node_name = f'{{{XMLNS}}}Factura'
|
||||||
|
node = ET.SubElement(self._node_addenda, node_name, **attr, nsmap=NSMAP)
|
||||||
|
|
||||||
|
for key, attr in data.items():
|
||||||
|
node_name = f'{{{XMLNS}}}{key}'
|
||||||
|
ET.SubElement(node, node_name, **attr)
|
||||||
|
|
||||||
|
if not partes:
|
||||||
|
return
|
||||||
|
|
||||||
|
node_name = f'{{{XMLNS}}}Partes'
|
||||||
|
node = ET.SubElement(node, node_name)
|
||||||
|
|
||||||
|
for parte in partes:
|
||||||
|
referencias = parte.pop('referencias')
|
||||||
|
node_name = f'{{{XMLNS}}}Parte'
|
||||||
|
sub_node = ET.SubElement(node, node_name, **parte)
|
||||||
|
node_name = f'{{{XMLNS}}}Referencias'
|
||||||
|
ET.SubElement(sub_node, node_name, **referencias)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
class DataToDict():
|
class DataToDict():
|
||||||
TRASLADO = 'T'
|
TRASLADO = 'T'
|
||||||
|
@ -245,11 +318,16 @@ class DataToDict():
|
||||||
'05': '_conceptos',
|
'05': '_conceptos',
|
||||||
'06': '_impuestos',
|
'06': '_impuestos',
|
||||||
'10': '_leyendas',
|
'10': '_leyendas',
|
||||||
|
'50': '_boveda',
|
||||||
|
'51': '_addenda',
|
||||||
|
'52': '_addenda_partes',
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__ (self, data):
|
def __init__ (self, data):
|
||||||
self._data = data
|
self._data = data
|
||||||
self._cfdi = {'conceptos': [], 'complementos': {}}
|
self._cfdi = {'conceptos': [], 'complementos': {}, 'addenda': {}}
|
||||||
|
self._type_header = ''
|
||||||
|
self._partes = []
|
||||||
self._process_data()
|
self._process_data()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -268,6 +346,8 @@ class DataToDict():
|
||||||
continue
|
continue
|
||||||
if hasattr(self, header):
|
if hasattr(self, header):
|
||||||
getattr(self, header)(parts[2:])
|
getattr(self, header)(parts[2:])
|
||||||
|
|
||||||
|
self._cfdi['addenda']['partes'] = self._partes
|
||||||
return
|
return
|
||||||
|
|
||||||
def _comprobante(self, data):
|
def _comprobante(self, data):
|
||||||
|
@ -434,6 +514,68 @@ class DataToDict():
|
||||||
self._cfdi['complementos']['leyendas'] = leyendas
|
self._cfdi['complementos']['leyendas'] = leyendas
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _boveda(self, data):
|
||||||
|
type_addenda = data[0]
|
||||||
|
fields = (
|
||||||
|
'Razon_Social_destino',
|
||||||
|
'Calle_Destino',
|
||||||
|
'Colonia_Destino',
|
||||||
|
'Ciudad_Destino',
|
||||||
|
'Estado_Destino',
|
||||||
|
'Pais_Destino',
|
||||||
|
'CP_Destino_consigan',
|
||||||
|
'RFC_Destino_consigna',
|
||||||
|
'Telefono_Receptor',
|
||||||
|
'Peso_Bruto',
|
||||||
|
'Peso_Neto',
|
||||||
|
'Incoterm',
|
||||||
|
'leyenda_pie',
|
||||||
|
'R.vto',
|
||||||
|
'TIPO_CAMBIO_FACTURA',
|
||||||
|
'R.cte',
|
||||||
|
'RI_Solicitante',
|
||||||
|
'R.fefa',
|
||||||
|
'Razon_Social_facturado',
|
||||||
|
'Calle_facturado',
|
||||||
|
'Colonia_facturado',
|
||||||
|
'RFC_destino',
|
||||||
|
'Telefono_facturado',
|
||||||
|
'NUMCTAPAGO',
|
||||||
|
)
|
||||||
|
boveda = {}
|
||||||
|
for i, f in enumerate(fields):
|
||||||
|
boveda[f] = data[i+1]
|
||||||
|
|
||||||
|
self._cfdi['addenda']['type'] = type_addenda
|
||||||
|
self._cfdi['addenda']['boveda'] = boveda
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
def _addenda(self, header):
|
||||||
|
self._type_header = header[1]
|
||||||
|
if self._type_header == '4':
|
||||||
|
data = {'version': header[3]}
|
||||||
|
data['Moneda'] = {'tipoMoneda': header[7]}
|
||||||
|
data['Proveedor'] = {'codigo': header[10], 'nombre': header[11]}
|
||||||
|
data['Referencias'] = {'referenciaProveedor': header[16]}
|
||||||
|
|
||||||
|
self._cfdi['addenda']['cliente'] = data
|
||||||
|
return
|
||||||
|
|
||||||
|
def _addenda_partes(self, parte):
|
||||||
|
if self._type_header == '4':
|
||||||
|
attr = {'posicion': parte[0],
|
||||||
|
'numeroMaterial': parte[1],
|
||||||
|
'descripcionMaterial': parte[2],
|
||||||
|
'referencias': {
|
||||||
|
'ordenCompra': parte[7],
|
||||||
|
'numeroPKN': parte[8],
|
||||||
|
'numeroASN': parte[9],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self._partes.append(attr)
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
def stamp_cfdi(cfdi, cert):
|
def stamp_cfdi(cfdi, cert):
|
||||||
xslt = open(PATH_XSLT, 'rb')
|
xslt = open(PATH_XSLT, 'rb')
|
||||||
|
@ -486,6 +628,8 @@ def make_cfdi(source, target, dir_cert, nombre):
|
||||||
cert = Cert(dir_cert, nombre)
|
cert = Cert(dir_cert, nombre)
|
||||||
paths = _get_files(source, 'txt')
|
paths = _get_files(source, 'txt')
|
||||||
for path in paths:
|
for path in paths:
|
||||||
|
# ~ _version33(path, target)
|
||||||
|
# ~ continue
|
||||||
data = _read_file(path)
|
data = _read_file(path)
|
||||||
data = DataToDict(data).cfdi
|
data = DataToDict(data).cfdi
|
||||||
cfdi = DictToCfdi(data).cfdi
|
cfdi = DictToCfdi(data).cfdi
|
||||||
|
@ -515,3 +659,16 @@ def stamp_pac(source, target):
|
||||||
f.write(result['xml'])
|
f.write(result['xml'])
|
||||||
log.info(f'\tTimbrada: {new_path}')
|
log.info(f'\tTimbrada: {new_path}')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# ~ To delete
|
||||||
|
|
||||||
|
def _version33(path, target):
|
||||||
|
from .cfdi_xml import CFDI
|
||||||
|
|
||||||
|
data = util2.load_data(path)
|
||||||
|
cfdi = CFDI()
|
||||||
|
xml = cfdi.get_xml(data)
|
||||||
|
_save_file(path, target, xml)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
Loading…
Reference in New Issue