def _add_qrCode(xml, **kwargs): xml = etree.fromstring(xml) inf_nfe = kwargs['NFes'][0]['infNFe'] nfe = xml.find(".//{http://www.portalfiscal.inf.br/nfe}NFe") infnfesupl = etree.Element('infNFeSupl') qrcode = etree.Element('qrCode') chave_nfe = inf_nfe['Id'][3:] dh_emissao = inf_nfe['ide']['dhEmi'].encode('hex') versao = '100' ambiente = kwargs['ambiente'] valor_total = inf_nfe['total']['vNF'] dest_cpf = 'Inexistente' dest = nfe.find(".//{http://www.portalfiscal.inf.br/nfe}dest") if dest: dest_parent = dest.getparent() dest_parent.remove(dest) if inf_nfe.get('dest', False): if inf_nfe['dest'].get('CPF', False): dest_cpf = inf_nfe['dest']['CPF'] dest = etree.Element('dest') cpf = etree.Element('CPF') cpf.text = dest_cpf dest.append(cpf) dest_parent.append(dest) icms_total = inf_nfe['total']['vICMS'] dig_val = xml.find( ".//{http://www.w3.org/2000/09/xmldsig#}DigestValue")\ .text.encode('hex') cid_token = kwargs['NFes'][0]['infNFe']['codigo_seguranca']['cid_token'] csc = kwargs['NFes'][0]['infNFe']['codigo_seguranca']['csc'] c_hash_QR_code = "chNFe={0}&nVersao={1}&tpAmb={2}&cDest={3}&dhEmi={4}&vNF\ ={5}&vICMS={6}&digVal={7}&cIdToken={8}{9}" .\ format(chave_nfe, versao, ambiente, dest_cpf, dh_emissao, valor_total, icms_total, dig_val, cid_token, csc) c_hash_QR_code = hashlib.sha1(c_hash_QR_code).hexdigest() QR_code_url = "?chNFe={0}&nVersao={1}&tpAmb={2}&{3}dhEmi={4}&vNF={5}&vICMS\ ={6}&digVal={7}&cIdToken={8}&cHashQRCode={9}" .\ format(chave_nfe, versao, ambiente, 'cDest={}&'.format(dest_cpf) if dest_cpf != 'Inexistente' else '', dh_emissao, valor_total, icms_total, dig_val, cid_token, c_hash_QR_code) qr_code_server = localizar_qrcode(kwargs['estado'], ambiente) qrcode_text = qr_code_server + QR_code_url qrcode.text = etree.CDATA(qrcode_text) infnfesupl.append(qrcode) nfe.insert(1, infnfesupl) return etree.tostring(xml)
def _add_qrCode(xml, **kwargs): xml = etree.fromstring(xml) inf_nfe = kwargs['NFes'][0]['infNFe'] nfe = xml.find(".//{http://www.portalfiscal.inf.br/nfe}NFe") infnfesupl = etree.Element('infNFeSupl') qrcode = etree.Element('qrCode') chave_nfe = inf_nfe['Id'][3:] dh_emissao = binascii.hexlify(inf_nfe['ide']['dhEmi'].encode()).decode() versao = '100' ambiente = kwargs['ambiente'] valor_total = inf_nfe['total']['vNF'] dest_cpf = 'Inexistente' dest = nfe.find(".//{http://www.portalfiscal.inf.br/nfe}dest") if inf_nfe.get('dest', False): if inf_nfe['dest'].get('CPF', False): dest_cpf = inf_nfe['dest']['CPF'] dest = etree.Element('dest') cpf = etree.Element('CPF') cpf.text = dest_cpf dest.append(cpf) icms_total = inf_nfe['total']['vICMS'] dig_val = binascii.hexlify(xml.find( ".//{http://www.w3.org/2000/09/xmldsig#}DigestValue").text.encode()).decode() cid_token = kwargs['NFes'][0]['infNFe']['codigo_seguranca']['cid_token'] csc = kwargs['NFes'][0]['infNFe']['codigo_seguranca']['csc'] c_hash_QR_code = "chNFe={0}&nVersao={1}&tpAmb={2}&cDest={3}&dhEmi={4}&vNF\ ={5}&vICMS={6}&digVal={7}&cIdToken={8}{9}".\ format(chave_nfe, versao, ambiente, dest_cpf, dh_emissao, valor_total, icms_total, dig_val, cid_token, csc) c_hash_QR_code = hashlib.sha1(c_hash_QR_code.encode()).hexdigest() QR_code_url = "?chNFe={0}&nVersao={1}&tpAmb={2}&{3}dhEmi={4}&vNF={5}&vICMS\ ={6}&digVal={7}&cIdToken={8}&cHashQRCode={9}".\ format(chave_nfe, versao, ambiente, 'cDest={}&'.format(dest_cpf) if dest_cpf != 'Inexistente' else '', dh_emissao, valor_total, icms_total, dig_val, cid_token, c_hash_QR_code) qr_code_server = localizar_qrcode(kwargs['estado'], ambiente) qrcode_text = qr_code_server + QR_code_url qrcode.text = etree.CDATA(qrcode_text) infnfesupl.append(qrcode) nfe.insert(1, infnfesupl) return etree.tostring(xml)
def _add_qrCode(xml, **kwargs): xml = etree.fromstring(xml) inf_nfe = kwargs['NFes'][0]['infNFe'] nfe = xml.find(".//{http://www.portalfiscal.inf.br/nfe}NFe") infnfesupl = etree.Element('infNFeSupl') # Cria o nó qrCode no XML qrcode = etree.Element('qrCode') url_consulta = etree.Element('urlChave') # Busca a chave da NFe chave_nfe = inf_nfe['Id'][3:] # Versão do QR-Code versao = '100' # Tipo do Ambiente de Emissão ambiente = kwargs['ambiente'] # Documento de Identificação do Cliente dest_cpf = None dest = nfe.find(".//{http://www.portalfiscal.inf.br/nfe}dest") if dest: dest_parent = dest.getparent() dest_parent.remove(dest) if inf_nfe.get('dest', False): if inf_nfe['dest'].get('CPF', False): dest_cpf = inf_nfe['dest']['CPF'] dest = etree.Element('dest') cpf = etree.Element('CPF') cpf.text = dest_cpf dest.append(cpf) dest_parent.append(dest) # Data e Hora de emissão da NFC-e dh_emissao = inf_nfe['ide']['dhEmi'].encode() dh_emissao = base64.b16encode(dh_emissao).decode() # Valor Total da NFC-e valor_total = inf_nfe['total']['vNF'] # Valor Total do ICMS icms_total = inf_nfe['total']['vICMS'] # Digest Value dig_val = xml.find( ".//{http://www.w3.org/2000/09/xmldsig#}DigestValue").text.encode() dig_val = base64.b16encode(dig_val).decode() # CID Token cid_token = kwargs['NFes'][0]['infNFe']['codigo_seguranca']['cid_token'] # Código de Segurança do Contribuinte csc = kwargs['NFes'][0]['infNFe']['codigo_seguranca']['csc'] # Geração do Hash QR-Code if dest_cpf == None: c_hash_QR_code = "chNFe={}&nVersao={}&tpAmb={}&dhEmi={}&vNF={}&vICMS={}&digVal={}&cIdToken={}{}"\ .format(chave_nfe, versao, ambiente, dh_emissao.lower(), valor_total, icms_total, dig_val.lower(), cid_token, csc) else: c_hash_QR_code = "chNFe={}&nVersao={}&tpAmb={}&cDest={}&dhEmi={}&vNF={}&vICMS={}&digVal={}&cIdToken={}{}"\ .format(chave_nfe, versao, ambiente, dest_cpf, dh_emissao.lower(),\ valor_total, icms_total, dig_val.lower(), cid_token, csc) c_hash_QR_code = hashlib.sha1(c_hash_QR_code.encode()).digest() c_hash_QR_code = base64.b16encode(c_hash_QR_code).decode() # URL QR-Code if dest_cpf == None: QR_code_url = "?chNFe={}&nVersao={}&tpAmb={}&dhEmi={}&vNF={}&vICMS={}&digVal={}&cIdToken={}&cHashQRCode={}"\ .format(chave_nfe, versao, ambiente, dh_emissao.lower(), valor_total,\ icms_total, dig_val.lower(), cid_token, c_hash_QR_code.upper()) else: QR_code_url = "?chNFe={}&nVersao={}&tpAmb={}&cDest={}&dhEmi={}&vNF={}&vICMS={}&digVal={}&cIdToken={}&cHashQRCode={}"\ .format(chave_nfe, versao, ambiente, dest_cpf, dh_emissao.lower(),\ valor_total, icms_total, dig_val.lower(), cid_token, c_hash_QR_code.upper()) qr_code_server = localizar_qrcode(kwargs['estado'], ambiente) url_consulta_nfce = localizar_url_nfce(kwargs['estado'], ambiente) qrcode_text = qr_code_server + QR_code_url qrcode.text = etree.CDATA(qrcode_text) url_consulta.text = url_consulta_nfce infnfesupl.append(qrcode) infnfesupl.append(url_consulta) nfe.insert(1, infnfesupl) return etree.tostring(xml, encoding=str)
def test_localizar_qrcode(self): url = localizar_qrcode("35") self.assertEqual(url, url_qrcode_homologacao_sp)
def test_localizar_qrcode(self): url = localizar_qrcode('35') self.assertEqual(url, url_qrcode_homologacao_sp)
def _prepare_eletronic_invoice_values(self): res = super(InvoiceEletronic, self)._prepare_eletronic_invoice_values() if self.model not in ('55', '65'): return res local_datetime = datetime.now(pytz.timezone( self.env.user.tz)).isoformat() dt_format = local_datetime[0:19] + local_datetime[26:32] ide = { 'cUF': self.company_id.state_id.ibge_code, 'cNF': "%08d" % self.numero_controle, 'natOp': self.fiscal_position_id.name, 'mod': self.model, 'serie': self.serie.code, 'nNF': self.numero, 'dhEmi': dt_format, 'dhSaiEnt': dt_format, 'tpNF': '0' if self.tipo_operacao == 'entrada' else '1', 'idDest': self.ind_dest or 1, 'cMunFG': "%s%s" % (self.company_id.state_id.ibge_code, self.company_id.city_id.ibge_code), # Formato de Impressão do DANFE - 1 - Danfe Retrato, 4 - Danfe NFCe 'tpImp': '1' if self.model == '55' else '4', 'tpEmis': int(self.tipo_emissao) if self.model == '55' else 9, #'dhCont': dt_format if self.model == '65' else None, #'xJust': 'Indisponibilidade de Internet' if self.model == '65' else None, 'tpAmb': 2 if self.ambiente == 'homologacao' else 1, 'finNFe': self.finalidade_emissao, 'indFinal': self.ind_final or '1', 'indPres': self.ind_pres or '1', 'procEmi': 0 } #if self.model == '65': # ide['dhCont'] = dt_format if self.model == '65' else None # ide['xJust'] = 'Indisponibilidade de Internet' if self.model == '65' else None # Documentos Relacionados documentos = [] for doc in self.fiscal_document_related_ids: data = fields.Datetime.from_string(doc.date) if doc.document_type == 'nfe': documentos.append({'refNFe': doc.access_key}) elif doc.document_type == 'nf': documentos.append({ 'refNF': { 'cUF': doc.state_id.ibge_code, 'AAMM': data.strftime("%y%m"), 'CNPJ': re.sub('[^0-9]', '', doc.cnpj_cpf), 'mod': doc.fiscal_document_id.code, 'serie': doc.serie, 'nNF': doc.internal_number, } }) elif doc.document_type == 'cte': documentos.append({'refCTe': doc.access_key}) elif doc.document_type == 'nfrural': cnpj_cpf = re.sub('[^0-9]', '', doc.cnpj_cpf) documentos.append({ 'refNFP': { 'cUF': doc.state_id.ibge_code, 'AAMM': data.strftime("%y%m"), 'CNPJ': cnpj_cpf if len(cnpj_cpf) == 14 else '', 'CPF': cnpj_cpf if len(cnpj_cpf) == 11 else '', 'IE': doc.inscr_est, 'mod': doc.fiscal_document_id.code, 'serie': doc.serie, 'nNF': doc.internal_number, } }) elif doc.document_type == 'cf': documentos.append({ 'refECF': { 'mod': doc.fiscal_document_id.code, 'nECF': doc.serie, 'nCOO': doc.internal_number, } }) ide['NFref'] = documentos emit = { 'tipo': self.company_id.partner_id.company_type, 'cnpj_cpf': re.sub('[^0-9]', '', self.company_id.cnpj_cpf), 'xNome': self.company_id.legal_name, 'xFant': self.company_id.name, 'enderEmit': { 'xLgr': self.company_id.street, 'nro': self.company_id.number, 'xBairro': self.company_id.district, 'cMun': '%s%s' % (self.company_id.partner_id.state_id.ibge_code, self.company_id.partner_id.city_id.ibge_code), 'xMun': self.company_id.city_id.name, 'UF': self.company_id.state_id.code, 'CEP': re.sub('[^0-9]', '', self.company_id.zip), 'cPais': self.company_id.country_id.ibge_code, 'xPais': self.company_id.country_id.name, 'fone': re.sub('[^0-9]', '', self.company_id.phone or '') }, 'IE': re.sub('[^0-9]', '', self.company_id.inscr_est), 'CRT': self.company_id.fiscal_type, } if self.company_id.cnae_main_id and self.company_id.inscr_mun: emit['IM'] = re.sub('[^0-9]', '', self.company_id.inscr_mun or '') emit['CNAE'] = re.sub('[^0-9]', '', self.company_id.cnae_main_id.code or '') dest = None exporta = None if self.commercial_partner_id: partner = self.commercial_partner_id dest = { 'tipo': partner.company_type, 'cnpj_cpf': re.sub('[^0-9]', '', partner.cnpj_cpf or ''), 'xNome': partner.legal_name or partner.name, 'enderDest': { 'xLgr': partner.street, 'nro': partner.number, 'xBairro': partner.district, 'cMun': '%s%s' % (partner.state_id.ibge_code, partner.city_id.ibge_code), 'xMun': partner.city_id.name, 'UF': partner.state_id.code, 'CEP': re.sub('[^0-9]', '', partner.zip or ''), 'cPais': (partner.country_id.bc_code or '')[-4:], 'xPais': partner.country_id.name, 'fone': re.sub('[^0-9]', '', partner.phone or '') }, 'indIEDest': self.ind_ie_dest, 'IE': re.sub('[^0-9]', '', partner.inscr_est or ''), 'ISUF': re.sub('[^0-9]', '', partner.suframa or ''), } if self.ambiente == 'homologacao': dest[ 'xNome'] = u'NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL' if partner.country_id.id != self.company_id.country_id.id: dest['idEstrangeiro'] = re.sub('[^0-9]', '', partner.cnpj_cpf or '') dest['enderDest']['UF'] = 'EX' dest['enderDest']['xMun'] = 'Exterior' dest['enderDest']['cMun'] = '9999999' exporta = { 'UFSaidaPais': self.uf_saida_pais_id.code or '', 'xLocExporta': self.local_embarque or '', 'xLocDespacho': self.local_despacho or '', } if self.model == '65': dest = None autorizados = [] if self.company_id.accountant_id: autorizados.append({ 'CNPJ': re.sub('[^0-9]', '', self.company_id.accountant_id.cnpj_cpf) }) eletronic_items = [] for item in self.eletronic_item_ids: eletronic_items.append( self._prepare_eletronic_invoice_item(item, self)) total = { # ICMS 'vBC': "%.02f" % self.valor_bc_icms, 'vICMS': "%.02f" % self.valor_icms, 'vICMSDeson': "%.02f" % self.valor_icms_deson, #incluir campos no modelo 'vFCP': '0.00', 'vFCPST': '0.00', 'vFCPSTRet': '0.00', 'vIPIDevol': '0.00', 'vBCST': "%.02f" % self.valor_bc_icmsst, 'vST': "%.02f" % self.valor_icmsst, 'vProd': "%.02f" % self.valor_bruto, 'vFrete': "%.02f" % self.valor_frete, 'vSeg': "%.02f" % self.valor_seguro, 'vDesc': "%.02f" % self.valor_desconto, 'vII': "%.02f" % self.valor_ii, 'vIPI': "%.02f" % self.valor_ipi, 'vPIS': "%.02f" % self.valor_pis, 'vCOFINS': "%.02f" % self.valor_cofins, 'vOutro': "%.02f" % self.valor_despesas, 'vNF': "%.02f" % self.valor_final, 'vFCPUFDest': "%.02f" % self.valor_icms_fcp_uf_dest, 'vICMSUFDest': "%.02f" % self.valor_icms_uf_dest, 'vICMSUFRemet': "%.02f" % self.valor_icms_uf_remet, 'vTotTrib': "%.02f" % self.valor_estimado_tributos, # ISSQn 'vServ': '0.00', # Retenções } if self.transportadora_id.street: end_transp = "%s - %s, %s" % ( self.transportadora_id.street, self.transportadora_id.number or '', self.transportadora_id.district or '') else: end_transp = '' transp = { 'modFrete': self.modalidade_frete, 'transporta': { 'xNome': self.transportadora_id.legal_name or self.transportadora_id.name or '', 'IE': re.sub('[^0-9]', '', self.transportadora_id.inscr_est or ''), 'xEnder': end_transp if self.transportadora_id else '', 'xMun': self.transportadora_id.city_id.name or '', 'UF': self.transportadora_id.state_id.code or '' }, 'veicTransp': { 'placa': self.placa_veiculo or '', 'UF': self.uf_veiculo or '', 'RNTC': self.rntc or '', } } cnpj_cpf = re.sub('[^0-9]', '', self.transportadora_id.cnpj_cpf or '') if self.transportadora_id.is_company: transp['transporta']['CNPJ'] = cnpj_cpf else: transp['transporta']['CPF'] = cnpj_cpf reboques = [] for item in self.reboque_ids: reboques.append({ 'placa': item.placa_veiculo or '', 'UF': item.uf_veiculo or '', 'RNTC': item.rntc or '', 'vagao': item.vagao or '', 'balsa': item.balsa or '', }) transp['reboque'] = reboques volumes = [] for item in self.volume_ids: volumes.append({ 'qVol': item.quantidade_volumes or '', 'esp': item.especie or '', 'marca': item.marca or '', 'nVol': item.numeracao or '', 'pesoL': "%.03f" % item.peso_liquido if item.peso_liquido else '', 'pesoB': "%.03f" % item.peso_bruto if item.peso_bruto else '', }) transp['vol'] = volumes duplicatas = [] for dup in self.duplicata_ids: vencimento = fields.Datetime.from_string(dup.data_vencimento) duplicatas.append({ 'nDup': dup.numero_duplicata, 'dVenc': vencimento.strftime('%Y-%m-%d'), 'vDup': "%.02f" % dup.valor }) cobr = { 'fat': { 'nFat': self.numero_fatura or '', 'vOrig': "%.02f" % self.fatura_bruto if self.fatura_bruto else '', 'vDesc': "%.02f" % self.fatura_desconto if self.fatura_desconto else '', 'vLiq': "%.02f" % self.fatura_liquido if self.fatura_liquido else '', }, 'dup': duplicatas } pag = [] if self.model == '55': pag.append({ 'indPag': self.payment_term_id.indPag or '0', 'tPag': self.metodo_pagamento or '90', 'vPag': "%.02f" % self.fatura_liquido or '0.00', #'vTroco': "%.02f" % self.troco, }) if self.model == '65': for p in self.payment_ids: pag.append({ 'indPag': self.payment_term_id.indPag or '0', 'tPag': p.metodo_pagamento, 'vPag': "%.02f" % p.valor, }) for p in pag: if p['tPag'] == '01': p['vTroco'] = "%.02f" % self.troco self.informacoes_complementares = self.informacoes_complementares.\ replace('\n', '<br />') self.informacoes_legais = self.informacoes_legais.replace( '\n', '<br />') infAdic = { 'infCpl': self.informacoes_complementares or '', 'infAdFisco': self.informacoes_legais or '', } compras = { 'xNEmp': self.nota_empenho or '', 'xPed': self.pedido_compra or '', 'xCont': self.contrato_compra or '', } codigo_seguranca = { 'cid_token': self.company_id.id_token_csc, 'csc': self.company_id.csc, } vals = { 'Id': '', 'ide': ide, 'emit': emit, 'dest': dest, 'autXML': autorizados, 'detalhes': eletronic_items, 'total': total, 'transp': transp, 'infAdic': infAdic, 'pag': pag, 'exporta': exporta, 'compra': compras, } if len(duplicatas) > 0: vals['cobr'] = cobr if self.model == '65': vals['codigo_seguranca'] = codigo_seguranca chave_nfe = self.chave_nfe ambiente = 1 if self.ambiente == 'producao' else 2 estado = self.company_id.state_id.ibge_code cid_token = int(self.company_id.id_token_csc) csc = self.company_id.csc c_hash_QR_code = "{0}|2|{1}|{2}{3}".format(chave_nfe, ambiente, int(cid_token), csc) c_hash_QR_code = hashlib.sha1(c_hash_QR_code.encode()).hexdigest() QR_code_url = "p={0}|2|{1}|{2}|{3}".format(chave_nfe, ambiente, int(cid_token), c_hash_QR_code) qr_code_server = localizar_qrcode(estado, ambiente) url_chave = localizar_url_nfce(estado, ambiente) vals['qrCode'] = qr_code_server + QR_code_url vals['urlChave'] = url_chave return vals