示例#1
0
    def test_issue46(self):
        """Example for sending an arbitrary header using SimpleXMLElement"""

        # fake connection (just to test xml_request):
        client = SoapClient(location="https://localhost:666/",
                            namespace='http://localhost/api')

        # Using WSDL, the equivalent is:
        # client['MyTestHeader'] = {'username': '******', 'password': '******'}

        headers = SimpleXMLElement("<Headers/>")
        my_test_header = headers.add_child("MyTestHeader")
        my_test_header['xmlns'] = "service"
        my_test_header.marshall('username', 'test')
        my_test_header.marshall('password', 'password')

        try:
            client.methodname(headers=headers)
        except:
            open("issue46.xml", "wb").write(client.xml_request)
            self.assert_(
                '<soap:Header><MyTestHeader xmlns="service">'
                '<username>test</username>'
                '<password>password</password>'
                '</MyTestHeader></soap:Header>' in client.xml_request.decode(),
                "header not in request!")
示例#2
0
    def test_issue78(self):
        "Example for sending an arbitrary header using SimpleXMLElement and WSDL"
        
        # fake connection (just to test xml_request):
        client = SoapClient(wsdl='http://dczorgwelzijn-test.qmark.nl/qmwise4/qmwise.asmx?wsdl')

        # Using WSDL, the easier form is but this doesn't allow for namespaces to be used.
        # If the server requires these (buggy server?) the dictionary method won't work
        # and marshall will not marshall 'ns:username' style keys
        # client['MyTestHeader'] = {'username': '******', 'password': '******'}

        namespace = 'http://questionmark.com/QMWISe/'
        ns = 'qmw'
        header = SimpleXMLElement('<Headers/>', namespace=namespace, prefix=ns)
        security = header.add_child("Security")
        security['xmlns:qmw']=namespace
        security.marshall('ClientID','NAME',ns=ns)
        security.marshall('Checksum','PASSWORD',ns=ns)
        client['Security']=security

        try:
            client.GetParticipantList()
        except:
            #open("issue78.xml", "wb").write(client.xml_request)
            print client.xml_request
            header="""<soap:Header><qmw:Security xmlns:qmw="http://questionmark.com/QMWISe/"><qmw:ClientID>NAME</qmw:ClientID><qmw:Checksum>PASSWORD</qmw:Checksum></qmw:Security></soap:Header>"""
            self.assert_(header in client.xml_request, "header not in request!")
示例#3
0
 def test_issue69(self):
     """Boolean value not converted correctly during marshall"""
     span = SimpleXMLElement('<span><name>foo</name></span>')
     span.marshall('value', True)
     d = {'span': {'name': str, 'value': bool}}
     e = {'span': {'name': 'foo', 'value': True}}
     self.assertEqual(span.unmarshall(d), e)
示例#4
0
    def test_issue78(self):
        """Example for sending an arbitrary header using SimpleXMLElement and WSDL"""

        # fake connection (just to test xml_request):
        client = SoapClient(
            wsdl='http://dczorgwelzijn-test.qmark.nl/qmwise4/qmwise.asmx?wsdl')

        # Using WSDL, the easier form is but this doesn't allow for namespaces to be used.
        # If the server requires these (buggy server?) the dictionary method won't work
        # and marshall will not marshall 'ns:username' style keys
        # client['MyTestHeader'] = {'username': '******', 'password': '******'}

        namespace = 'http://questionmark.com/QMWISe/'
        ns = 'qmw'
        header = SimpleXMLElement('<Headers/>', namespace=namespace, prefix=ns)
        security = header.add_child("Security")
        security['xmlns:qmw'] = namespace
        security.marshall('ClientID', 'NAME', ns=ns)
        security.marshall('Checksum', 'PASSWORD', ns=ns)
        client['Security'] = security

        try:
            client.GetParticipantList()
        except:
            #open("issue78.xml", "wb").write(client.xml_request)
            #print(client.xml_request)
            header = '<soap:Header>' \
                         '<qmw:Security xmlns:qmw="http://questionmark.com/QMWISe/">' \
                             '<qmw:ClientID>NAME</qmw:ClientID>' \
                             '<qmw:Checksum>PASSWORD</qmw:Checksum>' \
                         '</qmw:Security>' \
                     '</soap:Header>'
            xml = SimpleXMLElement(client.xml_request)
            self.assertEquals(str(xml.ClientID), "NAME")
            self.assertEquals(str(xml.Checksum), "PASSWORD")
示例#5
0
    def test_issue46(self):
        """Example for sending an arbitrary header using SimpleXMLElement"""

        # fake connection (just to test xml_request):
        client = SoapClient(
            location="https://localhost:666/",
            namespace='http://localhost/api'
        )

        # Using WSDL, the equivalent is:
        # client['MyTestHeader'] = {'username': '******', 'password': '******'}

        headers = SimpleXMLElement("<Headers/>")
        my_test_header = headers.add_child("MyTestHeader")
        my_test_header['xmlns'] = "service"
        my_test_header.marshall('username', 'test')
        my_test_header.marshall('password', 'password')

        try:
            client.methodname(headers=headers)
        except:
            open("issue46.xml", "wb").write(client.xml_request)
            self.assert_('<soap:Header><MyTestHeader xmlns="service">'
                            '<username>test</username>'
                            '<password>password</password>'
                         '</MyTestHeader></soap:Header>' in client.xml_request.decode(),
                         "header not in request!")
示例#6
0
 def test_issue69(self):
     """Boolean value not converted correctly during marshall"""
     span = SimpleXMLElement('<span><name>foo</name></span>')
     span.marshall('value', True)
     d = {'span': {'name': str, 'value': bool}}
     e = {'span': {'name': 'foo', 'value': True}}
     self.assertEqual(span.unmarshall(d), e)
示例#7
0
 def __init__(self):
     self.__service = SoapClient(location='https://ws.espol.edu.ec/saac/wsandroid.asmx',
                                 namespace='http://tempuri.org/', action='http://tempuri.org/')
     self.header = SimpleXMLElement('<Header/>')
     security = self.header.add_child("GTSIAuthSoapHeader")
     security['xmlns'] = "http://tempuri.org/"
     security.marshall('usuario', os.environ['SPIDER_USER'])
     security.marshall('key', os.environ['SPIDER_KEY'])
示例#8
0
def createOrUpdateClientEx(target):
    client = SoapClient(location="http://aboweb.com/aboweb/ClientService?wsdl",trace=False)
    client['wsse:Security'] = {
           'wsse:UsernameToken': {
                'wsse:Username': '******',
                'wsse:Password': '******',
                }
            }
    target = SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><ges:createOrUpdateClientEx xmlns:ges="http://www.gesmag.com/">'+ repr(target) +'</ges:createOrUpdateClientEx>')
    client.call('createOrUpdateClientEx',target)
    xml = SimpleXMLElement(client.xml_response)
    return xml
示例#9
0
def getClient(codeClient):
    client = SoapClient(location="http://aboweb.com/aboweb/ClientService?wsdl",trace=False)
    client['wsse:Security'] = {
           'wsse:UsernameToken': {
                'wsse:Username': '******',
                'wsse:Password': '******',
                # 'wsse:Password': '******',
                }
            }
    params = SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><ges:getClient xmlns:ges="http://www.gesmag.com/"><codeClient>'+codeClient+'</codeClient></ges:getClient>');
    result = client.call("getClient",params)
    xml = SimpleXMLElement(client.xml_response)
    return xml.children().children().children()
示例#10
0
def authenticateByEmail(username,password):
    # wsdl = "http://dev.aboweb.com/aboweb/ClientService?wsdl"
    client = SoapClient(location = "http://aboweb.com/aboweb/ClientService",trace=False)
    client['wsse:Security'] = {
           'wsse:UsernameToken': {
                'wsse:Username': '******',
                # 'wsse:Password': '******',
                'wsse:Password': '******',
                }
            }
    params = SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><ges:authenticateByEmail xmlns:ges="http://www.gesmag.com/"><email>'+username+'</email><encryptedPassword>'+ b64encode(sha1(password).digest()) +'</encryptedPassword></ges:authenticateByEmail>')
    response = client.call("authenticateByEmail",params)
    xml = SimpleXMLElement(client.xml_response)
    return str(xml('result'))
示例#11
0
def getAbonnements(codeClient):
    # return xml containing a list of user abonnements 
    clientAbonnement = SoapClient(location ="http://aboweb.com/aboweb/AbonnementService",trace=False)
    clientAbonnement['wsse:Security'] = {
                    'wsse:UsernameToken': {
                        'wsse:Username': '******',
                        # 'wsse:Password': '******',
                        'wsse:Password': '******',
                    }
                }

    params = SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><ges:getAbonnements xmlns:ges="http://www.gesmag.com/"><codeClient>%s</codeClient><offset>0</offset></ges:getAbonnements>' % codeClient)
    result = clientAbonnement.call("getAbonnements",params)
    xml = SimpleXMLElement(clientAbonnement.xml_response)
    return xml
示例#12
0
def ABM_TEST_MAIL(mail):
    # webservice to check for mail occurence in aboweb DB
    # Status should be 00 (found) or 01 (not found)
    clientABM = SoapClient(wsdl="http://aboweb.com/aboweb/abmWeb?wsdl", ns="web", trace=False)
    clientABM['AuthHeaderElement'] = {'login': '******', 'password': '******'}
    resultABM = clientABM.ABM_TEST_MAIL(refEditeur='207',refSociete='1',email=mail)
    xml = SimpleXMLElement(clientABM.xml_response)
    return xml('status')
示例#13
0
    def test_issue47_raw(self):
        "Same example (clarizen), with raw headers (no wsdl)!"
        client = SoapClient(location="https://api.clarizen.com/v1.0/Clarizen.svc", namespace='http://clarizen.com/api', trace=False)
            
        headers = SimpleXMLElement("<Headers/>", namespace="http://clarizen.com/api", prefix="ns1")
        session = headers.add_child("Session")
        session['xmlns'] = "http://clarizen.com/api"
        session.marshall('ID', '1234')

        client.location = "https://api.clarizen.com/v1.0/Clarizen.svc"
        client.action = "http://clarizen.com/api/IClarizen/Logout"
        try:
            client.call("Logout", headers=headers)
        except:
            open("issue47_raw.xml", "wb").write(client.xml_request)
            self.assert_("""<soap:Header><ns1:Session xmlns="http://clarizen.com/api"><ID>1234</ID></ns1:Session></soap:Header>""" in client.xml_request,
                        "Session header not in request!")
示例#14
0
 def SetTicketAcceso(self, ta_string):
     "Establecer el token y sign desde un ticket de acceso XML"
     if ta_string:
         ta = SimpleXMLElement(ta_string)
         self.Token = str(ta.credentials.token)
         self.Sign = str(ta.credentials.sign)
         return True
     else:
         raise RuntimeError("Ticket de Acceso vacio!")
示例#15
0
 def LoginCMS(self, cms):
     "Obtener ticket de autorización (TA)"
     results = self.client.loginCms(in0=str(cms))
     ta_xml = results['loginCmsReturn'].encode("utf-8")
     self.xml = ta = SimpleXMLElement(ta_xml)
     self.Token = str(ta.credentials.token)
     self.Sign = str(ta.credentials.sign)
     self.ExpirationTime = str(ta.header.expirationTime)
     return ta_xml
示例#16
0
 def SetTicketAcceso(self, ta_string):
     "Establecer el token y sign desde un ticket de acceso XML"
     if ta_string:
         ta = SimpleXMLElement(ta_string)
         self.Token = str(ta.credentials.token)
         self.Sign = str(ta.credentials.sign)
         self.ExpiracionTicketAcceso = datetime.datetime.strptime(
             str(ta.header.expirationTime)[:19], '%Y-%m-%dT%H:%M:%S')
         return True
     else:
         raise RuntimeError("Ticket de Acceso vacio!")
示例#17
0
def ABM_ACCES_CLIENT(username, password):
    clientABM = SoapClient(wsdl="http://aboweb.com/aboweb/abmWeb?wsdl",
                           ns="web",
                           trace=False)
    clientABM['AuthHeaderElement'] = {
        'login': '******',
        'password': '******'
    }
    resultABM = clientABM.ABM_ACCES_CLIENT('207', username, password)
    xml = SimpleXMLElement(clientABM.xml_response)
    return xml('codeClient')
示例#18
0
def ABM_MOT_PASSE_OUBLIE(mail):
    clientABM = SoapClient(wsdl="http://aboweb.com/aboweb/abmWeb?wsdl",
                           ns="web",
                           trace=False)
    clientABM['AuthHeaderElement'] = {
        'login': '******',
        'password': '******'
    }
    resultABM = clientABM.ABM_MOT_PASSE_OUBLIE(refEditeur='207', email=mail)
    xml = SimpleXMLElement(clientABM.xml_response)
    return xml('return')
示例#19
0
 def LoginCMS(self, cms):
     "Obtener ticket de autorización (TA)"
     if not isinstance(cms, str):
         cms = cms.decode("utf8")
     results = self.client.loginCms(in0=cms)
     ta_xml = results["loginCmsReturn"]
     self.xml = ta = SimpleXMLElement(ta_xml)
     self.Token = str(ta.credentials.token)
     self.Sign = str(ta.credentials.sign)
     self.ExpirationTime = str(ta.header.expirationTime)
     return ta_xml
示例#20
0
 def test_consultar(self):
     "consulta ao resultado do processamento dos arquivos de cupons fiscai"
     # create the client webservice
     client = SoapClient(wsdl=WSDL, soap_ns="soap12env")
     # set user login credentials in the soap header:
     client['Autenticacao'] = SimpleXMLElement(
         HEADER_XML % ("user", "password", "fed_tax_num", 1))
     # call the webservice
     response = client.Consultar(Protocolo="")
     self.assertEqual(
         response['ConsultarResult'],
         u'999|O protocolo informado n\xe3o \xe9 um n\xfamero v\xe1lido')
示例#21
0
 def AnalizarXml(self, xml=""):
     "Analiza un mensaje XML (por defecto el ticket de acceso)"
     try:
         if not xml or xml=='XmlResponse':
             xml = self.XmlResponse 
         elif xml=='XmlRequest':
             xml = self.XmlRequest 
         self.xml = SimpleXMLElement(xml)
         return True
     except Exception, e:
         self.Excepcion = traceback.format_exception_only( sys.exc_type, sys.exc_value)[0]
         return False
示例#22
0
    def test_issue47_raw(self):
        "Same example (clarizen), with raw headers (no wsdl)!"
        client = SoapClient(
            location="https://api.clarizen.com/v1.0/Clarizen.svc",
            namespace='http://clarizen.com/api',
            trace=False)

        headers = SimpleXMLElement("<Headers/>",
                                   namespace="http://clarizen.com/api",
                                   prefix="ns1")
        session = headers.add_child("Session")
        session['xmlns'] = "http://clarizen.com/api"
        session.marshall('ID', '1234')

        client.location = "https://api.clarizen.com/v1.0/Clarizen.svc"
        client.action = "http://clarizen.com/api/IClarizen/Logout"
        try:
            client.call("Logout", headers=headers)
        except:
            open("issue47_raw.xml", "wb").write(client.xml_request)
            self.assertTrue(
                """<soap:Header><ns1:Session xmlns="http://clarizen.com/api"><ID>1234</ID></ns1:Session></soap:Header>"""
                in client.xml_request, "Session header not in request!")
示例#23
0
    def test_issue66(self):
        """Verify marshaled requests can be sent with no children"""
        # fake connection (just to test xml_request):
        client = SoapClient(location="https://localhost:666/",
                            namespace='http://localhost/api')

        request = SimpleXMLElement("<ChildlessRequest/>")
        try:
            client.call('ChildlessRequest', request)
        except:
            open("issue66.xml", "wb").write(client.xml_request)
            self.assert_('<ChildlessRequest' in client.xml_request.decode(),
                         "<ChildlessRequest not in request!")
            self.assert_('</ChildlessRequest>' in client.xml_request.decode(),
                         "</ChildlessRequest> not in request!")
示例#24
0
 def test_issue89(self):
     """Setting attributes for request tag."""
     # fake connection (just to test xml_request):
     client = SoapClient(location="https://localhost:666/",
                         namespace='http://localhost/api')
     request = SimpleXMLElement(
         """<?xml version="1.0" encoding="UTF-8"?><test a="b"><a>3</a></test>"""
     )  # manually make request msg
     try:
         client.call('test', request)
     except:
         open("issue89.xml", "wb").write(client.xml_request)
         self.assert_(
             '<test a="b" xmlns="http://localhost/api">'
             in client.xml_request.decode(), "attribute not in request!")
示例#25
0
    def test_retificar(self):
        "Prueba da retifica de arquivos de cupons fiscais"

        # create the client webservice
        client = SoapClient(wsdl=WSDL, soap_ns="soap12env")
        # set user login credentials in the soap header:
        client['Autenticacao'] = SimpleXMLElement(
            HEADER_XML % ("user", "password", "fed_tax_num", 1))
        # call the webservice
        response = client.Retificar(NomeArquivo="file_name",
                                    ConteudoArquivo="content",
                                    EnvioNormal=True,
                                    Observacoes="")
        self.assertEqual(response['RetificarResult'],
                         u'206|CNPJ informado inv\xe1lido')
示例#26
0
    def test_issue105(self):
        """Test target namespace in wsdl (conflicting import)"""
        WSDL = "https://api.dc2.computing.cloud.it/WsEndUser/v2.4/WsEndUser.svc?wsdl"
        client = SoapClient(wsdl=WSDL)
        try:
            client.SetEnqueueServerStop(serverId=37)
        except SoapFault as sf:
            # ignore exception caused by missing credentials sent in this test:
            if sf.faultstring != "An error occurred when verifying security for the message.":
                raise

        # verify the correct namespace:
        xml = SimpleXMLElement(client.xml_request)
        ns_uri = xml.SetEnqueueServerStop['xmlns']
        self.assertEqual(ns_uri, "https://api.computing.cloud.it/WsEndUser")
示例#27
0
    def test_issue113(self):
        """Test target namespace in wsdl import"""
        WSDL = "https://test.paymentgate.ru/testpayment/webservices/merchant-ws?wsdl"
        client = SoapClient(wsdl=WSDL)
        try:
            client.getOrderStatusExtended(order={'merchantOrderNumber': '1'})
        except SoapFault as sf:
            # ignore exception caused by missing credentials sent in this test:
            if sf.faultstring != "An error was discovered processing the <wsse:Security> header":
                raise

        # verify the correct namespace:
        xml = SimpleXMLElement(client.xml_request)
        ns_uri = xml.getOrderStatusExtended['xmlns']
        self.assertEqual(ns_uri,
                         "http://engine.paymentgate.ru/webservices/merchant")
示例#28
0
def create_tra(service=SERVICE, ttl=2400):
    "Crear un Ticket de Requerimiento de Acceso (TRA)"
    tra = SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?>'
                           '<loginTicketRequest version="1.0">'
                           "</loginTicketRequest>")
    tra.add_child("header")
    # El source es opcional. Si falta, toma la firma (recomendado).
    # tra.header.addChild('source','subject=...')
    # tra.header.addChild('destination','cn=wsaahomo,o=afip,c=ar,serialNumber=CUIT 33693450239')
    tra.header.add_child("uniqueId", str(date("U")))
    tra.header.add_child("generationTime", str(date("c", date("U") - ttl)))
    tra.header.add_child("expirationTime", str(date("c", date("U") + ttl)))
    tra.add_child("service", service)
    return tra.as_xml()
示例#29
0
 def get_secondary_amount(cls, invoice, value):
     Currency = Pool().get('currency.currency')
     if invoice.pos and invoice.pos.pos_type == 'electronic':
         afip_tr, = [
             tr for tr in invoice.transactions if tr.pyafipws_result == 'A'
         ]
         request = SimpleXMLElement(unidecode(afip_tr.pyafipws_xml_request))
         if invoice.pos.pyafipws_electronic_invoice_service == 'wsfex':
             ctz = Decimal(str(request('Moneda_ctz')))
         elif invoice.pos.pyafipws_electronic_invoice_service == 'wsfe':
             ctz = Decimal(str(request('MonCotiz')))
     currency_rate = invoice.currency_rate or ctz
     context = dict(date=invoice.currency_date)
     if currency_rate:
         context['currency_rate'] = currency_rate
     with Transaction().set_context(context):
         amount = Currency.compute(invoice.currency, value,
                                   invoice.company.currency)
     return amount
示例#30
0
 def test_issue114(self):
     """Test no schema in wsdl (Lotus-Domino)"""
     WSDL = "https://pysimplesoap.googlecode.com/issues/attachment?aid=1140000000&name=WebRequest.xml&token=QVf8DlJ1qmKRH8LAbU4eSe2Ban0%3A1399084258723"
     # WSDL= "file:WebRequest.xml"
     try:
         client = SoapClient(wsdl=WSDL, soap_server="axis")
         #print client.help("CREATEREQUEST")
         ret = client.CREATEREQUEST(LOGIN="******",
                                    REQUESTTYPE=1,
                                    REQUESTCONTENT="test")
     except ExpatError:
         # the service seems to be expecting basic auth
         pass
     except SoapFault as sf:
         # todo: check as service is returning DOM failure
         # verify the correct namespace:
         xml = SimpleXMLElement(client.xml_request)
         ns_uri = xml.CREATEREQUEST['xmlns']
         self.assertEqual(ns_uri, "http://tps.ru")
示例#31
0
def create_tra(service=SERVICE,ttl=2400):
    "Crear un Ticket de Requerimiento de Acceso (TRA)"
    tra = SimpleXMLElement(
        '<?xml version="1.0" encoding="UTF-8"?>'
        '<loginTicketRequest version="1.0">'
        '</loginTicketRequest>')
    tra.add_child('header')
    # El source es opcional. Si falta, toma la firma (recomendado).
    #tra.header.addChild('source','subject=...')
    #tra.header.addChild('destination','cn=wsaahomo,o=afip,c=ar,serialNumber=CUIT 33693450239')
    tra.header.add_child('uniqueId',str(date('U')))
    tra.header.add_child('generationTime',str(date('c',date('U')-ttl)))
    tra.header.add_child('expirationTime',str(date('c',date('U')+ttl)))
    tra.add_child('service',service)
    return tra.as_xml()
示例#32
0
def create_tra(service=None, ttl=2400, cert=None):
    "Create a Access Request Ticket (TRA)"
    # Base TRA squeleton (Ticket de Requerimiento de Acceso)
    tra = SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?>'
                           '<loginTicketRequest version="1.0">'
                           '</loginTicketRequest>')
    tra.add_child('header')
    # get the source from the certificate subject, ie "CN=empresa, O=dna, C=py"
    if cert:
        crt = xmlsec.x509_parse_cert(cert)
        tra.header.add_child('source', crt.get_subject().as_text())
    tra.header.add_child('destination', 'C=py, O=dna, OU=sofia, CN=wsaatest')
    d = int(time.mktime(datetime.datetime.now().timetuple()))
    tra.header.add_child('uniqueId', str(d))
    date = lambda ts: datetime.datetime.fromtimestamp(ts).isoformat()
    tra.header.add_child('generationTime', str(date(d - ttl)))
    tra.header.add_child('expirationTime', str(date(d + ttl)))
    tra.add_child('service', service)
    return tra.as_xml()
示例#33
0
def create_tra(service=None, ttl=2400, cert=None):
    "Create a Access Request Ticket (TRA)"
    # Base TRA squeleton (Ticket de Requerimiento de Acceso)
    tra = SimpleXMLElement(
        '<?xml version="1.0" encoding="UTF-8"?>'
        '<loginTicketRequest version="1.0">'
        '</loginTicketRequest>')
    tra.add_child('header')
    # get the source from the certificate subject, ie "CN=empresa, O=dna, C=py"
    if cert:
        crt = xmlsec.x509_parse_cert(cert)
        tra.header.add_child('source', crt.get_subject().as_text())
    tra.header.add_child('destination', 'C=py, O=dna, OU=sofia, CN=wsaatest')
    d = int(time.mktime(datetime.datetime.now().timetuple()))
    tra.header.add_child('uniqueId', str(d))
    date = lambda ts: datetime.datetime.fromtimestamp(ts).isoformat()
    tra.header.add_child('generationTime', str(date(d-ttl)))
    tra.header.add_child('expirationTime', str(date(d+ttl)))
    tra.add_child('service', service)
    return tra.as_xml()
示例#34
0
    def export_citi_comprobante_ventas(self):
        logger.info('exportar CITI REG3685 Comprobante Ventas')
        pool = Pool()
        Invoice = pool.get('account.invoice')
        Currency = pool.get('currency.currency')

        invoices = Invoice.search([
            ('type', '=', 'out'),
            ('pos.pos_do_not_report', '=', False),
            ['OR', ('state', 'in', ['posted', 'paid']),
                [('state', '=', 'cancelled'), ('number', '!=', None)]],
            ('move.period', '=', self.start.period),
            ], order=[
            ('pos', 'ASC'),
            ('invoice_date', 'ASC'),
            ('invoice_type', 'ASC'),
            ('number', 'ASC'),
            ])
        lines = ""
        for invoice in invoices:
            alicuotas = {
                3: 0,
                4: 0,
                5: 0,
                6: 0,
                8: 0,
                9: 0,
                }
            cant_alicuota = 0
            fecha_comprobante = invoice.invoice_date.strftime("%Y%m%d")
            tipo_comprobante = invoice.invoice_type.invoice_type.rjust(3, '0')
            punto_de_venta = invoice.number.split('-')[0].rjust(5, '0')
            if int(tipo_comprobante) in COMPROBANTES_EXCLUIDOS:
                punto_de_venta = ''.rjust(5, '0')  # se informan ceros
            if ':' in invoice.number:
                parte_desde = invoice.number.split(':')[0]
                parte_hasta = invoice.number.split(':')[1]
                numero_comprobante = parte_desde.split('-')[1].rjust(20, '0')
                numero_comprobante_hasta = parte_hasta.rjust(20, '0')
            else:
                numero_comprobante = invoice.number.split(
                    '-')[1].rjust(20, '0')
                #if int(punto_de_venta) in [33, 331, 332]:
                #    numero_comprobante = 'COE'
                numero_comprobante_hasta = invoice.number.split(
                    '-')[1].rjust(20, '0')

            identificacion_comprador = None
            codigo_documento_comprador = invoice.party.tipo_documento
            if invoice.party.vat_number:
                # Si tenemos vat_number, entonces tenemos CUIT Argentino
                # use the Argentina AFIP's global CUIT for the country:
                identificacion_comprador = invoice.party.vat_number
                codigo_documento_comprador = '80'
            elif invoice.party.vat_number_afip_foreign:
                # use the VAT number directly
                identificacion_comprador = \
                    invoice.party.vat_number_afip_foreign
            else:
                for identifier in invoice.party.identifiers:
                    if identifier.type == 'ar_dni':
                        identificacion_comprador = identifier.code
                        codigo_documento_comprador = '96'
                        break
                if identificacion_comprador is None:
                    identificacion_comprador = '0'  # only "consumidor final"
                    codigo_documento_comprador = '99'  # consumidor final

            identificacion_comprador = identificacion_comprador.strip().rjust(
                20, '0')
            if codigo_documento_comprador == '99':
                apellido_nombre_comprador = 'VENTA GLOBAL DIARIA'.ljust(30)
            else:
                s = self.strip_accents(invoice.party.name[:30])
                apellido_nombre_comprador = ''.join(
                    x for x in s if x.isalnum()).ljust(30)

            importe_total = Currency.round(invoice.currency,
                abs(invoice.total_amount)).to_eng_string().replace(
                    '.', '').rjust(15, '0')

            # iterar sobre lineas de facturas
            importe_total_lineas_sin_impuesto = Decimal('0')  # se calcula
            percepcion_no_categorizados = Decimal('0')  # se calcula
            importe_operaciones_exentas = Decimal('0')  # 0
            importe_total_percepciones = Decimal('0')  # 0
            importe_total_impuesto_iibb = Decimal('0')  # se calcula
            importe_total_percepciones_municipales = Decimal('0')  # 0
            importe_total_impuestos_internos = Decimal('0')  # 0

            # COMPROBANTES QUE NO CORESPONDE
            if int(tipo_comprobante) not in [19, 20, 21, 22]:
                importe_total_lineas_sin_impuesto = invoice.pyafipws_imp_tot_conc
                importe_operaciones_exentas = invoice.pyafipws_imp_op_ex

            # calculo total de percepciones
            for invoice_tax in invoice.taxes:
                if invoice_tax.tax.group.afip_kind == 'gravado':
                    iva_id = int(invoice_tax.tax.iva_code)
                    alicuotas[iva_id] += 1
                elif invoice_tax.tax.group.afip_kind == 'nacional':
                    importe_total_percepciones += invoice.currency.round(
                        abs(invoice_tax.amount))
                elif invoice_tax.tax.group.afip_kind == 'provincial':
                    importe_total_impuesto_iibb += abs(invoice_tax.amount)
                elif invoice_tax.tax.group.afip_kind == 'interno':
                    importe_total_impuestos_internos += abs(invoice_tax.amount)

            importe_total_lineas_sin_impuesto = Currency.round(
                invoice.currency, importe_total_lineas_sin_impuesto
                ).to_eng_string().replace('.', '').rjust(15, '0')
            percepcion_no_categorizados = Currency.round(invoice.currency,
                percepcion_no_categorizados).to_eng_string().replace('.',
                    '').rjust(15, '0')

            # En caso de que en una misma operación se vendan productos
            # exentos con gravados, la alícuota será la correspondiente a
            # los productos gravados. En este caso el monto correspondiente a
            # la parte exenta se consignará en este campo, y la porción
            # gravada en el campo correspondiente del detalle de alícuotas de
            # IVA.
            importe_operaciones_exentas = Currency.round(invoice.currency,
                importe_operaciones_exentas).to_eng_string().replace('.',
                    '').rjust(15, '0')

            importe_total_percepciones = Currency.round(invoice.currency,
                importe_total_percepciones).to_eng_string().replace('.',
                    '').rjust(15, '0')
            importe_total_impuesto_iibb = Currency.round(invoice.currency,
                importe_total_impuesto_iibb).to_eng_string().replace('.',
                    '').rjust(15, '0')
            importe_total_percepciones_municipales = Currency.round(
                invoice.currency, importe_total_percepciones_municipales
                ).to_eng_string().replace('.', '').rjust(15, '0')
            importe_total_impuestos_internos = Currency.round(invoice.currency,
                importe_total_impuestos_internos).to_eng_string().replace('.',
                    '').rjust(15, '0')
            codigo_moneda = invoice.currency.afip_code or 'PES'
            ctz = '1.00'
            if codigo_moneda != 'PES':
                for afip_tr in invoice.transactions:
                    if afip_tr.pyafipws_result == 'A':
                        request = SimpleXMLElement(unidecode(
                            afip_tr.pyafipws_xml_request))
                        ctz = str(request('Moneda_ctz'))
                        break
            ctz = Currency.round(invoice.currency, Decimal(ctz))
            tipo_de_cambio = str("%.6f" % ctz)
            tipo_de_cambio = tipo_de_cambio.replace('.', '').rjust(10, '0')

            # recorrer alicuotas y saber cuantos tipos de alicuotas hay
            for key, value in alicuotas.items():
                if value != 0:
                    cant_alicuota += 1

            cantidad_alicuotas = str(cant_alicuota)
            if cant_alicuota == 0:
                cantidad_alicuotas = '1'
                # Factura E
                if int(invoice.invoice_type.invoice_type) in [19, 20, 21, 22]:
                    codigo_operacion = 'X'  # Exportaciones del exterior
                # Clase C
                elif int(invoice.invoice_type.invoice_type) in [
                        11, 12, 13, 15, 211, 212, 213]:
                    codigo_operacion = 'N'  # No gravado
                # Operacion exenta
                elif invoice.company.party.iva_condition == 'exento':
                    codigo_operacion = 'E'  # Operaciones exentas
            else:
                # Segun tabla codigo de operaciones
                codigo_operacion = ' '

            otros_atributos = '0'.rjust(15, '0')
            # Opcional para resto de comprobantes. Obligatorio para liquidacion
            # servicios clase A y B
            fecha_venc_pago = '0'.rjust(8, '0')

            campos = [fecha_comprobante, tipo_comprobante, punto_de_venta,
                numero_comprobante, numero_comprobante_hasta,
                codigo_documento_comprador, identificacion_comprador,
                apellido_nombre_comprador, importe_total,
                importe_total_lineas_sin_impuesto, percepcion_no_categorizados,
                importe_operaciones_exentas, importe_total_percepciones,
                importe_total_impuesto_iibb,
                importe_total_percepciones_municipales,
                importe_total_impuestos_internos,
                codigo_moneda, tipo_de_cambio, cantidad_alicuotas,
                codigo_operacion, otros_atributos, fecha_venc_pago]

            separador = self.start.csv_format and _SEPARATOR or ''
            lines += separador.join(campos) + _EOL

        logger.info('Comienza attach comprobante de venta')
        self.exportar.comprobante_ventas = lines.encode('utf-8')
示例#35
0
client = SoapClient(LOCATION,
                    ACTION,
                    namespace="http://dgi.gub.uy",
                    ns="dgi",
                    soap_ns="soapenv",
                    trace=True)

# si se usa el WSDL, se puede consultar client.help("EFACRECEPCIONSOBRE")

# Procedimiento tentativo:
# ========================

# leer los datos del comprobante
# NOTA: se podría usar más SimpleXMLElement para armar el xml pythonicamente

cfe = SimpleXMLElement(open("dgicfe_uy.xml").read())
caratula = cfe("DGICFE:Caratula")

# establecer la fecha actual
setattr(
    caratula, "DGICFE:Fecha",
    datetime.datetime.now().strftime(
        "%Y-%m-%dT%H:%M:%S-03:00"))  #utcnow().strftime("%Y-%m-%dT%H:%M:%S"))

# leer el certificado (PEM) del emisor y agregarlo
cert_lines = open("certificado.crt").readlines()
cert_pem = ''.join([line for line in cert_lines if not line.startswith("---")])
setattr(caratula, "DGICFE:X509Certificate", cert_pem)

# preparar la plantilla para la info de firma con los namespaces padres (CFE)
plantilla = SimpleXMLElement(xmlsec.SIGN_ENV_TMPL)
示例#36
0
    def enviar_dte(self):
        if self.type in (
                'out_invoice', 'out_refund'
        ) and self.env.user.company_id.invoice_line and self.invoice_line_count > self.env.user.company_id.invoice_line:
            raise UserError(u'Ha excedido de %d líneas para ésta factura.' %
                            self.env.user.company_id.invoice_line)
        fmt = "%Y%m%d"
        ####Variables comunes
        wsaa_url = self.company_id.ambiente_produccion == 'T' and "https://wsaahomo.afip.gov.ar/ws/services/LoginCms?wsdl" \
            or "https://wsaa.afip.gov.ar/ws/services/LoginCms?wsdl"
        cert = self.company_id.ruta_cert
        clave = self.company_id.pass_cert
        self.check_path(cert, 'cert')
        self.check_path(clave, 'key')
        companyCuit = self.company_id.cuit.replace("-", '')
        fecha_cbte = self.date_invoice.strftime("%Y%m%d")
        tipo_cbte = int(self.tipo_comprobante.codigo)
        punto_vta = int(self.punto_venta.name)
        if not self.date_invoice:
            raise ValidationError("Ingrese la fecha de la factura")
        moneda_id = "PES"
        moneda_ctz = '1.000'
        imp_tot_conc = 0.0
        partner_id = self.partner_id.commercial_partner_id
        if self.currency_id.name == 'USD':
            moneda_id = "DOL"
            if self.manual_currency_rate:
                moneda_ctz = self.currency_rate_invoice
            else:
                moneda_ctz = self.currency_id._get_actual_currency_rate(
                    self.date_invoice)
        if self.currency_id.name == 'EUR':
            moneda_id = "060"
            if self.manual_currency_rate:
                moneda_ctz = self.currency_rate_invoice
            else:
                moneda_ctz = self.currency_id._get_actual_currency_rate(
                    self.date_invoice)
        imp_total = self.amount_total  ## Importe Total de la factura
        wsaa = WSAA()
        # five hours
        DEFAULT_TTL = 60 * 60 * 5
        tax_map = {
            '10.5': 4,
            '21.0': 5,
            '27.0': 6,
            '0.0': 3
        }  # 4: 10.5%, 5: 21%, 6: 27% (no enviar si es otra alicuota)
        if self.punto_venta.tax_assets:
            lines = self.invoice_line_ids.filtered(
                lambda l: not l.product_id.bfe_check or not l.product_id.
                bfe_ncm)
            if lines:
                raise UserError(
                    'Algunos productos no cuentan con codigo NCM, por favor verificar antes de enviar factura.'
                )
            zona = 1
            # Generar un Ticket de Requerimiento de Acceso (TRA) para WSBFE
            solicitar = True
            session = self.env['afip.session'].search(
                [('xml_tag', '=', 'wsbfe'),
                 ('environment', '=', self.company_id.ambiente_produccion),
                 ('company_id', '=', self.company_id.id)],
                order='id DESC',
                limit=1)
            if session and session.expirationTime:
                expiracion = session.expirationTime
                solicitar = wsaa.Expirado(expiracion)
            if solicitar:
                tra = WSAA().CreateTRA(service="wsbfe", ttl=DEFAULT_TTL)
                # Generar el mensaje firmado (CMS)
                cms = WSAA().SignTRA(tra, cert, clave)
                # Llamar al web service para autenticar
                wsaa.Conectar(None, wsaa_url, '')
                ta = wsaa.LoginCMS(cms)
                if ta:
                    session = self.env['afip.session'].sudo().create({
                        'xml_tag':
                        'wsbfe',
                        'environment':
                        self.company_id.ambiente_produccion,
                        'company_id':
                        self.company_id.id,
                        'sign':
                        wsaa.ObtenerTagXml("sign"),
                        'token':
                        wsaa.ObtenerTagXml("token"),
                        'expirationTime':
                        wsaa.ObtenerTagXml("expirationTime")
                    })
                    self._cr.commit()
            url = self.company_id.ambiente_produccion == 'T' and "https://wswhomo.afip.gov.ar/" \
                      or "https://servicios1.afip.gov.ar/"
            wsdl = "%swsbfev1/service.asmx?WSDL" % url
            wsbfe = WSBFEv1()
            ok = wsbfe.Conectar(cache=None, wsdl=wsdl)
            if not ok:
                raise ValidationError(
                    "Error conexión con libreria. WSBFEV1: %s" %
                    wsbfe.Excepcion)
            wsbfe.LanzarExcepciones = True

            wsbfe.Cuit = companyCuit
            token = session.token
            sign = session.sign
            wsbfe.Token = token
            wsbfe.Sign = sign
            try:
                cbte_nro = wsbfe.GetLastCMP(
                    tipo_cbte, punto_vta) is None and 1 or wsbfe.GetLastCMP(
                        tipo_cbte, punto_vta) + 1
                cbt_id = wsbfe.GetLastID() and wsbfe.GetLastID() + 1 or 1
            except Exception as e:
                raise AccessError("Error de AFIP:" + str(e))
            if self.company_id.use_afip_rate:
                moneda_ctz = moneda_id != 'PES' and wsbfe.GetParamCtz(
                    moneda_id) or '1.000'
                self.env['res.currency.rate'].create({
                    'name':
                    datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                    'rate':
                    float(moneda_ctz),
                    'currency_id':
                    self.currency_id.id
                })
            self.currency_rate = moneda_ctz
            ## Cliente
            tipo_doc = int(partner_id.documento_id.codigo)
            nro_doc = partner_id.cuit.replace("-", '')
            imp_neto = str("%.2f" % abs(self.amount_untaxed))
            imp_iva = str("%.2f" % abs(self.amount_iva))
            imp_tot_conc = str("%.2f" % abs(self.no_gravado))
            impto_liq_rni = 0.0
            imp_op_ex = str("%.2f" % abs(self.amount_excempt))
            imp_perc = 0.0
            imp_iibb = 0.0
            imp_perc_mun = 0.0
            imp_internos = str("%.2f" % abs(self.amount_other_tax))
            fecha_venc_pago = None
            if self.tipo_comprobante.comprobante_credito and not self.type == 'out_refund':
                date_due = self.date_due and self.date_due or self.date_invoice
            if date_due:
                fecha_venc_pago = date_due.strftime("%Y%m%d")
            wsbfe.CrearFactura(tipo_doc, nro_doc, zona, tipo_cbte, punto_vta,
                               cbte_nro, fecha_cbte, imp_total, imp_neto,
                               imp_iva, imp_tot_conc, impto_liq_rni, imp_op_ex,
                               imp_perc, imp_iibb, imp_perc_mun, imp_internos,
                               moneda_id, moneda_ctz, fecha_venc_pago)

            for line in self.invoice_line_ids:
                codigo = line.product_id.bfe_ncm.name
                sec = ""
                ds = line.name
                qty = line.quantity
                umed = 1
                precio = line.price_unit
                importe = line.price_subtotal
                # calculamos bonificacion haciendo teorico menos importe
                bonif = line.discount and (precio * qty - importe) or None
                iva_id = 2
                imp_iva = 0.0
                taxes = line.invoice_line_tax_ids.filtered(lambda t: t.is_iva)
                if taxes:
                    if tax_map.get(str(taxes[0].amount)):
                        iva_id = tax_map[str(taxes[0].amount)]
                        price_unit = line.price_unit * (
                            1 - (line.discount or 0.0) / 100.0)
                        taxesv = line.invoice_line_tax_ids.compute_all(
                            price_unit, self.currency_id, line.quantity,
                            line.product_id, partner_id)['taxes']
                        for t in taxesv:
                            if t['id'] == taxes[0].id:
                                imp_iva = t['amount']
                wsbfe.AgregarItem(codigo, sec, ds, qty, umed, precio, bonif,
                                  iva_id, importe + imp_iva)
            if self.tipo_comprobante.comprobante_credito and self.company_id.cbu and self.type != 'out_refund':
                wsbfe.AgregarOpcional(2101, self.company_id.cbu)
            if self.tipo_comprobante.comprobante_credito and self.company_id.cbu:
                oc = self.client_purchase_ref
                if not oc:
                    oc = self.refund_invoice_id and self.refund_invoice_id.client_purchase_ref and self.refund_invoice_id.client_purchase_ref or self.refund_invoice_id.name
                if not oc:
                    oc = 'N/A'
                wsbfe.AgregarOpcional(23, oc)
            if self.tipo_comprobante.comprobante_credito and self.type == 'out_refund':
                wsbfe.AgregarOpcional(22, self.anulacion and 'S' or 'N')
            wsbfe.Authorize(cbt_id)
            if not wsbfe.CAE:
                raise ValidationError("%s .%s" % (wsbfe.ErrMsg, wsbfe.Obs))
            else:
                # datos devueltos por AFIP:
                self.no_cae = wsbfe.CAE
                self._cr.commit()
                vence = wsbfe.Vencimiento
                self.vence_date = '%s-%s-%s' % (vence[6:10], vence[3:5],
                                                vence[0:2])
                path1 = "/tmp/xmlrequest.xml"
                open(path1, "wb").write(wsbfe.XmlRequest)
                self.requestXml = base64.encodestring(
                    bytes(open(path1, 'r').read(), 'utf8'))
                self.requestXml_fname = 'peticion%s.xml' % wsbfe.CAE
                path2 = "/tmp/xmlresponse.xml"
                responseFile = open(path2, "wb").write(wsbfe.XmlResponse)
                self.num_comprobante = str(int(cbte_nro))
                self.responseXml = base64.encodestring(
                    bytes(open(path2, 'r').read(), 'utf8'))
                self.responseXml_fname = 'respuesta%s.xml' % wsbfe.CAE
                digit = self.company_id.cuit.split('-')[1]
                barcode_str = '%s%s%s%s%s%s' % (companyCuit, str(
                    tipo_cbte).zfill(2), punto_vta, wsbfe.CAE, vence, digit)
                self.cod_barra = barcode_str
                self.message_post(
                    body=("Factura Aceptada por la AFIP con No: %s" %
                          str(cbte_nro)))
                if wsbfe.Resultado == 'A':
                    self.state_dte = 'accepted'
                    self._cr.commit()
                elif wsbfe.Resultado == 'R':
                    self.state_dte = 'rejected'
        else:
            if self.tipo_comprobante.codigo in ['019', '020', '021']:
                if not partner_id.country_id:
                    raise ValidationError("Debe asociar un país al cliente")
                aIva = float_is_zero(self.amount_iva,
                                     self.currency_id.rounding)
                aOther = float_is_zero(self.amount_other_tax,
                                       self.currency_id.rounding)
                if not aIva or not aOther:
                    raise ValidationError(
                        "La factura de exportacion es exenta de impuestos. Favor eliminar impuestos de las lineas de factura"
                    )
                #Generar un Ticket de Requerimiento de Acceso (TRA) para WSFEX
                solicitar = True
                session = self.env['afip.session'].search(
                    [('xml_tag', '=', 'wsfex'),
                     ('environment', '=', self.company_id.ambiente_produccion),
                     ('company_id', '=', self.company_id.id)],
                    order='id DESC',
                    limit=1)
                if session and session.expirationTime:
                    expiracion = session.expirationTime
                    solicitar = wsaa.Expirado(expiracion)
                if solicitar:
                    tra = WSAA().CreateTRA(service="wsfex", ttl=DEFAULT_TTL)
                    # Generar el mensaje firmado (CMS)
                    cms = WSAA().SignTRA(tra, cert, clave)
                    # Llamar al web service para autenticar
                    wsaa.Conectar(None, wsaa_url, '')
                    ta = wsaa.LoginCMS(cms)
                    if ta:
                        session = self.env['afip.session'].sudo().create({
                            'xml_tag':
                            'wsfex',
                            'environment':
                            self.company_id.ambiente_produccion,
                            'company_id':
                            self.company_id.id,
                            'sign':
                            wsaa.ObtenerTagXml("sign"),
                            'token':
                            wsaa.ObtenerTagXml("token"),
                            'expirationTime':
                            wsaa.ObtenerTagXml("expirationTime")
                        })
                        self._cr.commit()
                # autenticarse frente a AFIP (obtención de ticket de acceso):
                # conectar al webservice de negocio
                url = self.company_id.ambiente_produccion == 'T' and "https://wswhomo.afip.gov.ar/" \
                      or "https://servicios1.afip.gov.ar/"
                wsdl = "%swsfexv1/service.asmx?WSDL" % url
                wsfex = WSFEX()
                ok = wsfex.Conectar(wsdl)
                if not ok:
                    raise ValidationError(
                        "Error conexión con libreria. WSFEX: %s" %
                        wsfex.Excepcion)
                wsfex.LanzarExcepciones = True
                #Setear tocken y sing de autorización (pasos previos)
                #CUIT del emisor (debe estar registrado en la AFIP)
                wsfex.Cuit = companyCuit
                token = session.token
                sign = session.sign
                wsfex.Token = token
                wsfex.Sign = sign
                try:
                    cbte_nro = wsfex.GetLastCMP(
                        tipo_cbte,
                        punto_vta) is None and 1 or wsfex.GetLastCMP(
                            tipo_cbte, punto_vta) + 1
                    cbt_id = wsfex.GetLastID() and wsfex.GetLastID() + 1 or 1
                except Exception as e:
                    raise AccessError("Error de AFIP:" + str(e))
                ## Tipo de Exportación
                tipo_expo = self.tipo_expo or 1
                if self.company_id.use_afip_rate:
                    moneda_ctz = moneda_id != 'PES' and wsfex.GetParamCtz(
                        moneda_id) or '1.000'
                    self.env['res.currency.rate'].create({
                        'name':
                        datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                        'rate':
                        float(moneda_ctz),
                        'currency_id':
                        self.currency_id.id
                    })
                self.currency_rate = moneda_ctz
                ## Permiso
                permiso_existente = self.permiso_existente
                if self.tipo_comprobante.codigo in ['020', '021']:
                    permiso_existente = ''
                    tipo_expo = '1'
                ## Pais Destino
                if not partner_id.country_id.cod_nacionalidad:
                    raise ValidationError(
                        "Ingrese el código de la nacionalidad")
                dst_cmp = partner_id.country_id.cod_nacionalidad
                ## Cliente
                cliente = partner_id.name
                ## Cuit del pais del cliente
                if partner_id.state_id == self.env.ref(
                        'base.state_ar_v', raise_if_not_found=False):
                    cuit_pais_cliente = partner_id.cuit.replace('-', '')
                else:
                    if not partner_id.country_id.cuit_pais:
                        raise ValidationError("Ingrese el cuit del pais")
                    cuit_pais_cliente = partner_id.country_id.cuit_pais.replace(
                        '-', '')
                ## Direccion Cliente
                domicilio_cliente = partner_id.street
                ## id_impositivo
                id_impositivo = partner_id.cuit
                ## obs_comerciales
                obs_generales = self.comment and self.comment or ""
                forma_pago = self.payment_term_id and self.payment_term_id.name or ""
                obs_comerciales = forma_pago
                ## incoterms
                incoterms = self.incoterms and self.incoterms or "FOB"
                ## Idioma del Comprobante
                idioma_cbte = 1
                ##Creo una factura (internamente, no se llama al WebService):
                wsfex.CrearFactura(tipo_cbte, punto_vta, cbte_nro, fecha_cbte,
                                   imp_total, tipo_expo, permiso_existente,
                                   dst_cmp, cliente, cuit_pais_cliente,
                                   domicilio_cliente, id_impositivo, moneda_id,
                                   moneda_ctz, obs_comerciales, obs_generales,
                                   forma_pago, incoterms, idioma_cbte)
                #Agregar items
                for line in self.invoice_line_ids:
                    umed = 1  #Ver tabla de parámetros (unidades de medida)
                    #lo agrego a la factura (internamente, no se llama al WebService):
                    discount = line.quantity * line.price_unit - line.price_subtotal
                    if discount > 0.00:
                        wsfex.AgregarItem(line.product_id.default_code, line.product_id.name, line.quantity, \
                                          umed, line.price_unit, line.price_subtotal,
                                          discount)
                    else:
                        wsfex.AgregarItem(line.product_id.default_code, line.product_id.name, line.quantity,\
                            umed, line.price_unit, line.price_subtotal)
                #Agrego un permiso (ver manual para el desarrollador)
                if permiso_existente == "S":
                    permiso_id = "99999AAXX999999A"
                    dst = 225  #país destino de la mercaderia
                    wsfex.AgregarPermiso(permiso_id, dst)
                #Agrego un comprobante asociado (ver manual para el desarrollador)
                if tipo_cbte != 19 and self.refund_invoice_id:
                    tipo_cbte_asoc = int(
                        self.refund_invoice_id.tipo_comprobante.codigo
                    )  # tipo de comprobante asociado
                    punto_vta_asoc = int(self.refund_invoice_id.punto_venta.
                                         name)  # punto de venta
                    cbte_nro_asoc = int(self.refund_invoice_id.num_comprobante
                                        )  # nro de comprobante asociado
                    wsfex.AgregarCmpAsoc(tipo_cbte_asoc, punto_vta_asoc,
                                         cbte_nro_asoc)
                wsfex.Authorize(cbt_id)
                if not wsfex.CAE:
                    raise ValidationError("%s .%s" % (wsfex.ErrMsg, wsfex.Obs))
                else:
                    # datos devueltos por AFIP:
                    self.no_cae = wsfex.CAE
                    self._cr.commit()
                    vence = wsfex.Vencimiento
                    self.vence_date = '%s-%s-%s' % (vence[6:10], vence[3:5],
                                                    vence[0:2])
                    path1 = "/tmp/xmlrequest.xml"
                    open(path1, "wb").write(wsfex.XmlRequest)
                    self.requestXml = base64.encodestring(
                        bytes(open(path1, 'r').read(), 'utf8')).decode("utf-8")
                    self.requestXml_fname = 'peticion%s.xml' % wsfex.CAE
                    path2 = "/tmp/xmlresponse.xml"
                    responseFile = open(path2, "wb").write(wsfex.XmlResponse)
                    self.num_comprobante = str(int(cbte_nro))
                    self.responseXml = base64.encodestring(
                        bytes(open(path2, 'r').read(), 'utf8')).decode("utf-8")
                    self.responseXml_fname = 'respuesta%s.xml' % wsfex.CAE
                    digit = self.company_id.cuit.split('-')[1]
                    ve = '%s%s%s' % (vence[6:10], vence[3:5], vence[0:2])
                    barcode_str = '%s%s%s%s%s%s' % (companyCuit, str(
                        tipo_cbte).zfill(2), punto_vta, wsfex.CAE, ve, digit)
                    self.cod_barra = barcode_str
                    #imgPath = '/tmp/barcode.png'
                    #PyI25().GenerarImagen(barcode_str, imgPath)
                    #imgFile = open(imgPath, "rb")
                    #self.barcode_img = imgFile.read().encode("base64")
                    self.message_post(body=(
                        "Factura de Exportación Aceptada por la AFIP con No: %s"
                        % str(cbte_nro)))
                    if wsfex.Resultado == 'A':
                        self.state_dte = 'accepted'
                        self._cr.commit()
                    elif wsfex.Resultado != 'A':
                        self.state_dte = 'rejected'
            else:  #Factura Electrónica
                # instanciar el componente para factura electrónica mercado interno
                wsfev1 = WSFEv1()
                wsfev1.LanzarExcepciones = True
                # datos de conexión (cambiar URL para producción)
                cache = None
                url = self.company_id.ambiente_produccion == 'T' and "https://wswhomo.afip.gov.ar/" \
                      or "https://servicios1.afip.gov.ar/"
                wsdl = "%swsfev1/service.asmx?WSDL" % url
                # Iniciamos la conexion
                proxy = ""
                wrapper = ""  # "pycurl" para usar proxy avanzado / propietarios
                cacert = None  # "afip_ca_info.crt" para verificar canal seguro
                # conectar al webservice de negocio
                ok = wsfev1.Conectar(cache, wsdl, proxy, wrapper, cacert)
                if not ok:
                    raise ValidationError(
                        "Error conexión con libreria. WSFEv1: %s" %
                        WSAA.Excepcion)
                solicitar = True
                session = self.env['afip.session'].search(
                    [('xml_tag', '=', 'wsfe'),
                     ('environment', '=', self.company_id.ambiente_produccion),
                     ('company_id', '=', self.company_id.id)],
                    order='id DESC',
                    limit=1)
                if session and session.expirationTime:
                    expiracion = session.expirationTime
                    solicitar = wsaa.Expirado(expiracion)
                if solicitar:
                    # autenticarse frente a AFIP (obtención de ticket de acceso):
                    ta = WSAA().Autenticar("wsfe",
                                           cert,
                                           clave,
                                           wsaa_url,
                                           debug=True)
                    if not ta:
                        raise ValidationError(
                            "Error conexión con libreria. Error WSAA: %s" %
                            WSAA.Excepcion)
                    # establecer credenciales (token y sign) y cuit emisor:
                    wsfev1.SetTicketAcceso(ta)
                    if ta:
                        wsfev1.xml = SimpleXMLElement(ta)
                        session = self.env['afip.session'].sudo().create({
                            'xml_tag':
                            'wsfe',
                            'environment':
                            self.company_id.ambiente_produccion,
                            'company_id':
                            self.company_id.id,
                            'sign':
                            wsfev1.ObtenerTagXml("sign"),
                            'token':
                            wsfev1.ObtenerTagXml("token"),
                            'expirationTime':
                            wsfev1.ObtenerTagXml("expirationTime")
                        })
                        self._cr.commit()
                token = session.token
                sign = session.sign
                wsfev1.Token = token
                wsfev1.Sign = sign
                wsfev1.Cuit = companyCuit
                try:
                    cbte_nro = int(
                        wsfev1.CompUltimoAutorizado(tipo_cbte, punto_vta) or 0)
                except Exception as e:
                    raise AccessError("Error de AFIP:" + str(e))
                if not partner_id.cuit:
                    raise ValidationError("El partner no posee CUIT asociado")
                concepto = self.get_concept_type(self.invoice_line_ids)
                tipo_doc = int(partner_id.documento_id.codigo)
                nro_doc = partner_id.cuit.replace("-", '')
                cbt_desde = cbte_nro + 1  # usar proximo numero de comprobante
                cbt_hasta = cbte_nro + 1  # desde y hasta distintos solo lotes factura B
                imp_tot_conc = str("%.2f" % abs(
                    self.no_gravado))  # importe total conceptos no gravado?
                imp_neto = str("%.2f" % abs(self.neto_gravado)
                               )  # importe neto gravado (todas las alicuotas)
                imp_iva = str(
                    "%.2f" %
                    abs(self.amount_iva))  # importe total iva liquidado (idem)
                imp_trib = self.amount_other_tax + self.amount_perception  # importe total otros conceptos?
                imp_trib = str("%.2f" % abs(imp_trib))
                imp_op_ex = str("%.2f" % abs(
                    self.amount_excempt))  # importe total operaciones exentas
                date_due = self.date_due or ''
                if date_due < self.date_invoice:
                    date_due = self.date_invoice
                if date_due:
                    if not self.tipo_comprobante.comprobante_credito:
                        fecha_venc_pago = concepto != 1 and date_due.strftime(
                            "%Y%m%d") or ''
                    else:
                        fecha_venc_pago = date_due.strftime("%Y%m%d")
                else:
                    fecha_venc_pago = ''
                if concepto != 1 and not fecha_venc_pago and not self.tipo_comprobante.comprobante_credito:
                    fecha_venc_pago = fecha_cbte
                if not fecha_venc_pago and self.tipo_comprobante.comprobante_credito:
                    fecha_venc_pago = fecha_cbte
                if self.tipo_comprobante.comprobante_credito and self.type == 'out_refund':
                    fecha_venc_pago = ''
                # Fechas del período del servicio facturado (solo si concepto != 1)?
                fecha_serv_desde = concepto != 1 and fecha_cbte or ''
                fecha_serv_hasta = concepto != 1 and fecha_venc_pago or ''
                if concepto != 1 and not fecha_serv_hasta:
                    fecha_serv_hasta = fecha_cbte
                # inicializar la estructura de factura (interna)
                wsfev1.CrearFactura(concepto, tipo_doc, nro_doc, tipo_cbte,
                                    punto_vta, cbt_desde, cbt_hasta,
                                    str(imp_total), str(imp_tot_conc),
                                    str(imp_neto), str(imp_iva), str(imp_trib),
                                    str(imp_op_ex), fecha_cbte,
                                    fecha_venc_pago, fecha_serv_desde,
                                    fecha_serv_hasta, moneda_id, moneda_ctz)
                # agregar comprobantes asociados (solo para Notas de Débito y Cŕedito)
                if tipo_cbte not in (1, 6, 11) and self.refund_invoice_id:
                    tipo = int(self.refund_invoice_id.tipo_comprobante.codigo
                               )  # tipo de comprobante asociado
                    pto_vta = int(self.refund_invoice_id.punto_venta.name
                                  )  # punto de venta
                    nro = int(self.refund_invoice_id.num_comprobante
                              )  # nro de comprobante asociado
                    cuit = self.refund_invoice_id.company_id.cuit.replace(
                        "-", '')
                    fecha_cbte = self.refund_invoice_id.date_invoice.strftime(
                        "%Y%m%d")
                    wsfev1.AgregarCmpAsoc(tipo, pto_vta, nro, cuit, fecha_cbte)
                for tax in self.tax_line_ids:
                    t = tax.tax_id
                    base_imp = tax.base
                    if tax.base:
                        importe = round(
                            t._compute_amount(tax.base, tax.base, 1), 2)
                    else:
                        importe = round(tax.amount, 2)
                    if t.is_iva:
                        # agregar subtotales por tasa de iva (repetir por cada alicuota):
                        if tax_map.get(str(t.amount)):
                            taxId = tax_map[str(t.amount)]
                            print('%s: base(%s), imp(%s)' %
                                  (tax.name, tax.base, importe))
                            wsfev1.AgregarIva(taxId, base_imp, importe)
                    else:
                        # agregar otros impuestos (repetir por cada tributo diferente)
                        taxId = int(
                            t.tipo_tributo)  # tipo de tributo (ver tabla)
                        desc = tax.name  # descripción del tributo
                        alic = t.amount  # alicuota iva
                        wsfev1.AgregarTributo(taxId, desc, base_imp, alic,
                                              importe)
                # llamar al webservice de AFIP para autorizar la factura y obtener CAE:
                if self.tipo_comprobante.comprobante_credito and self.company_id.cbu and self.type != 'out_refund':
                    wsfev1.AgregarOpcional(2101, self.company_id.cbu)
                if self.tipo_comprobante.comprobante_credito and self.company_id.cbu:
                    oc = self.client_purchase_ref
                    if not oc:
                        oc = self.refund_invoice_id and self.refund_invoice_id.client_purchase_ref and self.refund_invoice_id.client_purchase_ref or self.refund_invoice_id.name
                    if not oc:
                        oc = 'N/A'
                    wsfev1.AgregarOpcional(23, oc)
                if self.tipo_comprobante.comprobante_credito and self.company_id.cbu and self.type == 'out_refund':
                    wsfev1.AgregarOpcional(22, 'N')
                wsfev1.CAESolicitar()
                if not wsfev1.CAE:
                    raise ValidationError("%s .%s" %
                                          (wsfev1.ErrMsg, wsfev1.Obs))
                else:
                    # datos devueltos por AFIP:
                    self.no_cae = wsfev1.CAE
                    self._cr.commit()
                    vence = wsfev1.Vencimiento
                    self.vence_date = '%s-%s-%s' % (vence[0:4], vence[4:6],
                                                    vence[6:8])
                    path1 = "/tmp/xmlrequest.xml"
                    open(path1, "wb").write(wsfev1.XmlRequest)
                    self.requestXml = base64.encodestring(
                        bytes(open(path1, 'r').read(), 'utf8'))
                    self.requestXml_fname = 'peticion%s.xml' % wsfev1.CAE
                    path2 = "/tmp/xmlresponse.xml"
                    responseFile = open(path2, "wb").write(wsfev1.XmlResponse)
                    self.num_comprobante = str(cbt_desde)
                    self.responseXml = base64.encodestring(
                        bytes(open(path2, 'r').read(), 'utf8'))
                    self.responseXml_fname = 'respuesta%s.xml' % wsfev1.CAE
                    digit = self.company_id.cuit.split('-')[1]
                    barcode_str = '%s%s%s%s%s%s' % (
                        companyCuit, str(tipo_cbte).zfill(2), punto_vta,
                        wsfev1.CAE, vence, digit)
                    self.cod_barra = barcode_str
                    self.message_post(
                        body=("Factura Aceptada por la AFIP con No: %s" %
                              str(cbt_desde)))
                    if wsfev1.Resultado == 'A':
                        self.state_dte = 'accepted'
                        self._cr.commit()
                    elif wsfev1.Resultado == 'R':
                        self.state_dte = 'rejected'
示例#37
0
# Instancio el cliente para consumir el webservice
client = SoapClient(LOCATION, ACTION,
                    namespace="http://dgi.gub.uy", 
                    ns="dgi", 
                    soap_ns="soapenv", trace=True)

# si se usa el WSDL, se puede consultar client.help("EFACRECEPCIONSOBRE")

# Procedimiento tentativo:
# ========================

# leer los datos del comprobante
# NOTA: se podría usar más SimpleXMLElement para armar el xml pythonicamente

cfe = SimpleXMLElement(open("dgicfe_uy.xml").read())
caratula = cfe("DGICFE:Caratula")

# establecer la fecha actual
setattr(caratula, "DGICFE:Fecha", 
                  datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S-03:00"))#utcnow().strftime("%Y-%m-%dT%H:%M:%S"))

# leer el certificado (PEM) del emisor y agregarlo 
cert_lines = open("certificado.crt").readlines()
cert_pem =  ''.join([line for line in cert_lines
                          if not line.startswith("---")])
setattr(caratula, "DGICFE:X509Certificate", cert_pem)

# preparar la plantilla para la info de firma con los namespaces padres (CFE)
plantilla = SimpleXMLElement(xmlsec.SIGN_ENV_TMPL)
plantilla["xmlns:DGICFE"] = plantilla["xmlns:ns0"] = "http://cfe.dgi.gub.uy"
示例#38
0
xmlsec.lxml = None                  # deshabilitar lxml y usar c14n.py

# Por el momento se utilizan llamadas crudas (RAW) y no se parsea el WSDL
##client = SoapClient(wsdl=wsdl, cache="cache")

# Instancio el cliente para consumir el webservice
client = SoapClient(LOCATION, ACTION,
                    namespace="DGI_Modernizacion_Consolidado", 
                    ns="dgi", 
                    soap_ns="soapenv", trace=True)

# si se usa el WSDL, se puede consultar client.help("EFACRECEPCIONSOBRE")

# construir los parámetros de la llamada al webservice (requerimiento):
param = SimpleXMLElement(
    """<dgi:WS_PersonaGetActEmpresarial.Execute xmlns:dgi="DGI_Modernizacion_Consolidado" />""", 
    namespace="DGI_Modernizacion_Consolidado", prefix="dgi")
rut = param.add_child("Rut", "210475730011", ns=True)

# agregar seguridad WSSE (mensaje firmado digitalmente para autenticacion)
#     usar el certificado unico asociado al RUT emisor emitidos por la 
#     Administración Nacional de Correos (CA: autoridad certificadora actual)

plugin = BinaryTokenSignature(certificate="certificado.crt",
                              private_key="private.key", 
                              password=None,
                              cacert="CorreoUruguayoCA.crt",
                              )
client.plugins += [plugin]

# llamar al método remoto
示例#39
0
import xml.dom.minidom
from pysimplesoap.client import SoapClient, SimpleXMLElement
from pysimplesoap.wsse import BinaryTokenSignature
from pysimplesoap import xmlsec


fechacfe = lambda *x: datetime.datetime.now().strftime("%Y-%m-%dT%H:%M:%S-03:00")

LOCATION = "https://efactura.dgi.gub.uy:6443/ePrueba/ws_eprueba?wsdl"
ACTION = "http://dgi.gub.uyaction/"


with open("documento.xml") as f:
    dataCFE = f.read()

cfe = SimpleXMLElement(dataCFE)

caratula = cfe("DGICFE:Caratula")
setattr(caratula, "DGICFE:Fecha", fechacfe())


# leer el certificado (PEM) del emisor y agregarlo
cert_lines = open("certificado.crt").readlines()
cert_fmt = [line for line in cert_lines if not line.startswith("---")]
cert_pem =  ''.join(cert_fmt)
setattr(caratula, "DGICFE:X509Certificate", cert_pem)


cfeXML = cfe("ns0:CFE")

# preparar la plantilla para la info de firma con los namespaces padres (CFE)