def get_barcode(self, no_product=False): partner_id = self.partner_id or self.company_id.partner_id ted = False RutEmisor = self.format_rut(self.company_id.main_id_number) result['TED']['DD']['RE'] = RutEmisor result['TED']['DD']['TD'] = self.location_id.document_type_id.code result['TED']['DD']['F'] = self.get_folio() result['TED']['DD']['FE'] = datetime.strftime(datetime.now(), '%Y-%m-%d') if not partner_id.commercial_partner_id.main_id_number: raise UserError(_("Fill Partner VAT")) result['TED']['DD']['RR'] = self.format_rut(partner_id.commercial_partner_id.main_id_number) result['TED']['DD']['RSR'] = pysiidte.str_shorten(partner_id.commercial_partner_id.name, 40) result['TED']['DD']['MNT'] = int(round(self.amount_total)) if no_product: result['TED']['DD']['MNT'] = 0 for line in self.move_lines: result['TED']['DD']['IT1'] = pysiidte.str_shorten(line.product_id.name,40) if line.product_id.default_code: result['TED']['DD']['IT1'] = pysiidte.str_shorten(line.product_id.name.replace( '['+line.product_id.default_code+'] ', ''), 40) break resultcaf = self.location_id.sequence_id.get_caf_file() result['TED']['DD']['CAF'] = resultcaf['AUTORIZACION']['CAF'] if RutEmisor != result['TED']['DD']['CAF']['DA']['RE']: raise UserError(_('NO coincide el Dueño del CAF : %s con el emisor Seleccionado: %s' % ( result['TED']['DD']['CAF']['DA']['RE'], RutEmisor))) dte = result['TED']['DD'] timestamp = pysiidte.time_stamp() if date(int(timestamp[:4]), int(timestamp[5:7]), int(timestamp[8:10])) < date( int(self.date[:4]), int(self.date[5:7]), int(self.date[8:10])): raise UserError("La fecha de timbraje no puede ser menor a la fecha de emisión del documento") dte['TSTED'] = timestamp ddxml = '<DD>'+dicttoxml.dicttoxml( dte, root=False, attr_type=False).decode().replace( '<key name="@version">1.0</key>', '', 1).replace( '><key name="@version">1.0</key>', ' version="1.0">', 1).replace( '><key name="@algoritmo">SHA1withRSA</key>', ' algoritmo="SHA1withRSA">').replace( '<key name="#text">', '').replace( '</key>', '').replace('<CAF>', '<CAF version="1.0">')+'</DD>' keypriv = resultcaf['AUTORIZACION']['RSASK'].replace('\t', '') # parser = etree.XMLParser(remove_blank_text=True) root = etree.XML(ddxml) # Daniel Blanco: se instancia el parser # root = etree.fromstring(ddxml, parser=parser) # Daniel Blanco: se instancia el parser ddxml = etree.tostring(root) # Daniel Blanco: test pretty_print: la mayoría no lo formatea frmt = self.signmessage(ddxml, keypriv) ted = '<TED version="1.0">{}<FRMT algoritmo="SHA1withRSA">{}</FRMT></TED>'.format(ddxml.decode(), frmt) self.sii_barcode = ted image = False if ted: barcodefile = BytesIO() image = self.pdf417bc(ted) image.save(barcodefile, 'PNG') data = barcodefile.getvalue() self.sii_barcode_img = base64.b64encode(data) ted += ''' <TmstFirma>{}</TmstFirma>'''.format(timestamp) return ted
def _caratula_recep(self, RutResponde, RutRecibe): caratula = collections.OrderedDict() caratula['RutResponde'] = RutResponde caratula['RutRecibe'] = RutRecibe caratula['NmbContacto'] = self.env.user.partner_id.name caratula['FonoContacto'] = self.env.user.partner_id.phone caratula['MailContacto'] = self.env.user.partner_id.email caratula['TmstFirmaEnv'] = pysiidte.time_stamp() return caratula
def _crear_libro(self): company_id = self.company_id dte_service = company_id.dte_service_provider try: signature_d = self.get_digital_signature(company_id) except: raise UserError( _('''There is no Signer Person with an \ authorized signature for you in the system. Please make sure that \ 'user_signature_key' module has been installed and enable a digital \ signature, for you or make the signer to authorize you to use his \ signature.''')) certp = signature_d['cert'].replace(BC, '').replace(EC, '').replace('\n', '') resumenes = [] resumenPeriodo = {} for rec in self.with_context(lang='es_CL').move_ids: resumen = self.getResumen(rec) resumenes.extend([{'Detalle': resumen}]) resumenPeriodo = self._setResumenPeriodo(resumen, resumenPeriodo) rPeriodo = collections.OrderedDict() fields = [ 'TotFolAnulado', 'TotGuiaAnulada', 'TotGuiaVenta', 'TotMntGuiaVta', 'TotMntModificado', 'itemTraslado' ] for f in fields: if f in resumenPeriodo: rPeriodo[f] = resumenPeriodo[f] dte = collections.OrderedDict() dte['ResumenPeriodo'] = rPeriodo dte['item'] = resumenes dte['TmstFirma'] = pysiidte.time_stamp() resol_data = self.env['account.invoice'].get_resolution_data( company_id) RUTEmisor = self.format_rut(company_id.main_id_number) RUTRecep = "60803000-K" # RUT SII xml = dicttoxml.dicttoxml(dte, root=False, attr_type=False).decode() doc_id = 'GUIA_' + self.periodo_tributario libro = self.create_template_envio(RUTEmisor, self.periodo_tributario, resol_data['dte_resolution_date'], resol_data['dte_resolution_number'], xml, signature_d, self.tipo_libro, self.tipo_envio, self.folio_notificacion, doc_id) xml = pysiidte.create_template_env(libro) root = etree.XML(xml) envio_dte = etree.tostring(root, pretty_print=True).decode().replace( '<item>', '\n').replace('</item>', '').replace('<itemTraslado>', '').replace('</itemTraslado>', '\n') envio_dte = self.sign_full_xml(envio_dte, signature_d['priv_key'], certp, doc_id, 'libro') return envio_dte, doc_id
def _create_envelope(self, n_atencion=False, RUTRecep="60803000-K"): DTEs = {} count = 0 company_id = False for rec in self.with_context(lang='es_CL'): if rec.company_id.dte_service_provider == 'SIIHOMO': # si ha sido timbrado offline, no se puede volver a timbrar rec._stamp(n_atencion) DTEs.update({str(rec.sii_document_number): rec.sii_xml_dte}) if not company_id: company_id = rec.company_id elif company_id.id != rec.company_id.id: raise UserError("Está combinando compañías") company_id = rec.company_id file_name = 'T52' dtes="" SubTotDTE = '' resol_data = self.env['account.invoice'].get_resolution_data(company_id) signature_d = self.env.user.get_digital_signature(company_id) RUTEmisor = self.format_rut(company_id.main_id_number) NroDte = 0 for rec_id, documento in DTEs.items(): dtes += '\n' + documento NroDte += 1 file_name += 'F' + rec_id SubTotDTE += '''<SubTotDTE> <TpoDTE>52</TpoDTE> <NroDTE>''' + str(NroDte) + '''</NroDTE> </SubTotDTE>''' RUTRecep = "60803000-K" # RUT SII dtes = self.create_template_envio( RUTEmisor, RUTRecep, resol_data['dte_resolution_date'], resol_data['dte_resolution_number'], pysiidte.time_stamp(), dtes, signature_d, SubTotDTE, ) envio_dte = pysiidte.create_template_env(dtes) certp = signature_d['cert'].replace(BC, '').replace(EC, '').replace('\n', '') envio_dte = self.env['account.invoice'].sudo(self.env.user.id).with_context( {'company_id': company_id.id}).sign_full_xml( envio_dte.replace('<?xml version="1.0" encoding="ISO-8859-1"?>\n', ''), signature_d['priv_key'], pysiidte.split_cert(certp), 'SetDoc', 'env' ) return { # 'xml_envio': '<?xml version="1.0" encoding="ISO-8859-1"?>\n' + envio_dte, 'xml_envio': envio_dte, 'name': file_name, 'company_id': company_id.id, 'user_id': self.env.uid, }
def _caratula_respuesta(self, RutResponde, RutRecibe, IdRespuesta="1", NroDetalles=0): caratula = collections.OrderedDict() caratula['RutResponde'] = RutResponde caratula['RutRecibe'] = RutRecibe caratula['IdRespuesta'] = IdRespuesta caratula['NroDetalles'] = NroDetalles caratula['NmbContacto'] = self.env.user.partner_id.name caratula['FonoContacto'] = self.env.user.partner_id.phone caratula['MailContacto'] = self.env.user.partner_id.email caratula['TmstFirmaResp'] = pysiidte.time_stamp() return caratula
def _recep(self, inv, RutFirma): # raise UserError('document invoice: %s' % inv.document_type_id.code) receipt = collections.OrderedDict() receipt['TipoDoc'] = inv.document_type_id.code receipt['Folio'] = int(inv.document_number) receipt['FchEmis'] = inv.date_invoice receipt['RUTEmisor'] = inv.format_vat(inv.partner_id.main_id_number) receipt['RUTRecep'] = inv.format_vat(inv.company_id.main_id_number) receipt['MntTotal'] = int(round(inv.amount_total)) receipt['Recinto'] = inv.company_id.street receipt['RutFirma'] = RutFirma receipt['Declaracion'] = 'El acuse de recibo que se declara en este acto, de acuerdo a lo dispuesto \ en la letra b) del Art. 4, y la letra c) del Art. 5 de la Ley 19.983, acredita que la entrega de mercaderias o \ servicio(s) prestado(s) ha(n) sido recibido(s).' receipt['TmstFirmaRecibo'] = pysiidte.time_stamp() return receipt
def _record_detail(self, dict1, dict2): if True: inv_obj = self.env['account.invoice'] #-try: resol_data = inv_obj.get_resolution_data(self.company_id) signature_d = self.get_digital_signature_pem(self.company_id) #-except: #-_logger.info(u'First entry: unknown company') #-return False dict1n = self.insert_son_values( dict1, 'ResumenPeriodo', 'TotIVANoRec', ['CodIVANoRec', 'TotMntIVANoRec', 'TotOpIVANoRec']) dict1n = self.insert_son_values( dict1n, 'ResumenPeriodo', 'TotOtrosImp', ['CodImp', 'TotMntImp']) xml_detail1 = self.replace_tags(self.replace_tags( self.replace_tags( dicttoxml.dicttoxml( dict1n, root=False, attr_type=False).decode().replace( 'item', 'TotalesPeriodo').replace('>0.0<', '>0<').replace( '.0<', '<'), tag_replace01, '0'), tag_replace_1, ''), tag_replace01, '0.0') dict2n = self.insert_son_values( dict2, 'Detalles', 'IVANoRec', ['CodIVANoRec', 'MntIVANoRec']) # raise UserError(json.dumps(dict2n)) dict2n = self.insert_son_values( dict2n, 'Detalles', 'OtrosImp', ['CodImp', 'TasaImp', 'MntImp']) # print dict2n xml_detail2 = dicttoxml.dicttoxml( dict2n, root=False, attr_type=False).decode().replace( 'item', 'Detalle').replace('<Detalles>', '').replace( '</Detalles>', '').replace('>0.0<', '>0<').replace( '.0<', '<') xml_detail2 = self.replace_tags( self.replace_tags(xml_detail2.replace( '<TpoDocRef/>', '').replace( '<FolioDocRef/>', ''), tag_replace02, '0'), tag_replace_2, '').replace('uTasaImp', 'TasaImp') print(xml_detail2) # raise UserError('xml_detail2') xml_envio_report = """<EnvioLibro ID="{}">\ <Caratula>\ <RutEmisorLibro>{}</RutEmisorLibro>\ <RutEnvia>{}</RutEnvia>\ <PeriodoTributario>{}</PeriodoTributario>\ <FchResol>{}</FchResol>\ <NroResol>{}</NroResol>\ <TipoOperacion>{}</TipoOperacion>\ <TipoLibro>{}</TipoLibro>\ <TipoEnvio>{}</TipoEnvio>\ <FolioNotificacion>{}</FolioNotificacion>\ <CodAutRec>{}</CodAutRec>\ </Caratula>{}{}<TmstFirma>{}</TmstFirma></EnvioLibro>""".format( self.name.replace(' ', '_'), inv_obj.format_vat(self.company_id.vat), signature_d['subject_serial_number'], self.fiscal_period, resol_data['dte_resolution_date'], resol_data['dte_resolution_number'], operation_type_[self.operation_type], report_type_[self.report_type], sending_type_[self.sending_type], self.notification_number or '', self.amendment_code or '', xml_detail1, xml_detail2, pysiidte.time_stamp()).replace( '<FolioNotificacion></FolioNotificacion>', '', 1).replace( '<CodAutRec></CodAutRec>', '', 1) _logger.info(xml_envio_report) xml1 = xml.dom.minidom.parseString(xml_envio_report) xml_pret = xml1.toprettyxml() if True: # try: xml_pret = pysiidte.convert_encoding( xml_pret, 'ISO-8859-1').decode().replace( '<?xml version="1.0" ?>', '') else: # except: _logger.info(u'no pude decodificar algún caracter. La versión \ guardada del xml es la siguiente: {}'.format(xml_pret)) # raise UserError('xml pret sin decodificar') certp = signature_d['cert'].replace( BC, '').replace(EC, '').replace('\n', '') _logger.info("\n\n\n Aqui el xml_pret antes del envelop %s \n\n\n" % xml_pret) xml_pret = self._envelope_book(xml_pret) _logger.info(xml_pret) xml_pret = self.sign_full_xml( xml_pret.replace('<?xml version="1.0" encoding="ISO-8859-1"?>\n', ''), signature_d['priv_key'], certp, self.name.replace(' ', '_'), type='book') _logger.info(xml_pret) return xml_pret else: # except: _logger.info('Could not get files (first attempt)') return False
def commercial_acceptance(self): date = pysiidte.time_stamp() inv_obj = self.env['account.invoice'] for message_id in self.message_ids: for attachment_id in message_id.attachment_ids: # if not (attachment_id.mimetype in [ # 'text/plain'] and attachment_id.name.lower().find( # '.xml')): # _logger.info(u'El adjunto no es un XML. # Revisando otro...') # continue _logger.info('El adjunto es un XML') xml = self._get_xml_content(attachment_id.datas) soup = bs(xml, 'xml') # se crea un arbol de xml envio_dte = soup.find_all('EnvioDTE') # busqueda if envio_dte: signature_d = inv_obj.get_digital_signature( self.env.user.company_id) certp = signature_d['cert'].replace(BC, '').replace( EC, '').replace('\n', '') tz = pytz.timezone('America/Santiago') day = datetime.now(tz).strftime('%y%d%H%M') idrespuesta = day caratula = collections.OrderedDict() caratula['RutResponde'] = '{}'.format( soup.RutReceptor.string) caratula['RutRecibe'] = '{}'.format(soup.RUTEmisor.string) caratula['IdRespuesta'] = idrespuesta caratula['NroDetalles'] = 1 caratula['NmbContacto'] = self.env.user.name caratula['FonoContacto'] = self.env.user.partner_id.phone caratula['MailContacto'] = self.env.user.partner_id.email caratula['TmstFirmaResp'] = date caratula_xml = dicttoxml.dicttoxml(caratula, root=False, attr_type=False) apectacionComercial = collections.OrderedDict() apectacionComercial['TipoDTE'] = '{}'.format( soup.TipoDTE.string) apectacionComercial['Folio'] = '{}'.format( soup.Folio.string) apectacionComercial['FchEmis'] = '{}'.format( soup.FchEmis.string) apectacionComercial['RUTEmisor'] = '{}'.format( soup.RUTEmisor.string) apectacionComercial['RUTRecep'] = '{}'.format( soup.RUTRecep.string) apectacionComercial['MntTotal'] = int(soup.MntTotal.string) apectacionComercial['CodEnvio'] = idrespuesta apectacionComercial['EstadoDTE'] = 0 apectacionComercial['EstadoDTEGlosa'] = '' _logger.info(apectacionComercial) aceptacion_xml = dicttoxml.dicttoxml( apectacionComercial, root=False, attr_type=False, ) dicttoxml.set_debug(False) xml = '''<?xml version="1.0" encoding="ISO-8859-1"?> <RespuestaDTE xmlns="http://www.sii.cl/SiiDte" \ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \ version="1.0" xsi:schemaLocation="http://www.sii.cl/SiiDte \ RespuestaEnvioDTE_v10.xsd"> <Resultado ID="Odoo_resp"> <Caratula version="1.0"> {0} </Caratula> <ResultadoDTE> {1} </ResultadoDTE> </Resultado> </RespuestaDTE> '''.format(caratula_xml, aceptacion_xml) aceptacion_comercial = inv_obj.sign_full_xml( xml, signature_d['priv_key'], inv_obj.split_cert(certp), 'Odoo_resp', 'env_resp') self.save_xml_knowledge( aceptacion_comercial, 'acceptance_{}'.format(idrespuesta)) self.sii_xml_accept = aceptacion_comercial attachment = self.env['ir.attachment'].search([ ('res_model', '=', 'sii.dte.incoming'), ('res_id', '=', self.id) ]) file_name = attachment[0].name result = inv_obj.send_xml_file(aceptacion_comercial, file_name, self.env.user.company_id) _logger.info('Enviado: %s' % result)
def document_received(self): date = pysiidte.time_stamp() inv_obj = self.env['account.invoice'] for message_id in self.message_ids: for attachment_id in message_id.attachment_ids: # if not (attachment_id.mimetype in [ # 'text/plain'] and attachment_id.name.lower().find('.xml')): # _logger.info(u'El adjunto no es un XML. Revisando otro...') # continue _logger.info('El adjunto es un XML') xml = self._get_xml_content(attachment_id.datas) soup = bs(xml, 'xml') # se crea un arbol de xml envio_dte = soup.find_all('EnvioDTE') # busqueda if envio_dte: # signature_d = inv_obj.get_digital_signature( # self.env.user.company_id) try: signature_d = inv_obj.get_digital_signature( self.env.user.company_id) except: raise UserError( _('''There is no Signer Person with \ an authorized signature for you in the system. Please make sure that \ 'user_signature_key' module has been installed and enable a digital \ signature, for you or make the signer to authorize you to use his \ signature.''')) certp = signature_d['cert'].replace(BC, '').replace( EC, '').replace('\n', '') tz = pytz.timezone('America/Santiago') day = datetime.now(tz).strftime('%y%d%H%M') idrespuesta = day caratula = collections.OrderedDict() caratula['RutResponde'] = '{}'.format( soup.RutReceptor.string) caratula['RutRecibe'] = '{}'.format(soup.RUTEmisor.string) caratula['IdRespuesta'] = idrespuesta caratula['NroDetalles'] = 1 caratula['TmstFirmaResp'] = date caratula_xml = dicttoxml.dicttoxml(caratula, root=False, attr_type=False) fecha = datetime.strptime( message_id.date, '%Y-%m-%d %H:%M:%S').strftime('%Y-%m-%dT%H:%M:%S') RecepcionEnvio = collections.OrderedDict() RecepcionEnvio['NmbEnvio'] = '{}'.format( attachment_id.name) RecepcionEnvio['FchRecep'] = fecha RecepcionEnvio['CodEnvio'] = idrespuesta RecepcionEnvio['EnvioDTEID'] = soup.Documento['ID'] # soup.SetDTE['ID'] RecepcionEnvio['Digest'] = '{}'.format( soup.DigestValue.string) RecepcionEnvio['RutEmisor'] = '{}'.format( soup.RUTEmisor.string) RecepcionEnvio['RutReceptor'] = '{}'.format( soup.RUTRecep.string) RecepcionEnvio['EstadoRecepEnv'] = '0' RecepcionEnvio['RecepEnvGlosa'] = 'Envio Recibido Conforme' recepcionenvio_xml = dicttoxml.dicttoxml( RecepcionEnvio, root=False, attr_type=False, ) dicttoxml.set_debug(False) xml = '''<?xml version="1.0" encoding="ISO-8859-1"?> <RespuestaDTE xmlns="http://www.sii.cl/SiiDte" \ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0" \ xsi:schemaLocation="http://www.sii.cl/SiiDte RespuestaEnvioDTE_v10.xsd"> <Resultado ID="Odoo_resp"> <Caratula version="1.0"> {0} </Caratula> <RecepcionEnvio> {1} </RecepcionEnvio> </Resultado> </RespuestaDTE> '''.format(caratula_xml, recepcionenvio_xml) acuse_recibo = inv_obj.sign_full_xml( xml, signature_d['priv_key'], inv_obj.split_cert(certp), 'Odoo_resp', 'env_resp') _logger.info('estamos por crear') self.save_xml_knowledge(acuse_recibo, 'received_{}'.format(idrespuesta)) self.sii_xml_request = acuse_recibo
def receive_merchandise(self): # date = pysiidte.time_stamp() inv_obj = self.env['account.invoice'] for message_id in self.message_ids: for attachment_id in message_id.attachment_ids: # if not (attachment_id.mimetype in [ # 'text/plain'] and attachment_id.name.lower().find('.xml')): # _logger.info(u'El adjunto no es un XML. Revisando otro...') # continue _logger.info('El adjunto es un XML') xml = self._get_xml_content(attachment_id.datas) soup = bs(xml, 'xml') # se crea un arbol de xml libro_guia = soup.find_all('EnvioDTE') # busqueda if libro_guia: signature_d = inv_obj.get_digital_signature( self.env.user.company_id) certp = signature_d['cert'].replace(BC, '').replace( EC, '').replace('\n', '') date = pysiidte.time_stamp() caratula = collections.OrderedDict() caratula['RutResponde'] = '{}'.format(soup.RUTRecep.string) caratula['RutRecibe'] = '{}'.format(soup.RUTEmisor.string) caratula['NmbContacto'] = self.env.user.partner_id.name caratula['FonoContacto'] = self.env.user.partner_id.phone caratula['MailContacto'] = self.env.user.partner_id.email caratula['TmstFirmaEnv'] = date caratula_xml = dicttoxml.dicttoxml(caratula, root=False, attr_type=False) merchandise = collections.OrderedDict() merchandise['TipoDoc'] = int(soup.TipoDTE.string) merchandise['Folio'] = int(soup.Folio.string) merchandise['FchEmis'] = '{}'.format(soup.FchEmis.string) merchandise['RUTEmisor'] = '{}'.format( soup.RUTEmisor.string) merchandise['RUTRecep'] = '{}'.format(soup.RUTRecep.string) merchandise['MntTotal'] = int(soup.MntTotal.string) merchandise['Recinto'] = self.env.user.company_id.street merchandise['RutFirma'] = signature_d[ 'subject_serial_number'] merchandise['Declaracion'] = '''El acuse de recibo que \ se declara en este acto, de acuerdo a lo dispuesto en la letra b) del Art. 4, \ y la letra c) del Art. 5 de la Ley 19.983, acredita que la entrega de \ mercaderias o servicio(s) prestado(s) ha(n) sido recibido(s).''' merchandise['TmstFirmaRecibo'] = date merchandise_xml = dicttoxml.dicttoxml( merchandise, root=False, attr_type=False, ) dicttoxml.set_debug(False) id = "T" + str(soup.TipoDTE.string) + "F" + str( soup.Folio.string) doc = '''<Recibo version="1.0" \ xmlns="http://www.sii.cl/SiiDte" \ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" \ xsi:schemaLocation="http://www.sii.cl/SiiDte Recibos_v10.xsd"> <DocumentoRecibo ID="{0}" > {1} </DocumentoRecibo> </Recibo> '''.format(id, merchandise_xml) recibo_merca = inv_obj.sign_full_xml( doc, signature_d['priv_key'], inv_obj.split_cert(certp), 'Recibo', 'recep') xml = '''<?xml version="1.0" encoding="ISO-8859-1"?> <EnvioRecibos xmlns='http://www.sii.cl/SiiDte' \ xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' \ xsi:schemaLocation='http://www.sii.cl/SiiDte EnvioRecibos_v10.xsd' \ version="1.0"> <SetRecibos ID="SetDteRecibidos"> <Caratula version="1.0"> {0} </Caratula> {1} </SetRecibos> </EnvioRecibos>'''.format(caratula_xml, recibo_merca) envio_dte = inv_obj.sign_full_xml(xml, signature_d['priv_key'], certp, 'SetDteRecibidos', 'env_recep') self.save_xml_knowledge(envio_dte, 'merchandise_{}'.format(id)) self.sii_xml_merchandise = envio_dte