Skip to content

Commit 0dd59dc

Browse files
Merge pull request #134 from avadev/SDK_bug_fixes
MR : fixed AS-134 and AS-135
2 parents 864a482 + 03713e8 commit 0dd59dc

File tree

8 files changed

+282
-104
lines changed

8 files changed

+282
-104
lines changed

src/avalara/transaction_builder.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,11 @@ def __init__(self, client, comp_code, type_, cust_code):
5252
# Keeps track of line number when adding multiple lines
5353
self.line_num = 1
5454
# The in-progress model
55+
5556
self.create_model = {
5657
'companyCode': comp_code,
5758
'customerCode': cust_code,
5859
'type': type_,
5960
'date': '{}'.format(datetime.now()),
60-
'lines': []
61+
'lines': [],
6162
}

src/avalara/transaction_builder_methods.py

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,22 @@ def with_latlong(self, address_type, lat, long_):
123123
:return: TransactionBuilder
124124
"""
125125
self.create_model.setdefault('addresses', {})
126-
self.create_model['addresses'][address_type] = {'latitude': float(lat),
127-
'longitude': float(long_)}
126+
self.create_model['addresses'][address_type] = {
127+
'latitude': float(lat),
128+
'longitude': float(long_),
129+
}
128130
return self
129131

130-
def with_line(self, amount, quantity, item_code, tax_code, line_number=None):
132+
def with_line(
133+
self,
134+
amount,
135+
quantity,
136+
item_code,
137+
tax_code="",
138+
line_number=None,
139+
tax_included=False,
140+
exemption_code="",
141+
):
131142
r"""
132143
Add a line to the transaction.
133144
@@ -136,42 +147,58 @@ def with_line(self, amount, quantity, item_code, tax_code, line_number=None):
136147
:param string item_code: Code of the item.
137148
:param string tax_code: Tax Code of the item. If left blank, \
138149
the default item (P0000000) is assumed.
139-
:param [int] line_number: Value of the line number.
150+
:param Any line_number: Value of the line number.
151+
:param bool tax_included: Is line amount tax included, defaults \
152+
to false
153+
:param string exemption_code: exemption_code in case of exempt \
154+
line, defaults to blank
140155
:return: TransactionBuilder
141156
"""
157+
# fix for issue #133
158+
# in case line number is set as string, use it as transaction line
159+
# number and continue incrementing object level line number for other
160+
# lines (with no line numbers)
161+
txn_line_number = self.line_num
142162
if line_number is not None:
143-
self.line_num = line_number;
144-
163+
if isinstance(
164+
line_number, (int, float, complex)
165+
) and not isinstance(line_number, bool):
166+
self.line_num = line_number
167+
txn_line_number = self.line_num
168+
else:
169+
txn_line_number = line_number
170+
145171
temp = {
146-
'number': str(self.line_num),
172+
'number': str(txn_line_number),
147173
'amount': amount,
148174
'quantity': quantity,
149175
'itemCode': str(item_code),
150-
'taxCode': str(tax_code)
176+
'taxCode': str(tax_code),
177+
'taxIncluded': tax_included,
178+
'exemptionCode': str(exemption_code),
151179
}
180+
152181
self.create_model['lines'].append(temp)
153182
self.line_num += 1
154183
return self
155184

156-
def with_exempt_line(self, amount, item_code, exemption_code):
185+
def with_exempt_line(self, amount, item_code, exemption_code, quantity=1):
157186
"""
158187
Add a line with an exemption to this transaction.
159188
160189
:param float amount: The amount of this line item
161190
:param string item_code: The code for the item
162191
:param string exemption_code: The exemption code for this line item
192+
:param int quantity: quantity, defaults to 1
163193
:return: TransactionBuilder
164194
"""
195+
self.with_line(
196+
quantity=quantity,
197+
item_code=item_code,
198+
amount=amount,
199+
exemption_code=exemption_code,
200+
)
165201

166-
temp = {
167-
'number': str(self.line_num),
168-
'quantity': 1,
169-
'amount': amount,
170-
'exemptionCode': str(exemption_code),
171-
'itemCode': str(item_code)
172-
}
173-
self.create_model['lines'].append(temp)
174-
self.line_num += 1
175202
return self
176203

177204
def with_diagnostics(self):
@@ -238,7 +265,12 @@ def get_most_recent_line(self, member_name=None):
238265
"""
239266
line = self.create_model['lines']
240267
if not len(line): # if length is zero
241-
raise Exception('No lines have been added. The {} method applies to the most recent line. To use this function, first add a line.'.format(member_name))
268+
raise Exception(
269+
'No lines have been added. The {} method applies to the most \
270+
recent line. To use this function, first add a line.'.format(
271+
member_name
272+
)
273+
)
242274
return line[-1]
243275

244276
def create(self, include=None):
@@ -270,7 +302,7 @@ def with_line_tax_override(self, type_, reason, tax_amount, tax_date):
270302
'type': str(type_),
271303
'reason': str(reason),
272304
'taxAmount': float(tax_amount),
273-
'taxDate': tax_date
305+
'taxDate': tax_date,
274306
}
275307
return self
276308

@@ -293,7 +325,7 @@ def with_tax_override(self, type_, reason, tax_amount, tax_date):
293325
'type': str(type_),
294326
'reason': str(reason),
295327
'taxAmount': tax_amount,
296-
'taxDate': tax_date
328+
'taxDate': tax_date,
297329
}
298330
return self
299331

@@ -321,9 +353,7 @@ def with_separate_address_line(self, amount, type_, address):
321353
'number': self.line_num,
322354
'quantity': 1,
323355
'amount': amount,
324-
'addresses': {
325-
type_: address
326-
}
356+
'addresses': {type_: address},
327357
}
328358

329359
self.create_model['lines'].append(temp)
@@ -341,5 +371,5 @@ def create_adjustment_request(self, desc, reason):
341371
return {
342372
'newTransaction': self.create_model,
343373
'adjustmentDescription': desc,
344-
'adjustmentReason': reason
374+
'adjustmentReason': reason,
345375
}

tests/__init__.py

Whitespace-only changes.

tests/conftest.py

Lines changed: 68 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Conftest is a file recognize by pytest module, allowing us to share fixture across multiple tests."""
2-
from avalara import AvataxClient
3-
from avalara.transaction_builder import TransactionBuilder
2+
from src.avalara import AvataxClient
3+
from src.avalara.transaction_builder import TransactionBuilder
44
import os
55
import pytest
66

@@ -53,7 +53,7 @@ def ship_from_address():
5353
'line1': '123 Main Street',
5454
'city': 'Irvine',
5555
'region': 'CA',
56-
'postalCode': '92615'
56+
'postalCode': '92615',
5757
}
5858
return address
5959

@@ -95,29 +95,38 @@ def five_transactions():
9595
('Poulsbo', '200 Moe St Ne', '98370', 'WA'),
9696
('Los Angeles', '1945 S Hill St', '90007', 'CA'),
9797
('Chicago', '50 W Washington St', '60602', 'IL'),
98-
('Irvine', '123 Main Street', '92615', 'CA')
98+
('Irvine', '123 Main Street', '92615', 'CA'),
9999
]
100100
for city, line1, postal, region in addresses:
101101
tax_document = {
102-
'addresses': {'SingleLocation': {'city': city,
103-
'country': 'US',
104-
'line1': line1,
105-
'postalCode': postal,
106-
'region': region}},
102+
'addresses': {
103+
'SingleLocation': {
104+
'city': city,
105+
'country': 'US',
106+
'line1': line1,
107+
'postalCode': postal,
108+
'region': region,
109+
}
110+
},
107111
'commit': False,
108112
'companyCode': 'DEFAULT',
109113
'currencyCode': 'USD',
110114
'customerCode': 'ABC',
111115
'date': '2017-04-12',
112116
'description': 'Yarn',
113-
'lines': [{'amount': 100,
114-
'description': 'Yarn',
115-
'itemCode': 'Y0001',
116-
'number': '1',
117-
'quantity': 1,
118-
'taxCode': 'PS081282'}],
117+
'lines': [
118+
{
119+
'amount': 100,
120+
'description': 'Yarn',
121+
'itemCode': 'Y0001',
122+
'number': '1',
123+
'quantity': 1,
124+
'taxCode': 'PS081282',
125+
}
126+
],
119127
'purchaseOrderNo': '2017-04-12-001',
120-
'type': 'SalesInvoice'}
128+
'type': 'SalesInvoice',
129+
}
121130
r = client.create_transaction(tax_document, None)
122131
trans_codes.append(r.json()['code'])
123132
return trans_codes
@@ -128,6 +137,7 @@ def tax_document():
128137
"""Create a tax document dictionary."""
129138
return default_trans_model()
130139

140+
131141
@pytest.fixture(scope='function')
132142
def init_comp_model():
133143
"""Return the following initialize company model for company DEFAULT."""
@@ -145,41 +155,64 @@ def init_comp_model():
145155
"title": "Owner",
146156
"email": "bob@example.org",
147157
"phoneNumber": "714 555-2121",
148-
"mobileNumber": "714 555-1212"}
158+
"mobileNumber": "714 555-1212",
159+
}
160+
149161

150162
def cred_determine():
151163
"""Return the appropriate pair of cred."""
152164
if os.environ.get('USERNAME') and os.environ.get('PASSWORD'):
153165
return (os.environ.get('USERNAME'), os.environ.get('PASSWORD'))
154-
elif os.environ.get('SANDBOX_CLIENTID') and os.environ.get('SANDBOX_LICENSEKEY'):
155-
return (os.environ.get('SANDBOX_CLIENTID'), os.environ.get('SANDBOX_LICENSEKEY'))
156-
elif os.environ.get('SANDBOX_USERNAME') and os.environ.get('SANDBOX_PASSWORD'):
157-
return (os.environ.get('SANDBOX_USERNAME'), os.environ.get('SANDBOX_PASSWORD'))
166+
elif os.environ.get('SANDBOX_CLIENTID') and os.environ.get(
167+
'SANDBOX_LICENSEKEY'
168+
):
169+
return (
170+
os.environ.get('SANDBOX_CLIENTID'),
171+
os.environ.get('SANDBOX_LICENSEKEY'),
172+
)
173+
elif os.environ.get('SANDBOX_USERNAME') and os.environ.get(
174+
'SANDBOX_PASSWORD'
175+
):
176+
return (
177+
os.environ.get('SANDBOX_USERNAME'),
178+
os.environ.get('SANDBOX_PASSWORD'),
179+
)
158180
else:
159181
raise ValueError()
160182

183+
161184
def default_trans_model():
162185
"""Return the default transaction model."""
163186
return {
164-
'addresses': {'SingleLocation': {'city': 'Irvine',
165-
'country': 'US',
166-
'line1': '123 Main Street',
167-
'postalCode': '92615',
168-
'region': 'CA'}},
187+
'addresses': {
188+
'SingleLocation': {
189+
'city': 'Irvine',
190+
'country': 'US',
191+
'line1': '123 Main Street',
192+
'postalCode': '92615',
193+
'region': 'CA',
194+
}
195+
},
169196
'commit': False,
170197
'companyCode': 'DEFAULT',
171198
'currencyCode': 'USD',
172199
'customerCode': 'ABC',
173200
'date': '2017-04-12',
174201
'description': 'Yarn',
175-
'lines': [{'amount': 100,
176-
'description': 'Yarn',
177-
'itemCode': 'Y0001',
178-
'number': '1',
179-
'quantity': 1,
180-
'taxCode': 'PS081282'}],
202+
'lines': [
203+
{
204+
'amount': 100,
205+
'description': 'Yarn',
206+
'itemCode': 'Y0001',
207+
'number': '1',
208+
'quantity': 1,
209+
'taxCode': 'PS081282',
210+
}
211+
],
181212
'purchaseOrderNo': '2017-04-12-001',
182-
'type': 'SalesInvoice'}
213+
'type': 'SalesInvoice',
214+
}
215+
183216

184217
def pytest_runtest_makereport(item, call):
185218
"""For incremental testing fixture called mark.increment."""
@@ -188,11 +221,10 @@ def pytest_runtest_makereport(item, call):
188221
parent = item.parent
189222
parent._previousfailed = item
190223

224+
191225
def pytest_runtest_setup(item):
192226
"""For incremental testing fixture called mark.increment."""
193227
if "incremental" in item.keywords:
194228
previousfailed = getattr(item.parent, "_previousfailed", None)
195229
if previousfailed is not None:
196-
pytest.xfail("previous test failed (%s)" %previousfailed.name)
197-
198-
230+
pytest.xfail("previous test failed (%s)" % previousfailed.name)

tests/test_auth.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""Test the add_credential method."""
22
import pytest
33
from requests.auth import HTTPBasicAuth
4-
from avalara.client import AvataxClient
4+
from src.avalara.client import AvataxClient
55

66

77
def test_username_auth(unauth_client):
@@ -59,4 +59,3 @@ def test_no_auth_if_no_cred_is_added(unauth_client):
5959
def test_if_valid_pair_sandbox_cred_in_place(auth_client):
6060
"""Test if there is a pair of valid Avatax credentials stored in env."""
6161
assert auth_client is not None
62-

tests/test_client.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Test the client model."""
2-
from avalara.client import AvataxClient
2+
from src.avalara.client import AvataxClient
33

44

55
def test_client_can_be_created(unauth_client):
@@ -29,7 +29,10 @@ def test_client_has_machine_name_attribute(unauth_client):
2929

3030
def test_that_client_id_is_created(unauth_client):
3131
"""Test that the client id is created and properly formatted."""
32-
assert unauth_client.client_id == 'test app; ver 0.0; Python SDK; 18.5; test machine;'
32+
assert (
33+
unauth_client.client_id
34+
== 'test app; ver 0.0; Python SDK; 18.5; test machine;'
35+
)
3336

3437

3538
def test_client_can_obtain_production_url_as_base_url():
@@ -40,6 +43,7 @@ def test_client_can_obtain_production_url_as_base_url():
4043

4144
def test_client_can_obtain_their_own_base_url():
4245
"""Test the client can input a url as the base url."""
43-
client = AvataxClient('test app', 'ver 0.0', 'test machine', 'https://myurl.com')
46+
client = AvataxClient(
47+
'test app', 'ver 0.0', 'test machine', 'https://myurl.com'
48+
)
4449
assert client.base_url == 'https://myurl.com'
45-

tests/test_create_trans.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ def test_transaction_is_saved_when_commit_is_false(auth_client, tax_document):
2222
assert '"status":"Saved"' in r.text
2323

2424

25-
def test_transaction_is_commited_when_commit_is_true(auth_client, tax_document):
25+
def test_transaction_is_commited_when_commit_is_true(
26+
auth_client, tax_document
27+
):
2628
"""Test that a transaction is commited when commit is true."""
2729
tax_document['commit'] = True
2830
r = auth_client.create_transaction(tax_document, None)
@@ -41,4 +43,3 @@ def test_include_param_is_addresses(auth_client, tax_document):
4143
include = {'$include': 'Addresses'}
4244
r = auth_client.create_transaction(tax_document, include)
4345
assert 'addresses' in r.text
44-

0 commit comments

Comments
 (0)