diff --git a/.copier-answers.yml b/.copier-answers.yml index 4619aa9..4cc764f 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,17 +1,18 @@ # Do NOT update manually; changes here will be overwritten by Copier _commit: v1.20 _src_path: https://github.com/OCA/oca-addons-repo-template.git +additional_ruff_rules: [] ci: GitHub convert_readme_fragments_to_markdown: false generate_requirements_txt: true github_check_license: false github_ci_extra_env: {} -github_enable_codecov: false -github_enable_makepot: false +github_enable_codecov: true +github_enable_makepot: true github_enable_stale_action: false github_enforce_dev_status_compatibility: false include_wkhtmltopdf: false -odoo_test_flavor: Odoo +odoo_test_flavor: Both odoo_version: 17.0 org_name: OpenG2P org_slug: OpenG2P @@ -20,6 +21,6 @@ repo_description: Self Service Portal repo_name: OpenG2P Self Service Portal repo_slug: openg2p-self-service-portal repo_website: https://github.com/OpenG2P/openg2p-self-service-portal -use_pyproject_toml: false -use_ruff: false +use_pyproject_toml: true +use_ruff: true diff --git a/.eslintrc.yml b/.eslintrc.yml index 31ff493..209e512 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -8,7 +8,6 @@ parserOptions: overrides: - files: - - "**/*.esm.js" - "**/*.js" parserOptions: sourceType: module diff --git a/.flake8 b/.flake8 deleted file mode 100644 index ff1c593..0000000 --- a/.flake8 +++ /dev/null @@ -1,12 +0,0 @@ -[flake8] -max-line-length = 110 -max-complexity = 16 -# B = bugbear -# B9 = bugbear opinionated (incl line length) -select = C,E,F,W,B,B9 -# E203: whitespace before ':' (black behaviour) -# E501: flake8 line length (covered by bugbear B950) -# W503: line break before binary operator (black behaviour) -ignore = E203,E501,W503 -per-file-ignores= - __init__.py:F401 diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index c58f629..610b332 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -2,12 +2,7 @@ name: pre-commit on: pull_request: - branches: - - "17.0*" push: - branches: - - "17.0" - - "17.0-ocabot-*" jobs: pre-commit: @@ -27,15 +22,6 @@ jobs: run: pip install pre-commit - name: Run pre-commit run: pre-commit run --all-files --show-diff-on-failure --color=always - env: - # Consider valid a PR that changes README fragments but doesn't - # change the README.rst file itself. It's not really a problem - # because the bot will update it anyway after merge. This way, we - # lower the barrier for functional contributors that want to fix the - # readme fragments, while still letting developers get README - # auto-generated (which also helps functionals when using runboat). - # DOCS https://pre-commit.com/#temporarily-disabling-hooks - SKIP: oca-gen-addon-readme - name: Check that all files generated by pre-commit are in git run: | newfiles="$(git ls-files --others --exclude-from=.gitignore)" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5848ee1..8e6e90e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,16 +3,18 @@ name: tests on: pull_request: branches: - - "17.0*" + - "15.0*" - "17.0*" push: branches: - - "17.0" - - "17.0-ocabot-*" - + - "15.0*" + - "17.0*" +env: + OCA_GIT_USER_NAME: openg2p + OCA_GIT_USER_EMAIL: bot@openg2p.org jobs: unreleased-deps: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 name: Detect unreleased dependencies steps: - uses: actions/checkout@v3 @@ -28,19 +30,44 @@ jobs: fi fi done + matrix_prep: + runs-on: ubuntu-22.04 + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - id: set-matrix + run: | + BRANCH_NAME=$(echo ${{ github.base_ref || github.ref }} | sed -e 's,.*/\(.*\),\1,') + if [[ $BRANCH_NAME = 15.0* ]] ; then + matrix='{"include": [{ + "container": "ghcr.io/oca/oca-ci/py3.8-odoo15.0:latest", + "makepot": "true", + "name": "test with Odoo 15" + },{ + "container": "ghcr.io/oca/oca-ci/py3.8-ocb15.0:latest", + "name": "test with OCB 15" + }]}' + elif [[ $BRANCH_NAME = 17.0* ]] ; then + matrix='{"include": [{ + "container": "ghcr.io/oca/oca-ci/py3.10-odoo17.0:latest", + "makepot": "true", + "name": "test with Odoo 17" + },{ + "container": "ghcr.io/oca/oca-ci/py3.10-ocb17.0:latest", + "name": "test with OCB 17" + }]}' + fi + echo "matrix=$matrix" | tr -d '\n' >> $GITHUB_OUTPUT test: - runs-on: ubuntu-latest + needs: matrix_prep + runs-on: ubuntu-22.04 container: ${{ matrix.container }} name: ${{ matrix.name }} permissions: contents: write strategy: fail-fast: false - matrix: - include: - - container: ghcr.io/oca/oca-ci/py3.10-odoo17.0:latest - name: test with Odoo - makepot: "false" + matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}} services: postgres: image: postgres:12.0 @@ -51,7 +78,6 @@ jobs: ports: - 5432:5432 steps: - - uses: actions/checkout@v3 - uses: actions/checkout@v3 with: persist-credentials: false @@ -67,6 +93,7 @@ jobs: run: oca_init_test_database - name: Run tests run: oca_run_tests + - uses: codecov/codecov-action@v1 - name: Update .pot files run: oca_export_and_push_pot https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }} if: ${{ matrix.makepot == 'true' && github.event_name == 'push' && github.repository_owner == 'openg2p' }} diff --git a/.isort.cfg b/.isort.cfg deleted file mode 100644 index 1a48ae4..0000000 --- a/.isort.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[settings] -; see https://github.com/psf/black -multi_line_output=3 -include_trailing_comma=True -force_grid_wrap=0 -combine_as_imports=True -use_parentheses=True -line_length=110 -known_odoo=odoo -known_odoo_addons=odoo.addons -sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER -default_section=THIRDPARTY -ensure_newline_before_comments = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3e13afb..34a94b5 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,41 +36,32 @@ repos: entry: found a en.po file language: fail files: '[a-zA-Z0-9_]*/i18n/en\.po$' + - repo: https://github.com/sbidoul/whool + rev: v0.5 + hooks: + - id: whool-init - repo: https://github.com/oca/maintainer-tools rev: 9a170331575a265c092ee6b24b845ec508e8ef75 hooks: # update the NOT INSTALLABLE ADDONS section above - id: oca-update-pre-commit-excluded-addons - id: oca-fix-manifest-website - args: ["https://github.com/OpenG2P/openg2p-self-service-portal"] + args: ["https://openg2p.org"] - id: oca-gen-addon-readme args: - --addons-dir=. - - --branch=17.0 + - --branch=17.0-develop - --org-name=OpenG2P - --repo-name=openg2p-self-service-portal - --if-source-changed - --keep-source-digest + - id: oca-gen-addons-table + - id: oca-gen-external-dependencies - repo: https://github.com/OCA/odoo-pre-commit-hooks rev: v0.0.25 hooks: - id: oca-checks-odoo-module - id: oca-checks-po - - repo: https://github.com/myint/autoflake - rev: v1.6.1 - hooks: - - id: autoflake - args: - - --expand-star-imports - - --ignore-init-module-imports - - --in-place - - --remove-all-unused-imports - - --remove-duplicate-keys - - --remove-unused-variables - - repo: https://github.com/psf/black - rev: 22.8.0 - hooks: - - id: black - repo: https://github.com/pre-commit/mirrors-prettier rev: v2.7.1 hooks: @@ -112,35 +103,12 @@ repos: - id: check-xml - id: mixed-line-ending args: ["--fix=lf"] - - repo: https://github.com/asottile/pyupgrade - rev: v2.38.2 - hooks: - - id: pyupgrade - args: ["--keep-percent-format"] - - repo: https://github.com/PyCQA/isort - rev: 5.12.0 - hooks: - - id: isort - name: isort except __init__.py - args: - - --settings=. - exclude: /__init__\.py$ - - repo: https://github.com/acsone/setuptools-odoo - rev: 3.1.8 - hooks: - - id: setuptools-odoo-make-default - - id: setuptools-odoo-get-requirements - args: - - --output - - requirements.txt - - --header - - "# generated from manifests external_dependencies" - - repo: https://github.com/PyCQA/flake8 - rev: 3.9.2 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.1.3 hooks: - - id: flake8 - name: flake8 - additional_dependencies: ["flake8-bugbear==21.9.2"] + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format - repo: https://github.com/OCA/pylint-odoo rev: v9.0.4 hooks: diff --git a/.pylintrc b/.pylintrc index 9815b2f..5ffeaa7 100644 --- a/.pylintrc +++ b/.pylintrc @@ -9,7 +9,7 @@ readme-template-url="https://github.com/OCA/maintainer-tools/blob/master/templat manifest-required-authors=OpenG2P manifest-required-keys=license manifest-deprecated-keys=description,active -license-allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3 +license-allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3,Other OSI approved licence valid-odoo-versions=17.0 [MESSAGES CONTROL] diff --git a/.pylintrc-mandatory b/.pylintrc-mandatory index ec88e47..27076d0 100644 --- a/.pylintrc-mandatory +++ b/.pylintrc-mandatory @@ -8,7 +8,7 @@ readme-template-url="https://github.com/OCA/maintainer-tools/blob/master/templat manifest-required-authors=OpenG2P manifest-required-keys=license manifest-deprecated-keys=description,active -license-allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3 +license-allowed=AGPL-3,GPL-2,GPL-2 or any later version,GPL-3,GPL-3 or any later version,LGPL-3,Other OSI approved licence valid-odoo-versions=17.0 [MESSAGES CONTROL] diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 0000000..8511d42 --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,31 @@ + +target-version = "py310" +fix = true +line-length = 110 + +[lint] +extend-select = [ + "B", + "C90", + "E501", # line too long (default 88) + "I", # isort + "UP", # pyupgrade +] +exclude = ["setup/*"] + +[format] +exclude = ["setup/*"] + +[per-file-ignores] +"__init__.py" = ["F401", "I001"] # ignore unused and unsorted imports in __init__.py +"__manifest__.py" = ["B018"] # useless expression + +[isort] +section-order = ["future", "standard-library", "third-party", "odoo", "odoo-addons", "first-party", "local-folder"] + +[isort.sections] +"odoo" = ["odoo"] +"odoo-addons" = ["odoo.addons"] + +[mccabe] +max-complexity = 16 diff --git a/README.md b/README.md index 6236a34..90f727b 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,15 @@ -[![Pre-commit Status](https://github.com/OpenG2P/openg2p-self-service-portal/actions/workflows/pre-commit.yml/badge.svg?branch=17.0)](https://github.com/OpenG2P/openg2p-self-service-portal/actions/workflows/pre-commit.yml?query=branch%3A17.0) -[![Build Status](https://github.com/OpenG2P/openg2p-self-service-portal/actions/workflows/test.yml/badge.svg?branch=17.0)](https://github.com/OpenG2P/openg2p-self-service-portal/actions/workflows/test.yml?query=branch%3A17.0) -[![codecov](https://codecov.io/gh/OpenG2P/openg2p-self-service-portal/branch/17.0/graph/badge.svg)](https://codecov.io/gh/OpenG2P/openg2p-self-service-portal) +[![Pre-commit Status](https://github.com/OpenG2P/openg2p-self-service-portal/actions/workflows/pre-commit.yml/badge.svg?branch=17.0-develop)](https://github.com/OpenG2P/openg2p-self-service-portal/actions/workflows/pre-commit.yml?query=branch%3A17.0-develop) +[![Build Status](https://github.com/OpenG2P/openg2p-self-service-portal/actions/workflows/test.yml/badge.svg?branch=17.0-develop)](https://github.com/OpenG2P/openg2p-self-service-portal/actions/workflows/test.yml?query=branch%3A17.0-develop) +[![codecov](https://codecov.io/gh/OpenG2P/openg2p-self-service-portal/branch/17.0-develop/graph/badge.svg)](https://codecov.io/gh/OpenG2P/openg2p-self-service-portal) # OpenG2P Self Service Portal -Beneficiary facing self service portal. Refer to [OpenG2P Docs](https://docs.openg2p.org/v/1.1). +Beneficiary facing self service portal. Refer to [OpenG2P Docs](https://docs.openg2p.org). @@ -21,8 +21,8 @@ Available addons ---------------- addon | version | maintainers | summary --- | --- | --- | --- -[g2p_self_service_portal](g2p_self_service_portal/) | 17.0.1.0.0 | | G2P Self Service Portal -[g2p_service_provider_portal](g2p_service_provider_portal/) | 17.0.1.0.0 | | G2P Service Provider Portal +[g2p_self_service_portal](g2p_self_service_portal/) | 17.0.1.2.0 | | G2P Self Service Portal +[g2p_service_provider_portal](g2p_service_provider_portal/) | 17.0.1.2.0 | | G2P Service Provider Portal [//]: # (end addons) diff --git a/g2p_self_service_portal/README.rst b/g2p_self_service_portal/README.rst index 06964b9..98f69c6 100644 --- a/g2p_self_service_portal/README.rst +++ b/g2p_self_service_portal/README.rst @@ -14,7 +14,7 @@ G2P Self Service Portal :target: https://odoo-community.org/page/development-status :alt: Alpha .. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--self--service--portal-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-self-service-portal/tree/17.0/g2p_self_service_portal + :target: https://github.com/OpenG2P/openg2p-self-service-portal/tree/17.0-develop/g2p_self_service_portal :alt: OpenG2P/openg2p-self-service-portal |badge1| |badge2| @@ -37,7 +37,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -52,6 +52,6 @@ Authors Maintainers ~~~~~~~~~~~ -This module is part of the `OpenG2P/openg2p-self-service-portal `_ project on GitHub. +This module is part of the `OpenG2P/openg2p-self-service-portal `_ project on GitHub. You are welcome to contribute. diff --git a/g2p_self_service_portal/__manifest__.py b/g2p_self_service_portal/__manifest__.py index 69aa1ed..15ad9f7 100644 --- a/g2p_self_service_portal/__manifest__.py +++ b/g2p_self_service_portal/__manifest__.py @@ -1,10 +1,10 @@ { "name": "G2P Self Service Portal", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.1.2.0", "sequence": 1, "author": "OpenG2P", - "website": "https://github.com/OpenG2P/openg2p-self-service-portal", + "website": "https://openg2p.org", "license": "Other OSI approved licence", "development_status": "Alpha", "depends": [ @@ -15,6 +15,7 @@ "g2p_program_documents", "website", "web", + "g2p_portal_auth", ], "data": [ "data/g2p_self_service_form_action_data.xml", @@ -28,8 +29,6 @@ "views/g2p_self_service_aboutus.xml", "views/g2p_self_service_otherpage.xml", "views/g2p_self_service_contactus.xml", - # TODO: The 'auth_oidc' module was removed; a replacement is needed in the code. - # "views/auth_oauth_provider.xml", "views/g2p_self_service_form_page_template.xml", "views/program_view.xml", "views/g2p_self_service_signup.xml", @@ -40,7 +39,6 @@ "wizard/g2p_self_service_program_view_wizard.xml", ], "assets": { - "web.assets_backend": [], "web.assets_frontend": [ "g2p_self_service_portal/static/src/js/self_service_form_action.js", # # "g2p_self_service_portal/static/src/js/self_service_pie_chart.js", diff --git a/g2p_self_service_portal/controllers/main.py b/g2p_self_service_portal/controllers/main.py index b975f52..cb9f45e 100644 --- a/g2p_self_service_portal/controllers/main.py +++ b/g2p_self_service_portal/controllers/main.py @@ -13,10 +13,6 @@ from odoo.addons.auth_signup.controllers.main import AuthSignupHome from odoo.addons.web.controllers.home import Home -# TODO: The 'auth_oidc' module was removed; a replacement is needed in the code. -# from odoo.addons.auth_oidc.controllers.main import OpenIDLogin - - _logger = logging.getLogger(__name__) @@ -30,39 +26,36 @@ def self_service_root(self, **kwargs): @http.route(["/selfservice/login"], type="http", auth="public", website=True) def self_service_login(self, **kwargs): + redirect_uri = request.params.get("redirect") or "/selfservice/home" if request.session and request.session.uid: - return request.redirect("/selfservice/home") - request.params["redirect"] = "/" - context = {} - - providers = [] + return request.redirect(redirect_uri) - # TODO: The 'auth_oidc' module was removed; a replacement is needed in the code." - # try: - # providers = OpenIDLogin().list_providers( - # domain=[("g2p_self_service_allowed", "=", True)] - # ) - # except Exception: - # providers = OpenIDLogin().list_providers() - - context.update(dict(providers=providers)) + context = {} if request.httprequest.method == "POST": res = Home().web_login(**kwargs) - - if not request.params["login_success"]: + if request.params["login_success"]: + return res + else: context["error"] = "Invalid Credentials" - return request.render( - "g2p_self_service_portal.login_page", qcontext=context - ) - return res + providers = ( + request.env["auth.oauth.provider"] + .sudo() + .get_portal_auth_providers( + domain=(("g2p_self_service_allowed", "=", True),), + redirect=redirect_uri, + base_url=request.httprequest.url_root.rstrip("/"), + db_name=request.session.db, + ) + or [] + ) + context.update(dict(providers=providers)) return request.render("g2p_self_service_portal.login_page", qcontext=context) @http.route(["/selfservice/signup"], type="http", auth="public", website=True) def self_service_signup(self, **kwargs): - if request.session and request.session.uid: return request.redirect("/selfservice/home") request.session["signup_form_filled"] = True @@ -71,16 +64,13 @@ def self_service_signup(self, **kwargs): stored_otp = request.session["otp"] if stored_otp and int(kwargs["otp"]) and stored_otp == int(kwargs["otp"]): - request.session.pop("otp") request.session.pop("signup_form_filled") # TODO: Check if user already present # TODO: Enable both email and phone login - request.params["login"] = ( - kwargs["email"] if kwargs["email"] else kwargs["phone"] - ) + request.params["login"] = kwargs["email"] if kwargs["email"] else kwargs["phone"] AuthSignupHome().web_auth_signup(**kwargs) current_partner = request.env.user.partner_id @@ -99,9 +89,7 @@ def self_service_signup(self, **kwargs): # Adding VID number config = request.env["ir.config_parameter"].sudo() - reg_id_type_id = config.get_param( - "g2p_self_service_portal.self_service_signup_id_type", None - ) + reg_id_type_id = config.get_param("g2p_self_service_portal.self_service_signup_id_type", None) def_notif_pref = config.get_param( "g2p_notifications_base.default_notification_preference", None ) @@ -109,7 +97,6 @@ def self_service_signup(self, **kwargs): current_partner.write({"notification_preference": def_notif_pref}) if kwargs["vid"] and reg_id_type_id: - ( request.env["g2p.reg.id"] .sudo() @@ -150,7 +137,6 @@ def self_service_signup(self, **kwargs): csrf=False, ) def self_service_signup_otp(self, **kw): - if not request.session.get("signup_form_filled"): return request.redirect("/selfservice") @@ -161,11 +147,7 @@ def self_service_signup_otp(self, **kw): if request.httprequest.method == "POST": kw["name"] = ( - kw["family_name"].title() - + ", " - + kw["given_name"].title() - + " " - + kw["addl_name"].title() + kw["family_name"].title() + ", " + kw["given_name"].title() + " " + kw["addl_name"].title() ) return request.render( @@ -176,9 +158,7 @@ def self_service_signup_otp(self, **kw): @http.route(["/selfservice/logo"], type="http", auth="public", website=True) def self_service_logo(self, **kwargs): config = request.env["ir.config_parameter"].sudo() - attachment_id = config.get_param( - "g2p_self_service_portal.self_service_logo_attachment" - ) + attachment_id = config.get_param("g2p_self_service_portal.self_service_logo_attachment") return request.redirect("/web/content/%s" % attachment_id) @http.route(["/selfservice/myprofile"], type="http", auth="public", website=True) @@ -243,57 +223,39 @@ def self_service_home(self, **kwargs): ) if len(membership) > 0: for rec in membership.program_registrant_info_ids: + total_issued = rec.entitlement_id.initial_amount if rec.entitlement_id else 0 + total_paid = sum( + (pay.amount_paid for pay in rec.entitlement_id.payment_ids if pay) + if rec.entitlement_id + else [] + ) myprograms.append( { "id": program.id, "name": program.name, "has_applied": len(membership) > 0, - "single_submission": len( - membership.program_registrant_info_ids - ) - == 1, - "program_status": program_states.get( - membership.state, "Error" - ), - "application_status": application_states.get( - rec.state, "Error" - ) + "single_submission": len(membership.program_registrant_info_ids) == 1, + "program_status": program_states.get(membership.state, "Error"), + "application_status": application_states.get(rec.state, "Error") if membership.state not in ("not_eligible", "duplicated") else program_states.get(membership.state, "Error"), - "issued": "{:,.2f}".format( - rec.entitlement_id.initial_amount - if rec.entitlement_id - else 0 - ), - "paid": "{:,.2f}".format( - sum( - pay.amount_paid if pay else 0 - for pay in rec.entitlement_id.payment_ids - ) - or 0 - ), + "issued": f"{total_issued:,.2f}", + "paid": f"{total_paid:,.2f}", "enrollment_date": rec.create_date.strftime("%d-%b-%Y") if rec.create_date else None, - "is_latest": (datetime.today() - program.create_date).days - < 21, - "application_id": rec.application_id - if rec.application_id - else None, + "is_latest": (datetime.today() - program.create_date).days < 21, + "application_id": rec.application_id if rec.application_id else None, } ) entitlement = sum( ent.initial_amount if ent.state == "approved" else 0 - for ent in request.env["g2p.entitlement"] - .sudo() - .search([("partner_id", "=", partner_id.id)]) + for ent in request.env["g2p.entitlement"].sudo().search([("partner_id", "=", partner_id.id)]) ) received = sum( pay.amount_paid if pay.status == "paid" else 0 - for pay in request.env["g2p.payment"] - .sudo() - .search([("partner_id", "=", partner_id.id)]) + for pay in request.env["g2p.payment"].sudo().search([("partner_id", "=", partner_id.id)]) ) pending = entitlement - received @@ -312,9 +274,7 @@ def self_service_all_programs(self, **kwargs): programs = request.env["g2p.program"].sudo().search([("state", "=", "active")]) if programs.fields_get("is_reimbursement_program"): - programs = programs.search( - [("state", "=", "active"), ("is_reimbursement_program", "=", False)] - ) + programs = programs.search([("state", "=", "active"), ("is_reimbursement_program", "=", False)]) partner_id = request.env.user.partner_id states = { @@ -342,20 +302,14 @@ def self_service_all_programs(self, **kwargs): "name": program.name, "description": program.description, "has_applied": len(membership) > 0, - "single_submission": len(membership.program_registrant_info_ids) - == 1, + "single_submission": len(membership.program_registrant_info_ids) == 1, "status": states.get(membership.state, "Error"), - "is_application_rejected": membership.latest_registrant_info_status - == "rejected" + "is_application_rejected": membership.latest_registrant_info_status == "rejected" if membership.latest_registrant_info_status else False, "is_latest": (datetime.today() - program.create_date).days < 21, - "is_form_mapped": True - if program.self_service_portal_form - else False, - "is_multiple_form_submission": True - if program.multiple_form_submission - else False, + "is_form_mapped": True if program.self_service_portal_form else False, + "is_multiple_form_submission": True if program.multiple_form_submission else False, } ) @@ -370,9 +324,7 @@ def self_service_all_programs(self, **kwargs): }, ) - @http.route( - ["/selfservice/submissions/"], type="http", auth="user", website=True - ) + @http.route(["/selfservice/submissions/"], type="http", auth="user", website=True) def self_service_all_submissions(self, _id): self.self_service_check_roles("REGISTRANT") program = request.env["g2p.program"].sudo().browse(_id) @@ -396,8 +348,7 @@ def self_service_all_submissions(self, _id): "applied_on": detail.create_date.strftime("%d-%b-%Y"), "application_id": detail.application_id, "status": detail.state - if detail.program_membership_id.state - not in ("duplicated", "not_eligible") + if detail.program_membership_id.state not in ("duplicated", "not_eligible") else detail.program_membership_id.state, } ) @@ -417,15 +368,11 @@ def self_service_all_submissions(self, _id): "program_id": program.id, "submission_records": submission_records, "re_apply": re_apply, - "is_multiple_form_submission": True - if program.multiple_form_submission - else False, + "is_multiple_form_submission": True if program.multiple_form_submission else False, }, ) - @http.route( - ["/selfservice/apply/"], type="http", auth="user", website=True - ) + @http.route(["/selfservice/apply/"], type="http", auth="user", website=True) def self_service_apply_programs(self, _id): self.self_service_check_roles("REGISTRANT") @@ -587,18 +534,11 @@ def self_service_form_details(self, _id, **kwargs): { "program": program.name, "submission_date": program_reg_info.create_date.strftime("%d-%b-%Y"), - "application_status": application_states.get( - program_reg_info.state, "Error" - ) - if program_reg_info.program_membership_id.state - not in ("not_eligible", "duplicated") - else program_states.get( - program_reg_info.program_membership_id.state, "Error" - ), + "application_status": application_states.get(program_reg_info.state, "Error") + if program_reg_info.program_membership_id.state not in ("not_eligible", "duplicated") + else program_states.get(program_reg_info.program_membership_id.state, "Error"), # TODO: Redirect to different page if application doesn't exist - "application_id": program_reg_info.application_id - if program_reg_info - else None, + "application_id": program_reg_info.application_id if program_reg_info else None, "user": current_partner.given_name.capitalize() if current_partner.given_name else current_partner.name, @@ -619,9 +559,7 @@ def jsonize_form_data(self, data, program, membership=None): if isinstance(value, list): if len(value) > 0 and isinstance(value[0], FileStorage): if not program.supporting_documents_store: - _logger.error( - "Supporting Documents Store is not set in Program Configuration" - ) + _logger.error("Supporting Documents Store is not set in Program Configuration") data[key] = None continue @@ -684,14 +622,10 @@ def send_otp(self, otp, data): otp_notification_managers = config.get_param( "g2p_self_service_portal.otp_notification_managers", None ) - otp_notification_managers = self.objects_from_ref_list_string( - otp_notification_managers - ) + otp_notification_managers = self.objects_from_ref_list_string(otp_notification_managers) for manager in otp_notification_managers: if not hasattr(manager, "on_otp_send"): - _logger.error( - "Notification Module not Installed. Error for %s", str(manager) - ) + _logger.error("Notification Module not Installed. Error for %s", str(manager)) continue manager.on_otp_send(**data) diff --git a/g2p_self_service_portal/models/__init__.py b/g2p_self_service_portal/models/__init__.py index 5609e5f..fd607e5 100644 --- a/g2p_self_service_portal/models/__init__.py +++ b/g2p_self_service_portal/models/__init__.py @@ -1,4 +1,3 @@ -from . import auth_oauth_provider from . import res_config_settings from . import programs from . import website diff --git a/g2p_self_service_portal/models/auth_oauth_provider.py b/g2p_self_service_portal/models/auth_oauth_provider.py deleted file mode 100644 index 980690e..0000000 --- a/g2p_self_service_portal/models/auth_oauth_provider.py +++ /dev/null @@ -1,9 +0,0 @@ -from odoo import fields, models - - -class G2PSelfServiceOauthProvider(models.Model): - _inherit = "auth.oauth.provider" - - g2p_self_service_allowed = fields.Boolean( - "Allowed in Self Service Portal", default=False - ) diff --git a/g2p_self_service_portal/pyproject.toml b/g2p_self_service_portal/pyproject.toml new file mode 100644 index 0000000..4231d0c --- /dev/null +++ b/g2p_self_service_portal/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_self_service_portal/static/description/index.html b/g2p_self_service_portal/static/description/index.html index 0f50ace..d242681 100644 --- a/g2p_self_service_portal/static/description/index.html +++ b/g2p_self_service_portal/static/description/index.html @@ -368,7 +368,7 @@

G2P Self Service Portal

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:3a6f181ca8e6c6c9908a819106ede1b875fc539e31723b5b654722a4805ba1b4 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Alpha OpenG2P/openg2p-self-service-portal

+

Alpha OpenG2P/openg2p-self-service-portal

OpenG2P Self Service Portal

Important

@@ -392,7 +392,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -405,7 +405,7 @@

Authors

Maintainers

-

This module is part of the OpenG2P/openg2p-self-service-portal project on GitHub.

+

This module is part of the OpenG2P/openg2p-self-service-portal project on GitHub.

You are welcome to contribute.

diff --git a/g2p_self_service_portal/static/src/js/apply_program_form_editor.js b/g2p_self_service_portal/static/src/js/apply_program_form_editor.js index b641e1d..9f67910 100644 --- a/g2p_self_service_portal/static/src/js/apply_program_form_editor.js +++ b/g2p_self_service_portal/static/src/js/apply_program_form_editor.js @@ -1,7 +1,7 @@ /** @odoo-module **/ -import {_t} from "@web/core/l10n/translation"; import FormEditorRegistry from "@website/js/form_editor_registry"; +import {_t} from "@web/core/l10n/translation"; FormEditorRegistry.add("apply_for_program", { formFields: [ diff --git a/g2p_self_service_portal/views/auth_oauth_provider.xml b/g2p_self_service_portal/views/auth_oauth_provider.xml deleted file mode 100644 index 306bf89..0000000 --- a/g2p_self_service_portal/views/auth_oauth_provider.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/g2p_self_service_portal/wizard/program_form_mapping_wizard.py b/g2p_self_service_portal/wizard/program_form_mapping_wizard.py index 06b47cf..6a1de50 100644 --- a/g2p_self_service_portal/wizard/program_form_mapping_wizard.py +++ b/g2p_self_service_portal/wizard/program_form_mapping_wizard.py @@ -15,7 +15,7 @@ class G2PCreateProgramWizard(models.TransientModel): multiple_form_submission = fields.Boolean(default=False) def create_program(self): - res = super(G2PCreateProgramWizard, self).create_program() + res = super().create_program() program = self.env["g2p.program"].browse(res["res_id"]) portal_form = self.self_service_portal_form diff --git a/g2p_service_provider_portal/README.rst b/g2p_service_provider_portal/README.rst index 4452371..89c2aa2 100644 --- a/g2p_service_provider_portal/README.rst +++ b/g2p_service_provider_portal/README.rst @@ -14,7 +14,7 @@ G2P Service Provider Portal :target: https://odoo-community.org/page/development-status :alt: Alpha .. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--self--service--portal-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-self-service-portal/tree/17.0/g2p_service_provider_portal + :target: https://github.com/OpenG2P/openg2p-self-service-portal/tree/17.0-develop/g2p_service_provider_portal :alt: OpenG2P/openg2p-self-service-portal |badge1| |badge2| @@ -37,7 +37,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -52,6 +52,6 @@ Authors Maintainers ~~~~~~~~~~~ -This module is part of the `OpenG2P/openg2p-self-service-portal `_ project on GitHub. +This module is part of the `OpenG2P/openg2p-self-service-portal `_ project on GitHub. You are welcome to contribute. diff --git a/g2p_service_provider_portal/__manifest__.py b/g2p_service_provider_portal/__manifest__.py index e589d93..d5a01ae 100644 --- a/g2p_service_provider_portal/__manifest__.py +++ b/g2p_service_provider_portal/__manifest__.py @@ -1,10 +1,10 @@ { "name": "G2P Service Provider Portal", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.1.2.0", "sequence": 1, "author": "OpenG2P", - "website": "https://github.com/OpenG2P/openg2p-self-service-portal", + "website": "https://openg2p.org", "license": "Other OSI approved licence", "development_status": "Alpha", "depends": [ @@ -13,8 +13,6 @@ ], "data": [ "data/g2p_service_provider_form_action_data.xml", - # TODO: The 'auth_oidc' module was removed; a replacement is needed in the code. - # "views/auth_oauth_provider.xml", "views/g2p_service_provider_aboutus.xml", "views/g2p_service_provider_base.xml", "views/g2p_service_provider_contactus.xml", @@ -27,10 +25,7 @@ "views/program_view.xml", ], "assets": { - "web.assets_backend": [], - "web.assets_frontend": [], - "web.assets_common": [], - "website.assets_wysiwyg": [ + "website.assets_editor": [ "g2p_service_provider_portal/static/src/js/reim_form_editor.js", ], }, diff --git a/g2p_service_provider_portal/controllers/main.py b/g2p_service_provider_portal/controllers/main.py index 3ba38fa..8b62d89 100644 --- a/g2p_service_provider_portal/controllers/main.py +++ b/g2p_service_provider_portal/controllers/main.py @@ -11,10 +11,6 @@ from odoo.addons.g2p_self_service_portal.controllers.main import SelfServiceController from odoo.addons.web.controllers.home import Home -# TODO: The 'auth_oidc' module was removed; a replacement is needed in the code." -# from odoo.addons.auth_oidc.controllers.main import OpenIDLogin - - _logger = logging.getLogger(__name__) @@ -28,45 +24,40 @@ def portal_root(self, **kwargs): @http.route(["/serviceprovider/login"], type="http", auth="public", website=True) def service_provider_login(self, **kwargs): + redirect_uri = request.params.get("redirect") or "/serviceprovider/home" if request.session and request.session.uid: - return request.redirect("/serviceprovider/home") - request.params["redirect"] = "/" - context = {} - - providers = [] + return request.redirect(redirect_uri) - # TODO: The 'auth_oidc' module was removed; a replacement is needed in the code." - # try: - # providers = OpenIDLogin().list_providers( - # domain=[("g2p_service_provider_allowed", "=", True)] - # ) - # except Exception: - # providers = OpenIDLogin().list_providers() + context = {} - context.update(dict(providers=providers)) if request.httprequest.method == "POST": res = Home().web_login(**kwargs) - - if not request.params["login_success"]: + if request.params["login_success"]: + return res + else: context["error"] = "Invalid Credentials" - return request.render( - "g2p_service_provider_portal.login_page", qcontext=context - ) - return res - - return request.render( - "g2p_service_provider_portal.login_page", qcontext=context + providers = ( + request.env["auth.oauth.provider"] + .sudo() + .get_portal_auth_providers( + domain=(("g2p_service_provider_allowed", "=", True),), + redirect=redirect_uri, + base_url=request.httprequest.url_root.rstrip("/"), + db_name=request.session.db, + ) + or [] ) + context.update(dict(providers=providers)) + return request.render("g2p_service_provider_portal.login_page", qcontext=context) + @http.route(["/serviceprovider/home"], type="http", auth="user", website=True) def portal_home(self, **kwargs): self.check_roles("SERVICEPROVIDER") return request.redirect("/serviceprovider/voucher") - @http.route( - ["/serviceprovider/myprofile"], type="http", auth="public", website=True - ) + @http.route(["/serviceprovider/myprofile"], type="http", auth="public", website=True) def portal_profile(self, **kwargs): if request.session and request.session.uid: current_partner = request.env.user.partner_id @@ -81,15 +72,11 @@ def portal_profile(self, **kwargs): def portal_about_us(self, **kwargs): return request.render("g2p_service_provider_portal.aboutus_page") - @http.route( - ["/serviceprovider/contactus"], type="http", auth="public", website=True - ) + @http.route(["/serviceprovider/contactus"], type="http", auth="public", website=True) def portal_contact_us(self, **kwargs): return request.render("g2p_service_provider_portal.contact_us") - @http.route( - ["/serviceprovider/otherpage"], type="http", auth="public", website=True - ) + @http.route(["/serviceprovider/otherpage"], type="http", auth="public", website=True) def portal_other_page(self, **kwargs): return request.render("g2p_service_provider_portal.other_page") @@ -124,12 +111,9 @@ def portal_new_entitlements(self, **kwargs): "beneficiary_name": entitlement.partner_id.name, "initial_amount": entitlement.initial_amount, "is_submitted": is_submitted, - "status": "New" - if not is_submitted - else entitlement.reimbursement_entitlement_ids.state, + "status": "New" if not is_submitted else entitlement.reimbursement_entitlement_ids.state, "is_form_mapped": True - if reimbursement_program - and reimbursement_program.self_service_portal_form + if reimbursement_program and reimbursement_program.self_service_portal_form else False, } ) @@ -155,10 +139,7 @@ def portal_new_submission(self, _id, **kwargs): entitlement = request.env["g2p.entitlement"].sudo().browse(_id) beneficiary = entitlement.partner_id - if ( - entitlement.service_provider_id.id != current_partner.id - or entitlement.state != "approved" - ): + if entitlement.service_provider_id.id != current_partner.id or entitlement.state != "approved": raise Forbidden() file_size = entitlement.program_id.reimbursement_program_id.file_size_spp @@ -167,9 +148,7 @@ def portal_new_submission(self, _id, **kwargs): if len(entitlement.reimbursement_entitlement_ids) > 0: return request.redirect(f"/serviceprovider/claim/{_id}") - view = ( - entitlement.program_id.reimbursement_program_id.self_service_portal_form.view_id - ) + view = entitlement.program_id.reimbursement_program_id.self_service_portal_form.view_id return request.render( view.id, @@ -200,10 +179,7 @@ def portal_claim_submission(self, _id, **kwargs): # TODO: get only issued entitlements entitlement = request.env["g2p.entitlement"].sudo().browse(_id) - if ( - entitlement.service_provider_id.id != current_partner.id - or entitlement.state != "approved" - ): + if entitlement.service_provider_id.id != current_partner.id or entitlement.state != "approved": raise Forbidden() if request.httprequest.method == "POST": @@ -216,11 +192,8 @@ def portal_claim_submission(self, _id, **kwargs): # TODO: Check if reimbursement program mapped to original program - current_partner_membership = ( - current_partner.program_membership_ids.filtered( - lambda x: x.program_id.id - == entitlement.program_id.reimbursement_program_id.id - ) + current_partner_membership = current_partner.program_membership_ids.filtered( + lambda x: x.program_id.id == entitlement.program_id.reimbursement_program_id.id ) # TODO: Check current partner not part of prog memberships of # reimbursement program. @@ -244,18 +217,14 @@ def portal_claim_submission(self, _id, **kwargs): membership=current_partner_membership, ) if not supporting_document_files: - _logger.warning( - "Empty/No File received for field %s", "Statement of Account" - ) + _logger.warning("Empty/No File received for field %s", "Statement of Account") supporting_document_file_ids = None else: supporting_document_file_ids = [] # saving the multiple document id for document_id in supporting_document_files: - supporting_document_file_ids.append( - document_id.get("document_id", None) - ) + supporting_document_file_ids.append(document_id.get("document_id", None)) reimbursement_claim = entitlement.submit_reimbursement_claim( current_partner, @@ -325,9 +294,7 @@ def check_roles(self, role_to_check): if not request.session or not request.env.user: raise Unauthorized(_("User is not logged in")) if not request.env.user.partner_id.supplier_rank > 0: - raise Forbidden( - _AppendAction("User is not allowed to access the portal") - ) + raise Forbidden(_AppendAction("User is not allowed to access the portal")) @http.route("/get_voucher_codes", type="http", auth="user", website=True) def get_voucher_codes(self): diff --git a/g2p_service_provider_portal/models/__init__.py b/g2p_service_provider_portal/models/__init__.py index 8583f01..521d735 100644 --- a/g2p_service_provider_portal/models/__init__.py +++ b/g2p_service_provider_portal/models/__init__.py @@ -1,2 +1 @@ -from . import auth_oauth_provider from . import programs diff --git a/g2p_service_provider_portal/models/auth_oauth_provider.py b/g2p_service_provider_portal/models/auth_oauth_provider.py deleted file mode 100644 index 8d6a92d..0000000 --- a/g2p_service_provider_portal/models/auth_oauth_provider.py +++ /dev/null @@ -1,9 +0,0 @@ -from odoo import fields, models - - -class G2PServiceProviderOauthProvider(models.Model): - _inherit = "auth.oauth.provider" - - g2p_service_provider_allowed = fields.Boolean( - "Allowed in Service Provider Portal", default=False - ) diff --git a/g2p_service_provider_portal/models/programs.py b/g2p_service_provider_portal/models/programs.py index 37d95b6..cf3ba59 100644 --- a/g2p_service_provider_portal/models/programs.py +++ b/g2p_service_provider_portal/models/programs.py @@ -26,4 +26,4 @@ def update_form_template(self): } ) else: - return super(G2PReimbursementProgram, self).update_form_template() + return super().update_form_template() diff --git a/g2p_service_provider_portal/pyproject.toml b/g2p_service_provider_portal/pyproject.toml new file mode 100644 index 0000000..4231d0c --- /dev/null +++ b/g2p_service_provider_portal/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_service_provider_portal/static/description/index.html b/g2p_service_provider_portal/static/description/index.html index 5a6eca5..5586253 100644 --- a/g2p_service_provider_portal/static/description/index.html +++ b/g2p_service_provider_portal/static/description/index.html @@ -368,7 +368,7 @@

G2P Service Provider Portal

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:13c95bf8ce5a3382c16b19bc7a92fd5a55eb20a20a20844a985dfff75ebd9667 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Alpha OpenG2P/openg2p-self-service-portal

+

Alpha OpenG2P/openg2p-self-service-portal

OpenG2P Service Provider Portal

Important

@@ -392,7 +392,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -405,7 +405,7 @@

Authors

Maintainers

-

This module is part of the OpenG2P/openg2p-self-service-portal project on GitHub.

+

This module is part of the OpenG2P/openg2p-self-service-portal project on GitHub.

You are welcome to contribute.

diff --git a/g2p_service_provider_portal/views/auth_oauth_provider.xml b/g2p_service_provider_portal/views/auth_oauth_provider.xml deleted file mode 100644 index 8c8ea0c..0000000 --- a/g2p_service_provider_portal/views/auth_oauth_provider.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - diff --git a/setup/.setuptools-odoo-make-default-ignore b/setup/.setuptools-odoo-make-default-ignore deleted file mode 100644 index 207e615..0000000 --- a/setup/.setuptools-odoo-make-default-ignore +++ /dev/null @@ -1,2 +0,0 @@ -# addons listed in this file are ignored by -# setuptools-odoo-make-default (one addon per line) diff --git a/setup/README b/setup/README deleted file mode 100644 index a63d633..0000000 --- a/setup/README +++ /dev/null @@ -1,2 +0,0 @@ -To learn more about this directory, please visit -https://pypi.python.org/pypi/setuptools-odoo diff --git a/setup/g2p_self_service_portal/odoo/addons/g2p_self_service_portal b/setup/g2p_self_service_portal/odoo/addons/g2p_self_service_portal deleted file mode 120000 index ab6aa69..0000000 --- a/setup/g2p_self_service_portal/odoo/addons/g2p_self_service_portal +++ /dev/null @@ -1 +0,0 @@ -../../../../g2p_self_service_portal \ No newline at end of file diff --git a/setup/g2p_self_service_portal/setup.py b/setup/g2p_self_service_portal/setup.py deleted file mode 100644 index 28c57bb..0000000 --- a/setup/g2p_self_service_portal/setup.py +++ /dev/null @@ -1,6 +0,0 @@ -import setuptools - -setuptools.setup( - setup_requires=['setuptools-odoo'], - odoo_addon=True, -) diff --git a/setup/g2p_service_provider_portal/odoo/addons/g2p_service_provider_portal b/setup/g2p_service_provider_portal/odoo/addons/g2p_service_provider_portal deleted file mode 120000 index fdf51c5..0000000 --- a/setup/g2p_service_provider_portal/odoo/addons/g2p_service_provider_portal +++ /dev/null @@ -1 +0,0 @@ -../../../../g2p_service_provider_portal \ No newline at end of file diff --git a/setup/g2p_service_provider_portal/setup.py b/setup/g2p_service_provider_portal/setup.py deleted file mode 100644 index 28c57bb..0000000 --- a/setup/g2p_service_provider_portal/setup.py +++ /dev/null @@ -1,6 +0,0 @@ -import setuptools - -setuptools.setup( - setup_requires=['setuptools-odoo'], - odoo_addon=True, -) diff --git a/test-requirements.txt b/test-requirements.txt index 666219f..08c7806 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,16 +1,16 @@ -git+https://github.com/OpenG2P/odoo-json-field@15.0-develop#subdirectory=setup/g2p_json_field -git+https://github.com/OpenG2P/openg2p-documents@15.0-develop#subdirectory=setup/g2p_documents -git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_registry_base -git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_registry_group -git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_registry_individual -git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_registry_membership -git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_bank -git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_registry_rest_api -git+https://github.com/OpenG2P/openg2p-registry@15.0-develop#subdirectory=setup/g2p_bank_rest_api -git+https://github.com/OpenG2P/openg2p-program@15.0-develop#subdirectory=setup/g2p_programs -git+https://github.com/OpenG2P/openg2p-program@15.0-develop#subdirectory=setup/g2p_program_documents -git+https://github.com/OpenG2P/openg2p-program@15.0-develop#subdirectory=setup/g2p_program_reimbursement -git+https://github.com/OpenG2P/openg2p-program@15.0-develop#subdirectory=setup/g2p_program_assessment -git+https://github.com/OpenG2P/openg2p-program@15.0-develop#subdirectory=setup/g2p_program_registrant_info -git+https://github.com/OpenG2P/openg2p-program@15.0-develop#subdirectory=setup/g2p_programs_rest_api -git+https://github.com/OpenG2P/openg2p-notifications@15.0-develop#subdirectory=setup/g2p_notifications_base +git+https://github.com/OpenG2P/storage@17.0#subdirectory=storage_backend +git+https://github.com/OpenG2P/storage@17.0#subdirectory=storage_backend_s3 +git+https://github.com/OpenG2P/storage@17.0#subdirectory=storage_file +git+https://github.com/OpenG2P/openg2p-documents@17.0-develop#subdirectory=g2p_documents +git+https://github.com/OpenG2P/openg2p-registry@17.0-develop#subdirectory=g2p_registry_base +git+https://github.com/OpenG2P/openg2p-registry@17.0-develop#subdirectory=g2p_registry_individual +git+https://github.com/OpenG2P/openg2p-registry@17.0-develop#subdirectory=g2p_registry_group +git+https://github.com/OpenG2P/openg2p-registry@17.0-develop#subdirectory=g2p_registry_membership +git+https://github.com/OpenG2P/openg2p-registry@17.0-develop#subdirectory=g2p_bank +git+https://github.com/OpenG2P/openg2p-program@17.0-develop#subdirectory=g2p_programs +git+https://github.com/OpenG2P/openg2p-program@17.0-develop#subdirectory=g2p_program_documents +git+https://github.com/OpenG2P/openg2p-program@17.0-develop#subdirectory=g2p_program_assessment +git+https://github.com/OpenG2P/openg2p-program@17.0-develop#subdirectory=g2p_program_reimbursement +git+https://github.com/OpenG2P/openg2p-program@17.0-develop#subdirectory=g2p_program_registrant_info +git+https://github.com/OpenG2P/openg2p-notifications@17.0-develop#subdirectory=g2p_notifications_base +git+https://github.com/OpenG2P/openg2p-auth@17.0-develop#subdirectory=g2p_portal_auth