From 4fd877c909ce0cc8c3d844d9e8488b761c1e579e Mon Sep 17 00:00:00 2001 From: colts661 Date: Mon, 22 Apr 2024 21:50:56 -0700 Subject: [PATCH 1/4] Added Bulk Daklapack Order Verification --- microsetta_admin/server.py | 24 +++++++++++++++--- .../templates/submit_daklapack_order.html | 25 ++++++++++++++++++- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/microsetta_admin/server.py b/microsetta_admin/server.py index d023e70..b5b59de 100644 --- a/microsetta_admin/server.py +++ b/microsetta_admin/server.py @@ -921,12 +921,27 @@ 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))] + # validate spreadsheet rows + empty_field_criteria = ( + addresses_df + .drop(columns=['insertion', 'address2']) + .isna() + .any(axis=1) + ) + hold_submission_addresses = ( + addresses_df[empty_field_criteria] + .to_dict(orient='records') + ) + + # prepare addresses for submission + addresses_df = addresses_df[~empty_field_criteria].fillna("") + addresses_list = addresses_df.to_dict(orient='records') status, post_output = APIRequest.post( '/api/admin/daklapack_orders', @@ -959,7 +974,8 @@ def return_error(msg): **build_login_variables(), error_message=error_message, success_submissions=success_submissions, - failure_submissions=failure_submissions) + failure_submissions=failure_submissions, + hold_submission_addresses=hold_submission_addresses) @app.route('/authrocket_callback') diff --git a/microsetta_admin/templates/submit_daklapack_order.html b/microsetta_admin/templates/submit_daklapack_order.html index 96e6280..95f0eae 100644 --- a/microsetta_admin/templates/submit_daklapack_order.html +++ b/microsetta_admin/templates/submit_daklapack_order.html @@ -144,7 +144,29 @@

Submit Daklapack Order

{{ error_message }} {% endautoescape %} -{% elif success_submissions or failure_submissions %} +{% elif success_submissions or failure_submissions or hold_submission_addresses %} + {% if hold_submission_addresses|length > 0 %} +

+The following addresses are incomplete and NOT submitted to Daklapack. +Please fill in all fields except for `insertion` and `address2`, then re-submit. +

+ + + + + + + + {% for curr_address in hold_submission_addresses %} + + + + {% endfor %} + +
Address
{{ curr_address }}
+
+ {% endif %} + {% if failure_submissions|length > 0 %}

The following orders were NOT successfully submitted to Daklapack. @@ -168,6 +190,7 @@

Submit Daklapack Order

{% endfor %} +
{% endif %} {% if success_submissions|length > 0 %} From 95a56c9757ef0d05f4ea8db604be89436020983b Mon Sep 17 00:00:00 2001 From: colts661 Date: Mon, 22 Apr 2024 21:53:01 -0700 Subject: [PATCH 2/4] Fixed style --- microsetta_admin/server.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microsetta_admin/server.py b/microsetta_admin/server.py index b5b59de..2bd0999 100644 --- a/microsetta_admin/server.py +++ b/microsetta_admin/server.py @@ -922,7 +922,7 @@ def return_error(msg): f" {expected_headers}") # disregard empty rows - addresses_df = addresses_df.dropna(how='all').copy() + addresses_df = addresses_df.dropna(how='all').copy() # add (same) contact phone number to every address addresses_df['phone'] = phone_number From 2949a2e8ccccd36a08cdc13066957cf0409d89ef Mon Sep 17 00:00:00 2001 From: colts661 Date: Tue, 23 Apr 2024 20:59:40 -0700 Subject: [PATCH 3/4] Display missing fields --- microsetta_admin/server.py | 76 ++++++++++++------- .../templates/submit_daklapack_order.html | 11 ++- 2 files changed, 54 insertions(+), 33 deletions(-) diff --git a/microsetta_admin/server.py b/microsetta_admin/server.py index 2bd0999..76d783c 100644 --- a/microsetta_admin/server.py +++ b/microsetta_admin/server.py @@ -934,48 +934,66 @@ def return_error(msg): .isna() .any(axis=1) ) - hold_submission_addresses = ( - addresses_df[empty_field_criteria] - .to_dict(orient='records') - ) + + # 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') - 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 - } - ) + # 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 + # 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, - hold_submission_addresses=hold_submission_addresses) + hold_submissions_list=hold_submissions_list) @app.route('/authrocket_callback') diff --git a/microsetta_admin/templates/submit_daklapack_order.html b/microsetta_admin/templates/submit_daklapack_order.html index 95f0eae..0fc5e61 100644 --- a/microsetta_admin/templates/submit_daklapack_order.html +++ b/microsetta_admin/templates/submit_daklapack_order.html @@ -144,22 +144,25 @@

Submit Daklapack Order

{{ error_message }} {% endautoescape %} -{% elif success_submissions or failure_submissions or hold_submission_addresses %} - {% if hold_submission_addresses|length > 0 %} +{% elif success_submissions or failure_submissions or hold_submissions_list %} + {% if hold_submissions_list|length > 0 %}

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.

+ - {% for curr_address in hold_submission_addresses %} + {% for hold_submission in hold_submissions_list %} - + + {% endfor %} From 7783434168a3a3031fde9a2446c0e5c96ad188ae Mon Sep 17 00:00:00 2001 From: colts661 Date: Tue, 23 Apr 2024 20:59:56 -0700 Subject: [PATCH 4/4] Add tests --- .../tests/data/order_addresses_sample.xlsx | Bin 8960 -> 9047 bytes .../data/order_addresses_sample_hold.xlsx | Bin 0 -> 9075 bytes microsetta_admin/tests/test_routes.py | 41 ++++++++++++++++-- 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 microsetta_admin/tests/data/order_addresses_sample_hold.xlsx diff --git a/microsetta_admin/tests/data/order_addresses_sample.xlsx b/microsetta_admin/tests/data/order_addresses_sample.xlsx index 005ac0a9eb4a559d75501e5b272bc83badb97430..902ecdcf81169227e67ce7773e7ed6632101865d 100644 GIT binary patch delta 5392 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 XC#wD=Lz4fp=OMt%%-D{gzaIYuat#lX diff --git a/microsetta_admin/tests/data/order_addresses_sample_hold.xlsx b/microsetta_admin/tests/data/order_addresses_sample_hold.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..23db5d0ec2080e033b4587a906f07db4619b87d5 GIT binary patch literal 9075 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 T{B!{TO!y}N?$a0Pet!EutIW2~ literal 0 HcmV?d00001 diff --git a/microsetta_admin/tests/test_routes.py b/microsetta_admin/tests/test_routes.py index 43fed19..6ad3ed4 100644 --- a/microsetta_admin/tests/test_routes.py +++ b/microsetta_admin/tests/test_routes.py @@ -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': '', @@ -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''), 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''), 5) + def test_post_submit_daklapack_order_fail_api(self): # server side issues one POST to the API api_post_1 = DummyResponse(400, {
Required Field(s) Missing Address
{{ curr_address }}{{ hold_submission['missing_columns'] }}{{ hold_submission['address_dict'] }}