diff --git a/edivorce/apps/core/utils/question_step_mapping.py b/edivorce/apps/core/utils/question_step_mapping.py index d1203ceb..420d8d55 100644 --- a/edivorce/apps/core/utils/question_step_mapping.py +++ b/edivorce/apps/core/utils/question_step_mapping.py @@ -34,13 +34,105 @@ pre_qual_step_question_mapping = { } } +children_substep_question_mapping = { + 'your_children': { + 'claimant_children' + }, + 'income_expenses': { + 'how_will_calculate_income', + 'annual_gross_income', + 'spouse_annual_gross_income', + 'payor_monthly_child_support_amount', + 'special_extraordinary_expenses', + 'child_care_expenses', + 'children_healthcare_premiums', + 'health_related_expenses', + 'extraordinary_educational_expenses', + 'post_secondary_expenses', + 'extraordinary_extracurricular_expenses', + 'total_section_seven_expenses', + 'your_proportionate_share_percent', + 'your_proportionate_share_amount', + 'spouse_proportionate_share_percent', + 'spouse_proportionate_share_amount', + 'describe_order_special_extra_expenses', + }, + 'facts': { + 'child_support_payor', + # Fact sheet B + 'number_of_children', + 'time_spent_with_you', + 'time_spent_with_spouse', + 'your_child_support_paid_b', + 'your_spouse_child_support_paid_b', + 'additional_relevant_spouse_children_info', + # Fact sheet C + 'number_of_children_claimant', + 'your_spouse_child_support_paid_c', + 'number_of_children_claimant_spouse', + 'your_child_support_paid_c', + # Fact sheet D + 'agree_to_guideline_child_support_amount', + 'appropriate_spouse_paid_child_support', + 'suggested_child_support', + # Fact sheet E + 'claiming_undue_hardship', + 'claimant_debts', + 'claimant_expenses', + 'supporting_non_dependents', + 'supporting_dependents', + 'supporting_disabled', + 'undue_hardship', + 'income_others', + # Fact sheet F + 'number_children_seeking_support_you', + 'child_support_amount_under_high_income_you', + 'percent_income_over_high_income_limit_you', + 'amount_income_over_high_income_limit_you', + 'total_guideline_amount_you', + 'agree_to_child_support_amount_you', + 'agreed_child_support_amount_you', + 'reason_child_support_amount_you', + 'number_children_seeking_support_spouse', + 'child_support_amount_under_high_income_spouse', + 'percent_income_over_high_income_limit_spouse', + 'amount_income_over_high_income_limit_spouse', + 'total_guideline_amount_spouse', + 'agree_to_child_support_amount_spouse', + 'agreed_child_support_amount_spouse', + 'reason_child_support_amount_spouse', + }, + 'payor_medical': { + 'medical_coverage_available', + 'whose_plan_is_coverage_under', + 'child_support_payments_in_arrears', + 'child_support_arrears_amount', + }, + 'what_for': { + 'child_support_in_order', + 'order_monthly_child_support_amount', + 'child_support_in_order_reason', + 'claimants_agree_to_child_support_amount', + 'child_support_payment_special_provisions', + 'have_separation_agreement', + 'have_court_order', + 'what_parenting_arrangements', + 'want_parenting_arrangements', + 'order_respecting_arrangement', + 'order_for_child_support', + 'child_support_act' + }, +} + """ Mapping between questions and steps Usage: For each step title, list all questions_keys belong to that step """ question_step_mapping = { - 'prequalification': ['married_marriage_like', 'lived_in_bc', - 'lived_in_bc_at_least_year', 'separation_date', + 'prequalification': ['married_marriage_like', + 'lived_in_bc', + 'lived_in_bc_at_least_year', + 'separation_date', 'children_of_marriage', 'number_children_under_19', 'number_children_over_19', @@ -49,34 +141,47 @@ question_step_mapping = { 'original_marriage_certificate', 'provide_certificate_later', 'provide_certificate_later_reason', - 'not_provide_certificate_reason', 'divorce_reason', + 'not_provide_certificate_reason', + 'divorce_reason', 'marriage_certificate_in_english', 'try_reconcile_after_separated', 'reconciliation_period'], 'which_orders': ['want_which_orders'], - 'your_information': ['name_you', 'any_other_name_you', 'other_name_you', - 'last_name_born_you', 'last_name_before_married_you', - 'birthday_you', 'lived_in_bc_you', - 'moved_to_bc_date_you', 'occupation_you'], - 'your_spouse': ['name_spouse', 'any_other_name_spouse', 'other_name_spouse', - 'last_name_born_spouse', 'last_name_before_married_spouse', - 'birthday_spouse', 'lived_in_bc_spouse', - 'moved_to_bc_date_spouse', 'occupation_spouse'], - 'your_marriage': ['when_were_you_married', 'where_were_you_married_city', + 'your_information': ['name_you', + 'any_other_name_you', + 'other_name_you', + 'last_name_born_you', + 'last_name_before_married_you', + 'birthday_you', + 'lived_in_bc_you', + 'moved_to_bc_date_you', + 'occupation_you'], + 'your_spouse': ['name_spouse', + 'any_other_name_spouse', + 'other_name_spouse', + 'last_name_born_spouse', + 'last_name_before_married_spouse', + 'birthday_spouse', + 'lived_in_bc_spouse', + 'moved_to_bc_date_spouse', + 'occupation_spouse'], + 'your_marriage': ['when_were_you_married', + 'where_were_you_married_city', 'where_were_you_married_prov', 'where_were_you_married_country', 'where_were_you_married_other_country', 'marital_status_before_you', 'marital_status_before_spouse', 'when_were_you_live_married_like'], - 'your_separation': ['no_reconciliation_possible', 'no_collusion'], + 'your_separation': ['no_reconciliation_possible', + 'no_collusion'], 'your_children': ['claimant_children', # Income & Expenses 'how_will_calculate_income', 'annual_gross_income', 'spouse_annual_gross_income', 'payor_monthly_child_support_amount', - + # Special extraordinary expenses 'special_extraordinary_expenses', 'child_care_expenses', 'children_healthcare_premiums', @@ -117,25 +222,7 @@ question_step_mapping = { 'supporting_disabled', 'undue_hardship', 'income_others', - # Medical and other expenses - 'medical_coverage_available', - 'whose_plan_is_coverage_under', - 'child_support_payments_in_arrears', - 'child_support_arrears_amount', - # What are you asking for - 'child_support_in_order', - 'order_monthly_child_support_amount', - 'child_support_in_order_reason', - 'claimants_agree_to_child_support_amount', - 'have_separation_agreement', - 'have_court_order', - - 'what_parenting_arrangements', - 'want_parenting_arrangements', - 'order_respecting_arrangement', - 'order_for_child_support', - 'child_support_act', - 'child_support_payment_special_provisions', + # Fact sheet F 'number_children_seeking_support_you', 'child_support_amount_under_high_income_you', 'percent_income_over_high_income_limit_you', @@ -152,13 +239,33 @@ question_step_mapping = { 'agree_to_child_support_amount_spouse', 'agreed_child_support_amount_spouse', 'reason_child_support_amount_spouse', - ], - 'spousal_support': ['spouse_support_details', 'spouse_support_act'], + # Medical and other expenses + 'medical_coverage_available', + 'whose_plan_is_coverage_under', + 'child_support_payments_in_arrears', + 'child_support_arrears_amount', + # What are you asking for + 'child_support_in_order', + 'order_monthly_child_support_amount', + 'child_support_in_order_reason', + 'claimants_agree_to_child_support_amount', + 'child_support_payment_special_provisions', + 'have_separation_agreement', + 'have_court_order', + 'what_parenting_arrangements', + 'want_parenting_arrangements', + 'order_respecting_arrangement', + 'order_for_child_support', + 'child_support_act'], + 'spousal_support': ['spouse_support_details', + 'spouse_support_act'], 'property_and_debt': ['deal_with_property_debt', 'how_to_divide_property_debt', 'other_property_claims'], - 'other_orders': ['name_change_you', 'name_change_you_fullname', - 'name_change_spouse', 'name_change_spouse_fullname', + 'other_orders': ['name_change_you', + 'name_change_you_fullname', + 'name_change_spouse', + 'name_change_spouse_fullname', 'other_orders_detail'], 'other_questions': ['address_to_send_official_document_street_you', 'address_to_send_official_document_city_you', @@ -182,6 +289,7 @@ question_step_mapping = { } page_step_mapping = { + 'prequalification': 'prequalification', 'orders': 'which_orders', 'claimant': 'your_information', 'respondent': 'your_spouse', @@ -195,7 +303,6 @@ page_step_mapping = { 'filing_locations': 'filing_locations', } - """ List of court registries """ list_of_registries = ['Fort St. John', 'Dawson Creek', 'Prince Rupert', 'Terrace', 'Smithers', 'Prince George', 'Quesnel', diff --git a/edivorce/apps/core/utils/step_completeness.py b/edivorce/apps/core/utils/step_completeness.py index df136cb2..602a52a5 100644 --- a/edivorce/apps/core/utils/step_completeness.py +++ b/edivorce/apps/core/utils/step_completeness.py @@ -1,7 +1,7 @@ from django.urls import reverse from edivorce.apps.core.models import Question -from edivorce.apps.core.utils.question_step_mapping import page_step_mapping, pre_qual_step_question_mapping +from edivorce.apps.core.utils.question_step_mapping import children_substep_question_mapping, page_step_mapping, pre_qual_step_question_mapping, question_step_mapping from edivorce.apps.core.utils.conditional_logic import get_cleaned_response_value @@ -38,18 +38,16 @@ def get_step_completeness(questions_by_step): Returns {step: status}, {step: [missing_question_key]} """ status_dict = {} - missing_response_dict = {} - for step, question_list in questions_by_step.items(): - if not_started(question_list): + for step, questions_dict in questions_by_step.items(): + if not_started(questions_dict): status_dict[step] = "Not started" else: - complete, missing_responses = is_complete(question_list) + complete = is_complete(questions_dict) if complete: status_dict[step] = "Complete" else: - missing_response_dict[step] = missing_responses status_dict[step] = "Started" - return status_dict, missing_response_dict + return status_dict def not_started(question_list): @@ -60,11 +58,10 @@ def not_started(question_list): def is_complete(question_list): - missing_responses = [] for question_dict in question_list: if question_dict['error']: - missing_responses.append(question_dict) - return len(missing_responses) == 0, missing_responses + return False + return True def get_formatted_incomplete_list(missed_question_keys): @@ -87,13 +84,34 @@ def get_formatted_incomplete_list(missed_question_keys): return missed_questions -def get_error_dict(step, missing_questions): +def get_error_dict(questions_by_step, step, substep=None): """ - Returns a dict of {question_key_error: True} for any + Accepts questions dict of {step: [{question_dict}]} and a step (and substep) + Returns a dict of {question_key_error: True} for missing questions that are part of that step (and substep) """ responses_dict = {} question_step = page_step_mapping[step] - for question_dict in missing_questions.get(question_step, []): - field_error_key = question_dict['question_id'] + '_error' - responses_dict[field_error_key] = True + step_questions = questions_by_step.get(question_step) + if substep: + substep_questions = children_substep_question_mapping[substep] + step_questions = list(filter(lambda question_dict: question_dict['question_id'] in substep_questions, step_questions)) + if not not_started(step_questions) and not is_complete(step_questions): + for question_dict in step_questions: + if question_dict['error']: + field_error_key = question_dict['question_id'] + '_error' + responses_dict[field_error_key] = True return responses_dict + + +def get_missed_question_keys(questions_by_step, step): + """ + Accepts questions dict of {step: [{question_dict}]} and a step + Returns a list of [question_key] for missing questions that are part of that step + """ + missed_questions = [] + question_step = page_step_mapping[step] + step_questions = questions_by_step.get(question_step) + for question_dict in step_questions: + if question_dict['error']: + missed_questions.append(question_dict['question_id']) + return missed_questions diff --git a/edivorce/apps/core/utils/user_response.py b/edivorce/apps/core/utils/user_response.py index 2e87d82b..ed1a5f03 100644 --- a/edivorce/apps/core/utils/user_response.py +++ b/edivorce/apps/core/utils/user_response.py @@ -155,19 +155,15 @@ def get_responses_from_session(request): def get_responses_from_session_grouped_by_steps(request): - question_list = Question.objects.filter(key__in=question_step_mapping['prequalification']) - - lst = [] - - for question in question_list: - lst += [{'question__conditional_target': question.conditional_target, - 'question__reveal_response': question.reveal_response, - 'value': request.session.get(question.pk, ''), - 'question__name': question.name, - 'question__required': question.required, - 'question_id': question.pk}] - - return {'prequalification': lst} + step_questions_dict = _get_questions_dict_set_for_step('prequalification') + step_questions_list = [] + for question_key, question_dict in step_questions_dict.items(): + question_details = _get_question_details(question_key, step_questions_dict, request.session) + question_dict['value'] = question_details['value'] + question_dict['error'] = question_details['error'] + step_questions_list.append(question_dict) + + return {'prequalification': step_questions_list} def save_to_db(serializer, question, value, bceid_user): diff --git a/edivorce/apps/core/views/main.py b/edivorce/apps/core/views/main.py index c2ace4e7..09dbbbff 100644 --- a/edivorce/apps/core/views/main.py +++ b/edivorce/apps/core/views/main.py @@ -8,7 +8,7 @@ from django.utils import timezone from edivorce.apps.core.utils.derived import get_derived_data from ..decorators import bceid_required, intercept from ..utils.question_step_mapping import list_of_registries -from ..utils.step_completeness import get_error_dict, get_step_completeness, is_complete, get_formatted_incomplete_list +from ..utils.step_completeness import get_error_dict, get_missed_question_keys, get_step_completeness, is_complete, get_formatted_incomplete_list from ..utils.template_step_order import template_step_order from ..utils.user_response import ( get_data_for_user, @@ -48,7 +48,7 @@ def prequalification(request, step): responses_dict = get_data_for_user(request.user) responses_dict['active_page'] = 'prequalification' responses_by_step = get_step_responses(responses_dict) - step_status, _ = get_step_completeness(responses_by_step) + step_status = get_step_completeness(responses_by_step) responses_dict['step_status'] = step_status return render(request, template_name=template, context=responses_dict) @@ -62,7 +62,7 @@ def success(request): return redirect(settings.PROXY_BASE_URL + settings.FORCE_SCRIPT_NAME[:-1] + '/overview') prequal_responses = get_responses_from_session_grouped_by_steps(request)['prequalification'] - complete, _ = is_complete('prequalification', prequal_responses) + complete = is_complete(prequal_responses) if complete: return render(request, 'success.html', context={'register_url': settings.REGISTER_URL,'register_sc_url': settings.REGISTER_SC_URL}) return redirect(settings.PROXY_BASE_URL + settings.FORCE_SCRIPT_NAME[:-1] + '/incomplete') @@ -72,8 +72,8 @@ def incomplete(request): """ This page is shown if the user misses any pre-qualification questions """ - prequal_responses = get_responses_from_session_grouped_by_steps(request)['prequalification'] - _, missed_question_keys = is_complete('prequalification', prequal_responses) + prequal_responses = get_responses_from_session_grouped_by_steps(request) + missed_question_keys = get_missed_question_keys(prequal_responses, 'prequalification') missed_questions = get_formatted_incomplete_list(missed_question_keys) responses_dict = get_responses_from_session(request) @@ -163,7 +163,7 @@ def overview(request): responses_dict_by_step = get_step_responses(responses_dict) # Add step status dictionary - step_status, _ = get_step_completeness(responses_dict_by_step) + step_status = get_step_completeness(responses_dict_by_step) responses_dict_by_step['step_status'] = step_status responses_dict_by_step['active_page'] = 'overview' responses_dict_by_step['derived'] = get_derived_data(responses_dict) @@ -198,7 +198,7 @@ def question(request, step, sub_step=None): if step == "review": data_dict = get_data_for_user(request.user) responses_dict_by_step = get_step_responses(data_dict) - step_status, missing_questions = get_step_completeness(responses_dict_by_step) + step_status = get_step_completeness(responses_dict_by_step) derived = get_derived_data(data_dict) responses_dict = {} @@ -212,8 +212,8 @@ def question(request, step, sub_step=None): else: responses_dict = get_data_for_user(request.user) responses_dict_by_step = get_step_responses(responses_dict) - step_status, missing_questions = get_step_completeness(responses_dict_by_step) - responses_dict.update(get_error_dict(step, missing_questions)) + step_status = get_step_completeness(responses_dict_by_step) + responses_dict.update(get_error_dict(responses_dict_by_step, step, sub_step)) derived = get_derived_data(responses_dict) # Add step status dictionary