Add template for CFDI 4.0
This commit is contained in:
parent
1a507d2eeb
commit
ae259e461b
|
@ -1840,7 +1840,7 @@ def _receptor(doc, version, values):
|
|||
return data
|
||||
|
||||
data['usocfdi'] = values['usocfdi']
|
||||
data.update(values['receptor'])
|
||||
# ~ data.update(values['receptor'])
|
||||
return data
|
||||
|
||||
|
||||
|
@ -2121,6 +2121,7 @@ def get_data_from_xml(invoice, values, pdf_from='1'):
|
|||
data = {'cancelada': invoice.cancelada, 'donativo': False}
|
||||
if hasattr(invoice, 'donativo'):
|
||||
data['donativo'] = invoice.donativo
|
||||
|
||||
doc = parse_xml(invoice.xml)
|
||||
data['comprobante'] = _comprobante(doc, values)
|
||||
version = data['comprobante']['version']
|
||||
|
|
|
@ -270,6 +270,53 @@ class CfdiToDict(object):
|
|||
'03': '[03] Arrendador',
|
||||
'04': '[04] Notificado',
|
||||
}
|
||||
REGIMEN_FISCAL = {
|
||||
'601': '[601] General de Ley Personas Morales',
|
||||
'603': '[603] Personas Morales con Fines no Lucrativos',
|
||||
'605': '[605] Sueldos y Salarios e Ingresos Asimilados a Salarios',
|
||||
'606': '[606] Arrendamiento',
|
||||
'607': '[607] Régimen de Enajenación o Adquisición de Bienes',
|
||||
'608': '[608] Demás ingresos',
|
||||
'610': '[610] Residentes en el Extranjero sin Establecimiento Permanente en México',
|
||||
'611': '[611] Ingresos por Dividendos (socios y accionistas)',
|
||||
'612': '[612] Personas Físicas con Actividades Empresariales y Profesionales',
|
||||
'614': '[614] Ingresos por intereses',
|
||||
'615': '[615] Régimen de los ingresos por obtención de premios',
|
||||
'616': '[616] Sin obligaciones fiscales',
|
||||
'620': '[620] Sociedades Cooperativas de Producción que optan por diferir sus ingresos',
|
||||
'621': '[621] Incorporación Fiscal',
|
||||
'622': '[622] Actividades Agrícolas, Ganaderas, Silvícolas y Pesqueras',
|
||||
'623': '[623] Opcional para Grupos de Sociedades',
|
||||
'624': '[624] Coordinados',
|
||||
'625': '[625] Régimen de las Actividades Empresariales con ingresos a través de Plataformas Tecnológicas',
|
||||
'626': '[626] Régimen Simplificado de Confianza',
|
||||
}
|
||||
USO_CFDI = {
|
||||
'G01': '[G01] Adquisición de mercancías.',
|
||||
'G02': '[G02] Devoluciones, descuentos o bonificaciones.',
|
||||
'G03': '[G03] Gastos en general.',
|
||||
'I01': '[I01] Construcciones.',
|
||||
'I02': '[I02] Mobiliario y equipo de oficina por inversiones.',
|
||||
'I03': '[I03] Equipo de transporte.',
|
||||
'I04': '[I04] Equipo de computo y accesorios.',
|
||||
'I05': '[I05] Dados, troqueles, moldes, matrices y herramental.',
|
||||
'I06': '[I06] Comunicaciones telefónicas.',
|
||||
'I07': '[I07] Comunicaciones satelitales.',
|
||||
'I08': '[I08] Otra maquinaria y equipo.',
|
||||
'D01': '[D01] Honorarios médicos, dentales y gastos hospitalarios.',
|
||||
'D02': '[D02] Gastos médicos por incapacidad o discapacidad.',
|
||||
'D03': '[D03] Gastos funerales.',
|
||||
'D04': '[D04] Donativos.',
|
||||
'D05': '[D05] Intereses reales efectivamente pagados por créditos hipotecarios (casa habitación).',
|
||||
'D06': '[D06] Aportaciones voluntarias al SAR.',
|
||||
'D07': '[D07] Primas por seguros de gastos médicos.',
|
||||
'D08': '[D08] Gastos de transportación escolar obligatoria.',
|
||||
'D09': '[D09] Depósitos en cuentas para el ahorro, primas que tengan como base planes de pensiones.',
|
||||
'D10': '[D10] Pagos por servicios educativos (colegiaturas).',
|
||||
'S01': '[S01] Sin efectos fiscales.',
|
||||
'CP01': '[CP01] Pagos',
|
||||
'CN01': '[CN01] Nómina',
|
||||
}
|
||||
PAISES = {
|
||||
'MEX': 'México',
|
||||
}
|
||||
|
@ -324,9 +371,21 @@ class CfdiToDict(object):
|
|||
version = self._root.attrib['Version']
|
||||
ns = f'cfdi{version}'
|
||||
self.NS['cfdi'] = self.NS_VERSION[ns]
|
||||
|
||||
self._receptor()
|
||||
self._complementos()
|
||||
return
|
||||
|
||||
def _receptor(self):
|
||||
path = '//cfdi:Receptor'
|
||||
receptor = self._root.xpath(path, namespaces=self.NS)[0]
|
||||
attr = CaseInsensitiveDict(receptor.attrib)
|
||||
attr['domiciliofiscal'] = attr['DomicilioFiscalReceptor']
|
||||
attr['regimenfiscal'] = self.REGIMEN_FISCAL[attr['RegimenFiscalReceptor']]
|
||||
attr['usocfdi'] = self.USO_CFDI[attr['UsoCFDI']]
|
||||
self._values['receptor'] = attr
|
||||
return
|
||||
|
||||
def _set_carta_porte_domicilio(self, data):
|
||||
municipio = data['Municipio']
|
||||
estado = self.ESTADOS[data['Estado']]
|
||||
|
|
|
@ -4722,10 +4722,10 @@ class Facturas(BaseModel):
|
|||
obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion)
|
||||
values['tiporelacion'] = str(obj)
|
||||
|
||||
receptor = Socios.select().where(Socios.id==invoice.cliente.id).dicts()[0]
|
||||
values['receptor'] = {}
|
||||
for k, v in receptor.items():
|
||||
values['receptor'][k] = v
|
||||
# ~ receptor = Socios.select().where(Socios.id==invoice.cliente.id).dicts()[0]
|
||||
# ~ values['receptor'] = {}
|
||||
# ~ for k, v in receptor.items():
|
||||
# ~ values['receptor'][k] = v
|
||||
|
||||
# ~ use_packing = Configuracion.get_bool('chk_use_packing')
|
||||
# ~ if use_packing:
|
||||
|
@ -4739,6 +4739,21 @@ class Facturas(BaseModel):
|
|||
|
||||
return values
|
||||
|
||||
def _get_not_in_xml2(self, invoice, data):
|
||||
fields = (
|
||||
Socios.calle,
|
||||
Socios.no_exterior,
|
||||
Socios.no_interior,
|
||||
Socios.colonia,
|
||||
Socios.municipio,
|
||||
Socios.estado,
|
||||
Socios.pais,
|
||||
)
|
||||
where = (Socios.id==invoice.cliente.id)
|
||||
partner = Socios.select(*fields).where(where).dicts()[0]
|
||||
data['receptor'].update(partner)
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def get_pdf(cls, id, rfc, sync=True):
|
||||
try:
|
||||
|
@ -4756,7 +4771,9 @@ class Facturas(BaseModel):
|
|||
|
||||
#Tmp to v2
|
||||
data = util.get_data_from_xml(obj, values, pdf_from)
|
||||
|
||||
data.update(utils.CfdiToDict(obj.xml).values)
|
||||
cls._get_not_in_xml2(cls, obj, data)
|
||||
|
||||
doc = util.to_pdf(data, emisor.rfc, pdf_from=pdf_from)
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue