Join the social network of Tech Nerds, increase skill rank, get work, manage projects...
 
  • "How to validate address of customer in Ava Tax in openerp-7 (Odoo) " ?

    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 333
    Comment on it

    It is answer to the questions like
        a- how to verify address of partner in openerp
        b- how to correct address entered by user

    We need to verify and valid address in several cases like for - shipping address. 
    Here I am going to tell you how to verify your address with Ava Tax (https://development.avalara.net/). It is a short integration.
    Follow these simple steps:-

    1. for this you have to install a python package "suds" -
        can use command - pip install suds

    2. then import suds into your code -
          import suds

    3. then get instance of client -
          client = suds.client.Client(wsdl)

    4. put this wsdl address into your code -
          wsdl = "https://avatax.avalara.net/%s/%ssvc.wsdl"

    5. now create a usps id -
          go to address - **http://avatax.avalara.com/services**     register your self . You will get USPS user id. put that into variable usps_id into your code
          **usps_id = "269SHIVACXXXX"** // example

    6. now you can use "VerifyAddress" method of client class , to validate and correct address .
          Here is sample code =>

    import suds
    import socket
    import urllib2
    import string
    import os
    import datetime
    import base64
    
    from tools.translate import _
    from osv import osv
    
    class AvaTaxService:
    
        def enable_log(self):
            import logging, tempfile
            logger = logging.getLogger('suds.client')
            logger.setLevel(logging.DEBUG)
            handler = logging.FileHandler(os.path.join(tempfile.gettempdir(), "soap-messages.log"))
            logger.propagate = False
            formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
            handler.setFormatter(formatter)
            logger.addHandler(handler)
    
        def __init__(self, username, password, url, timeout, enable_log=False):
            self.username = username    #This is the company's Development/Production Account number
            self.password = password #Put in the License Key received from AvaTax
            self.url = url
            self.timeout = timeout
            enable_log and self.enable_log()
    
        def create_tax_service(self):
            self.taxSvc = self.service('tax')
            return self
    
        def create_address_service(self):
            self.addressSvc = self.service('address')
            return self
    
        def create_account_service(self):
            self.accountSvc = self.service('account')
            return self
    
    
        def service(self, name):
            nameCap = string.capitalize(name) # So this will be 'Tax' or 'Address'
            # The Python SUDS library can fetch the WSDL down from the server
            # or use a local file URL. We'll use a local file URL.
    #        wsdl_url = 'file:///' + os.getcwd().replace('\\', '/') + '/%ssvc.wsdl.xml' % name
            # If you want to fetch the WSDL from the server, use this instead:
            wsdl_url = 'https://avatax.avalara.net/%s/%ssvc.wsdl' % (nameCap, nameCap)
    
            try:
                 svc = suds.client.Client(url=wsdl_url)
            except urllib2.URLError, details:
                raise osv.except_osv(_('Avatax: Server Failed to Response'), _(details))
            else:
                svc.set_options(service='%sSvc' % nameCap)
                svc.set_options(port='%sSvcSoap' % nameCap)
                svc.set_options(location='%s/%s/%sSvc.asmx' % (self.url, nameCap, nameCap))
                svc.set_options(wsse=self.my_security(self.username, self.password))
                svc.set_options(soapheaders=self.my_profile())
                svc.set_options(timeout=self.timeout)
                return svc
    
        def my_security(self, username, password):
            """Using username and password as key to verify user account to access avalara API's"""
            token = suds.wsse.UsernameToken(username, password)
    
            token.setnonce()
    
            token.setcreated()
            security = suds.wsse.Security()
            security.tokens.append(token)
            return security
    
        def my_profile(self):
    
            # Set elements adapter defaults
            ADAPTER = 'Pragmatic'
    
            # Profile Client.
            CLIENT = 'Pragmatic'
    
            #Build the Profile element
            profileNameSpace = ('ns1', 'http://avatax.avalara.com/services')
            profile = suds.sax.element.Element('Profile', ns=profileNameSpace)
            profile.append(suds.sax.element.Element('Client', ns=profileNameSpace).setText(CLIENT))
            profile.append(suds.sax.element.Element('Adapter', ns=profileNameSpace).setText(ADAPTER))
            hostname = socket.gethostname()
            profile.append(suds.sax.element.Element('Machine', ns=profileNameSpace).setText(hostname))
            return profile
    
        def get_result(self, svc, operation, request):
            try:
                result = operation(request)
            except suds.WebFault, e:
                raise osv.except_osv(_('Avatax: Error'), _(e.fault.faultstring))
            except urllib2.HTTPError, e:
                raise osv.except_osv(_('Avatax: Server Failed to Response'), _(e.code))
            except urllib2.URLError, details:
                # We could also print the SOAP request here:
                raise osv.except_osv(_('Failed to reach the server'), _(details.reason))
            else:
                if (result.ResultCode != 'Success'):
                    for w_message in result.Messages.Message:
                        if (w_message._Name == 'AddressRangeError' or  w_message._Name == 'AddressUnknownStreetError' or w_message._Name == 'AddressNotGeocodedError' or w_message._Name == 'NonDeliverableAddressError' ):
                            raise osv.except_osv(_('Avatax: Warning \n Avatax could not validate the street address.'), _('Avatax will make an attempt to compute taxes based on the zip code if not corrected.'))
                    raise osv.except_osv(('Avatax: Error'), _(AvaTaxError(result.ResultCode, result.Messages)))
                else:
                    return result
    
    
        def ping(self):
            return self.get_result(self.taxSvc, self.taxSvc.service.Ping, '')
    
        def is_authorized(self):
            return self.get_result(self.taxSvc, self.taxSvc.service.IsAuthorized, 'GetTax,PostTax')
    
        def validate_address(self, baseaddress, textcase='Default'):
            request = self.addressSvc.factory.create('ValidateRequest')
            textCase = self.addressSvc.factory.create('TextCase')
            request.TextCase = textcase
            request.Coordinates = True
            request.Taxability = False
            request.Date = '2013-08-09'
            request.Address = baseaddress
    
            result = self.get_result(self.addressSvc, self.addressSvc.service.Validate, request)
            return result
    
        def get_tax(self, company_code, doc_date, doc_type, partner_code, doc_code, origin, destination,
                   received_lines, exemption_no=None, customer_usage_type=None, salesman_code=None, commit=False, invoice_date=None, reference_code=None, 
                   location_code=None, currency_code='USD', vat_id=None):
            """ Create tax request and get tax amount by customer address
                @currency_code : 'USD' is the default currency code for avalara, if user not specify in the own company
                @request.DetailLevel = 'Document': Document (GetTaxResult) level details; TaxLines will not be returned.
                @request.DetailLevel = 'Diagnostic': In addition to Tax level details, indicates that the server should 
                return information about how the tax was calculated. Intended for use only while the SDK is in a development environment.
            """
            lineslist = []
            request = self.taxSvc.factory.create('GetTaxRequest')
            request.Commit = commit
            request.DetailLevel = 'Diagnostic'
    #        request.DetailLevel = 'Document'
            request.Discount = 0.0
            request.ServiceMode = 'Automatic'   ##service mode = Automatic/Local/Remote
            request.PaymentDate = doc_date
            request.ExchangeRate = 45
            request.ExchangeRateEffDate = '2011-07-07'
            request.HashCode = 0
            request.LocationCode = location_code
            request.ReferenceCode = reference_code
            if invoice_date:
                taxoverride = self.taxSvc.factory.create('TaxOverride')
                taxoverride.TaxOverrideType = 'TaxDate'
                taxoverride.TaxDate = invoice_date
                taxoverride.TaxAmount = 0
                taxoverride.Reason = 'Return Items'
                request.TaxOverride = taxoverride
    
            request.CompanyCode = company_code
            request.DocDate = doc_date
            request.DocType = doc_type
            request.DocCode = doc_code
            request.CustomerCode = partner_code
            request.ExemptionNo = exemption_no
            request.CustomerUsageType = customer_usage_type
            request.SalespersonCode = salesman_code
            request.CurrencyCode = currency_code
            request.BusinessIdentificationNo = vat_id
    
            addresses = self.taxSvc.factory.create('ArrayOfBaseAddress')
            addresses.BaseAddress = [origin, destination]
            request.Addresses = addresses
            request.OriginCode = '0' # Referencing an address above
            request.DestinationCode = '1' # Referencing an address above
            for line in range(0, len(received_lines)):
                line1 = self.taxSvc.factory.create('Line')
                line1.Qty = received_lines[line].get('qty', 1)
                line1.Discounted = False
                line1.No = '%d' %line
                line1.ItemCode = received_lines[line].get('itemcode', None)
                line1.Description = received_lines[line].get('description', None)
                line1.Amount = received_lines[line].get('amount', 0.0)
                line1.TaxCode = received_lines[line].get('tax_code', None)
                lineslist.append(line1)
            # So now we build request.Lines
            lines = self.taxSvc.factory.create('ArrayOfLine')
            lines.Line = lineslist
            request.Lines = lines
            # And we're ready to make the call
            result = self.get_result(self.taxSvc, self.taxSvc.service.GetTax, request)
            return result
    
        def get_tax_history(self, company_code, doc_code, doc_type):
            request = self.taxSvc.factory.create('GetTaxHistoryRequest')
            request.DetailLevel = 'Document'
            request.CompanyCode = company_code
            request.DocCode = doc_code
            request.DocType = doc_type
    #        request.CancelCode = cancel_code
            result = self.get_result(self.taxSvc, self.taxSvc.service.GetTaxHistory, request)
            return result
    
    
        def cancel_tax(self, company_code, doc_code, doc_type, cancel_code):
            request = self.taxSvc.factory.create('CancelTaxRequest')
            request.CompanyCode = company_code
            request.DocCode = doc_code
            request.DocType = doc_type
            request.CancelCode = cancel_code
            result = self.get_result(self.taxSvc, self.taxSvc.service.CancelTax, request)
            return result
    
    class Error(Exception):
        """Base class for exceptions in this module."""
        pass
    
    class AvaTaxError(Error):
        """Exception raised for errors calling AvaTax.
    
        Attributes:
            resultCode -- result.ResultCode
            messages  -- result.Messages
        """
    
        def __init__(self, resultCode, messages):
            self.resultCode = resultCode
            self.messages = messages
    
        def __str__(self):
            str = ''
            for item in self.messages:
                message = item[1][0] # SUDS gives us the message in a list, in a tuple
    
                str = "Severity: %s\n\nDetails: %s\n\n RefersTo: %s\n\n Summary: %s" \
                % (message.Severity, message.Details, message.RefersTo, message.Summary)
            return str
    
    class BaseAddress:
    
        def __init__(self, addSvc, Line1=None, Line2=None, City=None, PostalCode=None, Region=None, Country=None, AddressCode=None):
            self.data = addSvc.factory.create('BaseAddress')
            self.data.TaxRegionId = 0
            self.data.Line1 = Line1
            self.data.Line2 = Line2
            self.data.City = City
            self.data.PostalCode = PostalCode
            self.data.Region = Region
            self.data.Country = Country
            self.data.AddressCode = AddressCode
    
    class Line:
    
        def __init__(self, taxSvc, ItemCode, Amount, Qty, Description=None, TaxCode=None):
            self.taxSvc = taxSvc
            # We're not setting No here
            self.data = self.defaultLine()
            self.data.ItemCode = ItemCode
            self.data.Amount = Amount
            self.data.Qty = Qty
            self.data.Description = Description
            self.data.TaxCode = TaxCode
    
        def defaultLine(self):
            line = self.taxSvc.factory.create('Line')
            line.Qty = 1
            line.Discounted = False
            return line

    Note - It requires a working internet connection

 0 Comment(s)

Sign In
                           OR                           
                           OR                           
Register

Sign up using

                           OR                           
Forgot Password
Fill out the form below and instructions to reset your password will be emailed to you:
Reset Password
Fill out the form below and reset your password: