Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Daklapack Bulk Order Validation #101

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 62 additions & 28 deletions microsetta_admin/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,45 +921,79 @@ def return_error(msg):
f"not match expected column names"
f" {expected_headers}")

# disregard empty rows
addresses_df = addresses_df.dropna(how='all').copy()

# add (same) contact phone number to every address
addresses_df['phone'] = phone_number

addresses_df = addresses_df.fillna("")
temp_dict = addresses_df.to_dict(orient='index')
addresses_list = [temp_dict[n] for n in range(len(temp_dict))]

status, post_output = APIRequest.post(
'/api/admin/daklapack_orders',
json={
"project_ids": project_ids_list,
"article_code": dak_article_code,
"quantity": article_quantity,
"addresses": addresses_list,
"shipping_provider": shipping_provider,
"shipping_type": shipping_type,
"planned_send_date": planned_send_date,
"description": description,
"fedex_ref_1": fedex_ref_1,
"fedex_ref_2": fedex_ref_2,
"fedex_ref_3": fedex_ref_3
}
# validate spreadsheet rows
empty_field_criteria = (
addresses_df
.drop(columns=['insertion', 'address2'])
.isna()
.any(axis=1)
)

# if the post failed, keep track of the error so it can be displayed
if status != 200:
error_message = post_output
# display missing columns for incomplete addresses
hold_submissions_addresses = addresses_df[empty_field_criteria]
hold_submissions = pd.DataFrame({
'missing_columns': hold_submissions_addresses.apply(
lambda ser: ', '.join(
ser.index[ser.isna()] # find null fields
.drop(['insertion', 'address2'], errors='ignore')
),
axis=1
),
'address_dict': hold_submissions_addresses.fillna("").apply(
lambda ser: ser.to_dict(),
axis=1
)
})
hold_submissions_list = hold_submissions.to_dict(orient='records')

# prepare addresses for submission
addresses_df = addresses_df[~empty_field_criteria].fillna("")
addresses_list = addresses_df.to_dict(orient='records')

# skip API call if no valid address
if addresses_list:
status, post_output = APIRequest.post(
'/api/admin/daklapack_orders',
json={
"project_ids": project_ids_list,
"article_code": dak_article_code,
"quantity": article_quantity,
"addresses": addresses_list,
"shipping_provider": shipping_provider,
"shipping_type": shipping_type,
"planned_send_date": planned_send_date,
"description": description,
"fedex_ref_1": fedex_ref_1,
"fedex_ref_2": fedex_ref_2,
"fedex_ref_3": fedex_ref_3
}
)

# if the post failed, keep track of the error so it can be displayed
if status != 200:
error_message = post_output
else:
order_submissions = post_output["order_submissions"]
success_submissions = [x for x in order_submissions if
x["order_success"]]
failure_submissions = [x for x in order_submissions if not
x["order_success"]]
else:
order_submissions = post_output["order_submissions"]
success_submissions = [x for x in order_submissions if
x["order_success"]]
failure_submissions = [x for x in order_submissions if not
x["order_success"]]
success_submissions = []
failure_submissions = []

return render_template('submit_daklapack_order.html',
**build_login_variables(),
error_message=error_message,
success_submissions=success_submissions,
failure_submissions=failure_submissions)
failure_submissions=failure_submissions,
hold_submissions_list=hold_submissions_list)


@app.route('/authrocket_callback')
Expand Down
28 changes: 27 additions & 1 deletion microsetta_admin/templates/submit_daklapack_order.html
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,32 @@ <h3>Submit Daklapack Order</h3>
{{ error_message }}
{% endautoescape %}

{% elif success_submissions or failure_submissions %}
{% elif success_submissions or failure_submissions or hold_submissions_list %}
{% if hold_submissions_list|length > 0 %}
<p>
The following addresses are incomplete and NOT submitted to Daklapack.
The required fields missing are displayed below.
Please fill in all fields except for `insertion` and `address2`, then re-submit.
</p>
<table border="1">
<thead>
<tr>
<th>Required Field(s) Missing</th>
<th>Address</th>
</tr>
</thead>
<tbody>
{% for hold_submission in hold_submissions_list %}
<tr>
<td>{{ hold_submission['missing_columns'] }}</td>
<td>{{ hold_submission['address_dict'] }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<br>
{% endif %}

{% if failure_submissions|length > 0 %}
<p>
The following orders were NOT successfully submitted to Daklapack.
Expand All @@ -168,6 +193,7 @@ <h3>Submit Daklapack Order</h3>
{% endfor %}
</tbody>
</table>
<br>
{% endif %}

{% if success_submissions|length > 0 %}
Expand Down
Binary file modified microsetta_admin/tests/data/order_addresses_sample.xlsx
Binary file not shown.
Binary file not shown.
41 changes: 38 additions & 3 deletions microsetta_admin/tests/test_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,8 +474,7 @@ def test_post_submit_daklapack_order_success(self):
# server side issues one POST to the API
api_post_1 = DummyResponse(
200,
{'order_submissions':
[
{'order_submissions': [
{'order_id': '11211',
'order_address': {'address1': '123 Main St',
'address2': '',
Expand Down Expand Up @@ -505,16 +504,52 @@ def test_post_submit_daklapack_order_success(self):
'phone': '(858) 555-1212',
'postalCode': 'KG7-448',
'state': 'Ontario'},
'order_success': False}]}
'order_success': False},
{'order_id': '11213',
'order_address': {'address1': '38 Diagonal St',
'address2': '',
'city': 'Chiba',
'companyName': 'Dan H',
'country': 'Japan',
'countryCode': 'jp',
'firstName': 'Jerry',
'insertion': '',
'lastName': 'Index',
'phone': '(858) 555-1212',
'postalCode': '261-0022',
'state': 'Chiba'},
'order_success': True},
]}
)
self.mock_post.side_effect = [api_post_1]

response = self._test_post_submit_daklapack_order()
self.assertNotIn(b'The following addresses are incomplete and NOT '
b'submitted to Daklapack.', response.data)
self.assertIn(b'The following orders were NOT successfully submitted '
b'to Daklapack.', response.data)
self.assertIn(b'The following orders were successfully submitted '
b'to Daklapack', response.data)

# File: 3 complete addresses, 2 empty rows
# Expected: 3 addresses returned from Daklapack API + 2 table headers
self.assertEqual(response.data.count(b'<tr>'), 5)

def test_post_submit_daklapack_order_hold(self):
# No Private API Call
response = self._test_post_submit_daklapack_order(
"order_addresses_sample_hold.xlsx")
self.assertIn(b'The following addresses are incomplete and NOT '
b'submitted to Daklapack.', response.data)
self.assertNotIn(b'The following orders were NOT successfully '
b'submitted to Daklapack.', response.data)
self.assertNotIn(b'The following orders were successfully submitted '
b'to Daklapack', response.data)

# File: 4 complete addresses, 3 empty rows
# Expected: No API Call, 4 hold addresses + 1 table header
self.assertEqual(response.data.count(b'<tr>'), 5)

def test_post_submit_daklapack_order_fail_api(self):
# server side issues one POST to the API
api_post_1 = DummyResponse(400, {
Expand Down
Loading