diff --git a/README.md b/README.md index 4273c83e..c6874393 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ addon | version | maintainers | summary [g2p_payment_interop_layer](g2p_payment_interop_layer/) | 17.0.0.0.0 | | OpenG2P Program Payment (Payment Interoperability Layer) [g2p_payment_phee](g2p_payment_phee/) | 17.0.0.0.0 | | OpenG2P Program Payment (Payment Hub EE) [g2p_payment_simple_mpesa](g2p_payment_simple_mpesa/) | 17.0.0.0.0 | | OpenG2P Program Payment: Simple Mpesa Payment Manager +[g2p_pbms_socio_economic_model](g2p_pbms_socio_economic_model/) | 17.0.0.0.0 | | G2P PBMS Socio-Economic Model +[g2p_pbms_student_model](g2p_pbms_student_model/) | 17.0.0.0.0 | | G2P PBMS Student Model [g2p_program_approval](g2p_program_approval/) | 17.0.0.0.0 | | OpenG2P Program: Approval [g2p_program_assessment](g2p_program_assessment/) | 17.0.0.0.0 | | OpenG2P Program: Assessment [g2p_program_autoenrol](g2p_program_autoenrol/) | 17.0.0.0.0 | | OpenG2P Programs: Autoenrol diff --git a/g2p_pbms_socio_economic_model/README.md b/g2p_pbms_socio_economic_model/README.md new file mode 100644 index 00000000..e83fabee --- /dev/null +++ b/g2p_pbms_socio_economic_model/README.md @@ -0,0 +1,3 @@ +# G2P PBMS Socio-Economic Model + +Refer to https://docs.openg2p.org. diff --git a/g2p_pbms_socio_economic_model/__init__.py b/g2p_pbms_socio_economic_model/__init__.py new file mode 100644 index 00000000..5d6d1635 --- /dev/null +++ b/g2p_pbms_socio_economic_model/__init__.py @@ -0,0 +1,3 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/g2p_pbms_socio_economic_model/__manifest__.py b/g2p_pbms_socio_economic_model/__manifest__.py new file mode 100644 index 00000000..697ec32f --- /dev/null +++ b/g2p_pbms_socio_economic_model/__manifest__.py @@ -0,0 +1,18 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. +{ + "name": "G2P PBMS Socio-Economic Model", + "category": "G2P", + "version": "17.0.0.0.0", + "sequence": 1, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": ["g2p_registry_individual", "g2p_registry_group", "g2p_registry_membership", "g2p_programs"], + "data": ["views/group_view.xml", "views/individual_view.xml", "views/menu_view.xml"], + "assets": {}, + "demo": [], + "images": [], + "application": True, + "installable": True, + "auto_install": False, +} diff --git a/g2p_pbms_socio_economic_model/data/sr_pbms_import_jq_mapping.jq b/g2p_pbms_socio_economic_model/data/sr_pbms_import_jq_mapping.jq new file mode 100644 index 00000000..cbb9c606 --- /dev/null +++ b/g2p_pbms_socio_economic_model/data/sr_pbms_import_jq_mapping.jq @@ -0,0 +1,68 @@ +{ + "name": .name, + "is_group": .isGroup, + "address": .address, + "registration_date": .registrationDate, + "group_membership_ids": ( + if .groupMembershipIds? then + [ + .groupMembershipIds[] | { + "individual": { + "name": .individual.name, + "given_name": .individual.givenName, + "family_name": .individual.familyName, + "addl_name": .individual.addlName, + "email": .individual.email, + "address": .individual.address, + "registration_date": .individual.registrationDate, + "birth_place": .individual.birthPlace, + "birthdate": .individual.birthdate, + "create_date": .individual.createDate, + "write_date": .individual.writeDate, + "reg_ids": ( + if .individual.regIds? then + [.individual.regIds[] | {id_type: {name:.idTypeAsStr}, value: .value}] + else + [] + end + ), + "phone_number_ids": ( + if .individual.phoneNumberIds? then + [.individual.phoneNumberIds[] | { + phone_no: .phoneNo, + phone_sanitized: .phoneSanitized, + date_collected: .dateCollected, + disabled: .disabled + }] + else + [] + end + ) + }, + "kind": {name:.kind.name} + } + ] + else + [] + end + ), + "reg_ids": ( + if .regIds? then + [.regIds[] | {id_type: {name:.idTypeAsStr}, value: .value}] + else + [] + end + ), + "phone_number_ids": ( + if .phoneNumberIds? then + [.phoneNumberIds[] | { + phone_no: .phoneNo, + phone_sanitized: .phoneSanitized, + date_collected: .dateCollected, + disabled: .disabled + }] + else + [] + end + ) +} diff --git a/g2p_pbms_socio_economic_model/models/__init__.py b/g2p_pbms_socio_economic_model/models/__init__.py new file mode 100644 index 00000000..a471c819 --- /dev/null +++ b/g2p_pbms_socio_economic_model/models/__init__.py @@ -0,0 +1,4 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. + +from . import group_membership +from . import res_partner diff --git a/g2p_pbms_socio_economic_model/models/group_membership.py b/g2p_pbms_socio_economic_model/models/group_membership.py new file mode 100644 index 00000000..504f0317 --- /dev/null +++ b/g2p_pbms_socio_economic_model/models/group_membership.py @@ -0,0 +1,24 @@ +# Part of OpenG2P Registry. See LICENSE file for full copyright and licensing details. + +import logging + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + + +class G2PGroupMembershipInherit(models.Model): + _inherit = "g2p.group.membership" + + employment_status = fields.Selection(related="individual.employment_status") + + def get_household_head(self, registrant): + if registrant.is_group: + for member in registrant.group_membership_ids: + if member.kind and "Head" in [kind.name for kind in member.kind]: + return member.individual + + else: + for member in registrant.individual_membership_ids: + if member.kind and "Head" in [kind.name for kind in member.kind]: + return member.individual diff --git a/g2p_pbms_socio_economic_model/models/res_partner.py b/g2p_pbms_socio_economic_model/models/res_partner.py new file mode 100644 index 00000000..a3902179 --- /dev/null +++ b/g2p_pbms_socio_economic_model/models/res_partner.py @@ -0,0 +1,127 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. +import logging + +from odoo import api, fields, models + +_logger = logging.getLogger(__name__) + + +class G2PResPartnerInherited(models.Model): + _inherit = "res.partner" + + ####################################################### + ##### Social Status Information ##### + ####################################################### + + num_preg_lact_women = fields.Integer() + num_malnourished_children = fields.Integer() + num_disabled = fields.Integer() + type_of_disability = fields.Selection( + [ + ("visual_impairment", "Visual Impairment"), + ("hearing_impairment", "Hearing Impairment"), + ("physical_disability", "Physical Disability"), + ("cognitive_disability", "Cognitive Disability"), + ] + ) + caste_ethnic_group = fields.Selection( + [ + ("bantu", "Bantu"), + ("nilotic", "Nilotic"), + ("afro_asian", "Afro-Asiatic"), + ("khoisan", "Khoisan"), + ("pygmy", "Pygmy"), + ("other", "Other"), + ], + ) + belong_to_protected_groups = fields.Selection([("yes", "Yes"), ("no", "No")]) + other_vulnerable_status = fields.Selection([("yes", "Yes"), ("no", "No")]) + + ####################################################### + ##### Household Details ##### + ####################################################### + + education_level = fields.Selection( + [ + ("primary", "Primary"), + ("secondary", "Secondary"), + ("higher_secondary", "Higher Secondary"), + ("bachelors", "Bachelors"), + ("masters", "Masters"), + ] + ) + employment_status = fields.Selection( + [ + ("employed_full", "Employed - Full Time"), + ("employed_part", "Employed - Part Time"), + ("self_employed", "Self-employed"), + ("unemployed", "Unemployed"), + ] + ) + marital_status = fields.Selection( + [("single", "Single"), ("married", "Married"), ("divorced", "divorced")] + ) + + ####################################################### + ##### Economic Status Information ##### + ####################################################### + + income_sources = fields.Selection( + [ + ("agriculture", "Agriculture"), + ("business", "Business"), + ("mining", "Mining"), + ("manufacturing", "Manufacturing"), + ("construction", "Construction"), + ] + ) + # Income field was of INT type and it has validation which will cause the errors. + annual_income = fields.Selection( + [("below_5000", "Below 5000"), ("5001_10000", "5001-10,000"), ("above_10000", "Above 10,000")], + ) + owns_two_wheeler = fields.Selection([("yes", "Yes"), ("no", "No")]) + owns_three_wheeler = fields.Selection([("yes", "Yes"), ("no", "No")]) + owns_four_wheeler = fields.Selection([("yes", "Yes"), ("no", "No")]) + owns_cart = fields.Selection([("yes", "Yes"), ("no", "No")]) + land_ownership = fields.Selection([("yes", "Yes"), ("no", "No")]) + type_of_land_owned = fields.Selection( + [ + ("agricultural", "Agricultural Land"), + ("residential", "Residential Land"), + ("pastoral", "Pastoral Land"), + ("forest", "Forest Land"), + ("commercial", "Commercial Land"), + ("communal", "Communal Land"), + ("other", "Other"), + ] + ) + land_size = fields.Float() + owns_house = fields.Selection([("yes", "Yes"), ("no", "No")]) + owns_livestock = fields.Selection([("yes", "Yes"), ("no", "No")]) + + ####################################################### + ##### Housing Condition Information ##### + ####################################################### + + housing_type = fields.Selection( + [("permanent", "Permanent"), ("temporary", "Temporary")], "Type of Housing" + ) + house_condition = fields.Selection([("mud", "Mud"), ("cement", "Cement")]) + sanitation_condition = fields.Selection([("yes", "Yes"), ("no", "No")]) + water_access = fields.Selection([("yes", "Yes"), ("no", "No")]) + electricity_access = fields.Selection([("yes", "Yes"), ("no", "No")]) + + ####################################################### + ##### Computed Fields ##### + ####################################################### + + is_hh_unemployed = fields.Boolean(compute="_compute_hh_is_unemployed", store=True) + + @api.constrains("group_membership_ids", "employment_status") + def _compute_hh_is_unemployed(self): + for rec in self: + group_head = self.env["g2p.group.membership"].get_household_head(rec) + if group_head: + rec.is_hh_unemployed = group_head.employment_status == "unemployed" + else: + rec.is_hh_unemployed = False diff --git a/g2p_pbms_socio_economic_model/pyproject.toml b/g2p_pbms_socio_economic_model/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_pbms_socio_economic_model/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_pbms_socio_economic_model/static/description/icon.png b/g2p_pbms_socio_economic_model/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_pbms_socio_economic_model/static/description/icon.png differ diff --git a/g2p_pbms_socio_economic_model/views/group_view.xml b/g2p_pbms_socio_economic_model/views/group_view.xml new file mode 100644 index 00000000..fcce65ae --- /dev/null +++ b/g2p_pbms_socio_economic_model/views/group_view.xml @@ -0,0 +1,41 @@ + + + + + view_group_view_pbms_model + res.partner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/g2p_pbms_socio_economic_model/views/individual_view.xml b/g2p_pbms_socio_economic_model/views/individual_view.xml new file mode 100644 index 00000000..b59e1bfb --- /dev/null +++ b/g2p_pbms_socio_economic_model/views/individual_view.xml @@ -0,0 +1,18 @@ + + + + + view_individual_form_pbms_model + res.partner + + + + + + + + + + diff --git a/g2p_pbms_socio_economic_model/views/menu_view.xml b/g2p_pbms_socio_economic_model/views/menu_view.xml new file mode 100644 index 00000000..34fc0d6d --- /dev/null +++ b/g2p_pbms_socio_economic_model/views/menu_view.xml @@ -0,0 +1,15 @@ + + + + + + + diff --git a/g2p_pbms_student_model/README.md b/g2p_pbms_student_model/README.md new file mode 100644 index 00000000..658444f5 --- /dev/null +++ b/g2p_pbms_student_model/README.md @@ -0,0 +1,3 @@ +# G2P PBMS Student Model + +Refer to https://docs.openg2p.org. diff --git a/g2p_pbms_student_model/__init__.py b/g2p_pbms_student_model/__init__.py new file mode 100644 index 00000000..5d6d1635 --- /dev/null +++ b/g2p_pbms_student_model/__init__.py @@ -0,0 +1,3 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/g2p_pbms_student_model/__manifest__.py b/g2p_pbms_student_model/__manifest__.py new file mode 100644 index 00000000..9759ab8d --- /dev/null +++ b/g2p_pbms_student_model/__manifest__.py @@ -0,0 +1,18 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. +{ + "name": "G2P PBMS Student Model", + "category": "G2P", + "version": "17.0.0.0.0", + "sequence": 1, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": ["g2p_registry_individual", "g2p_programs"], + "data": ["views/individual_view.xml"], + "assets": {}, + "demo": [], + "images": [], + "application": True, + "installable": True, + "auto_install": False, +} diff --git a/g2p_pbms_student_model/models/__init__.py b/g2p_pbms_student_model/models/__init__.py new file mode 100644 index 00000000..a5507987 --- /dev/null +++ b/g2p_pbms_student_model/models/__init__.py @@ -0,0 +1,3 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. + +from . import res_partner diff --git a/g2p_pbms_student_model/models/res_partner.py b/g2p_pbms_student_model/models/res_partner.py new file mode 100644 index 00000000..70c12576 --- /dev/null +++ b/g2p_pbms_student_model/models/res_partner.py @@ -0,0 +1,65 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. +import logging + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + + +class ResPartner(models.Model): + _inherit = "res.partner" + + ########################## + ## Student Info ## + ########################## + + institution_name = fields.Selection( + [ + ("UCT", "University of Cape Town"), + ("SIT", "Stellenbosch Institute of Technology"), + ("DCE", "Durban College of Engineering"), + ] + ) + + year_of_study = fields.Selection( + [("1", "1st Year"), ("2", "2nd Year"), ("3", "3rd Year"), ("4", "4th Year")] + ) + + course_name = fields.Selection( + [ + ("cs", "Computer Science"), + ("ec", "Electrical Engineering"), + ("me", "Mechanical Engineering"), + ("ce", "Civil Engineering"), + ("fa", "Financial Accounting"), + ("mm", "Marketing Management"), + ("scl", "Supply Chain & Logistics"), + ("bt", "Biotechnology"), + ("es", "Environmental Science"), + ("pse", "Polymer Science"), + ] + ) + qualification_type = fields.Selection( + [("cerficiate", "Certificate"), ("diploma", "Diploma"), ("degree", "Degree")] + ) + duration_of_course = fields.Char() + previous_nsfas_beneficiary = fields.Selection([("yes", "Yes"), ("no", "No")]) + + ########################## + ## Parent/Guardian Info ## + ########################## + + guardian_name = fields.Char() + guardian_id = fields.Char() + household_income = fields.Selection( + [ + ("below_122000", "Below R122,000"), + ("122000_to_350000", "R122,000 - R350,000"), + ("above_350000", "Above R350,000"), + ] + ) + guardian_employment_status = fields.Selection([("employed", "Employed"), ("unemployed", "Unemployed")]) + number_of_dependents = fields.Integer() + accommodation_type = fields.Selection( + [("owned", "Owned"), ("rented", "Rented"), ("informal", "Informal Settlement")] + ) diff --git a/g2p_pbms_student_model/pyproject.toml b/g2p_pbms_student_model/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_pbms_student_model/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_pbms_student_model/static/description/icon.png b/g2p_pbms_student_model/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_pbms_student_model/static/description/icon.png differ diff --git a/g2p_pbms_student_model/views/individual_view.xml b/g2p_pbms_student_model/views/individual_view.xml new file mode 100644 index 00000000..2aaf161b --- /dev/null +++ b/g2p_pbms_student_model/views/individual_view.xml @@ -0,0 +1,35 @@ + + + + + view_individual_form_pbms_student_model + res.partner + + + + + + + + + + + + + + + + + + + + + + + + + + +