forked from Mapan/odoo17e
105 lines
4.5 KiB
Python
105 lines
4.5 KiB
Python
"""
|
|
AvaTax Software Development Kit for Python.
|
|
|
|
Copyright 2019 Avalara, Inc.
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
@author Robert Bronson
|
|
@author Phil Werner
|
|
@author Adrienne Karnoski
|
|
@author Han Bao
|
|
@copyright 2019 Avalara, Inc.
|
|
@license https://www.apache.org/licenses/LICENSE-2.0
|
|
@version TBD
|
|
@link https://github.com/avadev/AvaTax-REST-V2-Python-SDK
|
|
"""
|
|
# This is a stripped down version of the upstream Avatax library for Odoo. Changes were made to
|
|
# prevent arbitrary requests in case function references get leaked.
|
|
|
|
from requests.auth import HTTPBasicAuth
|
|
from datetime import datetime
|
|
from pprint import pformat
|
|
import requests
|
|
import logging
|
|
|
|
str_type = (str, type(None))
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class AvataxClient:
|
|
def __init__(self, app_name=None, app_version=None, machine_name=None,
|
|
environment=None, timeout_limit=None):
|
|
if not all(isinstance(i, str_type) for i in [app_name,
|
|
machine_name,
|
|
environment]):
|
|
raise ValueError('Input(s) must be string or none type object')
|
|
self.base_url = 'https://sandbox-rest.avatax.com'
|
|
self.is_production = environment and environment.lower() == 'production'
|
|
if self.is_production:
|
|
self.base_url = 'https://rest.avatax.com'
|
|
self.auth = None
|
|
self.app_name = app_name
|
|
self.app_version = app_version
|
|
self.machine_name = machine_name
|
|
self.client_id = '{}; {}; Python SDK; 18.5; {};'.format(app_name,
|
|
app_version,
|
|
machine_name)
|
|
self.client_header = {'X-Avalara-Client': self.client_id}
|
|
self.timeout_limit = timeout_limit
|
|
|
|
def add_credentials(self, username=None, password=None):
|
|
if not all(isinstance(i, str_type) for i in [username, password]):
|
|
raise ValueError('Input(s) must be string or none type object')
|
|
if username and not password:
|
|
self.client_header['Authorization'] = 'Bearer ' + username
|
|
else:
|
|
self.auth = HTTPBasicAuth(username, password)
|
|
return self
|
|
|
|
def request(self, method, endpoint, params, json):
|
|
"""Allow to enable a trace of requests in the logger."""
|
|
start = str(datetime.utcnow())
|
|
url = '{}/api/v2/{}'.format(self.base_url, endpoint)
|
|
response = requests.request(
|
|
method, url,
|
|
auth=self.auth,
|
|
headers=self.client_header,
|
|
timeout=self.timeout_limit if self.timeout_limit else 1200,
|
|
params=params,
|
|
json=json
|
|
).json()
|
|
end = str(datetime.utcnow())
|
|
if hasattr(self, 'logger'):
|
|
self.logger(
|
|
f"{method}\nstart={start}\nend={end}\nargs={pformat(url)}\nparams={pformat(params)}\njson={pformat(json)}\n"
|
|
f"response={pformat(response)}"
|
|
)
|
|
return response
|
|
|
|
def create_transaction(self, model, include=None):
|
|
return self.request('POST', 'transactions/createoradjust', params=include, json={'createTransactionModel': model})
|
|
|
|
def uncommit_transaction(self, companyCode, transactionCode, include=None):
|
|
return self.request('POST', 'companies/{}/transactions/{}/uncommit'.format(companyCode, transactionCode),
|
|
params=include, json=None)
|
|
|
|
def void_transaction(self, companyCode, transactionCode, model, include=None):
|
|
return self.request('POST', 'companies/{}/transactions/{}/void'.format(companyCode, transactionCode),
|
|
params=include, json=model)
|
|
|
|
def ping(self):
|
|
return self.request('GET', 'utilities/ping', params=None, json=None)
|
|
|
|
def resolve_address(self, model=None):
|
|
return self.request('POST', 'addresses/resolve', params=None, json=model)
|
|
|
|
def list_entity_use_codes(self, include=None):
|
|
return self.request('GET', 'definitions/entityusecodes', params=include, json=None)
|