forked from elmau/empresa-libre
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
|
return data
|
||||||
|
|
||||||
data['usocfdi'] = values['usocfdi']
|
data['usocfdi'] = values['usocfdi']
|
||||||
data.update(values['receptor'])
|
# ~ data.update(values['receptor'])
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@ -2121,6 +2121,7 @@ def get_data_from_xml(invoice, values, pdf_from='1'):
|
||||||
data = {'cancelada': invoice.cancelada, 'donativo': False}
|
data = {'cancelada': invoice.cancelada, 'donativo': False}
|
||||||
if hasattr(invoice, 'donativo'):
|
if hasattr(invoice, 'donativo'):
|
||||||
data['donativo'] = invoice.donativo
|
data['donativo'] = invoice.donativo
|
||||||
|
|
||||||
doc = parse_xml(invoice.xml)
|
doc = parse_xml(invoice.xml)
|
||||||
data['comprobante'] = _comprobante(doc, values)
|
data['comprobante'] = _comprobante(doc, values)
|
||||||
version = data['comprobante']['version']
|
version = data['comprobante']['version']
|
||||||
|
|
|
@ -270,6 +270,53 @@ class CfdiToDict(object):
|
||||||
'03': '[03] Arrendador',
|
'03': '[03] Arrendador',
|
||||||
'04': '[04] Notificado',
|
'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 = {
|
PAISES = {
|
||||||
'MEX': 'México',
|
'MEX': 'México',
|
||||||
}
|
}
|
||||||
|
@ -324,9 +371,21 @@ class CfdiToDict(object):
|
||||||
version = self._root.attrib['Version']
|
version = self._root.attrib['Version']
|
||||||
ns = f'cfdi{version}'
|
ns = f'cfdi{version}'
|
||||||
self.NS['cfdi'] = self.NS_VERSION[ns]
|
self.NS['cfdi'] = self.NS_VERSION[ns]
|
||||||
|
|
||||||
|
self._receptor()
|
||||||
self._complementos()
|
self._complementos()
|
||||||
return
|
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):
|
def _set_carta_porte_domicilio(self, data):
|
||||||
municipio = data['Municipio']
|
municipio = data['Municipio']
|
||||||
estado = self.ESTADOS[data['Estado']]
|
estado = self.ESTADOS[data['Estado']]
|
||||||
|
|
|
@ -4722,10 +4722,10 @@ class Facturas(BaseModel):
|
||||||
obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion)
|
obj = SATTipoRelacion.get(SATTipoRelacion.key==invoice.tipo_relacion)
|
||||||
values['tiporelacion'] = str(obj)
|
values['tiporelacion'] = str(obj)
|
||||||
|
|
||||||
receptor = Socios.select().where(Socios.id==invoice.cliente.id).dicts()[0]
|
# ~ receptor = Socios.select().where(Socios.id==invoice.cliente.id).dicts()[0]
|
||||||
values['receptor'] = {}
|
# ~ values['receptor'] = {}
|
||||||
for k, v in receptor.items():
|
# ~ for k, v in receptor.items():
|
||||||
values['receptor'][k] = v
|
# ~ values['receptor'][k] = v
|
||||||
|
|
||||||
# ~ use_packing = Configuracion.get_bool('chk_use_packing')
|
# ~ use_packing = Configuracion.get_bool('chk_use_packing')
|
||||||
# ~ if use_packing:
|
# ~ if use_packing:
|
||||||
|
@ -4739,6 +4739,21 @@ class Facturas(BaseModel):
|
||||||
|
|
||||||
return values
|
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
|
@classmethod
|
||||||
def get_pdf(cls, id, rfc, sync=True):
|
def get_pdf(cls, id, rfc, sync=True):
|
||||||
try:
|
try:
|
||||||
|
@ -4756,7 +4771,9 @@ class Facturas(BaseModel):
|
||||||
|
|
||||||
#Tmp to v2
|
#Tmp to v2
|
||||||
data = util.get_data_from_xml(obj, values, pdf_from)
|
data = util.get_data_from_xml(obj, values, pdf_from)
|
||||||
|
|
||||||
data.update(utils.CfdiToDict(obj.xml).values)
|
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)
|
doc = util.to_pdf(data, emisor.rfc, pdf_from=pdf_from)
|
||||||
|
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue