From 82b1e87462e7395f99e767cd5bbe73ddb3cdbbee Mon Sep 17 00:00:00 2001 From: Philip Wafula Date: Wed, 23 Jun 2021 13:25:09 +0000 Subject: [PATCH] Philip/add age metadata --- apps/cic-ussd/cic_ussd/db/ussd_menu.json | 12 ++++++ apps/cic-ussd/cic_ussd/processor.py | 7 +++- .../cic_ussd/state_machine/logic/menu.py | 12 ++++++ .../cic_ussd/state_machine/logic/user.py | 18 ++++++++- .../cic_ussd/state_machine/logic/validator.py | 12 ++++++ apps/cic-ussd/requirements.txt | 6 +-- .../states/account_management_states.json | 1 + .../cic-ussd/states/user_metadata_states.json | 1 + .../transitions/age_setting_transitions.json | 39 +++++++++++++++++++ .../transitions/name_setting_transitions.json | 2 +- .../user_metadata_transitions.json | 12 ++++-- apps/cic-ussd/var/lib/locale/ussd.en.yml | 18 +++++++-- apps/cic-ussd/var/lib/locale/ussd.sw.yml | 18 +++++++-- 13 files changed, 143 insertions(+), 15 deletions(-) create mode 100644 apps/cic-ussd/transitions/age_setting_transitions.json diff --git a/apps/cic-ussd/cic_ussd/db/ussd_menu.json b/apps/cic-ussd/cic_ussd/db/ussd_menu.json index ecc98173..bbb23d74 100644 --- a/apps/cic-ussd/cic_ussd/db/ussd_menu.json +++ b/apps/cic-ussd/cic_ussd/db/ussd_menu.json @@ -275,6 +275,18 @@ "display_key": "ussd.kenya.new_pin_confirmation", "name": "new_pin_confirmation", "parent": "metadata_management" + }, + "47": { + "description": "Year of birth entry menu.", + "display_key": "ussd.kenya.enter_date_of_birth", + "name": "enter_date_of_birth", + "parent": "metadata_management" + }, + "48": { + "description": "Pin entry menu for changing year of birth data.", + "display_key": "ussd.kenya.dob_edit_pin_authorization", + "name": "dob_edit_pin_authorization", + "parent": "metadata_management" } } diff --git a/apps/cic-ussd/cic_ussd/processor.py b/apps/cic-ussd/cic_ussd/processor.py index d9842df8..adf81f12 100644 --- a/apps/cic-ussd/cic_ussd/processor.py +++ b/apps/cic-ussd/cic_ussd/processor.py @@ -1,4 +1,5 @@ # standard imports +import datetime import logging import json import re @@ -257,6 +258,10 @@ def process_display_user_metadata(user: Account, display_key: str): contact_data = get_contact_data_from_vcard(vcard=user_metadata.get('vcard')) logg.debug(f'{contact_data}') full_name = f'{contact_data.get("given")} {contact_data.get("family")}' + date_of_birth = user_metadata.get('date_of_birth') + year_of_birth = date_of_birth.get('year') + present_year = datetime.datetime.now().year + age = present_year - year_of_birth gender = user_metadata.get('gender') products = ', '.join(user_metadata.get('products')) location = user_metadata.get('location').get('area_name') @@ -265,6 +270,7 @@ def process_display_user_metadata(user: Account, display_key: str): key=display_key, preferred_language=user.preferred_language, full_name=full_name, + age=age, gender=gender, location=location, products=products @@ -289,7 +295,6 @@ def process_display_user_metadata(user: Account, display_key: str): ) - def process_account_statement(user: Account, display_key: str, ussd_session: dict): """ :param user: diff --git a/apps/cic-ussd/cic_ussd/state_machine/logic/menu.py b/apps/cic-ussd/cic_ussd/state_machine/logic/menu.py index c7239ab5..a1889ce5 100644 --- a/apps/cic-ussd/cic_ussd/state_machine/logic/menu.py +++ b/apps/cic-ussd/cic_ussd/state_machine/logic/menu.py @@ -66,6 +66,18 @@ def menu_five_selected(state_machine_data: Tuple[str, dict, Account]) -> bool: return user_input == '5' +def menu_six_selected(state_machine_data: Tuple[str, dict, Account]) -> bool: + """ + This function checks that user input matches a string with value '6' + :param state_machine_data: A tuple containing user input, a ussd session and user object. + :type state_machine_data: tuple + :return: A user input's match with '6' + :rtype: bool + """ + user_input, ussd_session, user = state_machine_data + return user_input == '6' + + def menu_zero_zero_selected(state_machine_data: Tuple[str, dict, Account]) -> bool: """ This function checks that user input matches a string with value '00' diff --git a/apps/cic-ussd/cic_ussd/state_machine/logic/user.py b/apps/cic-ussd/cic_ussd/state_machine/logic/user.py index d2db5d29..4d1b9a38 100644 --- a/apps/cic-ussd/cic_ussd/state_machine/logic/user.py +++ b/apps/cic-ussd/cic_ussd/state_machine/logic/user.py @@ -93,6 +93,9 @@ def save_metadata_attribute_to_session_data(state_machine_data: Tuple[str, dict, if 'given_name' in current_state: key = 'given_name' + if 'date_of_birth' in current_state: + key = 'date_of_birth' + if 'family_name' in current_state: key = 'family_name' @@ -130,6 +133,13 @@ def format_user_metadata(metadata: dict, user: Account): given_name = metadata.get('given_name') family_name = metadata.get('family_name') + if isinstance(metadata.get('date_of_birth'), dict): + date_of_birth = metadata.get('date_of_birth') + else: + date_of_birth = { + "year": int(metadata.get('date_of_birth')[:4]) + } + # check whether there's existing location data if isinstance(metadata.get('location'), dict): location = metadata.get('location') @@ -154,6 +164,7 @@ def format_user_metadata(metadata: dict, user: Account): ) return { "date_registered": date_registered, + "date_of_birth": date_of_birth, "gender": gender, "identities": identities, "location": location, @@ -201,12 +212,12 @@ def edit_user_metadata_attribute(state_machine_data: Tuple[str, dict, Account]): given_name = ussd_session.get('session_data').get('given_name') family_name = ussd_session.get('session_data').get('family_name') + date_of_birth = ussd_session.get('session_data').get('date_of_birth') gender = ussd_session.get('session_data').get('gender') location = ussd_session.get('session_data').get('location') products = ussd_session.get('session_data').get('products') # validate user metadata - person = Person() user_metadata = json.loads(user_metadata) # edit specific metadata attribute @@ -214,6 +225,11 @@ def edit_user_metadata_attribute(state_machine_data: Tuple[str, dict, Account]): user_metadata['given_name'] = given_name if family_name: user_metadata['family_name'] = family_name + if date_of_birth and len(date_of_birth) == 4: + year = int(date_of_birth[:4]) + user_metadata['date_of_birth'] = { + 'year': year + } if gender: user_metadata['gender'] = gender if location: diff --git a/apps/cic-ussd/cic_ussd/state_machine/logic/validator.py b/apps/cic-ussd/cic_ussd/state_machine/logic/validator.py index 2f6203d4..2af1e8d3 100644 --- a/apps/cic-ussd/cic_ussd/state_machine/logic/validator.py +++ b/apps/cic-ussd/cic_ussd/state_machine/logic/validator.py @@ -56,3 +56,15 @@ def is_valid_gender_selection(state_machine_data: Tuple[str, dict, Account]): return True else: return False + + +def is_valid_date(state_machine_data: Tuple[str, dict, Account]): + """ + :param state_machine_data: + :type state_machine_data: + :return: + :rtype: + """ + user_input, ussd_session, user = state_machine_data + # For MVP this value is defaulting to year + return len(user_input) == 4 and int(user_input) >= 1900 diff --git a/apps/cic-ussd/requirements.txt b/apps/cic-ussd/requirements.txt index 7b5ef9df..4411509e 100644 --- a/apps/cic-ussd/requirements.txt +++ b/apps/cic-ussd/requirements.txt @@ -1,4 +1,4 @@ -cic_base[full_graph]~=0.1.2b17 -cic-eth~=0.11.0b17 +cic_base[full_graph]~=0.1.2b21 +cic-eth~=0.11.0b16 cic-notify~=0.4.0a5 -cic-types~=0.1.0a10 +cic-types~=0.1.0a11 diff --git a/apps/cic-ussd/states/account_management_states.json b/apps/cic-ussd/states/account_management_states.json index 456edd92..ea9027a2 100644 --- a/apps/cic-ussd/states/account_management_states.json +++ b/apps/cic-ussd/states/account_management_states.json @@ -7,6 +7,7 @@ "new_pin_confirmation", "display_user_metadata", "name_edit_pin_authorization", + "dob_edit_pin_authorization", "gender_edit_pin_authorization", "location_edit_pin_authorization", "products_edit_pin_authorization", diff --git a/apps/cic-ussd/states/user_metadata_states.json b/apps/cic-ussd/states/user_metadata_states.json index 59bc1fd7..21ef82df 100644 --- a/apps/cic-ussd/states/user_metadata_states.json +++ b/apps/cic-ussd/states/user_metadata_states.json @@ -5,5 +5,6 @@ "enter_age", "enter_location", "enter_products", + "enter_date_of_birth", "display_metadata_pin_authorization" ] \ No newline at end of file diff --git a/apps/cic-ussd/transitions/age_setting_transitions.json b/apps/cic-ussd/transitions/age_setting_transitions.json new file mode 100644 index 00000000..0fe67d03 --- /dev/null +++ b/apps/cic-ussd/transitions/age_setting_transitions.json @@ -0,0 +1,39 @@ +[ + { + "trigger": "scan_data", + "source": "enter_date_of_birth", + "dest": "dob_edit_pin_authorization", + "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data", + "conditions": [ + "cic_ussd.state_machine.logic.validator.has_cached_user_metadata", + "cic_ussd.state_machine.logic.validator.is_valid_date" + ] + }, + { + "trigger": "scan_data", + "source": "enter_date_of_birth", + "dest": "enter_gender", + "conditions": "cic_ussd.state_machine.logic.validator.is_valid_date", + "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data", + "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata" + }, + { + "trigger": "scan_data", + "source": "enter_date_of_birth", + "dest": "exit_invalid_input", + "unless": "cic_ussd.state_machine.logic.validator.is_valid_date" + }, + { + "trigger": "scan_data", + "source": "dob_edit_pin_authorization", + "dest": "exit", + "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin", + "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute" + }, + { + "trigger": "scan_data", + "source": "dob_edit_pin_authorization", + "dest": "exit_pin_blocked", + "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account" + } +] \ No newline at end of file diff --git a/apps/cic-ussd/transitions/name_setting_transitions.json b/apps/cic-ussd/transitions/name_setting_transitions.json index 38b5e58c..7d3493e3 100644 --- a/apps/cic-ussd/transitions/name_setting_transitions.json +++ b/apps/cic-ussd/transitions/name_setting_transitions.json @@ -15,7 +15,7 @@ { "trigger": "scan_data", "source": "enter_family_name", - "dest": "enter_gender", + "dest": "enter_date_of_birth", "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data", "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata" }, diff --git a/apps/cic-ussd/transitions/user_metadata_transitions.json b/apps/cic-ussd/transitions/user_metadata_transitions.json index dff068f6..f0f428e3 100644 --- a/apps/cic-ussd/transitions/user_metadata_transitions.json +++ b/apps/cic-ussd/transitions/user_metadata_transitions.json @@ -14,21 +14,27 @@ { "trigger": "scan_data", "source": "metadata_management", - "dest": "enter_location", + "dest": "enter_date_of_birth", "conditions": "cic_ussd.state_machine.logic.menu.menu_three_selected" }, { "trigger": "scan_data", "source": "metadata_management", - "dest": "enter_products", + "dest": "enter_location", "conditions": "cic_ussd.state_machine.logic.menu.menu_four_selected" }, { "trigger": "scan_data", "source": "metadata_management", - "dest": "display_metadata_pin_authorization", + "dest": "enter_products", "conditions": "cic_ussd.state_machine.logic.menu.menu_five_selected" }, + { + "trigger": "scan_data", + "source": "metadata_management", + "dest": "display_metadata_pin_authorization", + "conditions": "cic_ussd.state_machine.logic.menu.menu_six_selected" + }, { "trigger": "scan_data", "source": "display_metadata_pin_authorization", diff --git a/apps/cic-ussd/var/lib/locale/ussd.en.yml b/apps/cic-ussd/var/lib/locale/ussd.en.yml index d1f0653b..fae5eead 100644 --- a/apps/cic-ussd/var/lib/locale/ussd.en.yml +++ b/apps/cic-ussd/var/lib/locale/ussd.en.yml @@ -17,6 +17,9 @@ en: enter_family_name: |- CON Enter family name 0. Back + enter_date_of_birth: |- + CON Enter year of birth + 0. Back enter_gender: |- CON Enter gender 1. Male @@ -52,14 +55,16 @@ en: CON My profile 1. Edit name 2. Edit gender - 3. Edit location - 4. Edit products - 5. View my profile + 3. Edit Age + 4. Edit location + 5. Edit products + 6. View my profile 0. Back display_user_metadata: |- CON Your details are: Name: %{full_name} Gender: %{gender} + Age: %{age} Location: %{location} You sell: %{products} 0. Back @@ -117,6 +122,13 @@ en: retry: |- CON Please enter your PIN. You have %{remaining_attempts} attempts remaining 0. Back + dob_edit_pin_authorization: + first: |- + CON Please enter your PIN + 0. Back + retry: |- + CON Please enter your PIN. You have %{remaining_attempts} attempts remaining + 0. Back gender_edit_pin_authorization: first: |- CON Please enter your PIN diff --git a/apps/cic-ussd/var/lib/locale/ussd.sw.yml b/apps/cic-ussd/var/lib/locale/ussd.sw.yml index a40db2b7..8a8394e5 100644 --- a/apps/cic-ussd/var/lib/locale/ussd.sw.yml +++ b/apps/cic-ussd/var/lib/locale/ussd.sw.yml @@ -17,6 +17,9 @@ sw: enter_family_name: |- CON Weka jina lako la mwisho 0. Nyuma + enter_date_of_birth: |- + CON Weka mwaka wa kuzaliwa + 0. Nyuma enter_gender: |- CON Weka jinsia yako 1. Mwanaume @@ -52,14 +55,16 @@ sw: CON Wasifu wangu 1. Weka jina 2. Weka jinsia - 3. Weka eneo - 4. Weka bidhaa - 5. Angalia wasifu wako + 3 Weka umri + 4. Weka eneo + 5. Weka bidhaa + 6. Angalia wasifu wako 0. Nyuma display_user_metadata: |- CON Wasifu wako una maelezo yafuatayo: Jina: %{full_name} Jinsia: %{gender} + Umri: %{age} Eneo: %{location} Unauza: %{products} 0. Nyuma @@ -117,6 +122,13 @@ sw: retry: |- CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki. 0. Nyuma + dob_edit_pin_authorization: + first: |- + CON Tafadhali weka PIN yako + 0. Nyuma + retry: |- + CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki. + 0. Nyuma gender_edit_pin_authorization: first: |- CON Tafadhali weka PIN yako