diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index 412fd82b..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Trigger OpenG2P Packaging Workflow - -on: - push: - workflow_dispatch: - -jobs: - trigger-packaging: - runs-on: ubuntu-latest - steps: - - name: set variables - run: | - echo "BRANCH_NAME=$(echo ${{ github.ref }} | sed -e 's,.*/\(.*\),\1,')" >> $GITHUB_ENV - - name: Invoke workflow in another repo with inputs - uses: aurelien-baudet/workflow-dispatch@v2 - with: - token: ${{ secrets.GIT_PUSH_TOKEN }} - repo: OpenG2P/openg2p-packaging - workflow: OpenG2P Odoo Package Dockers build - input: "{\"packageName\": \"${{ env.BRANCH_NAME }}\"}" - ref: main diff --git a/.github/workflows/tag.yml b/.github/workflows/tag.yml new file mode 100644 index 00000000..b35ef190 --- /dev/null +++ b/.github/workflows/tag.yml @@ -0,0 +1,21 @@ +name: Tag the repo +on: + workflow_dispatch: + inputs: + new-tag: + description: Tag in "vN.N.N" format + required: true + type: string + previous-tag: + description: Previous tag. "None" if no previous tag + required: true + type: string + default: latest +jobs: + tag-repo: + uses: openg2p/openg2p-packaging/.github/workflows/tag.yml@main + with: + new-tag: ${{ inputs.new-tag }} + previous-tag: ${{ inputs.previous-tag }} + secrets: + OPENG2P_BOT_GITHUB_PAT: ${{ secrets.OPENG2P_BOT_GITHUB_PAT }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8e6e90e9..aff38800 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -81,6 +81,11 @@ jobs: - uses: actions/checkout@v3 with: persist-credentials: false + - name: Install test-pre-requirments + run: | + if [ -f test-pre-requirements.txt ]; then + pip install -r test-pre-requirements.txt + fi - name: Install addons and dependencies run: oca_install_addons - name: Check licenses @@ -93,7 +98,9 @@ jobs: run: oca_init_test_database - name: Run tests run: oca_run_tests - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v4 + with: + token: ${{ secrets.CODECOV_TOKEN }} - 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/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3e573ba8..022f2017 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,7 @@ exclude: | (?x) # NOT INSTALLABLE ADDONS + ^g2p_notifications_rest_api/| ^g2p_program_registrant_info_rest_api/| ^g2p_programs_rest_api/| # END NOT INSTALLABLE ADDONS @@ -49,14 +50,6 @@ repos: - id: oca-update-pre-commit-excluded-addons - id: oca-fix-manifest-website args: ["https://openg2p.org"] - - id: oca-gen-addon-readme - args: - - --addons-dir=. - - --branch=17.0-develop - - --org-name=OpenG2P - - --repo-name=openg2p-program - - --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 diff --git a/README.md b/README.md index cf390358..3869e244 100644 --- a/README.md +++ b/README.md @@ -21,44 +21,61 @@ Available addons ---------------- addon | version | maintainers | summary --- | --- | --- | --- -[g2p_entitlement_differential](g2p_entitlement_differential/) | 17.0.1.0.0 | | OpenG2P Entitlement: Differential -[g2p_entitlement_in_kind](g2p_entitlement_in_kind/) | 17.0.1.0.0 | | OpenG2P Entitlement: In-Kind -[g2p_entitlement_voucher](g2p_entitlement_voucher/) | 17.0.1.0.0 | | OpenG2P Entitlement: Voucher -[g2p_payment_cash](g2p_payment_cash/) | 17.0.1.0.0 | | OpenG2P Program Payment: Cash -[g2p_payment_files](g2p_payment_files/) | 17.0.1.0.0 | | OpenG2P Program Payments: In Files -[g2p_payment_g2p_connect](g2p_payment_g2p_connect/) | 17.0.1.0.0 | | OpenG2P Program Payment: G2P Connect Payment Manager -[g2p_payment_interop_layer](g2p_payment_interop_layer/) | 17.0.1.0.0 | | OpenG2P Program Payment (Payment Interoperability Layer) -[g2p_payment_phee](g2p_payment_phee/) | 17.0.1.0.0 | | OpenG2P Program Payment (Payment Hub EE) -[g2p_payment_simple_mpesa](g2p_payment_simple_mpesa/) | 17.0.1.0.0 | | OpenG2P Program Payment: Simple Mpesa Payment Manager -[g2p_program_approval](g2p_program_approval/) | 17.0.1.0.0 | | OpenG2P Program: Approval -[g2p_program_assessment](g2p_program_assessment/) | 17.0.1.0.0 | | OpenG2P Program: Assessment -[g2p_program_autoenrol](g2p_program_autoenrol/) | 17.0.1.0.0 | | OpenG2P Programs: Autoenrol -[g2p_program_cycleless](g2p_program_cycleless/) | 17.0.1.0.0 | | OpenG2P Programs: Cycleless -[g2p_program_documents](g2p_program_documents/) | 17.0.1.0.0 | | OpenG2P Program: Documents -[g2p_program_registrant_info](g2p_program_registrant_info/) | 17.0.1.0.0 | | G2P Program: Registrant Info -[g2p_program_reimbursement](g2p_program_reimbursement/) | 17.0.1.0.0 | | OpenG2P Programs: Reimbursement -[g2p_programs](g2p_programs/) | 17.0.1.0.0 | | OpenG2P Programs -[g2p_proxy_means_test](g2p_proxy_means_test/) | 17.0.1.0.0 | | G2P: Proxy Means Test +[g2p_entitlement_differential](g2p_entitlement_differential/) | 17.0.0.0.0 | | OpenG2P Entitlement: Differential +[g2p_entitlement_in_kind](g2p_entitlement_in_kind/) | 17.0.0.0.0 | | OpenG2P Entitlement: In-Kind +[g2p_entitlement_voucher](g2p_entitlement_voucher/) | 17.0.0.0.0 | | OpenG2P Entitlement: Voucher +[g2p_formio](g2p_formio/) | 17.0.0.0.0 | | Form builders allow you to create, manage, and use dynamic forms with ease. +[g2p_mis_importer](g2p_mis_importer/) | 17.0.0.0.0 | | G2P MIS Importer +[g2p_notifications_base](g2p_notifications_base/) | 17.0.0.0.0 | | G2P Notifications: Base +[g2p_notifications_fast2sms](g2p_notifications_fast2sms/) | 17.0.0.0.0 | | G2P Notifications: Fast2SMS Service Provider +[g2p_notifications_voucher](g2p_notifications_voucher/) | 17.0.0.0.0 | | G2P Notifications: Voucher +[g2p_notifications_wiserv](g2p_notifications_wiserv/) | 17.0.0.0.0 | | G2P Notifications: Wiserv SMS Service Provider +[g2p_odk_importer_program](g2p_odk_importer_program/) | 17.0.0.0.0 | | Import records from ODK and add then into Program +[g2p_openid_vci_programs](g2p_openid_vci_programs/) | 17.0.0.0.0 | | G2P OpenID VCI: Program Beneficiaries +[g2p_payment_cash](g2p_payment_cash/) | 17.0.0.0.0 | | OpenG2P Program Payment: Cash +[g2p_payment_files](g2p_payment_files/) | 17.0.0.0.0 | | OpenG2P Program Payments: In Files +[g2p_payment_g2p_connect](g2p_payment_g2p_connect/) | 17.0.0.0.0 | | OpenG2P Program Payment: G2P Connect Payment Manager +[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_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 +[g2p_program_cycleless](g2p_program_cycleless/) | 17.0.0.0.0 | | OpenG2P Programs: Cycleless +[g2p_program_documents](g2p_program_documents/) | 17.0.0.0.0 | | OpenG2P Program: Documents +[g2p_program_registrant_info](g2p_program_registrant_info/) | 17.0.0.0.0 | | G2P Program: Registrant Info +[g2p_program_reimbursement](g2p_program_reimbursement/) | 17.0.0.0.0 | | OpenG2P Programs: Reimbursement +[g2p_programs](g2p_programs/) | 17.0.0.0.0 | | OpenG2P Programs +[g2p_proxy_means_test](g2p_proxy_means_test/) | 17.0.0.0.0 | | G2P: Proxy Means Test +[g2p_social_registry_importer](g2p_social_registry_importer/) | 17.0.0.0.0 | | Import records from Social Registry +[g2p_theme](g2p_theme/) | 17.0.0.0.0 | | OpenG2P Theme Unported addons --------------- addon | version | maintainers | summary --- | --- | --- | --- -[g2p_program_registrant_info_rest_api](g2p_program_registrant_info_rest_api/) | 17.0.1.0.0 (unported) | | G2P Program : Program Registrant Info Rest API -[g2p_programs_rest_api](g2p_programs_rest_api/) | 17.0.1.0.0 (unported) | | G2P Programs: REST API +[g2p_notifications_rest_api](g2p_notifications_rest_api/) | 17.0.0.0.0 (unported) | | G2P Notifications: REST API +[g2p_program_registrant_info_rest_api](g2p_program_registrant_info_rest_api/) | 17.0.0.0.0 (unported) | | G2P Program : Program Registrant Info Rest API +[g2p_programs_rest_api](g2p_programs_rest_api/) | 17.0.0.0.0 (unported) | | G2P Programs: REST API [//]: # (end addons) -## License +## Contributors + +[OpenSPP](https://openspp.org) donated the original code to the project. + +Contributors include: -This repository is licensed under [MPL-2.0](LICENSE). +* Edwin Gonzales ([Newlogic](https://newlogic.com)) +* Jeremi Joslin ([Newlogic](https://newlogic.com)) +* Michael Gonzales ([Newlogic](https://newlogic.com)) + +## License -However, each module can have a totally different license, as long as they adhere to OpenG2P -policy. Consult each module's `__manifest__.py` file, which contains a `license` key -that explains its license. +This repository is licensed under [LGPL-3.0](LICENSE). ---- diff --git a/g2p_entitlement_differential/README.md b/g2p_entitlement_differential/README.md new file mode 100644 index 00000000..f9060750 --- /dev/null +++ b/g2p_entitlement_differential/README.md @@ -0,0 +1,3 @@ +# OpenG2P Entitlement: Differential + +Refer to https://docs.openg2p.org. diff --git a/g2p_entitlement_differential/README.rst b/g2p_entitlement_differential/README.rst deleted file mode 100644 index bc7c4fdf..00000000 --- a/g2p_entitlement_differential/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -================================= -OpenG2P Entitlement: Differential -================================= - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:b23d6bc3b4979b3a0e01614e27153d2933e89004e3ac6ad341c263817815dc61 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_entitlement_differential - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Differential Entitlement - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_entitlement_differential/__manifest__.py b/g2p_entitlement_differential/__manifest__.py index b27d6357..40d9e86e 100644 --- a/g2p_entitlement_differential/__manifest__.py +++ b/g2p_entitlement_differential/__manifest__.py @@ -2,12 +2,11 @@ "name": "OpenG2P Entitlement: Differential", "category": "G2P", # Part of OpenG2P. See LICENSE file for full copyright and licensing details. - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": ["spp_entitlement_cash"], "data": ["views/entitlement_manager_view.xml"], "demo": [], diff --git a/g2p_entitlement_differential/static/description/index.html b/g2p_entitlement_differential/static/description/index.html deleted file mode 100644 index b4d1b329..00000000 --- a/g2p_entitlement_differential/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Entitlement: Differential - - - -
-

OpenG2P Entitlement: Differential

- - -

Alpha OpenG2P/openg2p-program

-

G2P Differential Entitlement

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_entitlement_in_kind/README.md b/g2p_entitlement_in_kind/README.md new file mode 100644 index 00000000..ec836e59 --- /dev/null +++ b/g2p_entitlement_in_kind/README.md @@ -0,0 +1,3 @@ +# OpenG2P Entitlement: In-Kind + +Refer to https://docs.openg2p.org. diff --git a/g2p_entitlement_in_kind/README.rst b/g2p_entitlement_in_kind/README.rst deleted file mode 100644 index b4ee75e5..00000000 --- a/g2p_entitlement_in_kind/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -============================ -OpenG2P Entitlement: In-Kind -============================ - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:4b70ffad52869f9451d8653972dcbc12dd23b9637f4965484264bb04316adb03 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_entitlement_in_kind - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -OpenG2P In-Kind Entitlement - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_entitlement_in_kind/__manifest__.py b/g2p_entitlement_in_kind/__manifest__.py index 0f797a59..765fdd5d 100644 --- a/g2p_entitlement_in_kind/__manifest__.py +++ b/g2p_entitlement_in_kind/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Entitlement: In-Kind", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": ["spp_programs", "spp_entitlement_in_kind"], "data": [ "views/in_kind.xml", diff --git a/g2p_entitlement_in_kind/static/description/index.html b/g2p_entitlement_in_kind/static/description/index.html deleted file mode 100644 index 96b73919..00000000 --- a/g2p_entitlement_in_kind/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Entitlement: In-Kind - - - -
-

OpenG2P Entitlement: In-Kind

- - -

Alpha OpenG2P/openg2p-program

-

OpenG2P In-Kind Entitlement

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_entitlement_voucher/README.md b/g2p_entitlement_voucher/README.md new file mode 100644 index 00000000..09362f21 --- /dev/null +++ b/g2p_entitlement_voucher/README.md @@ -0,0 +1,3 @@ +# OpenG2P Entitlement: Voucher + +Refer to https://docs.openg2p.org. diff --git a/g2p_entitlement_voucher/README.rst b/g2p_entitlement_voucher/README.rst deleted file mode 100644 index bb128671..00000000 --- a/g2p_entitlement_voucher/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -============================ -OpenG2P Entitlement: Voucher -============================ - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:78e0dabe2a7d880d67ca916d39cbfea55892499a8a2ec276a714a644cbfcc6dd - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_entitlement_voucher - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Voucher Based Entitlement - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_entitlement_voucher/__manifest__.py b/g2p_entitlement_voucher/__manifest__.py index 25e1861c..6aabc20f 100644 --- a/g2p_entitlement_voucher/__manifest__.py +++ b/g2p_entitlement_voucher/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Entitlement: Voucher", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "g2p_encryption", "g2p_programs", diff --git a/g2p_entitlement_voucher/readme/DESCRIPTION.rst b/g2p_entitlement_voucher/readme/DESCRIPTION.rst deleted file mode 100644 index e1933bf2..00000000 --- a/g2p_entitlement_voucher/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Voucher Based Entitlement diff --git a/g2p_entitlement_voucher/static/description/index.html b/g2p_entitlement_voucher/static/description/index.html deleted file mode 100644 index 25330acd..00000000 --- a/g2p_entitlement_voucher/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Entitlement: Voucher - - - -
-

OpenG2P Entitlement: Voucher

- - -

Alpha OpenG2P/openg2p-program

-

G2P Voucher Based Entitlement

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_formio/README.md b/g2p_formio/README.md new file mode 100644 index 00000000..87523ff7 --- /dev/null +++ b/g2p_formio/README.md @@ -0,0 +1,3 @@ +# OpenG2P Formio + +Refer to https://docs.openg2p.org. diff --git a/g2p_formio/__init__.py b/g2p_formio/__init__.py new file mode 100644 index 00000000..9b429614 --- /dev/null +++ b/g2p_formio/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/g2p_formio/__manifest__.py b/g2p_formio/__manifest__.py new file mode 100644 index 00000000..9253cdd8 --- /dev/null +++ b/g2p_formio/__manifest__.py @@ -0,0 +1,24 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. +{ + "name": "OpenG2P Formio", + "category": "G2P", + "version": "17.0.0.0.0", + "sequence": 1, + "summary": "Form builders allow you to create, manage, and use dynamic forms with ease.", + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": ["formio", "g2p_programs", "formio_storage_filestore"], + "data": [ + "views/formio_builder.xml", + "views/program_view.xml", + "wizard/g2p_self_service_program_view_wizard.xml", + ], + "external_dependencies": {"python": ["formio-data"]}, + "assets": {}, + "demo": [], + "images": [], + "application": True, + "installable": True, + "auto_install": False, +} diff --git a/g2p_formio/models/__init__.py b/g2p_formio/models/__init__.py new file mode 100644 index 00000000..eda8aca9 --- /dev/null +++ b/g2p_formio/models/__init__.py @@ -0,0 +1 @@ +from . import program diff --git a/g2p_formio/models/program.py b/g2p_formio/models/program.py new file mode 100644 index 00000000..7125a4d5 --- /dev/null +++ b/g2p_formio/models/program.py @@ -0,0 +1,9 @@ +from odoo import fields, models + + +class G2PProgram(models.Model): + _inherit = "g2p.program" + + self_service_portal_form = fields.Many2one("formio.builder", string="Program Form") + + is_multiple_form_submission = fields.Boolean(default=False) diff --git a/g2p_formio/pyproject.toml b/g2p_formio/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_formio/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_formio/static/description/icon.png b/g2p_formio/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_formio/static/description/icon.png differ diff --git a/g2p_formio/views/formio_builder.xml b/g2p_formio/views/formio_builder.xml new file mode 100644 index 00000000..6cb21717 --- /dev/null +++ b/g2p_formio/views/formio_builder.xml @@ -0,0 +1,72 @@ + + + program_formio_builder_form + formio.builder + + + + + + + + + + + + 1 + + + 1 + + + 1 + + + 1 + + + + + + + program_formio_builder_tree + formio.builder + + + + + 1 + + + 1 + record + + 1 + + + 1 + + + + + + + + + diff --git a/g2p_formio/views/program_view.xml b/g2p_formio/views/program_view.xml new file mode 100644 index 00000000..1116ea94 --- /dev/null +++ b/g2p_formio/views/program_view.xml @@ -0,0 +1,20 @@ + + + + self.service.portal.form + g2p.program + + + + + + + + + + + + + diff --git a/g2p_formio/wizard/__init__.py b/g2p_formio/wizard/__init__.py new file mode 100644 index 00000000..cc6eb85d --- /dev/null +++ b/g2p_formio/wizard/__init__.py @@ -0,0 +1,3 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. + +from . import program_form_mapping_wizard diff --git a/g2p_formio/wizard/g2p_self_service_program_view_wizard.xml b/g2p_formio/wizard/g2p_self_service_program_view_wizard.xml new file mode 100644 index 00000000..62a92de6 --- /dev/null +++ b/g2p_formio/wizard/g2p_self_service_program_view_wizard.xml @@ -0,0 +1,21 @@ + + + + + self.service.create.wizard.form + g2p.program.create.wizard + + + + + + + + + + + + + diff --git a/g2p_formio/wizard/program_form_mapping_wizard.py b/g2p_formio/wizard/program_form_mapping_wizard.py new file mode 100644 index 00000000..d37dbd44 --- /dev/null +++ b/g2p_formio/wizard/program_form_mapping_wizard.py @@ -0,0 +1,24 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class G2PCreateProgramWizard(models.TransientModel): + _inherit = "g2p.program.create.wizard" + + self_service_portal_form = fields.Many2one("formio.builder", string="Program Form") + + is_multiple_form_submission = fields.Boolean(default=False) + + def create_program(self): + res = super().create_program() + + program = self.env["g2p.program"].browse(res["res_id"]) + portal_form = self.self_service_portal_form + + if portal_form: + program.self_service_portal_form = portal_form + + program.is_multiple_form_submission = self.is_multiple_form_submission + + return res diff --git a/g2p_mis_importer/README.md b/g2p_mis_importer/README.md new file mode 100644 index 00000000..5baefd03 --- /dev/null +++ b/g2p_mis_importer/README.md @@ -0,0 +1,3 @@ +# G2P MIS Importer + +Refer to https://docs.openg2p.org. diff --git a/g2p_mis_importer/__init__.py b/g2p_mis_importer/__init__.py new file mode 100644 index 00000000..8d5bb84e --- /dev/null +++ b/g2p_mis_importer/__init__.py @@ -0,0 +1,2 @@ +# Part of Newlogic G2P. See LICENSE file for full copyright and licensing details. +from . import models diff --git a/g2p_mis_importer/__manifest__.py b/g2p_mis_importer/__manifest__.py new file mode 100644 index 00000000..a90774e1 --- /dev/null +++ b/g2p_mis_importer/__manifest__.py @@ -0,0 +1,19 @@ +# Part of openG2P. See LICENSE file for full copyright and licensing details. + +{ + "name": "G2P MIS Importer", + "category": "G2P", + "version": "17.0.0.0.0", + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": ["g2p_programs", "queue_job"], + "data": [ + "security/ir.model.access.csv", + "views/mis_config_views.xml", + "views/mis_menu.xml", + ], + "application": True, + "installable": True, + "auto_install": False, +} diff --git a/g2p_mis_importer/i18n/g2p_mis_importer.pot b/g2p_mis_importer/i18n/g2p_mis_importer.pot new file mode 100644 index 00000000..c31c1f19 --- /dev/null +++ b/g2p_mis_importer/i18n/g2p_mis_importer.pot @@ -0,0 +1,224 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * g2p_mis_importer +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "Restart" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "Start" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "Stop" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_tree +msgid "Action mis conf action" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields.selection,name:g2p_mis_importer.selection__mis_config__job_status__completed +msgid "Completed" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__create_uid +msgid "Created by" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__create_date +msgid "Created on" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__cron_id +msgid "Cron Job" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__database +msgid "Database" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__display_name +msgid "Display Name" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields.selection,name:g2p_mis_importer.selection__mis_config__job_status__draft +msgid "Draft" +msgstr "" + +#. module: g2p_mis_importer +#. odoo-python +#: code:addons/g2p_mis_importer/models/mis_config.py:0 +#, python-format +msgid "Failed to connect to remote MIS" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__id +msgid "ID" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "Import Records" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "Import records" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.ui.menu,name:g2p_mis_importer.mis_menu_config +msgid "Importer Configurations" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__interval_minutes +msgid "Interval in minutes" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__last_updated_at +msgid "Last Updated At" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__write_date +msgid "Last Updated on" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__mis_api_url +msgid "MIS API URL" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "MIS Central" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.actions.server,name:g2p_mis_importer.action_mis_conf_action +msgid "MIS Config Start" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.actions.act_window,name:g2p_mis_importer.action_mis_config +#: model:ir.model,name:g2p_mis_importer.model_mis_config +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "MIS Configuration" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__mis_id_type +msgid "MIS ID Type" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.ui.menu,name:g2p_mis_importer.mis_menu_root +msgid "MIS Importer" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__mis_login_url +msgid "MIS Login URL" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__mis_logout_url +msgid "MIS Logout URL" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__mis_program_id +msgid "MIS Program ID" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__name +msgid "Name" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__password +msgid "Password" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_tree +msgid "Restart" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields.selection,name:g2p_mis_importer.selection__mis_config__job_status__running +msgid "Running" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__session_token +msgid "Session Token" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_tree +msgid "Start" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__job_status +msgid "Status" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_tree +msgid "Stop" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "Test Connection" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "Test connection" +msgstr "" + +#. module: g2p_mis_importer +#: model_terms:ir.ui.view,arch_db:g2p_mis_importer.view_mis_config_form +msgid "Time interval" +msgstr "" + +#. module: g2p_mis_importer +#: model:ir.model.fields,field_description:g2p_mis_importer.field_mis_config__username +msgid "Username" +msgstr "" diff --git a/g2p_mis_importer/models/__init__.py b/g2p_mis_importer/models/__init__.py new file mode 100644 index 00000000..7b70d785 --- /dev/null +++ b/g2p_mis_importer/models/__init__.py @@ -0,0 +1,3 @@ +# Part of Newlogic G2P. See LICENSE file for full copyright and licensing details. + +from . import mis_config diff --git a/g2p_mis_importer/models/mis_config.py b/g2p_mis_importer/models/mis_config.py new file mode 100644 index 00000000..75ddde38 --- /dev/null +++ b/g2p_mis_importer/models/mis_config.py @@ -0,0 +1,601 @@ +import json +import logging +from datetime import date, datetime + +import requests + +from odoo import _, fields, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class MisConfig(models.Model): + _name = "mis.config" + _description = "MIS Configuration" + + name = fields.Char(required=True) + mis_api_url = fields.Char(string="MIS API URL", required=True) + mis_login_url = fields.Char(string="MIS Login URL", required=True) + mis_logout_url = fields.Char(string="MIS Logout URL", required=True) + database = fields.Char(required=True) + username = fields.Char(required=True) + password = fields.Char(required=True) + last_updated_at = fields.Datetime() + cron_id = fields.Many2one("ir.cron", string="Cron Job", required=False) + job_status = fields.Selection( + [ + ("draft", "Draft"), + ("running", "Running"), + ("completed", "Completed"), + ], + string="Status", + required=True, + default="draft", + ) + interval_minutes = fields.Integer(string="Interval in minutes", required=True, default=10) + session_token = fields.Char() + mis_id_type = fields.Many2one("g2p.id.type", string="MIS ID Type", required=True) + mis_program_id = fields.Many2one("g2p.program", string="MIS Program ID", required=True) + + def login(self): + url = self.mis_login_url + payload = { + "jsonrpc": "2.0", + "params": { + "db": self.database, + "login": self.username, + "password": self.password, + }, + } + response = requests.post(url, json=payload, timeout=10) + try: + response.raise_for_status() + self.session_token = response.cookies.get("session_id") + except Exception: + _logger.error(f"Login failed with status code: {response.status_code}") + raise + + def logout(self): + url = self.mis_logout_url + cookies = {"session_id": self.session_token} + + response = requests.get(url, cookies=cookies, timeout=10) + + try: + response.raise_for_status() + self.session_token = None + except Exception: + _logger.error(f"Logout failed with status code: {response.status_code}") + + def test_connection(self): + self.ensure_one() + self.login() + + try: + test_url = self.mis_api_url + response = requests.get(test_url, cookies={"session_id": self.session_token}, timeout=10) + response.raise_for_status() + + except Exception as e: + _logger.error(f"Test Connection failed: {str(e)}") + raise UserError(_("Failed to connect to remote MIS")) from e + finally: + self.logout() + + # TODO: Split the methods into smaller methods + # ruff: noqa: C901 + def import_records(self, config_id=None): + if config_id: + config = self.browse(config_id) + else: + config = self + + config.ensure_one() + + config.login() + is_updated = False + individuals_list = [] + + import_url = config.mis_api_url + + response = requests.get(import_url, cookies={"session_id": config.session_token}, timeout=10) + response.raise_for_status() + response = response.json() + + for item in response: + group = None + create_date_str = item.get("create_date") + create_date = datetime.strptime(create_date_str, "%Y-%m-%dT%H:%M:%S.%f%z").replace(tzinfo=None) + write_date_str = item.get("write_date") + write_date = datetime.strptime(write_date_str, "%Y-%m-%dT%H:%M:%S.%f%z").replace(tzinfo=None) + prog_reg_info = item.get("program_membership_ids", None) + if prog_reg_info: + prog_reg_info = prog_reg_info[0].get("program_registrant_info_ids", None) + if prog_reg_info: + prog_reg_info = prog_reg_info[0].get("program_registrant_info", None) + + if (not config.last_updated_at) or create_date > config.last_updated_at: + group = self.env["res.partner"].create( + { + "name": item.get("name"), + "is_group": item.get("is_group"), + "is_registrant": True, + "registration_date": item.get("registration_date"), + "reg_ids": [ + ( + 0, + 0, + { + "id_type": self.env["g2p.id.type"] + .search( + [("name", "=", reg_id.get("id_type", None))], + )[0] + .id, + "value": reg_id.get("value", None), + "expiry_date": reg_id.get("expiry_date", None), + }, + ) + for reg_id in item.get("ids") + ] + + [ + ( + 0, + 0, + { + "id_type": config.mis_id_type.id, + "value": item.get("id"), + }, + ) + ], + "phone_number_ids": [ + ( + 0, + 0, + { + "phone_no": phone.get("phone_no"), + "date_collected": phone.get("date_collected"), + "disabled": phone.get("disabled"), + }, + ) + for phone in item.get("phone_numbers") + ], + "email": item.get("email"), + "address": item.get("address"), + "bank_ids": [ + ( + 0, + 0, + { + "bank_id": self.env["res.bank"] + .search([("name", "=", bank.get("bank_name"))], limit=1)[0] + .id, + "acc_number": bank.get("acc_number"), + }, + ) + for bank in item.get("bank_ids") + ], + "program_membership_ids": [ + ( + 0, + 0, + { + "program_id": config.mis_program_id.id, + "state": "draft", + "enrollment_date": date.today(), + }, + ) + ], + "program_registrant_info_ids": [ + ( + 0, + 0, + { + "program_id": config.mis_program_id.id, + "state": "active", + "program_registrant_info": json.dumps(prog_reg_info) + if prog_reg_info + else None, + }, + ) + ], + "notification_preference": item.get("notification_preference", None), + "kind": self.env["g2p.group.kind"] + .search([("name", "=", item.get("kind", None))], limit=1)[0] + .id + if item.get("kind", None) + else None, + "is_partial_group": item.get("is_partial_group"), + "active": item.get("active"), + } + ) + is_updated = True + + elif write_date > config.last_updated_at: + group = ( + self.env["g2p.reg.id"] + .search( + [ + ("id_type", "=", config.mis_id_type.id), + ("value", "=", item.get("id")), + ("partner_id.is_group", "=", True), + ] + )[0] + .partner_id + ) + group.update( + { + "name": item.get("name"), + "is_group": item.get("is_group"), + "registration_date": item.get("registration_date"), + "reg_ids": [ + (5,), + ] + + [ + ( + 0, + 0, + { + "id_type": self.env["g2p.id.type"] + .search( + [("name", "=", reg_id.get("id_type", None))], + )[0] + .id, + "value": reg_id.get("value", None), + "expiry_date": reg_id.get("expiry_date", None), + }, + ) + for reg_id in item.get("ids") + ] + + [ + ( + 0, + 0, + { + "id_type": config.mis_id_type.id, + "value": item.get("id"), + }, + ) + ], + "phone_number_ids": [ + (5,), + ] + + [ + ( + 0, + 0, + { + "phone_no": phone.get("phone_no"), + "date_collected": phone.get("date_collected"), + "disabled": phone.get("disabled"), + }, + ) + for phone in item.get("phone_numbers") + ], + "email": item.get("email"), + "address": item.get("address"), + "bank_ids": [ + (5,), + ] + + [ + ( + 0, + 0, + { + "bank_id": self.env["res.bank"] + .search([("name", "=", bank.get("bank_name"))], limit=1)[0] + .id, + "acc_number": bank.get("acc_number"), + }, + ) + for bank in item.get("bank_ids") + ], + "notification_preference": item.get("notification_preference", None), + "kind": self.env["g2p.group.kind"] + .search([("name", "=", item.get("kind", None))], limit=1)[0] + .id + if item.get("kind", None) + else None, + "is_partial_group": item.get("is_partial_group"), + "active": item.get("active"), + "program_registrant_info_ids": [ + (5,), + ] + + [ + ( + 0, + 0, + { + "program_id": config.mis_program_id.id, + "state": "active", + "program_registrant_info": json.dumps(prog_reg_info) + if prog_reg_info + else None, + }, + ) + ], + } + ) + is_updated = True + + for membership in item.get("members"): + individual = membership.get("individual") + if not any(ind.get("id") == individual.get("id") for ind in individuals_list): + individuals_list.append(individual) + + for member in individuals_list: + create_date_str = member.get("create_date") + create_date = datetime.strptime(create_date_str, "%Y-%m-%dT%H:%M:%S.%f%z").replace(tzinfo=None) + write_date_str = member.get("write_date") + write_date = datetime.strptime(write_date_str, "%Y-%m-%dT%H:%M:%S.%f%z").replace(tzinfo=None) + if (not config.last_updated_at) or create_date > config.last_updated_at: + individual = self.env["res.partner"].create( + { + "name": member.get("name"), + "is_group": member.get("is_group"), + "registration_date": member.get("registration_date"), + "phone_number_ids": [ + ( + 0, + 0, + { + "phone_no": phone.get("phone_no"), + "date_collected": phone.get("date_collected"), + "disabled": phone.get("disabled"), + }, + ) + for phone in member.get("phone_numbers") + ], + "reg_ids": [ + ( + 0, + 0, + { + "id_type": self.env["g2p.id.type"] + .search( + [("name", "=", reg_id.get("id_type", None))], + )[0] + .id, + "value": reg_id.get("value", None), + "expiry_date": reg_id.get("expiry_date", None), + }, + ) + for reg_id in member.get("ids") + ] + + [ + ( + 0, + 0, + { + "id_type": config.mis_id_type.id, + "value": member.get("id"), + }, + ) + ], + "email": member.get("email"), + "address": member.get("address"), + "bank_ids": [ + ( + 0, + 0, + { + "bank_id": self.env["res.bank"] + .search([("name", "=", bank.get("bank_name"))], limit=1)[0] + .id, + "acc_number": bank.get("acc_number"), + }, + ) + for bank in member.get("bank_ids") + ], + "notification_preference": member.get("notification_preference", None), + "given_name": member.get("given_name"), + "addl_name": member.get("addl_name"), + "family_name": member.get("family_name"), + "gender": member.get("gender"), + "birthdate": member.get("birthdate"), + "birth_place": member.get("birth_place"), + } + ) + + is_updated = True + elif write_date > config.last_updated_at: + individual = ( + self.env["g2p.reg.id"] + .search( + [ + ("id_type", "=", config.mis_id_type.id), + ("value", "=", member.get("id")), + ("partner_id.is_group", "=", False), + ] + )[0] + .partner_id + ) + individual.update( + { + "name": member.get("name"), + "is_group": member.get("is_group"), + "registration_date": member.get("registration_date"), + "phone_number_ids": [ + (5,), + ] + + [ + ( + 0, + 0, + { + "phone_no": phone.get("phone_no"), + "date_collected": phone.get("date_collected"), + "disabled": phone.get("disabled"), + }, + ) + for phone in member.get("phone_numbers") + ], + "reg_ids": [ + (5,), + ] + + [ + ( + 0, + 0, + { + "id_type": self.env["g2p.id.type"] + .search( + [("name", "=", reg_id.get("id_type", None))], + )[0] + .id, + "value": reg_id.get("value", None), + "expiry_date": reg_id.get("expiry_date", None), + }, + ) + for reg_id in member.get("ids") + ] + + [ + ( + 0, + 0, + { + "id_type": config.mis_id_type.id, + "value": member.get("id"), + }, + ) + ], + "email": member.get("email"), + "address": member.get("address"), + "bank_ids": [ + (5,), + ] + + [ + ( + 0, + 0, + { + "bank_id": self.env["res.bank"] + .search([("name", "=", bank.get("bank_name"))], limit=1)[0] + .id, + "acc_number": bank.get("acc_number"), + }, + ) + for bank in member.get("bank_ids") + ], + "notification_preference": member.get("notification_preference", None), + "given_name": member.get("given_name"), + "addl_name": member.get("addl_name"), + "family_name": member.get("family_name"), + "gender": member.get("gender"), + "birthdate": member.get("birthdate"), + "birth_place": member.get("birth_place"), + } + ) + is_updated = True + for item in response: + group = ( + self.env["g2p.reg.id"] + .search( + [ + ("id_type", "=", config.mis_id_type.id), + ("value", "=", item.get("id")), + ("partner_id.is_group", "=", True), + ] + )[0] + .partner_id + ) + + for membership in item.get("members"): + member = membership.get("individual") + individual = ( + self.env["g2p.reg.id"] + .search( + [ + ("id_type", "=", config.mis_id_type.id), + ("value", "=", member.get("id")), + ("partner_id.is_group", "=", False), + ] + )[0] + .partner_id + ) + + create_date_str = membership.get("create_date") + create_date = datetime.strptime(create_date_str, "%Y-%m-%dT%H:%M:%S.%f%z").replace( + tzinfo=None + ) + write_date_str = membership.get("write_date") + write_date = datetime.strptime(write_date_str, "%Y-%m-%dT%H:%M:%S.%f%z").replace(tzinfo=None) + + if (not config.last_updated_at) or create_date > config.last_updated_at: + group.update( + { + "group_membership_ids": [ + ( + 0, + 0, + { + "individual": individual.id, + "kind": [ + ( + 4, + config.get_or_create_kind(member_kind.get("name")).id, + ) + for member_kind in membership.get("kind") + ], + }, + ) + ] + } + ) + is_updated = True + elif write_date > config.last_updated_at: + group_membership = group.group_membership_ids.filter(individual=individual.id) + group_membership.update( + { + "kind": [ + (5,), + ] + + [ + ( + 4, + config.get_or_create_kind(member_kind.get("name")).id, + ) + for member_kind in membership.get("kind") + ] + } + ) + is_updated = True + + if is_updated: + config.last_updated_at = datetime.utcnow() + config.logout() + + def get_or_create_kind(self, kind_str): + kind = self.env["g2p.group.membership.kind"].search([("name", "=", kind_str)], limit=1) + if kind: + kind = kind[0] + else: + kind = self.env["g2p.group.membership.kind"].sudo().create({"name": kind_str}) + + return kind + + def mis_import_action_trigger(self): + for rec in self: + if rec.job_status == "draft" or rec.job_status == "completed": + ir_cron = self.env["ir.cron"].sudo() + rec.cron_id = ir_cron.create( + { + "name": "MIS Pull Cron " + rec.name + " #" + str(rec.id), + "active": True, + "interval_number": rec.interval_minutes, + "interval_type": "minutes", + "model_id": self.env["ir.model"].search([("model", "=", "mis.config")])[0].id, + "state": "code", + "code": "model.import_records(" + str(rec.id) + ")", + "doall": False, + "numbercall": -1, + } + ) + _logger.info("Job Started") + rec.job_status = "running" + + elif rec.job_status == "running": + _logger.info("Job Stopped") + rec.job_status = "completed" + rec.sudo().cron_id.unlink() + rec.cron_id = None diff --git a/g2p_mis_importer/pyproject.toml b/g2p_mis_importer/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_mis_importer/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_mis_importer/security/ir.model.access.csv b/g2p_mis_importer/security/ir.model.access.csv new file mode 100644 index 00000000..efaa8ed1 --- /dev/null +++ b/g2p_mis_importer/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_mis_config,MIS Configuration,model_mis_config,base.group_user,1,1,1,1 diff --git a/g2p_mis_importer/static/description/icon.png b/g2p_mis_importer/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_mis_importer/static/description/icon.png differ diff --git a/g2p_mis_importer/views/mis_config_views.xml b/g2p_mis_importer/views/mis_config_views.xml new file mode 100644 index 00000000..d6d8dbe6 --- /dev/null +++ b/g2p_mis_importer/views/mis_config_views.xml @@ -0,0 +1,132 @@ + + + + MIS Config Start + + code + + record.mis_import_action_trigger() + + + + + view_mis_config_tree + mis.config + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MIS Configuration + ir.actions.act_window + mis.config + tree,form + + {} + + + diff --git a/g2p_mis_importer/views/mis_menu.xml b/g2p_mis_importer/views/mis_menu.xml new file mode 100644 index 00000000..1d94f299 --- /dev/null +++ b/g2p_mis_importer/views/mis_menu.xml @@ -0,0 +1,13 @@ + + + + + + diff --git a/g2p_notifications_base/README.md b/g2p_notifications_base/README.md new file mode 100644 index 00000000..252f95a8 --- /dev/null +++ b/g2p_notifications_base/README.md @@ -0,0 +1,5 @@ +# G2P Notifications: Base + +OpenG2P Notification Module + +Refer to https://docs.openg2p.org. diff --git a/g2p_notifications_base/__init__.py b/g2p_notifications_base/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/g2p_notifications_base/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/g2p_notifications_base/__manifest__.py b/g2p_notifications_base/__manifest__.py new file mode 100644 index 00000000..1e8bb7e4 --- /dev/null +++ b/g2p_notifications_base/__manifest__.py @@ -0,0 +1,27 @@ +{ + "name": "G2P Notifications: Base", + "category": "G2P", + "version": "17.0.0.0.0", + "sequence": 1, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": [ + "g2p_programs", + ], + "data": [ + "views/email_notification_manager.xml", + "views/sms_notification_manager.xml", + "views/registrant.xml", + "security/ir.model.access.csv", + ], + "assets": { + "web.assets_backend": [], + "web.assets_qweb": [], + }, + "demo": [], + "images": [], + "application": False, + "installable": True, + "auto_install": False, +} diff --git a/g2p_notifications_base/i18n/g2p_notifications_base.pot b/g2p_notifications_base/i18n/g2p_notifications_base.pot new file mode 100644 index 00000000..daa06d3d --- /dev/null +++ b/g2p_notifications_base/i18n/g2p_notifications_base.pot @@ -0,0 +1,231 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * g2p_notifications_base +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: g2p_notifications_base +#: model_terms:ir.actions.act_window,help:g2p_notifications_base.action_notification_manager_email +msgid "Add an Email Notification Manager!" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields.selection,name:g2p_notifications_base.selection__res_partner__notification_preference__both +msgid "Both Email & SMS" +msgstr "" + +#. module: g2p_notifications_base +#: model_terms:ir.actions.act_window,help:g2p_notifications_base.action_notification_manager_email +msgid "Click the create button to enter a new Email notification manager." +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model,name:g2p_notifications_base.model_res_partner +msgid "Contact" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__create_uid +msgid "Created by" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__create_date +msgid "Created on" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model,name:g2p_notifications_base.model_g2p_program_payment_manager_default +msgid "Default Payment Manager" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__display_name +msgid "Display Name" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields.selection,name:g2p_notifications_base.selection__res_partner__notification_preference__email +msgid "Email" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model,name:g2p_notifications_base.model_g2p_program_notification_manager_email +#: model_terms:ir.ui.view,arch_db:g2p_notifications_base.view_notification_manager_email_form +msgid "Email Notification Manager" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.actions.act_window,name:g2p_notifications_base.action_notification_manager_email +#: model:ir.ui.menu,name:g2p_notifications_base.menu_notification_manager_email +msgid "Email Notification Managers" +msgstr "" + +#. module: g2p_notifications_base +#: model_terms:ir.ui.view,arch_db:g2p_notifications_base.view_notification_manager_email_form +msgid "Enter the Manager Name..." +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__id +msgid "ID" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_membership__is_enrolled_notification_sent +msgid "Is Enrolled Notification Sent" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_payment__is_payment_notification_sent +msgid "Is Payment Notification Sent" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__write_date +msgid "Last Updated on" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__name +msgid "Manager Name" +msgstr "" + +#. module: g2p_notifications_base +#: model_terms:ir.ui.view,arch_db:g2p_notifications_base.view_notification_manager_email_form +msgid "Name:" +msgstr "" + +#. module: g2p_notifications_base +#. odoo-python +#: code:addons/g2p_notifications_base/models/program.py:0 +#, python-format +msgid "No Notification Manager defined." +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields.selection,name:g2p_notifications_base.selection__res_partner__notification_preference__none +msgid "None" +msgstr "" + +#. module: g2p_notifications_base +#. odoo-python +#: code:addons/g2p_notifications_base/models/program.py:0 +#, python-format +msgid "Notification" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_membership__notification_preference +#: model:ir.model.fields,field_description:g2p_notifications_base.field_res_partner__notification_preference +#: model:ir.model.fields,field_description:g2p_notifications_base.field_res_users__notification_preference +msgid "Notification Preference" +msgstr "" + +#. module: g2p_notifications_base +#. odoo-python +#: code:addons/g2p_notifications_base/models/program.py:0 +#, python-format +msgid "Notifications are initiated" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__on_cycle_ended_template +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_sms__on_cycle_ended_template +msgid "On Cycle Ended Template" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__on_cycle_started_template +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_sms__on_cycle_started_template +msgid "On Cycle Started Template" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__on_enrolled_in_program_template +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_sms__on_enrolled_in_program_template +msgid "On Enrolled In Program Template" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__on_otp_send_template +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_sms__on_otp_send_template +msgid "On Otp Send Template" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__on_payment_send_template +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_sms__on_payment_send_template +msgid "On Payment Send Template" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model,name:g2p_notifications_base.model_g2p_payment +msgid "Payment" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model,name:g2p_notifications_base.model_g2p_program +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__program_id +msgid "Program" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model,name:g2p_notifications_base.model_g2p_program_membership +msgid "Program Membership" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model,name:g2p_notifications_base.model_g2p_program_notification_manager +msgid "Program Notification Manager" +msgstr "" + +#. module: g2p_notifications_base +#: model_terms:ir.ui.view,arch_db:g2p_notifications_base.view_notification_manager_email_form +msgid "Program:" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields.selection,name:g2p_notifications_base.selection__res_partner__notification_preference__sms +msgid "SMS" +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model,name:g2p_notifications_base.model_g2p_program_notification_manager_sms +msgid "SMS Program Notification Manager" +msgstr "" + +#. module: g2p_notifications_base +#: model_terms:ir.ui.view,arch_db:g2p_notifications_base.view_notification_manager_email_form +msgid "Select a program..." +msgstr "" + +#. module: g2p_notifications_base +#: model:ir.model.fields,field_description:g2p_notifications_base.field_g2p_program_notification_manager_email__send_immediately +msgid "Send Immediately" +msgstr "" + +#. module: g2p_notifications_base +#: model_terms:ir.ui.view,arch_db:g2p_notifications_base.view_notification_manager_email_form +msgid "Settings" +msgstr "" + +#. module: g2p_notifications_base +#: model_terms:ir.ui.view,arch_db:g2p_notifications_base.view_notification_manager_email_form +#: model_terms:ir.ui.view,arch_db:g2p_notifications_base.view_notification_manager_sms_inherit_form +msgid "TEMPLATES" +msgstr "" diff --git a/g2p_notifications_base/models/__init__.py b/g2p_notifications_base/models/__init__.py new file mode 100644 index 00000000..93f06f2b --- /dev/null +++ b/g2p_notifications_base/models/__init__.py @@ -0,0 +1,7 @@ +from . import registrant +from . import notification_manager +from . import sms_notification_manager +from . import program +from . import email_notification_manager +from . import program_membership +from . import payment_manager diff --git a/g2p_notifications_base/models/email_notification_manager.py b/g2p_notifications_base/models/email_notification_manager.py new file mode 100644 index 00000000..55f7692d --- /dev/null +++ b/g2p_notifications_base/models/email_notification_manager.py @@ -0,0 +1,87 @@ +import logging + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + + +class EmailNotificationManager(models.Model): + _name = "g2p.program.notification.manager.email" + _description = "Email Notification Manager" + _inherit = ["g2p.base.program.notification.manager", "g2p.manager.source.mixin"] + + notification_types = ("email", "both") + + send_immediately = fields.Boolean(default=False) + + on_enrolled_in_program_template = fields.Many2one("mail.template") + on_cycle_started_template = fields.Many2one("mail.template") + on_cycle_ended_template = fields.Many2one("mail.template") + on_otp_send_template = fields.Many2one("mail.template") + on_payment_send_template = fields.Many2one("mail.template") + + def on_enrolled_in_program(self, program_memberships): + if not self.on_enrolled_in_program_template: + return + # TODO: Make the following asynchrous and in bulk + for mem in program_memberships: + if mem.partner_id.notification_preference in self.notification_types and mem.partner_id.email: + self.on_enrolled_in_program_template.send_mail(mem.id, force_send=self.send_immediately) + + def on_otp_send(self, otp=None, email=None, **data): + if not self.on_otp_send_template: + return + # TODO: Make the following asynchrous and in bulk + if otp and email: + data["otp"] = otp + data["email"] = email + mail_values = self.on_otp_send_template.generate_email( + self.id, + [ + "subject", + "email_from", + "reply_to", + "email_cc", + ], + ) + mail_values["email_to"] = email + mail_values["body_html"] = self.on_otp_send_template._render_template( + self.on_otp_send_template.body_html, + self._name, + [ + self.id, + ], + add_context=data, + engine="qweb", + )[self.id] + mail = self.env["mail.mail"].create(mail_values) + mail.send() + return mail + return None + + def on_payment_send(self, batch): + if not self.on_payment_send_template: + return + + payments_to_notify = [ + payment + for payment in batch.payment_ids + if payment.status in ("paid",) and not payment.is_payment_notification_sent + ] + + for res in payments_to_notify: + if res.partner_id.notification_preference in self.notification_types and res.partner_id.email: + self.on_payment_send_template.send_mail(res.id, force_send=self.send_immediately) + res.is_payment_notification_sent = True + + def on_cycle_started(self, program_memberships, cycle_id): + if not self.on_cycle_started_template: + return + # TODO: to be implemented + return + + def on_cycle_ended(self, program_memberships, cycle_id): + if not self.on_cycle_ended_template: + return + # TODO: to be implemented + return diff --git a/g2p_notifications_base/models/notification_manager.py b/g2p_notifications_base/models/notification_manager.py new file mode 100644 index 00000000..c94ba64c --- /dev/null +++ b/g2p_notifications_base/models/notification_manager.py @@ -0,0 +1,12 @@ +from odoo import models + + +class NotificationManager(models.Model): + _inherit = "g2p.program.notification.manager" + + def _selection_manager_ref_id(self): + selection = super()._selection_manager_ref_id() + new_manager = ("g2p.program.notification.manager.email", "Email Notification") + if new_manager not in selection: + selection.append(new_manager) + return selection diff --git a/g2p_notifications_base/models/payment_manager.py b/g2p_notifications_base/models/payment_manager.py new file mode 100644 index 00000000..14b6a0c4 --- /dev/null +++ b/g2p_notifications_base/models/payment_manager.py @@ -0,0 +1,25 @@ +import logging + +from odoo import fields, models + +from odoo.addons.g2p_programs.models import constants + +_logger = logging.getLogger(__name__) + + +class DefaultPaymentManager(models.Model): + _inherit = "g2p.program.payment.manager.default" + + def send_payments(self, batches): + res = super().send_payments(batches) + if res and batches: + for manager in self.program_id.get_managers(constants.MANAGER_NOTIFICATION): + for batch in batches: + manager.on_payment_send(batch) + return res + + +class G2PPayment(models.Model): + _inherit = "g2p.payment" + + is_payment_notification_sent = fields.Boolean(default=False) diff --git a/g2p_notifications_base/models/program.py b/g2p_notifications_base/models/program.py new file mode 100644 index 00000000..b11afa62 --- /dev/null +++ b/g2p_notifications_base/models/program.py @@ -0,0 +1,42 @@ +import logging + +from odoo import _, models +from odoo.exceptions import UserError + +from odoo.addons.g2p_programs.models import constants + +_logger = logging.getLogger(__name__) + + +class G2PProgram(models.Model): + _inherit = "g2p.program" + + def notify_eligible_beneficiaries(self): + # TODO: Convert async + partners_to_notify = [ + mem + for mem in self.program_membership_ids + if mem.state in ("enrolled",) and not mem.is_enrolled_notification_sent + ] + notification_managers = self.get_managers(constants.MANAGER_NOTIFICATION) + if notification_managers: + for manager in notification_managers: + if manager: + manager.on_enrolled_in_program(partners_to_notify) + for mem in partners_to_notify: + mem.is_enrolled_notification_sent = True + message = _("Notifications are initiated") + return { + "type": "ir.actions.client", + "tag": "display_notification", + "params": { + "title": _("Notification"), + "message": message, + "sticky": True, + "next": { + "type": "ir.actions.act_window_close", + }, + }, + } + else: + raise UserError(_("No Notification Manager defined.")) diff --git a/g2p_notifications_base/models/program_membership.py b/g2p_notifications_base/models/program_membership.py new file mode 100644 index 00000000..4cc9a38d --- /dev/null +++ b/g2p_notifications_base/models/program_membership.py @@ -0,0 +1,17 @@ +from odoo import fields, models + +from odoo.addons.g2p_programs.models import constants + + +class G2PProgramMembership(models.Model): + _inherit = "g2p.program_membership" + + is_enrolled_notification_sent = fields.Boolean(default=False) + + def enroll_eligible_registrants(self): + res = super().enroll_eligible_registrants() + if res and res.get("params", {}).get("type", None) == "success": + for manager in self.program_id.get_managers(constants.MANAGER_NOTIFICATION): + manager.on_enrolled_in_program(self) + self.is_enrolled_notification_sent = True + return res diff --git a/g2p_notifications_base/models/registrant.py b/g2p_notifications_base/models/registrant.py new file mode 100644 index 00000000..eba04b62 --- /dev/null +++ b/g2p_notifications_base/models/registrant.py @@ -0,0 +1,22 @@ +from odoo import fields, models + + +class G2PRegistrant(models.Model): + _inherit = "res.partner" + + def _default_notification_preference(self): + return ( + self.env["ir.config_parameter"] + .sudo() + .get_param("g2p_notifications_base.default_notification_preference", "none") + ) + + notification_preference = fields.Selection( + [ + ("none", "None"), + ("email", "Email"), + ("sms", "SMS"), + ("both", "Both Email & SMS"), + ], + default=_default_notification_preference, + ) diff --git a/g2p_notifications_base/models/sms_notification_manager.py b/g2p_notifications_base/models/sms_notification_manager.py new file mode 100644 index 00000000..18547e5a --- /dev/null +++ b/g2p_notifications_base/models/sms_notification_manager.py @@ -0,0 +1,77 @@ +from odoo import fields, models + + +class SMSNotificationManager(models.Model): + _inherit = "g2p.program.notification.manager.sms" + + notification_types = ("sms", "both") + + on_enrolled_in_program_template = fields.Many2one("sms.template") + on_cycle_started_template = fields.Many2one("sms.template") + on_cycle_ended_template = fields.Many2one("sms.template") + on_otp_send_template = fields.Many2one("sms.template") + on_payment_send_template = fields.Many2one("sms.template") + + def on_enrolled_in_program(self, program_memberships): + if not self.on_enrolled_in_program_template: + return + # TODO: Make the following asynchrous and in bulk + send_sms_body_list = self.on_enrolled_in_program_template._render_template( + self.on_enrolled_in_program_template.body, + "g2p.program_membership", + [mem.id for mem in program_memberships], + engine="inline_template", + ) + for mem in program_memberships: + self.send_sms_to_membership(mem, send_sms_body_list.get(mem.id, None)) + + def on_cycle_started(self, program_memberships, cycle_id): + if not self.on_cycle_started_template: + return + # TODO: to be implemented + return + + def on_cycle_ended(self, program_memberships, cycle_id): + if not self.on_cycle_ended_template: + return + # TODO: to be implemented + return + + def on_otp_send(self, otp=None, phone=None, **data): + if not self.on_otp_send_template: + return + # TODO: Make the following asynchrous and in bulk + if otp and phone: + data["otp"] = otp + data["phone"] = phone + body = self.on_otp_send_template._render_template( + self.on_otp_send_template.body, + self._name, + [ + self.id, + ], + add_context=data, + engine="inline_template", + )[self.id] + return self.send_sms(phone, body) + return None + + def send_sms_to_membership(self, membership, body): + if ( + membership.partner_id.notification_preference in self.notification_types + and membership.partner_id.phone + and body + ): + return self.send_sms(membership.partner_id.phone, body) + return None + + def on_payment_send(self, batch): + if not self.on_payment_send_template: + return + + # TODO: to be implemented + return + + def send_sms(self, phone, body): + # TODO: To be Implemented. + raise NotImplementedError() diff --git a/g2p_notifications_base/pyproject.toml b/g2p_notifications_base/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_notifications_base/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_notifications_base/security/ir.model.access.csv b/g2p_notifications_base/security/ir.model.access.csv new file mode 100644 index 00000000..eac5d3e3 --- /dev/null +++ b/g2p_notifications_base/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +g2p_program_notification_manager_email_admin,Email Notification Manager Admin,g2p_notifications_base.model_g2p_program_notification_manager_email,g2p_registry_base.group_g2p_admin,1,1,1,1 +g2p_program_notification_manager_email_program_manager,Email Notification Manager Program Manager,g2p_notifications_base.model_g2p_program_notification_manager_email,g2p_programs.g2p_program_manager,1,1,1,0 +g2p_program_notification_manager_email_program_validator,Email Notification Manager Program Validator,g2p_notifications_base.model_g2p_program_notification_manager_email,g2p_programs.g2p_program_validator,1,0,0,0 diff --git a/g2p_notifications_base/static/description/icon.png b/g2p_notifications_base/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_notifications_base/static/description/icon.png differ diff --git a/g2p_notifications_base/views/email_notification_manager.xml b/g2p_notifications_base/views/email_notification_manager.xml new file mode 100644 index 00000000..4181c282 --- /dev/null +++ b/g2p_notifications_base/views/email_notification_manager.xml @@ -0,0 +1,85 @@ + + + + + view_notification_manager_email_tree + g2p.program.notification.manager.email + 1 + + + + + + + + + + view_notification_manager_email_form + g2p.program.notification.manager.email + 1 + +
+ +
+
+
+ + + + + + + + + + + + + + + + + Email Notification Managers + ir.actions.act_window + g2p.program.notification.manager.email + tree,form + {} + [] + +

+ Add an Email Notification Manager! +

+ Click the create button to enter a new Email notification manager. +

+
+
+ + + + diff --git a/g2p_notifications_base/views/registrant.xml b/g2p_notifications_base/views/registrant.xml new file mode 100644 index 00000000..6430f0ac --- /dev/null +++ b/g2p_notifications_base/views/registrant.xml @@ -0,0 +1,51 @@ + + + + + view_individual_notification_ext_form + res.partner + + + + + + + + + + + view_groups_notification_ext_form + res.partner + + + + + + + + + + + view_program_membership_notification_ext_form + g2p.program_membership + + + + + + + + + + + view_payment_notification_ext_form + g2p.payment + + + + + + + + + diff --git a/g2p_notifications_base/views/sms_notification_manager.xml b/g2p_notifications_base/views/sms_notification_manager.xml new file mode 100644 index 00000000..9ce5504a --- /dev/null +++ b/g2p_notifications_base/views/sms_notification_manager.xml @@ -0,0 +1,19 @@ + + + + view_notification_manager_sms_inherit_form + g2p.program.notification.manager.sms + + 100 + + + + + + + + + + + + diff --git a/g2p_notifications_fast2sms/README.md b/g2p_notifications_fast2sms/README.md new file mode 100644 index 00000000..e612fc2d --- /dev/null +++ b/g2p_notifications_fast2sms/README.md @@ -0,0 +1,5 @@ +# G2P Notifications: Fast2SMS Service Provider + +OpenG2P Notifications using Fast2SMS service provider + +Refer to https://docs.openg2p.org. diff --git a/g2p_notifications_fast2sms/__init__.py b/g2p_notifications_fast2sms/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/g2p_notifications_fast2sms/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/g2p_notifications_fast2sms/__manifest__.py b/g2p_notifications_fast2sms/__manifest__.py new file mode 100644 index 00000000..5d6a1cc8 --- /dev/null +++ b/g2p_notifications_fast2sms/__manifest__.py @@ -0,0 +1,25 @@ +{ + "name": "G2P Notifications: Fast2SMS Service Provider", + "category": "G2P", + "version": "17.0.0.0.0", + "sequence": 1, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": [ + "g2p_notifications_base", + ], + "data": [ + "views/fast2sms_notification_manager.xml", + "security/ir.model.access.csv", + ], + "assets": { + "web.assets_backend": [], + "web.assets_qweb": [], + }, + "demo": [], + "images": [], + "application": False, + "installable": True, + "auto_install": False, +} diff --git a/g2p_notifications_fast2sms/i18n/g2p_notifications_fast2sms.pot b/g2p_notifications_fast2sms/i18n/g2p_notifications_fast2sms.pot new file mode 100644 index 00000000..7de3f48b --- /dev/null +++ b/g2p_notifications_fast2sms/i18n/g2p_notifications_fast2sms.pot @@ -0,0 +1,134 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * g2p_notifications_fast2sms +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__access_token +msgid "Access Token" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model_terms:ir.actions.act_window,help:g2p_notifications_fast2sms.action_notification_manager_fast2sms +msgid "Add an Fast2SMS Notification Manager!" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model_terms:ir.actions.act_window,help:g2p_notifications_fast2sms.action_notification_manager_fast2sms +msgid "Click the create button to enter a new Fast2SMS notification manager." +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__create_uid +msgid "Created by" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__create_date +msgid "Created on" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__display_name +msgid "Display Name" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model,name:g2p_notifications_fast2sms.model_g2p_program_notification_manager_fast2sms +msgid "Fast2SMS Notification Manager" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.ui.menu,name:g2p_notifications_fast2sms.menu_notification_manager_fast2sms +msgid "Fast2SMS Notification Managers" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__id +msgid "ID" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__write_date +msgid "Last Updated on" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__name +msgid "Manager Name" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__on_cycle_ended_template +msgid "On Cycle Ended Template" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__on_cycle_started_template +msgid "On Cycle Started Template" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__on_enrolled_in_program_template +msgid "On Enrolled In Program Template" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__on_otp_send_template +msgid "On Otp Send Template" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__on_payment_send_template +msgid "On Payment Send Template" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__program_id +msgid "Program" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model,name:g2p_notifications_fast2sms.model_g2p_program_notification_manager +msgid "Program Notification Manager" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__sms_language +msgid "SMS Language" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__sms_route +msgid "SMS Route" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.model.fields,field_description:g2p_notifications_fast2sms.field_g2p_program_notification_manager_fast2sms__send_api_endpoint +msgid "Send API Endpoint" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model_terms:ir.ui.view,arch_db:g2p_notifications_fast2sms.view_notification_manager_fast2sms_form +msgid "Settings" +msgstr "" + +#. module: g2p_notifications_fast2sms +#: model:ir.actions.act_window,name:g2p_notifications_fast2sms.action_notification_manager_fast2sms +msgid "fast2sms Notification Managers" +msgstr "" diff --git a/g2p_notifications_fast2sms/models/__init__.py b/g2p_notifications_fast2sms/models/__init__.py new file mode 100644 index 00000000..3f807e29 --- /dev/null +++ b/g2p_notifications_fast2sms/models/__init__.py @@ -0,0 +1 @@ +from . import sms_notification_manager diff --git a/g2p_notifications_fast2sms/models/sms_notification_manager.py b/g2p_notifications_fast2sms/models/sms_notification_manager.py new file mode 100644 index 00000000..a6fdc2f5 --- /dev/null +++ b/g2p_notifications_fast2sms/models/sms_notification_manager.py @@ -0,0 +1,48 @@ +import logging + +import requests + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + + +class NotificationManager(models.Model): + _inherit = "g2p.program.notification.manager" + + def _selection_manager_ref_id(self): + selection = super()._selection_manager_ref_id() + new_manager = ( + "g2p.program.notification.manager.fast2sms", + "Fast2SMS Notification", + ) + if new_manager not in selection: + selection.append(new_manager) + return selection + + +class Fast2SMSNotificationManager(models.Model): + _name = "g2p.program.notification.manager.fast2sms" + _description = "Fast2SMS Notification Manager" + _inherit = ["g2p.program.notification.manager.sms"] + + send_api_endpoint = fields.Char("Send API Endpoint", required=True) + access_token = fields.Char(required=True) + sms_language = fields.Char("SMS Language", default="english") + sms_route = fields.Char("SMS Route", default="q") + + def send_sms(self, phone, body): + response = requests.post( + self.send_api_endpoint, + data={ + "message": body, + "language": self.sms_language, + "route": self.sms_route, + "numbers": phone, + }, + headers={ + "authorization": self.access_token, + }, + timeout=15, + ) + return response.text diff --git a/g2p_notifications_fast2sms/pyproject.toml b/g2p_notifications_fast2sms/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_notifications_fast2sms/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_notifications_fast2sms/security/ir.model.access.csv b/g2p_notifications_fast2sms/security/ir.model.access.csv new file mode 100644 index 00000000..1e2fb744 --- /dev/null +++ b/g2p_notifications_fast2sms/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +g2p_program_notification_manager_fast2sms_admin,Fast2SMS Notification Manager Admin,g2p_notifications_fast2sms.model_g2p_program_notification_manager_fast2sms,g2p_registry_base.group_g2p_admin,1,1,1,1 +g2p_program_notification_manager_fast2sms_program_manager,Fast2SMS Notification Manager Program Manager,g2p_notifications_fast2sms.model_g2p_program_notification_manager_fast2sms,g2p_programs.g2p_program_manager,1,1,1,0 +g2p_program_notification_manager_fast2sms_program_validator,Fast2SMS Notification Manager Program Validator,g2p_notifications_fast2sms.model_g2p_program_notification_manager_fast2sms,g2p_programs.g2p_program_validator,1,0,0,0 diff --git a/g2p_notifications_fast2sms/static/description/icon.png b/g2p_notifications_fast2sms/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_notifications_fast2sms/static/description/icon.png differ diff --git a/g2p_notifications_fast2sms/views/fast2sms_notification_manager.xml b/g2p_notifications_fast2sms/views/fast2sms_notification_manager.xml new file mode 100644 index 00000000..8ebc1c6a --- /dev/null +++ b/g2p_notifications_fast2sms/views/fast2sms_notification_manager.xml @@ -0,0 +1,62 @@ + + + + + view_notification_manager_fast2sms_tree + g2p.program.notification.manager.fast2sms + 1 + + + + + + + + + + view_notification_manager_fast2sms_form + g2p.program.notification.manager.fast2sms + + primary + 1 + + + Fast2SMS Notification Manager + + + + + + + + + + + + + + fast2sms Notification Managers + ir.actions.act_window + g2p.program.notification.manager.fast2sms + tree,form + {} + [] + +

+ Add an Fast2SMS Notification Manager! +

+ Click the create button to enter a new Fast2SMS notification manager. +

+
+
+ + + +
diff --git a/g2p_notifications_rest_api/README.md b/g2p_notifications_rest_api/README.md new file mode 100644 index 00000000..7bc70634 --- /dev/null +++ b/g2p_notifications_rest_api/README.md @@ -0,0 +1,3 @@ +# G2P Notifications: REST API + +Refer to https://docs.openg2p.org. diff --git a/g2p_notifications_rest_api/__init__.py b/g2p_notifications_rest_api/__init__.py new file mode 100644 index 00000000..71a02422 --- /dev/null +++ b/g2p_notifications_rest_api/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import services diff --git a/g2p_notifications_rest_api/__manifest__.py b/g2p_notifications_rest_api/__manifest__.py new file mode 100644 index 00000000..4aa47944 --- /dev/null +++ b/g2p_notifications_rest_api/__manifest__.py @@ -0,0 +1,20 @@ +{ + "name": "G2P Notifications: REST API", + "category": "G2P", + "version": "17.0.0.0.0", + "sequence": 1, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": ["g2p_registry_rest_api", "g2p_notifications_base"], + "data": [], + "assets": { + "web.assets_backend": [], + "web.assets_qweb": [], + }, + "demo": [], + "images": [], + "application": False, + "installable": False, + "auto_install": False, +} diff --git a/g2p_notifications_rest_api/i18n/g2p_notifications_rest_api.pot b/g2p_notifications_rest_api/i18n/g2p_notifications_rest_api.pot new file mode 100644 index 00000000..a11baf5c --- /dev/null +++ b/g2p_notifications_rest_api/i18n/g2p_notifications_rest_api.pot @@ -0,0 +1,13 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 15.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" diff --git a/g2p_notifications_rest_api/models/__init__.py b/g2p_notifications_rest_api/models/__init__.py new file mode 100644 index 00000000..28c22353 --- /dev/null +++ b/g2p_notifications_rest_api/models/__init__.py @@ -0,0 +1,2 @@ +from . import registrant +from . import group_membership diff --git a/g2p_notifications_rest_api/models/group_membership.py b/g2p_notifications_rest_api/models/group_membership.py new file mode 100644 index 00000000..c98350ff --- /dev/null +++ b/g2p_notifications_rest_api/models/group_membership.py @@ -0,0 +1,5 @@ +from odoo.addons.g2p_registry_rest_api.models import group_membership + + +class GroupMembersInfoIn(group_membership.GroupMembersInfoIn, extends=group_membership.GroupMembersInfoIn): + notification_preference: str = "none" diff --git a/g2p_notifications_rest_api/models/registrant.py b/g2p_notifications_rest_api/models/registrant.py new file mode 100644 index 00000000..a57424d7 --- /dev/null +++ b/g2p_notifications_rest_api/models/registrant.py @@ -0,0 +1,9 @@ +from odoo.addons.g2p_registry_rest_api.models import registrant + + +class RegistrantProgramMemberInfoIn(registrant.RegistrantInfoIn, extends=registrant.RegistrantInfoIn): + notification_preference: str = "none" + + +class RegistrantProgramMemberInfoOut(registrant.RegistrantInfoOut, extends=registrant.RegistrantInfoOut): + notification_preference: str = "none" diff --git a/g2p_notifications_rest_api/pyproject.toml b/g2p_notifications_rest_api/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_notifications_rest_api/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_notifications_rest_api/services/__init__.py b/g2p_notifications_rest_api/services/__init__.py new file mode 100644 index 00000000..60657088 --- /dev/null +++ b/g2p_notifications_rest_api/services/__init__.py @@ -0,0 +1,2 @@ +from . import process_individual_mixin +from . import process_group_mixin diff --git a/g2p_notifications_rest_api/services/process_group_mixin.py b/g2p_notifications_rest_api/services/process_group_mixin.py new file mode 100644 index 00000000..71e4016e --- /dev/null +++ b/g2p_notifications_rest_api/services/process_group_mixin.py @@ -0,0 +1,11 @@ +from odoo.addons.component.core import AbstractComponent + + +class ProcessGroupMixin(AbstractComponent): + _inherit = "process_group.rest.mixin" + + def _process_group(self, group_info): + res = super()._process_group(group_info) + if group_info.dict().get("notification_preference", None): + res["notification_preference"] = group_info.notification_preference + return res diff --git a/g2p_notifications_rest_api/services/process_individual_mixin.py b/g2p_notifications_rest_api/services/process_individual_mixin.py new file mode 100644 index 00000000..382d4ee1 --- /dev/null +++ b/g2p_notifications_rest_api/services/process_individual_mixin.py @@ -0,0 +1,11 @@ +from odoo.addons.component.core import AbstractComponent + + +class ProcessIndividualMixin(AbstractComponent): + _inherit = "process_individual.rest.mixin" + + def _process_individual(self, individual): + res = super()._process_individual(individual) + if individual.dict().get("notification_preference", None): + res["notification_preference"] = individual.notification_preference + return res diff --git a/g2p_notifications_rest_api/static/description/icon.png b/g2p_notifications_rest_api/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_notifications_rest_api/static/description/icon.png differ diff --git a/g2p_notifications_voucher/README.md b/g2p_notifications_voucher/README.md new file mode 100644 index 00000000..52ae39bc --- /dev/null +++ b/g2p_notifications_voucher/README.md @@ -0,0 +1,5 @@ +# G2P Notifications: Voucher + +OpenG2P Notification on Voucher Generation Module + +Refer to https://docs.openg2p.org. diff --git a/g2p_notifications_voucher/__init__.py b/g2p_notifications_voucher/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/g2p_notifications_voucher/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/g2p_notifications_voucher/__manifest__.py b/g2p_notifications_voucher/__manifest__.py new file mode 100644 index 00000000..60a6885d --- /dev/null +++ b/g2p_notifications_voucher/__manifest__.py @@ -0,0 +1,26 @@ +{ + "name": "G2P Notifications: Voucher", + "category": "G2P", + "version": "17.0.0.0.0", + "sequence": 1, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": [ + "g2p_entitlement_voucher", + "g2p_notifications_base", + ], + "data": [ + "views/email_notification_manager.xml", + "views/sms_notification_manager.xml", + ], + "assets": { + "web.assets_backend": [], + "web.assets_qweb": [], + }, + "demo": [], + "images": [], + "application": False, + "installable": True, + "auto_install": False, +} diff --git a/g2p_notifications_voucher/i18n/g2p_notifications_voucher.pot b/g2p_notifications_voucher/i18n/g2p_notifications_voucher.pot new file mode 100644 index 00000000..a66dae20 --- /dev/null +++ b/g2p_notifications_voucher/i18n/g2p_notifications_voucher.pot @@ -0,0 +1,37 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * g2p_notifications_voucher +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: g2p_notifications_voucher +#: model:ir.model,name:g2p_notifications_voucher.model_g2p_program_notification_manager_email +msgid "Email Notification Manager" +msgstr "" + +#. module: g2p_notifications_voucher +#: model:ir.model.fields,field_description:g2p_notifications_voucher.field_g2p_program_notification_manager_email__on_generate_voucher_template +#: model:ir.model.fields,field_description:g2p_notifications_voucher.field_g2p_program_notification_manager_fast2sms__on_generate_voucher_template +#: model:ir.model.fields,field_description:g2p_notifications_voucher.field_g2p_program_notification_manager_sms__on_generate_voucher_template +#: model:ir.model.fields,field_description:g2p_notifications_voucher.field_g2p_program_notification_manager_wiserv__on_generate_voucher_template +msgid "On Generate Voucher Template" +msgstr "" + +#. module: g2p_notifications_voucher +#: model:ir.model,name:g2p_notifications_voucher.model_g2p_program_notification_manager_sms +msgid "SMS Program Notification Manager" +msgstr "" + +#. module: g2p_notifications_voucher +#: model:ir.model,name:g2p_notifications_voucher.model_g2p_program_entitlement_manager_voucher +msgid "Voucher Entitlement Manager" +msgstr "" diff --git a/g2p_notifications_voucher/models/__init__.py b/g2p_notifications_voucher/models/__init__.py new file mode 100644 index 00000000..e1638c75 --- /dev/null +++ b/g2p_notifications_voucher/models/__init__.py @@ -0,0 +1,3 @@ +from . import entitlement_manager +from . import email_notification_manager +from . import sms_notification_manager diff --git a/g2p_notifications_voucher/models/email_notification_manager.py b/g2p_notifications_voucher/models/email_notification_manager.py new file mode 100644 index 00000000..fe6a279a --- /dev/null +++ b/g2p_notifications_voucher/models/email_notification_manager.py @@ -0,0 +1,19 @@ +import logging + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + + +class EmailNotificationManager(models.Model): + _inherit = "g2p.program.notification.manager.email" + + on_generate_voucher_template = fields.Many2one("mail.template") + + def on_generate_voucher(self, entitlements): + if not self.on_generate_voucher_template: + return + # TODO: Make the following asynchrous and in bulk + for entitlement in entitlements: + if entitlement.partner_id.email: + self.on_generate_voucher_template.send_mail(entitlement.id, force_send=self.send_immediately) diff --git a/g2p_notifications_voucher/models/entitlement_manager.py b/g2p_notifications_voucher/models/entitlement_manager.py new file mode 100644 index 00000000..b027100d --- /dev/null +++ b/g2p_notifications_voucher/models/entitlement_manager.py @@ -0,0 +1,14 @@ +from odoo import models + +from odoo.addons.g2p_programs.models import constants + + +class G2PVoucherEntitlementManagerNotification(models.Model): + _inherit = "g2p.program.entitlement.manager.voucher" + + def _generate_vouchers(self, entitlements): + err_count, files = super()._generate_vouchers(entitlements) + notif_managers = self.program_id.get_managers(constants.MANAGER_NOTIFICATION) + for notif_manager in notif_managers: + notif_manager.on_generate_voucher(entitlements) + return err_count, files diff --git a/g2p_notifications_voucher/models/sms_notification_manager.py b/g2p_notifications_voucher/models/sms_notification_manager.py new file mode 100644 index 00000000..1a82feab --- /dev/null +++ b/g2p_notifications_voucher/models/sms_notification_manager.py @@ -0,0 +1,20 @@ +from odoo import fields, models + + +class SMSNotificationManager(models.Model): + _inherit = "g2p.program.notification.manager.sms" + + on_generate_voucher_template = fields.Many2one("sms.template") + + def on_generate_voucher(self, entitlements): + if not self.on_generate_voucher_template: + return + # TODO: Make the following asynchrous and in bulk + send_sms_body_list = self.on_generate_voucher_template._render_template( + self.on_generate_voucher_template.body, + "g2p.entitlement", + [ent.id for ent in entitlements], + engine="inline_template", + ) + for ent in entitlements: + self.send_sms(ent.partner_id.phone, send_sms_body_list.get(ent.id, None)) diff --git a/g2p_notifications_voucher/pyproject.toml b/g2p_notifications_voucher/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_notifications_voucher/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_notifications_voucher/static/description/icon.png b/g2p_notifications_voucher/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_notifications_voucher/static/description/icon.png differ diff --git a/g2p_notifications_voucher/views/email_notification_manager.xml b/g2p_notifications_voucher/views/email_notification_manager.xml new file mode 100644 index 00000000..beae66e1 --- /dev/null +++ b/g2p_notifications_voucher/views/email_notification_manager.xml @@ -0,0 +1,13 @@ + + + + view_notification_manager_email_voucher_form + g2p.program.notification.manager.email + + + + + + + + diff --git a/g2p_notifications_voucher/views/sms_notification_manager.xml b/g2p_notifications_voucher/views/sms_notification_manager.xml new file mode 100644 index 00000000..8102239e --- /dev/null +++ b/g2p_notifications_voucher/views/sms_notification_manager.xml @@ -0,0 +1,13 @@ + + + + view_notification_manager_sms_voucher_form + g2p.program.notification.manager.sms + + + + + + + + diff --git a/g2p_notifications_wiserv/README.md b/g2p_notifications_wiserv/README.md new file mode 100644 index 00000000..8ccc198e --- /dev/null +++ b/g2p_notifications_wiserv/README.md @@ -0,0 +1,5 @@ +# G2P Notifications: Wiserv SMS Service Provider + +OpenG2P Notifications using Wiserv SMS service provider + +Refer to https://docs.openg2p.org. diff --git a/g2p_notifications_wiserv/__init__.py b/g2p_notifications_wiserv/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/g2p_notifications_wiserv/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/g2p_notifications_wiserv/__manifest__.py b/g2p_notifications_wiserv/__manifest__.py new file mode 100644 index 00000000..020f098e --- /dev/null +++ b/g2p_notifications_wiserv/__manifest__.py @@ -0,0 +1,24 @@ +{ + "name": "G2P Notifications: Wiserv SMS Service Provider", + "category": "G2P", + "version": "17.0.0.0.0", + "sequence": 1, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": ["g2p_notifications_base", "mail"], + "external_dependencies": {"python": ["zeep"]}, + "data": [ + "views/wiservsms_notification_manager.xml", + "security/ir.model.access.csv", + ], + "assets": { + "web.assets_backend": [], + "web.assets_qweb": [], + }, + "demo": [], + "images": [], + "application": False, + "installable": True, + "auto_install": False, +} diff --git a/g2p_notifications_wiserv/i18n/g2p_notifications_wiserv.pot b/g2p_notifications_wiserv/i18n/g2p_notifications_wiserv.pot new file mode 100644 index 00000000..13e002b7 --- /dev/null +++ b/g2p_notifications_wiserv/i18n/g2p_notifications_wiserv.pot @@ -0,0 +1,310 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * g2p_notifications_wiserv +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__api_url +msgid "API URL" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_needaction +msgid "Action Needed" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_ids +msgid "Activities" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_exception_decoration +msgid "Activity Exception Decoration" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_state +msgid "Activity State" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_type_icon +msgid "Activity Type Icon" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model_terms:ir.actions.act_window,help:g2p_notifications_wiserv.action_notification_manager_wiservsms +msgid "Add an Wiserv SMS Notification Manager!" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_attachment_count +msgid "Attachment Count" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model_terms:ir.actions.act_window,help:g2p_notifications_wiserv.action_notification_manager_wiservsms +msgid "" +"Click the create button to enter a new Wiserv SMS notification manager." +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__create_uid +msgid "Created by" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__create_date +msgid "Created on" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__display_name +msgid "Display Name" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_follower_ids +msgid "Followers" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_partner_ids +msgid "Followers (Partners)" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_type_icon +msgid "Font awesome icon e.g. fa-tasks" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__has_message +msgid "Has Message" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__id +msgid "ID" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_exception_icon +msgid "Icon" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_exception_icon +msgid "Icon to indicate an exception activity." +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_needaction +msgid "If checked, new messages require your attention." +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_has_error +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_has_sms_error +msgid "If checked, some messages have a delivery error." +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_is_follower +msgid "Is Follower" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__write_date +msgid "Last Updated on" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__name +msgid "Manager Name" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_has_error +msgid "Message Delivery error" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_ids +msgid "Messages" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__my_activity_date_deadline +msgid "My Activity Deadline" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_calendar_event_id +msgid "Next Activity Calendar Event" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_date_deadline +msgid "Next Activity Deadline" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_summary +msgid "Next Activity Summary" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_type_id +msgid "Next Activity Type" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_needaction_counter +msgid "Number of Actions" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_has_error_counter +msgid "Number of errors" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_needaction_counter +msgid "Number of messages requiring action" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_has_error_counter +msgid "Number of messages with delivery error" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__on_cycle_ended_template +msgid "On Cycle Ended Template" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__on_cycle_started_template +msgid "On Cycle Started Template" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__on_enrolled_in_program_template +msgid "On Enrolled In Program Template" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__on_otp_send_template +msgid "On Otp Send Template" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__on_payment_send_template +msgid "On Payment Send Template" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__wiserv_password +msgid "Password" +msgstr "" + +#. module: g2p_notifications_wiserv +#. odoo-python +#: code:addons/g2p_notifications_wiserv/models/sms_notification_manager.py:0 +#: code:addons/g2p_notifications_wiserv/models/sms_notification_manager.py:0 +#, python-format +msgid "Please configure Wiserv SMS configuration correctly." +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__program_id +msgid "Program" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model,name:g2p_notifications_wiserv.model_g2p_program_notification_manager +msgid "Program Notification Manager" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_user_id +msgid "Responsible User" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__message_has_sms_error +msgid "SMS Delivery error" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model_terms:ir.ui.view,arch_db:g2p_notifications_wiserv.view_notification_manager_wiservsms_form +msgid "Settings" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_state +msgid "" +"Status based on activities\n" +"Overdue: Due date is already passed\n" +"Today: Activity date is today\n" +"Planned: Future activities." +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__activity_exception_decoration +msgid "Type of the exception activity on record." +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__user_name +msgid "User Name" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,field_description:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__website_message_ids +msgid "Website Messages" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model.fields,help:g2p_notifications_wiserv.field_g2p_program_notification_manager_wiserv__website_message_ids +msgid "Website communication history" +msgstr "" + +#. module: g2p_notifications_wiserv +#. odoo-python +#: code:addons/g2p_notifications_wiserv/models/sms_notification_manager.py:0 +#, python-format +msgid "Wiserv Failure Response" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.model,name:g2p_notifications_wiserv.model_g2p_program_notification_manager_wiserv +msgid "Wiserv Notification Manager" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.ui.menu,name:g2p_notifications_wiserv.menu_notification_manager_wiservsms +msgid "Wiserv Notification Managers" +msgstr "" + +#. module: g2p_notifications_wiserv +#: model:ir.actions.act_window,name:g2p_notifications_wiserv.action_notification_manager_wiservsms +msgid "Wiservsms Notification Managers" +msgstr "" diff --git a/g2p_notifications_wiserv/models/__init__.py b/g2p_notifications_wiserv/models/__init__.py new file mode 100644 index 00000000..3f807e29 --- /dev/null +++ b/g2p_notifications_wiserv/models/__init__.py @@ -0,0 +1 @@ +from . import sms_notification_manager diff --git a/g2p_notifications_wiserv/models/sms_notification_manager.py b/g2p_notifications_wiserv/models/sms_notification_manager.py new file mode 100644 index 00000000..e990bbfb --- /dev/null +++ b/g2p_notifications_wiserv/models/sms_notification_manager.py @@ -0,0 +1,72 @@ +import logging + +from zeep import Client + +from odoo import _, fields, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class NotificationManager(models.Model): + _inherit = "g2p.program.notification.manager" + + def _selection_manager_ref_id(self): + selection = super()._selection_manager_ref_id() + new_manager = ( + "g2p.program.notification.manager.wiserv", + "Wiserv SMS Notification", + ) + if new_manager not in selection: + selection.append(new_manager) + return selection + + +class WiservNotificationManager(models.Model): + _name = "g2p.program.notification.manager.wiserv" + _description = "Wiserv Notification Manager" + _inherit = [ + "g2p.program.notification.manager.sms", + "mail.thread", + "mail.activity.mixin", + ] + + api_url = fields.Char("API URL") + user_name = fields.Char() + wiserv_password = fields.Char("Password") + + def send_sms_to_membership(self, membership, body): + if ( + membership.partner_id.notification_preference in self.notification_types + and membership.partner_id.phone + and body + ): + if self.api_url and self.user_name and self.wiserv_password: + return self.send_sms( + membership.partner_id.phone, + body, + partner_name=membership.partner_id.name, + ) + else: + raise UserError(_("Please configure Wiserv SMS configuration correctly.")) + + def send_sms(self, phone, body, partner_name=""): + if not (self.api_url and self.user_name and self.wiserv_password): + raise UserError(_("Please configure Wiserv SMS configuration correctly.")) + + try: + client = Client(self.api_url) + response = client.service.sendMessage( + UserName=self.user_name, + PassWord=self.wiserv_password, + MobileNo=phone, + Message=body, + ) + _logger.info("Wiserv API Response: %s", response) + return response + except Exception as e: + # Handle general exception + _logger.exception("Error occurred during sendMessage:%s" % e) + error_msg = f"Error occurred during sendMessage to this partner: {partner_name} ⟶ {e}" + self.message_post(body=error_msg, subject=_("Wiserv Failure Response")) + return None diff --git a/g2p_notifications_wiserv/pyproject.toml b/g2p_notifications_wiserv/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_notifications_wiserv/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_notifications_wiserv/security/ir.model.access.csv b/g2p_notifications_wiserv/security/ir.model.access.csv new file mode 100644 index 00000000..e8efdaa6 --- /dev/null +++ b/g2p_notifications_wiserv/security/ir.model.access.csv @@ -0,0 +1,4 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +g2p_program_notification_manager_Wiservsms_admin,Wiserv SMS Notification Manager Admin,g2p_notifications_wiserv.model_g2p_program_notification_manager_wiserv,g2p_registry_base.group_g2p_admin,1,1,1,1 +g2p_program_notification_manager_Wiservsms_program_manager,Wiserv SMS Notification Manager Program Manager,g2p_notifications_wiserv.model_g2p_program_notification_manager_wiserv,g2p_programs.g2p_program_manager,1,1,1,0 +g2p_program_notification_manager_Wiservsms_program_validator,Wiserv SMS Notification Manager Program Validator,g2p_notifications_wiserv.model_g2p_program_notification_manager_wiserv,g2p_programs.g2p_program_validator,1,0,0,0 diff --git a/g2p_notifications_wiserv/static/description/icon.png b/g2p_notifications_wiserv/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_notifications_wiserv/static/description/icon.png differ diff --git a/g2p_notifications_wiserv/views/wiservsms_notification_manager.xml b/g2p_notifications_wiserv/views/wiservsms_notification_manager.xml new file mode 100644 index 00000000..7eba2743 --- /dev/null +++ b/g2p_notifications_wiserv/views/wiservsms_notification_manager.xml @@ -0,0 +1,67 @@ + + + + + view_notification_manager_wiservsms_tree + g2p.program.notification.manager.wiserv + 1 + + + + + + + + + + view_notification_manager_wiservsms_form + g2p.program.notification.manager.wiserv + + primary + 1 + + + Wiservsms Notification Manager + + + + + + + + + +
+ + +
+
+
+
+ + + Wiservsms Notification Managers + ir.actions.act_window + g2p.program.notification.manager.wiserv + tree,form + {} + [] + +

+ Add an Wiserv SMS Notification Manager! +

+ Click the create button to enter a new Wiserv SMS notification manager. +

+
+
+ + + +
diff --git a/g2p_odk_importer_program/README.md b/g2p_odk_importer_program/README.md new file mode 100644 index 00000000..1767fb63 --- /dev/null +++ b/g2p_odk_importer_program/README.md @@ -0,0 +1,3 @@ +# G2P ODK Importer: Program + +Refer to https://docs.openg2p.org. diff --git a/g2p_odk_importer_program/__init__.py b/g2p_odk_importer_program/__init__.py new file mode 100644 index 00000000..1a5b30f8 --- /dev/null +++ b/g2p_odk_importer_program/__init__.py @@ -0,0 +1,3 @@ +# Part of Newlogic G2P. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/g2p_odk_importer_program/__manifest__.py b/g2p_odk_importer_program/__manifest__.py new file mode 100644 index 00000000..ceb894ec --- /dev/null +++ b/g2p_odk_importer_program/__manifest__.py @@ -0,0 +1,20 @@ +# Part of openG2P. See LICENSE file for full copyright and licensing details. + +{ + "name": "G2P ODK Importer: Program", + "category": "Connector", + "summary": "Import records from ODK and add then into Program", + "version": "17.0.0.0.0", + "sequence": 3, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": ["g2p_odk_importer", "g2p_program_registrant_info"], + "data": [ + "views/odk_import_views.xml", + ], + "external_dependencies": {}, + "application": True, + "installable": True, + "auto_install": False, +} diff --git a/g2p_odk_importer_program/i18n/g2p_odk_importer.pot b/g2p_odk_importer_program/i18n/g2p_odk_importer.pot new file mode 100644 index 00000000..32e9d4f3 --- /dev/null +++ b/g2p_odk_importer_program/i18n/g2p_odk_importer.pot @@ -0,0 +1,261 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * g2p_odk_importer_regisry +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Restart" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Start" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Stop" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_tree +msgid "Action odk conf action" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__base_url +msgid "Base URL" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields.selection,name:g2p_odk_importer_regisry.selection__odk_config__job_status__completed +msgid "Completed" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.ui.menu,name:g2p_odk_importer_regisry.odk_menu_config +msgid "Configuration" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__create_uid +msgid "Created by" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__create_date +msgid "Created on" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__cron_id +msgid "Cron Job" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__display_name +msgid "Display Name" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields.selection,name:g2p_odk_importer_regisry.selection__odk_config__job_status__draft +msgid "Draft" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__end_datetime +msgid "End Time" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__form_id +msgid "Form ID" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields.selection,name:g2p_odk_importer_regisry.selection__odk_config__target_registry__group +msgid "Group" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__id +msgid "ID" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Import Records" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Import records" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields.selection,name:g2p_odk_importer_regisry.selection__odk_config__target_registry__individual +msgid "Individual" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__interval_hours +msgid "Interval in hours" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__json_formatter +msgid "JSON Formatter" +msgstr "" + +#. module: g2p_odk_importer_regisry +#. odoo-python +#: code:addons/g2p_odk_importer_regisry/models/odk_config.py:0 +#, python-format +msgid "Json Format is not valid pyjq expression." +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__write_date +msgid "Last Updated on" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__last_sync_time +msgid "Last synced on" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__name +msgid "Name" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.ui.menu,name:g2p_odk_importer_regisry.odk_menu_root +msgid "ODK" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "ODK Central" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.actions.server,name:g2p_odk_importer_regisry.action_odk_conf_action +msgid "ODK Config Start" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.actions.act_window,name:g2p_odk_importer_regisry.action_odk_config +#: model:ir.model,name:g2p_odk_importer_regisry.model_odk_config +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "ODK Configuration" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__odk_program_id +msgid "ODK Program ID" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__password +msgid "Password" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Program details" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__project +msgid "Project" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Project details" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_tree +msgid "Restart" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields.selection,name:g2p_odk_importer_regisry.selection__odk_config__job_status__running +msgid "Running" +msgstr "" + +#. module: g2p_odk_importer_regisry +#. odoo-python +#: code:addons/g2p_odk_importer_regisry/models/odk_client.py:0 +#, python-format +msgid "Session not created" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_tree +msgid "Start" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__start_datetime +msgid "Start Time" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields.selection,name:g2p_odk_importer_regisry.selection__odk_config__job_status__started +msgid "Started" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__job_status +msgid "Status" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_tree +msgid "Stop" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__target_registry +msgid "Target Registry" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Target settings" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Test Connection" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_regisry.view_odk_config_form +msgid "Time interval" +msgstr "" + +#. module: g2p_odk_importer_regisry +#: model:ir.model.fields,field_description:g2p_odk_importer_regisry.field_odk_config__username +msgid "Username" +msgstr "" diff --git a/g2p_odk_importer_program/i18n/g2p_odk_importer_program.pot b/g2p_odk_importer_program/i18n/g2p_odk_importer_program.pot new file mode 100644 index 00000000..b7861283 --- /dev/null +++ b/g2p_odk_importer_program/i18n/g2p_odk_importer_program.pot @@ -0,0 +1,29 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * g2p_odk_importer_program +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: g2p_odk_importer_program +#: model:ir.model,name:g2p_odk_importer_program.model_odk_import +msgid "ODK Import" +msgstr "" + +#. module: g2p_odk_importer_program +#: model:ir.model.fields,field_description:g2p_odk_importer_program.field_odk_import__program +msgid "Program" +msgstr "" + +#. module: g2p_odk_importer_program +#: model_terms:ir.ui.view,arch_db:g2p_odk_importer_program.view_program_odk_config_form +msgid "Program details" +msgstr "" diff --git a/g2p_odk_importer_program/models/__init__.py b/g2p_odk_importer_program/models/__init__.py new file mode 100644 index 00000000..4dbdb56a --- /dev/null +++ b/g2p_odk_importer_program/models/__init__.py @@ -0,0 +1,4 @@ +# Part of Newlogic G2P. See LICENSE file for full copyright and licensing details. + +from . import odk_client +from . import odk_config diff --git a/g2p_odk_importer_program/models/odk_client.py b/g2p_odk_importer_program/models/odk_client.py new file mode 100644 index 00000000..41c14d98 --- /dev/null +++ b/g2p_odk_importer_program/models/odk_client.py @@ -0,0 +1,45 @@ +from datetime import date + +import odoo.addons.g2p_odk_importer.models.odk_client as base_odk_client + + +def patched_addl_data(self, mapped_json): + config = self.env["odk.config"].browse(self.id) + + program_id = config.program.id + + if "program_registrant_info_ids" in mapped_json: + prog_reg_info = mapped_json.get("program_registrant_info_ids", None) + + if not program_id: + del mapped_json["program_registrant_info_ids"] + return mapped_json + + mapped_json["program_membership_ids"] = [ + ( + 0, + 0, + { + "program_id": program_id, + "state": "draft", + "enrollment_date": date.today(), + }, + ) + ] + + mapped_json["program_registrant_info_ids"] = [ + ( + 0, + 0, + { + "program_id": program_id, + "state": "active", + "program_registrant_info": prog_reg_info if prog_reg_info else None, + }, + ) + ] + + return mapped_json + + +base_odk_client.ODKClient.get_addl_data = patched_addl_data diff --git a/g2p_odk_importer_program/models/odk_config.py b/g2p_odk_importer_program/models/odk_config.py new file mode 100644 index 00000000..b73c20da --- /dev/null +++ b/g2p_odk_importer_program/models/odk_config.py @@ -0,0 +1,7 @@ +from odoo import fields, models + + +class OdkConfig(models.Model): + _inherit = "odk.import" + + program = fields.Many2one("g2p.program", domain="[('target_type', '=', target_registry)]") diff --git a/g2p_odk_importer_program/pyproject.toml b/g2p_odk_importer_program/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_odk_importer_program/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_odk_importer_program/static/description/icon.png b/g2p_odk_importer_program/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_odk_importer_program/static/description/icon.png differ diff --git a/g2p_odk_importer_program/views/odk_import_views.xml b/g2p_odk_importer_program/views/odk_import_views.xml new file mode 100644 index 00000000..9b23ce0d --- /dev/null +++ b/g2p_odk_importer_program/views/odk_import_views.xml @@ -0,0 +1,16 @@ + + + + odk.config.form + odk.import + + + + + + + + + + + diff --git a/g2p_openid_vci_programs/README.md b/g2p_openid_vci_programs/README.md new file mode 100644 index 00000000..20de9a9d --- /dev/null +++ b/g2p_openid_vci_programs/README.md @@ -0,0 +1,5 @@ +# G2P OpenID VCI: Program Beneficiaries + +OpenG2P OpenID for Verifiable Credential Issuance for G2P Beneficiaries + +Refer to https://docs.openg2p.org. diff --git a/g2p_openid_vci_programs/__init__.py b/g2p_openid_vci_programs/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/g2p_openid_vci_programs/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/g2p_openid_vci_programs/__manifest__.py b/g2p_openid_vci_programs/__manifest__.py new file mode 100644 index 00000000..97910cfe --- /dev/null +++ b/g2p_openid_vci_programs/__manifest__.py @@ -0,0 +1,26 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. +{ + "name": "G2P OpenID VCI: Program Beneficiaries", + "category": "G2P", + "version": "17.0.0.0.0", + "sequence": 1, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": [ + "g2p_openid_vci", + "g2p_programs", + ], + "data": [ + "views/vci_issuers.xml", + ], + "assets": { + "web.assets_backend": [], + "web.assets_qweb": [], + }, + "demo": [], + "images": [], + "application": False, + "installable": True, + "auto_install": False, +} diff --git a/g2p_openid_vci_programs/data/default_contexts.json b/g2p_openid_vci_programs/data/default_contexts.json new file mode 100644 index 00000000..7ae70b3c --- /dev/null +++ b/g2p_openid_vci_programs/data/default_contexts.json @@ -0,0 +1,101 @@ +{ + "@context": { + "OpenG2PBeneficiaryVerifiableCredential": { + "@id": "https://openg2p.org/credential#OpenG2PBeneficiaryVerifiableCredential", + "@context": [ + "https://www.w3.org/2018/credentials/v1", + { + "@vocab": "https://openg2p.org/credential#OpenG2PBeneficiaryVerifiableCredential#", + "credentialSubject": { + "@id": "credentialSubject", + "@type": "@id", + "@context": { + "@vocab": "https://openg2p.org/credential#OpenG2PBeneficiaryVerifiableCredential#credentialSubject#", + "name": { + "@id": "name", + "@type": "@id", + "@context": { + "value": "@value", + "language": "@language" + } + }, + "fullName": { + "@id": "fullName", + "@type": "@id", + "@context": { + "value": "@value", + "language": "@language" + } + }, + "gender": { + "@id": "gender", + "@type": "@id", + "@context": { + "value": "@value", + "language": "@language" + } + }, + "dateOfBirth": "dateOfBirth", + "email": "email", + "phone": "phone", + "addressLine1": { + "@id": "addressLine1", + "@type": "@id", + "@context": { + "value": "@value", + "language": "@language" + } + }, + "addressLine2": { + "@id": "addressLine2", + "@type": "@id", + "@context": { + "value": "@value", + "language": "@language" + } + }, + "addressLine3": { + "@id": "addressLine3", + "@type": "@id", + "@context": { + "value": "@value", + "language": "@language" + } + }, + "province": { + "@id": "province", + "@type": "@id", + "@context": { + "value": "@value", + "language": "@language" + } + }, + "region": { + "@id": "region", + "@type": "@id", + "@context": { + "value": "@value", + "language": "@language" + } + }, + "postalCode": "postalCode", + "face": "face", + "vcVer": "vcVer", + "UIN": "UIN", + "nationalId": "nationalId", + "programName": { + "@id": "programName", + "@type": "@id", + "@context": { + "value": "@value", + "language": "@language" + } + }, + "validUntil": "validUntil" + } + } + } + ] + } + } +} diff --git a/g2p_openid_vci_programs/data/default_credential_format.jq b/g2p_openid_vci_programs/data/default_credential_format.jq new file mode 100644 index 00000000..53bae45f --- /dev/null +++ b/g2p_openid_vci_programs/data/default_credential_format.jq @@ -0,0 +1,74 @@ +{ + "@context": [ + "https://www.w3.org/2018/credentials/v1", + (.web_base_url + "/api/v1/vci/.well-known/contexts.json") + ], + "id": .vc_id, + "type": ["VerifiableCredential", .issuer.credential_type], + "issuer": .issuer.unique_issuer_id, + "issuanceDate": .curr_datetime, + "credentialSubject": { + "vcVer": "VC-V1", + "id": (.web_base_url + "/api/v1/registry/individual/" + (.partner.id | tostring)), + "name": [ + { + "language": "eng", + "value": (.partner.name // null) + } + ], + "fullName": [ + { + "language": "eng", + "value": (.partner.name // null) + } + ], + "gender": (if .partner.gender then [ + { + "language": "eng", + "value": .partner.gender + } + ] else null end), + "dateOfBirth": (.partner.birthdate // null), + "email": (.partner.email // null), + "phone": (.partner.phone // null), + "addressLine1": (if .partner_address.street_address then [ + { + "language": "eng", + "value": .partner_address.street_address + } + ] else null end), + "province": (if .partner_address.locality then [ + { + "language": "eng", + "value": .partner_address.locality + } + ] else null end), + "region": (if .partner_address.region then [ + { + "language": "eng", + "value": .partner_address.region + } + ] else null end), + "postalCode": .partner_address.postal_code, + "face": .partner_face, + "nationalId": .reg_ids["NATIONAL ID"]?.value, + "UIN": ( + (.reg_ids["NATIONAL ID"]?.value[0:5] | explode | reverse | implode) + + (.reg_ids["NATIONAL ID"]?.value[6:10] | explode | reverse| implode) + ), + "programName": [ + { + "language": "eng", + "value": .program.name + } + ], + "validUntil": ( + .curr_datetime + | sub(".[0-9]+Z$"; "Z") + | strptime("%Y-%m-%dT%H:%M:%SZ") + | mktime + | . + 31556926 + | strftime("%Y-%m-%d") + ) + } +} diff --git a/g2p_openid_vci_programs/data/default_issuer_metadata.jq b/g2p_openid_vci_programs/data/default_issuer_metadata.jq new file mode 100644 index 00000000..05cc1721 --- /dev/null +++ b/g2p_openid_vci_programs/data/default_issuer_metadata.jq @@ -0,0 +1,107 @@ +[ + { + "id": .credential_type, + "format": .supported_format, + "scope": .scope, + "cryptographic_binding_methods_supported": [ + "did:jwk" + ], + "credential_signing_alg_values_supported": [ + "RS256" + ], + "proof_types_supported": [ + "jwt" + ], + "credential_definition": { + "type": [ + "VerifiableCredential", + .credential_type + ], + "credentialSubject": { + "fullName": { + "display": [ + { + "name": "Name", + "locale": "en" + } + ] + }, + "gender": { + "display": [ + { + "name": "Gender", + "locale": "en" + } + ] + }, + "dateOfBirth": { + "display": [ + { + "name": "Date of Birth", + "locale": "en" + } + ] + }, + "address": { + "display": [ + { + "name": "Address", + "locale": "en" + } + ] + }, + "UIN": { + "display": [ + { + "name": "Beneficiary ID", + "locale": "en" + } + ] + }, + "nationalID": { + "display": [ + { + "name": "National ID", + "locale": "en" + } + ] + }, + "programName": { + "display": [ + { + "name": "Program Name", + "locale": "en" + } + ] + }, + "validUntil": { + "display": [ + { + "name": "Valid until", + "locale": "en" + } + ] + } + } + }, + "display": [ + { + "name": "OpenG2P Program Beneficiary Credential", + "locale": "en", + "logo": { + "url": (.web_base_url + "/g2p_openid_vci_programs/static/description/icon.png"), + "alt_text": "a square logo of a OpenG2P" + }, + "background_color": "#f5c538", + "text_color": "#03096e" + } + ], + "order": [ + "fullName", + "programName", + "gender", + "dateOfBirth", + "validUntil" + ] + } +] diff --git a/g2p_openid_vci_programs/i18n/g2p_openid_vci_programs.pot b/g2p_openid_vci_programs/i18n/g2p_openid_vci_programs.pot new file mode 100644 index 00000000..06840503 --- /dev/null +++ b/g2p_openid_vci_programs/i18n/g2p_openid_vci_programs.pot @@ -0,0 +1,34 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * g2p_openid_vci_programs +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: g2p_openid_vci_programs +#: model:ir.model.fields.selection,name:g2p_openid_vci_programs.selection__g2p_openid_vci_issuers__issuer_type__beneficiary +msgid "Beneficiary" +msgstr "" + +#. module: g2p_openid_vci_programs +#: model:ir.model.fields,field_description:g2p_openid_vci_programs.field_g2p_openid_vci_issuers__issuer_type +msgid "Issuer Type" +msgstr "" + +#. module: g2p_openid_vci_programs +#: model:ir.model,name:g2p_openid_vci_programs.model_g2p_openid_vci_issuers +msgid "OpenID VCI Issuer" +msgstr "" + +#. module: g2p_openid_vci_programs +#: model:ir.model.fields,field_description:g2p_openid_vci_programs.field_g2p_openid_vci_issuers__program_id +msgid "Program" +msgstr "" diff --git a/g2p_openid_vci_programs/models/__init__.py b/g2p_openid_vci_programs/models/__init__.py new file mode 100644 index 00000000..23d962ef --- /dev/null +++ b/g2p_openid_vci_programs/models/__init__.py @@ -0,0 +1 @@ +from . import vci_issuer diff --git a/g2p_openid_vci_programs/models/vci_issuer.py b/g2p_openid_vci_programs/models/vci_issuer.py new file mode 100644 index 00000000..c09aeaa3 --- /dev/null +++ b/g2p_openid_vci_programs/models/vci_issuer.py @@ -0,0 +1,98 @@ +import logging +import uuid +from datetime import datetime + +import jq + +from odoo import fields, models + +from odoo.addons.g2p_openid_vci.json_encoder import VCJSONEncoder + +_logger = logging.getLogger(__name__) + + +class BeneficiaryOpenIDVCIssuer(models.Model): + _inherit = "g2p.openid.vci.issuers" + + issuer_type = fields.Selection( + selection_add=[ + ( + "Beneficiary", + "Beneficiary", + ) + ], + ondelete={"Beneficiary": "cascade"}, + ) + + program_id = fields.Many2one("g2p.program") + + def issue_vc_Beneficiary(self, auth_claims, credential_request): + self.ensure_one() + web_base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url").rstrip("/") + + reg_id = ( + self.env["g2p.reg.id"] + .sudo() + .search( + [ + ("id_type", "=", self.auth_sub_id_type_id.id), + ("value", "=", auth_claims["sub"]), + ( + "partner_id.program_membership_ids.program_id", + "=", + self.program_id.id, + ), + ], + limit=1, + ) + ) + partner = None + if not reg_id: + raise ValueError( + "ID not found in DB. " + "Invalid Subject Received in auth claims. " + "Or person not part of the program." + ) + + partner = reg_id.partner_id + program_membership_id = partner.program_membership_ids.filtered( + lambda x: x.program_id.id == self.program_id.id + ) + if program_membership_id.state != "enrolled": + raise ValueError("Person not enrolled into program.") + + partner_dict = partner.read()[0] + program_membership_dict = program_membership_id.read()[0] + reg_ids_dict = {reg_id.id_type.name: reg_id.read()[0] for reg_id in partner.reg_ids} + program_dict = self.program_id.read()[0] + + curr_datetime = f'{datetime.utcnow().isoformat(timespec = "milliseconds")}Z' + credential = jq.first( + self.credential_format, + VCJSONEncoder.python_dict_to_json_dict( + { + "vc_id": str(uuid.uuid4()), + "web_base_url": web_base_url, + "issuer": self.read()[0], + "curr_datetime": curr_datetime, + "partner": partner_dict, + "partner_address": self.get_full_address(partner.address), + "partner_face": self.get_image_base64_data_in_url(partner.image_1920.decode()), + "reg_ids": reg_ids_dict, + "program_membership": program_membership_dict, + "program": program_dict, + }, + ), + ) + credential_response = { + "credential": self.sign_and_issue_credential(credential), + "format": credential_request["format"], + } + return credential_response + + def set_default_credential_type_Beneficiary(self): + self.credential_type = "OpenG2PBeneficiaryVerifiableCredential" + + def set_from_static_file_Beneficiary(self, **kwargs): + kwargs.setdefault("module_name", "g2p_openid_vci_programs") + return self.set_from_static_file_Registry(**kwargs) diff --git a/g2p_openid_vci_programs/pyproject.toml b/g2p_openid_vci_programs/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_openid_vci_programs/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_openid_vci_programs/static/description/icon.png b/g2p_openid_vci_programs/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_openid_vci_programs/static/description/icon.png differ diff --git a/g2p_openid_vci_programs/tests/__init__.py b/g2p_openid_vci_programs/tests/__init__.py new file mode 100644 index 00000000..7f374644 --- /dev/null +++ b/g2p_openid_vci_programs/tests/__init__.py @@ -0,0 +1 @@ +from . import test_vci_programs diff --git a/g2p_openid_vci_programs/tests/test_vci_programs.py b/g2p_openid_vci_programs/tests/test_vci_programs.py new file mode 100644 index 00000000..ff57fc9d --- /dev/null +++ b/g2p_openid_vci_programs/tests/test_vci_programs.py @@ -0,0 +1,155 @@ +import base64 +import os +from datetime import datetime +from unittest.mock import MagicMock, patch + +import requests +from jose import jws, jwt +from jwcrypto import jwk + +from odoo.tests import tagged +from odoo.tests.common import TransactionCase, _super_send +from odoo.tools import misc + + +@tagged("-at_install", "post_install") +class TestVCIIssuerProgram(TransactionCase): + def setUp(self): + super().setUp() + self.env["ir.config_parameter"].set_param("web.base.url", "http://openg2p.local") + self.id_type = self.env["g2p.id.type"].create( + { + "name": "NATIONAL ID", + } + ) + self.program = self.env["g2p.program"].create({"name": "Test Program"}) + self.issuer_scope = "openg2p_program_vc_ldp" + self.issuer = self.env["g2p.openid.vci.issuers"].create( + { + "name": "Test Issuer", + "issuer_type": "Beneficiary", + "scope": self.issuer_scope, + "program_id": self.program.id, + "auth_sub_id_type_id": self.id_type.id, + "auth_allowed_issuers": "http://openg2p.local/auth", + } + ) + self.jsonld_contexts = self.env["g2p.openid.vci.issuers"].get_all_contexts_json() + + self.registrant_national_id = "123456789" + self.registrant_face_bytes = base64.b64encode( + misc.file_open(os.path.join("base", "static", "img", "avatar.png"), mode="rb").read() + ) + self.registrant = self.env["res.partner"].create( + { + "name": "Givenname Familyname", + "image_1920": self.registrant_face_bytes, + "reg_ids": [(0, 0, {"id_type": self.id_type.id, "value": self.registrant_national_id})], + "program_membership_ids": [ + ( + 0, + 0, + { + "program_id": self.program.id, + "state": "enrolled", + }, + ) + ], + } + ) + + self.jwk = jwk.JWK.generate(kty="RSA", size=2048, alg="RS256", use="sig", kid="12345") + self.public_jwks = {"keys": [self.jwk.export(private_key=False, as_dict=True)]} + + self.default_auth_jwt = jwt.encode( + { + "scope": self.issuer_scope, + "iss": "http://openg2p.local/auth", + "aud": "http://openg2p.local/api/v1/vci/credential", + "sub": self.registrant_national_id, + "exp": int(datetime.utcnow().timestamp()) + 5 * 60, + }, + self.jwk, + algorithm="RS256", + ) + + # TODO: This is only required because of external context url resolution + @classmethod + def _request_handler(cls, s: requests.Session, r: requests.PreparedRequest, /, **kw): + return _super_send(s, r, **kw) + + def mock_request_get(self, url, **kwargs): + if url == "http://openg2p.local/auth/.well-known/jwks.json": + res = MagicMock() + res.json.return_value = self.public_jwks + res.headers = {} + return res + elif url == "http://openg2p.local/api/v1/vci/.well-known/contexts.json": + res = MagicMock() + res.json.return_value = self.jsonld_contexts + res.headers = {} + return res + return requests.request("get", url, timeout=10, **kwargs) + + def mock_jwt_sign(self, data, **kwargs): + return jws.sign(data, self.jwk, algorithm="RS256") + + @patch("requests.get") + @patch("odoo.addons.g2p_encryption.models.encryption_provider.G2PEncryptionProvider.jwt_sign") + def test_issue_vc_normal(self, mock_jwt_sign, mock_request): + mock_request.side_effect = self.mock_request_get + mock_jwt_sign.side_effect = self.mock_jwt_sign + res = self.env["g2p.openid.vci.issuers"].issue_vc( + {"format": "ldp_vc", "credential_definition": {"type": []}}, self.default_auth_jwt + ) + cred = res["credential"] + cred_subject = cred["credentialSubject"] + + self.assertTrue("OpenG2PBeneficiaryVerifiableCredential" in cred["type"]) + self.assertTrue("Givenname Familyname" in [name["value"] for name in cred_subject["name"]]) + self.assertTrue(not cred_subject["email"]) + self.assertTrue(not cred_subject["phone"]) + self.assertTrue(not cred_subject["addressLine1"]) + self.assertTrue(not cred_subject["postalCode"]) + self.assertEqual("54321987", cred_subject["UIN"]) + self.assertEqual(f"data:image/png;base64,{self.registrant_face_bytes.decode()}", cred_subject["face"]) + self.assertEqual("ldp_vc", res["format"]) + self.assertTrue("Test Program" in [program["value"] for program in cred_subject["programName"]]) + + @patch("requests.get") + def test_issue_vc_invalid_membership(self, mock_request): + mock_request.side_effect = self.mock_request_get + self.registrant.program_membership_ids[0].state = "draft" + with self.assertRaises(ValueError) as context: + self.env["g2p.openid.vci.issuers"].issue_vc( + {"format": "ldp_vc", "credential_definition": {"type": []}}, + self.default_auth_jwt, + ) + self.assertTrue("Person not enrolled into program." in str(context.exception)) + + @patch("requests.get") + def test_issue_vc_invalid_id(self, mock_request): + mock_request.side_effect = self.mock_request_get + with self.assertRaises(ValueError) as context: + self.env["g2p.openid.vci.issuers"].issue_vc( + {"format": "ldp_vc", "credential_definition": {"type": []}}, + jwt.encode( + { + "scope": self.issuer_scope, + "iss": "http://openg2p.local/auth", + "aud": "http://openg2p.local/api/v1/vci/credential", + "sub": "random-value", + "exp": int(datetime.utcnow().timestamp()) + 5 * 60, + }, + self.jwk, + algorithm="RS256", + ), + ) + self.assertTrue( + ( + "ID not found in DB. " + "Invalid Subject Received in auth claims. " + "Or person not part of the program." + ) + in str(context.exception) + ) diff --git a/g2p_openid_vci_programs/views/vci_issuers.xml b/g2p_openid_vci_programs/views/vci_issuers.xml new file mode 100644 index 00000000..98131918 --- /dev/null +++ b/g2p_openid_vci_programs/views/vci_issuers.xml @@ -0,0 +1,21 @@ + + + + + view_g2p_openid_vci_issuers_program_form + g2p.openid.vci.issuers + + 2 + + + + + + + diff --git a/g2p_payment_cash/README.md b/g2p_payment_cash/README.md new file mode 100644 index 00000000..b3ed3fd0 --- /dev/null +++ b/g2p_payment_cash/README.md @@ -0,0 +1,5 @@ +# OpenG2P Program Payment: Cash + +Only use this when physical cash is handed out to beneficiaries. + +Refer to https://docs.openg2p.org. diff --git a/g2p_payment_cash/README.rst b/g2p_payment_cash/README.rst deleted file mode 100644 index d08b43c3..00000000 --- a/g2p_payment_cash/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -============================= -OpenG2P Program Payment: Cash -============================= - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:33594bfb52715fec03487788ad4b3501e474a57eae23cde9194613be09d224c1 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_payment_cash - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Payment Payment in Cash. Only use this when physical cash is handed out to beneficiaries. - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_payment_cash/__manifest__.py b/g2p_payment_cash/__manifest__.py index 31054194..69026c6a 100644 --- a/g2p_payment_cash/__manifest__.py +++ b/g2p_payment_cash/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Program Payment: Cash", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "g2p_programs", "g2p_payment_files", diff --git a/g2p_payment_cash/readme/DESCRIPTION.rst b/g2p_payment_cash/readme/DESCRIPTION.rst deleted file mode 100644 index 2967c317..00000000 --- a/g2p_payment_cash/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Payment Payment in Cash. Only use this when physical cash is handed out to beneficiaries. diff --git a/g2p_payment_cash/static/description/index.html b/g2p_payment_cash/static/description/index.html deleted file mode 100644 index 1c0321c2..00000000 --- a/g2p_payment_cash/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Program Payment: Cash - - - -
-

OpenG2P Program Payment: Cash

- - -

Alpha OpenG2P/openg2p-program

-

G2P Payment Payment in Cash. Only use this when physical cash is handed out to beneficiaries.

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_payment_files/README.md b/g2p_payment_files/README.md new file mode 100644 index 00000000..f70c4837 --- /dev/null +++ b/g2p_payment_files/README.md @@ -0,0 +1,5 @@ +# OpenG2P Program Payments: In Files + +G2P Program Payment File Based + +Refer to https://docs.openg2p.org. diff --git a/g2p_payment_files/README.rst b/g2p_payment_files/README.rst deleted file mode 100644 index 374e8bf6..00000000 --- a/g2p_payment_files/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -================================== -OpenG2P Program Payments: In Files -================================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:387e034f2a18786a2afd14d330385ed42de5e469daf7e6b0f1de9acea9c0f67f - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_payment_files - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Program Payment File Based - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_payment_files/__manifest__.py b/g2p_payment_files/__manifest__.py index 4e0da0a2..862c7ae0 100644 --- a/g2p_payment_files/__manifest__.py +++ b/g2p_payment_files/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Program Payments: In Files", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "g2p_programs", "g2p_program_documents", diff --git a/g2p_payment_files/readme/DESCRIPTION.rst b/g2p_payment_files/readme/DESCRIPTION.rst deleted file mode 100644 index 0f14dc9c..00000000 --- a/g2p_payment_files/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Program Payment File Based diff --git a/g2p_payment_files/static/description/index.html b/g2p_payment_files/static/description/index.html deleted file mode 100644 index 778bb12f..00000000 --- a/g2p_payment_files/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Program Payments: In Files - - - -
-

OpenG2P Program Payments: In Files

- - -

Alpha OpenG2P/openg2p-program

-

G2P Program Payment File Based

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_payment_g2p_connect/README.md b/g2p_payment_g2p_connect/README.md new file mode 100644 index 00000000..f764e220 --- /dev/null +++ b/g2p_payment_g2p_connect/README.md @@ -0,0 +1,3 @@ +# OpenG2P Program Payment: G2P Connect Payment Manager + +Refer to https://docs.openg2p.org. diff --git a/g2p_payment_g2p_connect/README.rst b/g2p_payment_g2p_connect/README.rst deleted file mode 100644 index 7883327b..00000000 --- a/g2p_payment_g2p_connect/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -==================================================== -OpenG2P Program Payment: G2P Connect Payment Manager -==================================================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:a3b7235594fd9b2f7c893d7ef0635b1f16eceaf00ece6621405d1328860c201b - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_payment_g2p_connect - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Connect Payment Manager - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_payment_g2p_connect/__manifest__.py b/g2p_payment_g2p_connect/__manifest__.py index 63719c2e..23332b50 100644 --- a/g2p_payment_g2p_connect/__manifest__.py +++ b/g2p_payment_g2p_connect/__manifest__.py @@ -1,12 +1,11 @@ { "name": "OpenG2P Program Payment: G2P Connect Payment Manager", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "base", "g2p_registry_membership", diff --git a/g2p_payment_g2p_connect/readme/DESCRIPTION.rst b/g2p_payment_g2p_connect/readme/DESCRIPTION.rst deleted file mode 100644 index 981b7516..00000000 --- a/g2p_payment_g2p_connect/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Connect Payment Manager diff --git a/g2p_payment_g2p_connect/static/description/index.html b/g2p_payment_g2p_connect/static/description/index.html deleted file mode 100644 index 10fb22ce..00000000 --- a/g2p_payment_g2p_connect/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Program Payment: G2P Connect Payment Manager - - - -
-

OpenG2P Program Payment: G2P Connect Payment Manager

- - -

Alpha OpenG2P/openg2p-program

-

G2P Connect Payment Manager

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_payment_interop_layer/README.md b/g2p_payment_interop_layer/README.md new file mode 100644 index 00000000..84721508 --- /dev/null +++ b/g2p_payment_interop_layer/README.md @@ -0,0 +1,5 @@ +# OpenG2P Program Payment (Payment Interoperability Layer) + +G2P Payment Payment Interoperability Layer Payment Manager + +Refer to https://docs.openg2p.org. diff --git a/g2p_payment_interop_layer/README.rst b/g2p_payment_interop_layer/README.rst deleted file mode 100644 index 2bc0847f..00000000 --- a/g2p_payment_interop_layer/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -======================================================== -OpenG2P Program Payment (Payment Interoperability Layer) -======================================================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:0c0ab5d8146cb7feb0363c6d8b7fb06b1d1abbb302e46376983880a1eba4afaf - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_payment_interop_layer - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Payment Payment Interoperability Layer Payment Manager - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_payment_interop_layer/__manifest__.py b/g2p_payment_interop_layer/__manifest__.py index b1502876..5faae601 100644 --- a/g2p_payment_interop_layer/__manifest__.py +++ b/g2p_payment_interop_layer/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Program Payment (Payment Interoperability Layer)", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "base", "g2p_registry_base", diff --git a/g2p_payment_interop_layer/readme/DESCRIPTION.rst b/g2p_payment_interop_layer/readme/DESCRIPTION.rst deleted file mode 100644 index a3ab0bbb..00000000 --- a/g2p_payment_interop_layer/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Payment Payment Interoperability Layer Payment Manager diff --git a/g2p_payment_interop_layer/static/description/index.html b/g2p_payment_interop_layer/static/description/index.html deleted file mode 100644 index 65d01a42..00000000 --- a/g2p_payment_interop_layer/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Program Payment (Payment Interoperability Layer) - - - -
-

OpenG2P Program Payment (Payment Interoperability Layer)

- - -

Alpha OpenG2P/openg2p-program

-

G2P Payment Payment Interoperability Layer Payment Manager

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_payment_phee/README.md b/g2p_payment_phee/README.md new file mode 100644 index 00000000..dcc9eca9 --- /dev/null +++ b/g2p_payment_phee/README.md @@ -0,0 +1,3 @@ +# OpenG2P Program Payment (Payment Hub EE) + +Refer to https://docs.openg2p.org. diff --git a/g2p_payment_phee/README.rst b/g2p_payment_phee/README.rst deleted file mode 100644 index 3fa91723..00000000 --- a/g2p_payment_phee/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -======================================== -OpenG2P Program Payment (Payment Hub EE) -======================================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:deb8bae943255e23e925561bbe162891e7bf6c82621ed24433721480e6e47f05 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_payment_phee - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Payment Hub EE Payment Manager - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_payment_phee/__manifest__.py b/g2p_payment_phee/__manifest__.py index 937d44cc..c84925cc 100644 --- a/g2p_payment_phee/__manifest__.py +++ b/g2p_payment_phee/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Program Payment (Payment Hub EE)", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "base", "g2p_registry_base", diff --git a/g2p_payment_phee/readme/DESCRIPTION.rst b/g2p_payment_phee/readme/DESCRIPTION.rst deleted file mode 100644 index 5df7f7b9..00000000 --- a/g2p_payment_phee/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Payment Hub EE Payment Manager diff --git a/g2p_payment_phee/static/description/index.html b/g2p_payment_phee/static/description/index.html deleted file mode 100644 index a9998382..00000000 --- a/g2p_payment_phee/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Program Payment (Payment Hub EE) - - - -
-

OpenG2P Program Payment (Payment Hub EE)

- - -

Alpha OpenG2P/openg2p-program

-

G2P Payment Hub EE Payment Manager

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_payment_simple_mpesa/__manifest__.py b/g2p_payment_simple_mpesa/__manifest__.py index 23f5801a..fd29a559 100644 --- a/g2p_payment_simple_mpesa/__manifest__.py +++ b/g2p_payment_simple_mpesa/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Program Payment: Simple Mpesa Payment Manager", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "base", "g2p_registry_base", diff --git a/g2p_payment_simple_mpesa/static/description/index.html b/g2p_payment_simple_mpesa/static/description/index.html deleted file mode 100644 index 8f5108d7..00000000 --- a/g2p_payment_simple_mpesa/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Program Payment: Simple Mpesa Payment Manager - - - -
-

OpenG2P Program Payment: Simple Mpesa Payment Manager

- - -

Alpha OpenG2P/openg2p-program

-

G2P Simple Mpesa Payment Manager

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_program_approval/__manifest__.py b/g2p_program_approval/__manifest__.py index 4173e3a3..8b8f61b6 100644 --- a/g2p_program_approval/__manifest__.py +++ b/g2p_program_approval/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Program: Approval", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "g2p_programs", ], diff --git a/g2p_program_approval/static/description/index.html b/g2p_program_approval/static/description/index.html deleted file mode 100644 index 4876814d..00000000 --- a/g2p_program_approval/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Program: Approval - - - -
-

OpenG2P Program: Approval

- - -

Alpha OpenG2P/openg2p-program

-

OpenG2P Program Approval

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_program_assessment/README.md b/g2p_program_assessment/README.md new file mode 100644 index 00000000..b1e6f860 --- /dev/null +++ b/g2p_program_assessment/README.md @@ -0,0 +1,3 @@ +# OpenG2P Program: Assessment + +Refer to https://docs.openg2p.org. diff --git a/g2p_program_assessment/README.rst b/g2p_program_assessment/README.rst deleted file mode 100644 index 8e3ede93..00000000 --- a/g2p_program_assessment/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -=========================== -OpenG2P Program: Assessment -=========================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:ecbf09d4f887bd9ea89a4832be56a42b907eadd106fbeab4a842b7eff9db6a11 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_program_assessment - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -OpenG2P Program Assessment - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_program_assessment/__manifest__.py b/g2p_program_assessment/__manifest__.py index 4f7b90d6..10230c65 100644 --- a/g2p_program_assessment/__manifest__.py +++ b/g2p_program_assessment/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Program: Assessment", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "g2p_programs", "mail", diff --git a/g2p_program_assessment/readme/DESCRIPTION.rst b/g2p_program_assessment/readme/DESCRIPTION.rst deleted file mode 100644 index 8ccce19d..00000000 --- a/g2p_program_assessment/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -OpenG2P Program Assessment diff --git a/g2p_program_assessment/static/description/index.html b/g2p_program_assessment/static/description/index.html deleted file mode 100644 index 0f34a9cd..00000000 --- a/g2p_program_assessment/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Program: Assessment - - - -
-

OpenG2P Program: Assessment

- - -

Alpha OpenG2P/openg2p-program

-

OpenG2P Program Assessment

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_program_autoenrol/README.md b/g2p_program_autoenrol/README.md new file mode 100644 index 00000000..d6068e41 --- /dev/null +++ b/g2p_program_autoenrol/README.md @@ -0,0 +1,3 @@ +# OpenG2P Programs: Autoenrol + +Refer to https://docs.openg2p.org. diff --git a/g2p_program_autoenrol/README.rst b/g2p_program_autoenrol/README.rst deleted file mode 100644 index f03e2747..00000000 --- a/g2p_program_autoenrol/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -=========================== -OpenG2P Programs: Autoenrol -=========================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:20d80e41298948313c93e1d824aa7f87228185c86cd5dfd3d9843470e0759d9c - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_program_autoenrol - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Programs Autoenrol - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_program_autoenrol/__manifest__.py b/g2p_program_autoenrol/__manifest__.py index f29e2fd3..2368073c 100644 --- a/g2p_program_autoenrol/__manifest__.py +++ b/g2p_program_autoenrol/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Programs: Autoenrol", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "g2p_programs", ], diff --git a/g2p_program_autoenrol/readme/DESCRIPTION.rst b/g2p_program_autoenrol/readme/DESCRIPTION.rst deleted file mode 100644 index 8a715b36..00000000 --- a/g2p_program_autoenrol/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Programs Autoenrol diff --git a/g2p_program_autoenrol/static/description/index.html b/g2p_program_autoenrol/static/description/index.html deleted file mode 100644 index 85040a57..00000000 --- a/g2p_program_autoenrol/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Programs: Autoenrol - - - -
-

OpenG2P Programs: Autoenrol

- - -

Alpha OpenG2P/openg2p-program

-

G2P Programs Autoenrol

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_program_cycleless/README.md b/g2p_program_cycleless/README.md new file mode 100644 index 00000000..2e560368 --- /dev/null +++ b/g2p_program_cycleless/README.md @@ -0,0 +1,5 @@ +# OpenG2P Programs: Cycleless + +Cycleless G2P Programs + +Refer to https://docs.openg2p.org. diff --git a/g2p_program_cycleless/README.rst b/g2p_program_cycleless/README.rst deleted file mode 100644 index 142791a8..00000000 --- a/g2p_program_cycleless/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -=========================== -OpenG2P Programs: Cycleless -=========================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:5552bc305135adc568ac7907525704c12a1eb8558997e2ac1281e6c41bc7bae0 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_program_cycleless - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -Cycleless G2P Programs - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_program_cycleless/__manifest__.py b/g2p_program_cycleless/__manifest__.py index 46a2644b..6afeb501 100644 --- a/g2p_program_cycleless/__manifest__.py +++ b/g2p_program_cycleless/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Programs: Cycleless", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": ["g2p_programs"], "data": [ "views/program_view.xml", diff --git a/g2p_program_cycleless/static/description/index.html b/g2p_program_cycleless/static/description/index.html deleted file mode 100644 index 6d4f8128..00000000 --- a/g2p_program_cycleless/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Programs: Cycleless - - - -
-

OpenG2P Programs: Cycleless

- - -

Alpha OpenG2P/openg2p-program

-

Cycleless G2P Programs

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_program_documents/README.md b/g2p_program_documents/README.md new file mode 100644 index 00000000..d54561d9 --- /dev/null +++ b/g2p_program_documents/README.md @@ -0,0 +1,3 @@ +# OpenG2P Program: Documents + +Refer to https://docs.openg2p.org. diff --git a/g2p_program_documents/README.rst b/g2p_program_documents/README.rst deleted file mode 100644 index 5c151728..00000000 --- a/g2p_program_documents/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -========================== -OpenG2P Program: Documents -========================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:5c1408408e39466e54dcd9f44b081b58dd84e0fed5212f6c12fc02dd3410d834 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_program_documents - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Program Documents - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_program_documents/__manifest__.py b/g2p_program_documents/__manifest__.py index 936c1b62..8965c971 100644 --- a/g2p_program_documents/__manifest__.py +++ b/g2p_program_documents/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Program: Documents", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "g2p_documents", "g2p_programs", diff --git a/g2p_program_documents/readme/DESCRIPTION.rst b/g2p_program_documents/readme/DESCRIPTION.rst deleted file mode 100644 index ff71b7ed..00000000 --- a/g2p_program_documents/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Program Documents diff --git a/g2p_program_documents/static/description/index.html b/g2p_program_documents/static/description/index.html deleted file mode 100644 index d9d0a1ca..00000000 --- a/g2p_program_documents/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Program: Documents - - - -
-

OpenG2P Program: Documents

- - -

Alpha OpenG2P/openg2p-program

-

G2P Program Documents

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_program_registrant_info/README.md b/g2p_program_registrant_info/README.md new file mode 100644 index 00000000..a06c400e --- /dev/null +++ b/g2p_program_registrant_info/README.md @@ -0,0 +1,6 @@ +# G2P Program: Registrant Info + +This module adds support to Registry modules (registry_base, registry_individual and registry_group) which +adds new model to store a json data for each program-registrant mapping, and displays it as form. + +Refer to https://docs.openg2p.org. diff --git a/g2p_program_registrant_info/README.rst b/g2p_program_registrant_info/README.rst deleted file mode 100644 index 3b6f14ca..00000000 --- a/g2p_program_registrant_info/README.rst +++ /dev/null @@ -1,58 +0,0 @@ -============================ -G2P Program: Registrant Info -============================ - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:45fd87ce62c7f53aed653694df3260eb34f8da6aa5cc891b356a94abc3c99a95 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_program_registrant_info - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -This module adds support to Registry modules (registry_base, registry_individual and registry_group) -which adds new model to store a json data for each program-registrant mapping, and displays it as form. - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_program_registrant_info/__manifest__.py b/g2p_program_registrant_info/__manifest__.py index 80b6711d..b9851fe8 100644 --- a/g2p_program_registrant_info/__manifest__.py +++ b/g2p_program_registrant_info/__manifest__.py @@ -1,12 +1,11 @@ { "name": "G2P Program: Registrant Info", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "g2p_registry_base", "g2p_registry_individual", diff --git a/g2p_program_registrant_info/readme/DESCRIPTION.rst b/g2p_program_registrant_info/readme/DESCRIPTION.rst deleted file mode 100644 index 4508c755..00000000 --- a/g2p_program_registrant_info/readme/DESCRIPTION.rst +++ /dev/null @@ -1,2 +0,0 @@ -This module adds support to Registry modules (registry_base, registry_individual and registry_group) -which adds new model to store a json data for each program-registrant mapping, and displays it as form. diff --git a/g2p_program_registrant_info/static/description/index.html b/g2p_program_registrant_info/static/description/index.html deleted file mode 100644 index 1a5021bd..00000000 --- a/g2p_program_registrant_info/static/description/index.html +++ /dev/null @@ -1,416 +0,0 @@ - - - - - -G2P Program: Registrant Info - - - -
-

G2P Program: Registrant Info

- - -

Alpha OpenG2P/openg2p-program

-

This module adds support to Registry modules (registry_base, registry_individual and registry_group) -which adds new model to store a json data for each program-registrant mapping, and displays it as form.

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_program_registrant_info_rest_api/README.md b/g2p_program_registrant_info_rest_api/README.md new file mode 100644 index 00000000..1ef69408 --- /dev/null +++ b/g2p_program_registrant_info_rest_api/README.md @@ -0,0 +1,5 @@ +# G2P Program : Program Registrant Info Rest API + +This module adds REST API support to "G2P Program Registrant Info" + +Refer to https://docs.openg2p.org. diff --git a/g2p_program_registrant_info_rest_api/README.rst b/g2p_program_registrant_info_rest_api/README.rst deleted file mode 100644 index 3a70607f..00000000 --- a/g2p_program_registrant_info_rest_api/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -============================================== -G2P Program : Program Registrant Info Rest API -============================================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:397186dd0258aee823becd6cf0361d4b83f5a5fb8238d52357ef5e3686cf3fa3 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_program_registrant_info_rest_api - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -This module adds REST API support to "G2P Program Registrant Info" - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_program_registrant_info_rest_api/__manifest__.py b/g2p_program_registrant_info_rest_api/__manifest__.py index 10efd9ac..1beb735a 100644 --- a/g2p_program_registrant_info_rest_api/__manifest__.py +++ b/g2p_program_registrant_info_rest_api/__manifest__.py @@ -1,13 +1,12 @@ { "name": "G2P Program : Program Registrant Info Rest API", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", - "depends": ["g2p_programs_rest_api", "g2p_program_registrant_info"], + "license": "LGPL-3", + "depends": ["g2p_programs_rest_api", "g2p_program_registrant_info"], "data": [], "assets": { "web.assets_backend": [], diff --git a/g2p_program_registrant_info_rest_api/readme/DESCRIPTION.rst b/g2p_program_registrant_info_rest_api/readme/DESCRIPTION.rst deleted file mode 100644 index 4efb8d60..00000000 --- a/g2p_program_registrant_info_rest_api/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -This module adds REST API support to "G2P Program Registrant Info" diff --git a/g2p_program_registrant_info_rest_api/static/description/index.html b/g2p_program_registrant_info_rest_api/static/description/index.html deleted file mode 100644 index f35f1862..00000000 --- a/g2p_program_registrant_info_rest_api/static/description/index.html +++ /dev/null @@ -1,414 +0,0 @@ - - - - - -G2P Program : Program Registrant Info Rest API - - - -
-

G2P Program : Program Registrant Info Rest API

- - -

Alpha OpenG2P/openg2p-program

-

This module adds REST API support to “G2P Program Registrant Info”

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_program_reimbursement/README.md b/g2p_program_reimbursement/README.md new file mode 100644 index 00000000..272e4482 --- /dev/null +++ b/g2p_program_reimbursement/README.md @@ -0,0 +1,3 @@ +# OpenG2P Programs: Reimbursement + +Refer to https://docs.openg2p.org. diff --git a/g2p_program_reimbursement/README.rst b/g2p_program_reimbursement/README.rst deleted file mode 100644 index dad4cfb8..00000000 --- a/g2p_program_reimbursement/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -=============================== -OpenG2P Programs: Reimbursement -=============================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:084b908f80db3746877d19109949ad9af9e04fdae6a80460e9d17462b302c79f - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_program_reimbursement - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Programs for Reimbursement - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_program_reimbursement/__manifest__.py b/g2p_program_reimbursement/__manifest__.py index ad12990e..c5231ee3 100644 --- a/g2p_program_reimbursement/__manifest__.py +++ b/g2p_program_reimbursement/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Programs: Reimbursement", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "g2p_programs", # TODO: The following need not be a dependency diff --git a/g2p_program_reimbursement/readme/DESCRIPTION.rst b/g2p_program_reimbursement/readme/DESCRIPTION.rst deleted file mode 100644 index 32961b23..00000000 --- a/g2p_program_reimbursement/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Programs for Reimbursement diff --git a/g2p_program_reimbursement/static/description/index.html b/g2p_program_reimbursement/static/description/index.html deleted file mode 100644 index b5a20514..00000000 --- a/g2p_program_reimbursement/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -OpenG2P Programs: Reimbursement - - - -
-

OpenG2P Programs: Reimbursement

- - -

Alpha OpenG2P/openg2p-program

-

G2P Programs for Reimbursement

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_programs/readme/DESCRIPTION.rst b/g2p_programs/README.md similarity index 54% rename from g2p_programs/readme/DESCRIPTION.rst rename to g2p_programs/README.md index ae8f1343..eebc7b2c 100644 --- a/g2p_programs/readme/DESCRIPTION.rst +++ b/g2p_programs/README.md @@ -1,9 +1,13 @@ +# OpenG2P Programs + This addon is the core to manage Social Protection programs. -This project is based around the concepts of programs and cycles as defined in the [World Bank Source Book](https://openknowledge.worldbank.org/bitstream/handle/10986/34044/9781464815775.pdf?sequence=9&isAllowed=y). +This project is based around the concepts of programs and cycles as defined in the +[World Bank Source Book](https://openknowledge.worldbank.org/bitstream/handle/10986/34044/9781464815775.pdf?sequence=9&isAllowed=y). + +Refer to https://docs.openg2p.org. -Features --------- +## Features - Program creation wizard - Individuals or groups can be enrolled in a program diff --git a/g2p_programs/README.rst b/g2p_programs/README.rst deleted file mode 100644 index 51b95c7d..00000000 --- a/g2p_programs/README.rst +++ /dev/null @@ -1,79 +0,0 @@ -================ -OpenG2P Programs -================ - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:3fefee23e52038384debfe9cd8a9819739399819ccdb5ec1804a63aa9e20fe9a - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_programs - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -This addon is the core to manage Social Protection programs. - -This project is based around the concepts of programs and cycles as defined in the [World Bank Source Book](https://openknowledge.worldbank.org/bitstream/handle/10986/34044/9781464815775.pdf?sequence=9&isAllowed=y). - -Features --------- - -- Program creation wizard -- Individuals or groups can be enrolled in a program -- Modular API -- Multiple programs -- Multiple cycles - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Contributors -~~~~~~~~~~~~ - -`OpenSPP `__ donated the original code to the project. - -Contributors include: - -* Edwin Gonzales (`Newlogic `__) -* Jeremi Joslin (`Newlogic `__) -* Michael Gonzales (`Newlogic `__) - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_programs/__manifest__.py b/g2p_programs/__manifest__.py index 9a5c33a9..88041480 100644 --- a/g2p_programs/__manifest__.py +++ b/g2p_programs/__manifest__.py @@ -2,12 +2,11 @@ { "name": "OpenG2P Programs", "category": "G2P/G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": [ "account", "web", diff --git a/g2p_programs/readme/CONTRIBUTORS.rst b/g2p_programs/readme/CONTRIBUTORS.rst deleted file mode 100644 index 34e34526..00000000 --- a/g2p_programs/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,7 +0,0 @@ -`OpenSPP `__ donated the original code to the project. - -Contributors include: - -* Edwin Gonzales (`Newlogic `__) -* Jeremi Joslin (`Newlogic `__) -* Michael Gonzales (`Newlogic `__) diff --git a/g2p_programs/static/description/index.html b/g2p_programs/static/description/index.html deleted file mode 100644 index a42fc09e..00000000 --- a/g2p_programs/static/description/index.html +++ /dev/null @@ -1,437 +0,0 @@ - - - - - -OpenG2P Programs - - - -
-

OpenG2P Programs

- - -

Alpha OpenG2P/openg2p-program

-

This addon is the core to manage Social Protection programs.

-

This project is based around the concepts of programs and cycles as defined in the [World Bank Source Book](https://openknowledge.worldbank.org/bitstream/handle/10986/34044/9781464815775.pdf?sequence=9&isAllowed=y).

-
-

Features

-
    -
  • Program creation wizard
  • -
  • Individuals or groups can be enrolled in a program
  • -
  • Modular API
  • -
  • Multiple programs
  • -
  • Multiple cycles
  • -
-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Contributors

-

OpenSPP donated the original code to the project.

-

Contributors include:

- -
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
-
- - diff --git a/g2p_programs_rest_api/README.md b/g2p_programs_rest_api/README.md new file mode 100644 index 00000000..47d732a3 --- /dev/null +++ b/g2p_programs_rest_api/README.md @@ -0,0 +1,5 @@ +# G2P Programs: REST API + +This module adds REST API support to OpenG2P Programs. + +Refer to https://docs.openg2p.org. diff --git a/g2p_programs_rest_api/README.rst b/g2p_programs_rest_api/README.rst deleted file mode 100644 index 47d76a4b..00000000 --- a/g2p_programs_rest_api/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -====================== -G2P Programs: REST API -====================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:4c77516f05528983cb3e9e7bd86030a2b53f1fc5a8d06f3fa3899806a2806d2d - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_programs_rest_api - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -This module adds REST API support to OpenG2P Programs. - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_programs_rest_api/__manifest__.py b/g2p_programs_rest_api/__manifest__.py index aeb8ecaa..97aab706 100644 --- a/g2p_programs_rest_api/__manifest__.py +++ b/g2p_programs_rest_api/__manifest__.py @@ -1,13 +1,12 @@ { "name": "G2P Programs: REST API", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", - "depends": ["g2p_registry_rest_api", "g2p_programs"], + "license": "LGPL-3", + "depends": ["g2p_registry_rest_api", "g2p_programs"], "data": [], "assets": { "web.assets_backend": [], diff --git a/g2p_programs_rest_api/readme/DESCRIPTION.rst b/g2p_programs_rest_api/readme/DESCRIPTION.rst deleted file mode 100644 index 8db0344a..00000000 --- a/g2p_programs_rest_api/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -This module adds REST API support to OpenG2P Programs. diff --git a/g2p_programs_rest_api/static/description/index.html b/g2p_programs_rest_api/static/description/index.html deleted file mode 100644 index 5ca74915..00000000 --- a/g2p_programs_rest_api/static/description/index.html +++ /dev/null @@ -1,414 +0,0 @@ - - - - - -G2P Programs: REST API - - - -
-

G2P Programs: REST API

- - -

Alpha OpenG2P/openg2p-program

-

This module adds REST API support to OpenG2P Programs.

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_proxy_means_test/README.md b/g2p_proxy_means_test/README.md new file mode 100644 index 00000000..9a38b4fb --- /dev/null +++ b/g2p_proxy_means_test/README.md @@ -0,0 +1,3 @@ +# G2P: Proxy Means Test + +Refer to https://docs.openg2p.org. diff --git a/g2p_proxy_means_test/README.rst b/g2p_proxy_means_test/README.rst deleted file mode 100644 index f5b1352e..00000000 --- a/g2p_proxy_means_test/README.rst +++ /dev/null @@ -1,57 +0,0 @@ -===================== -G2P: Proxy Means Test -===================== - -.. - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:44bd63f2297ec819ed9fb5a104f81c2211d131a63674de68f89d90c96c6008c3 - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png - :target: https://odoo-community.org/page/development-status - :alt: Alpha -.. |badge2| image:: https://img.shields.io/badge/github-OpenG2P%2Fopeng2p--program-lightgray.png?logo=github - :target: https://github.com/OpenG2P/openg2p-program/tree/17.0-develop/g2p_proxy_means_test - :alt: OpenG2P/openg2p-program - -|badge1| |badge2| - -G2P Proxy Means Test - -.. IMPORTANT:: - This is an alpha version, the data model and design can change at any time without warning. - Only for development or testing purpose, do not use in production. - `More details on development status `_ - -**Table of contents** - -.. contents:: - :local: - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* OpenG2P - -Maintainers -~~~~~~~~~~~ - -This module is part of the `OpenG2P/openg2p-program `_ project on GitHub. - -You are welcome to contribute. diff --git a/g2p_proxy_means_test/__manifest__.py b/g2p_proxy_means_test/__manifest__.py index 8ae2a79c..5af4b7c3 100644 --- a/g2p_proxy_means_test/__manifest__.py +++ b/g2p_proxy_means_test/__manifest__.py @@ -2,12 +2,11 @@ { "name": "G2P: Proxy Means Test", "category": "G2P", - "version": "17.0.1.0.0", + "version": "17.0.0.0.0", "sequence": 1, "author": "OpenG2P", "website": "https://openg2p.org", - "license": "Other OSI approved licence", - "development_status": "Alpha", + "license": "LGPL-3", "depends": ["g2p_programs", "g2p_program_registrant_info"], "data": [ "security/ir.model.access.csv", diff --git a/g2p_proxy_means_test/readme/DESCRIPTION.rst b/g2p_proxy_means_test/readme/DESCRIPTION.rst deleted file mode 100644 index fafc7067..00000000 --- a/g2p_proxy_means_test/readme/DESCRIPTION.rst +++ /dev/null @@ -1 +0,0 @@ -G2P Proxy Means Test diff --git a/g2p_proxy_means_test/static/description/index.html b/g2p_proxy_means_test/static/description/index.html deleted file mode 100644 index e2f34ae2..00000000 --- a/g2p_proxy_means_test/static/description/index.html +++ /dev/null @@ -1,415 +0,0 @@ - - - - - -G2P: Proxy Means Test - - - -
-

G2P: Proxy Means Test

- - -

Alpha OpenG2P/openg2p-program

-

G2P Proxy Means Test

-
-

Important

-

This is an alpha version, the data model and design can change at any time without warning. -Only for development or testing purpose, do not use in production. -More details on development status

-
-

Table of contents

- -
-

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.

-

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

-
-
-

Credits

-
-

Authors

-
    -
  • OpenG2P
  • -
-
-
-

Maintainers

-

This module is part of the OpenG2P/openg2p-program project on GitHub.

-

You are welcome to contribute.

-
-
-
- - diff --git a/g2p_social_registry_importer/README.md b/g2p_social_registry_importer/README.md new file mode 100644 index 00000000..2b8aad24 --- /dev/null +++ b/g2p_social_registry_importer/README.md @@ -0,0 +1,3 @@ +# OpenG2P Social Registry Importer + +Refer to https://docs.openg2p.org. diff --git a/g2p_social_registry_importer/__init__.py b/g2p_social_registry_importer/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/g2p_social_registry_importer/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/g2p_social_registry_importer/__manifest__.py b/g2p_social_registry_importer/__manifest__.py new file mode 100644 index 00000000..861a27ef --- /dev/null +++ b/g2p_social_registry_importer/__manifest__.py @@ -0,0 +1,27 @@ +# Part of openG2P. See LICENSE file for full copyright and licensing details. + +{ + "name": "OpenG2P Social Registry Importer", + "category": "G2P", + "summary": "Import records from Social Registry", + "version": "17.0.0.0.0", + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "LGPL-3", + "depends": [ + "g2p_programs", + "g2p_registry_membership", + "spp_registry_data_source", + ], + "data": [ + "data/ir_config_params.xml", + "data/social_registry_data_source.xml", + "data/search_criteria.xml", + "security/ir.model.access.csv", + "views/fetch_social_registry_beneficiary_views.xml", + ], + "external_dependencies": {"python": ["camel_converter"]}, + "application": True, + "auto_install": False, + "installable": True, +} diff --git a/g2p_social_registry_importer/data/ir_config_params.xml b/g2p_social_registry_importer/data/ir_config_params.xml new file mode 100644 index 00000000..30ef1531 --- /dev/null +++ b/g2p_social_registry_importer/data/ir_config_params.xml @@ -0,0 +1,23 @@ + + + + + + + diff --git a/g2p_social_registry_importer/data/search_criteria.xml b/g2p_social_registry_importer/data/search_criteria.xml new file mode 100644 index 00000000..d8729fce --- /dev/null +++ b/g2p_social_registry_importer/data/search_criteria.xml @@ -0,0 +1,63 @@ + + + + Fetch Social Registry Data + + False + group + + { + getRegistrants(limit:2){ + name, + isGroup, + givenName, + familyName, + groupMembershipIds{ + individual{ + name, + gender, + givenName, + familyName, + addlName, + email, + gender, + address, + registrationDate, + birthPlace, + birthdate, + createDate, + writeDate, + regIds{ + idTypeAsStr, + value, + expiryDate + }, + phoneNumberIds{ + phoneNo, + phoneSanitized, + dateCollected, + disabled + } + }, + kind{ + name + }, + createDate, + writeDate + }, + phoneNumberIds{ + phoneNo, + phoneSanitized, + dateCollected, + disabled + }, + regIds{ + idTypeAsStr, + value, + expiryDate + } + } + } + + + diff --git a/g2p_social_registry_importer/data/social_registry_data_source.xml b/g2p_social_registry_importer/data/social_registry_data_source.xml new file mode 100644 index 00000000..a366ed1b --- /dev/null +++ b/g2p_social_registry_importer/data/social_registry_data_source.xml @@ -0,0 +1,24 @@ + + + + Social Registry + http://social-registry-odoo.social-registry/api/v1/g2p-connect + bearer_authentication + + + + Authentication + http://keycloak.keycloak/realms/openg2p/protocol/openid-connect/token + + + + Registry Sync Search + /registry/sync/search + + diff --git a/g2p_social_registry_importer/i18n/g2p_social_registry_importer.pot b/g2p_social_registry_importer/i18n/g2p_social_registry_importer.pot new file mode 100644 index 00000000..6ba8c9d4 --- /dev/null +++ b/g2p_social_registry_importer/i18n/g2p_social_registry_importer.pot @@ -0,0 +1,228 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * g2p_social_registry_importer +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: g2p_social_registry_importer +#: model:ir.model,name:g2p_social_registry_importer.model_res_partner +msgid "Contact" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__create_uid +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__create_uid +msgid "Created by" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__create_date +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__create_date +msgid "Created on" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__is_created +msgid "Created?" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__data_source_id +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_program_membership__data_source_id +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_res_partner__data_source_id +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_res_users__data_source_id +msgid "Data Source" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__display_name +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__display_name +msgid "Display Name" +msgstr "" + +#. module: g2p_social_registry_importer +#: model_terms:ir.ui.view,arch_db:g2p_social_registry_importer.fetch_social_registry_beneficiary_form +msgid "Fetch" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__fetch_social_registry_id +msgid "Fetch Social Registry" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model,name:g2p_social_registry_importer.model_g2p_fetch_social_registry_beneficiary +msgid "Fetch Social Registry Beneficiary" +msgstr "" + +#. module: g2p_social_registry_importer +#. odoo-python +#: code:addons/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py:0 +#, python-format +msgid "Fetching from Social Registry Started Asynchronously." +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields.selection,name:g2p_social_registry_importer.selection__g2p_fetch_social_registry_beneficiary__target_registry__group +msgid "Group" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__id +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__id +msgid "ID" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.ui.menu,name:g2p_social_registry_importer.fetch_social_registry_submenu +msgid "Import From Registry" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__import_registrant_without_id +msgid "Import Registrant without ID" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__imported_registrant_ids +msgid "Imported Regsitrants" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_program_membership__ind_is_imported_from_social_registry +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_res_partner__ind_is_imported_from_social_registry +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_res_users__ind_is_imported_from_social_registry +msgid "Imported from Social Registry" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields.selection,name:g2p_social_registry_importer.selection__g2p_fetch_social_registry_beneficiary__target_registry__individual +msgid "Individual" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__is_group +msgid "Is Group" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__write_uid +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__write_date +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__write_date +msgid "Last Updated on" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__last_sync_date +msgid "Last synced on" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__name +msgid "Name" +msgstr "" + +#. module: g2p_social_registry_importer +#. odoo-python +#: code:addons/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py:0 +#, python-format +msgid "No imported beneficiary" +msgstr "" + +#. module: g2p_social_registry_importer +#. odoo-python +#: code:addons/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py:0 +#, python-format +msgid "No matching records found." +msgstr "" + +#. module: g2p_social_registry_importer +#. odoo-python +#: code:addons/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py:0 +#: code:addons/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py:0 +#, python-format +msgid "No path in data source named {path} is configured!" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.actions.act_window,name:g2p_social_registry_importer.fetch_social_registry_beneficiary_action_window +msgid "Previous Search Criterias" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__query +msgid "Query" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__registrant_id +msgid "Registrant" +msgstr "" + +#. module: g2p_social_registry_importer +#: model_terms:ir.ui.view,arch_db:g2p_social_registry_importer.fetch_social_registry_beneficiary_tree +msgid "Search Criteria" +msgstr "" + +#. module: g2p_social_registry_importer +#. odoo-python +#: code:addons/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py:0 +#, python-format +msgid "Social Registry" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_program_membership__social_registry_import_ids +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_res_partner__social_registry_import_ids +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_res_users__social_registry_import_ids +msgid "Social Registry Import" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model,name:g2p_social_registry_importer.model_g2p_social_registry_imported_registrants +msgid "Social Registry Imported Registrants" +msgstr "" + +#. module: g2p_social_registry_importer +#. odoo-python +#: code:addons/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py:0 +#, python-format +msgid "Successfully Imported Social Registry Beneficiaries" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__target_program +msgid "Target Program" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_fetch_social_registry_beneficiary__target_registry +msgid "Target Registry" +msgstr "" + +#. module: g2p_social_registry_importer +#: model:ir.model.fields,field_description:g2p_social_registry_importer.field_g2p_social_registry_imported_registrants__is_updated +msgid "Updated?" +msgstr "" + +#. module: g2p_social_registry_importer +#. odoo-python +#: code:addons/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py:0 +#: code:addons/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py:0 +#, python-format +msgid "{reason}: Unable to connect to API." +msgstr "" diff --git a/g2p_social_registry_importer/models/__init__.py b/g2p_social_registry_importer/models/__init__.py new file mode 100644 index 00000000..1f279e70 --- /dev/null +++ b/g2p_social_registry_importer/models/__init__.py @@ -0,0 +1,4 @@ +from . import constants +from . import fetch_social_registry_beneficiary +from . import imported_registrants +from . import res_partner diff --git a/g2p_social_registry_importer/models/constants.py b/g2p_social_registry_importer/models/constants.py new file mode 100644 index 00000000..21363b12 --- /dev/null +++ b/g2p_social_registry_importer/models/constants.py @@ -0,0 +1,7 @@ +GRAPHQL = "graphql" + +DATA_SOURCE_NAME = "Social Registry" +DATA_SOURCE_SEARCH_PATH_NAME = "Registry Sync Search" +DATA_SOURCE_AUTH_PATH_NAME = "Authentication" + +REQUEST_TIMEOUT = 10 diff --git a/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py b/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py new file mode 100644 index 00000000..1f928124 --- /dev/null +++ b/g2p_social_registry_importer/models/fetch_social_registry_beneficiary.py @@ -0,0 +1,560 @@ +import json +import logging +import uuid +from datetime import datetime, timezone + +import requests +from camel_converter import dict_to_snake + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + +from odoo.addons.queue_job.delay import group + +from ..models import constants + +_logger = logging.getLogger(__name__) + + +class G2PFetchSocialRegistryBeneficiary(models.Model): + _name = "g2p.fetch.social.registry.beneficiary" + _description = "Fetch Social Registry Beneficiary" + + data_source_id = fields.Many2one("spp.data.source", required=True) + + name = fields.Char(required=True) + + import_registrant_without_id = fields.Boolean("Import Registrant without ID", default=False) + + target_registry = fields.Selection( + [("group", "Group"), ("individual", "Individual")], + required=True, + ) + + target_program = fields.Many2one( + "g2p.program", + domain=("[('target_type', '=', target_registry)]"), + ) + + query = fields.Text( + required=True, + ) + + last_sync_date = fields.Datetime(string="Last synced on", required=False) + + imported_registrant_ids = fields.One2many( + "g2p.social.registry.imported.registrants", + "fetch_social_registry_id", + "Imported Regsitrants", + readonly=True, + ) + + @api.onchange("registry") + def onchange_target_registry(self): + for rec in self: + rec.target_program = None + + def get_data_source_paths(self): + self.ensure_one() + + paths = {} + + for path_id in self.data_source_id.data_source_path_ids: + paths[path_id.key] = path_id.value + + if constants.DATA_SOURCE_SEARCH_PATH_NAME not in paths: + raise ValidationError( + _("No path in data source named {path} is configured!").format( + path=constants.DATA_SOURCE_SEARCH_PATH_NAME + ) + ) + + if constants.DATA_SOURCE_AUTH_PATH_NAME not in paths: + raise ValidationError( + _("No path in data source named {path} is configured!").format( + path=constants.DATA_SOURCE_AUTH_PATH_NAME + ) + ) + + return paths + + def get_social_registry_search_url(self, paths): + url = self.data_source_id.url + search_path = paths.get(constants.DATA_SOURCE_SEARCH_PATH_NAME) + + return f"{url}{search_path}" + + def get_social_registry_auth_url(self, paths): + url = self.data_source_id.url + auth_path = paths.get(constants.DATA_SOURCE_AUTH_PATH_NAME) + + if auth_path.lstrip().startswith("/"): + return f"{url}{auth_path}" + + else: + return auth_path + + def get_auth_token(self, auth_url): + client_id = self.env["ir.config_parameter"].sudo().get_param("g2p_import_social_registry.client_id") + client_secret = ( + self.env["ir.config_parameter"].sudo().get_param("g2p_import_social_registry.client_password") + ) + grant_type = self.env["ir.config_parameter"].sudo().get_param("g2p_import_social_registry.grant_type") + + data = { + "grant_type": grant_type, + "client_id": client_id, + "client_secret": client_secret, + } + + response = requests.post( + auth_url, + data=data, + timeout=constants.REQUEST_TIMEOUT, + ) + + _logger.debug("Authentication API response: %s", response.text) + + if response.ok: + result = response.json() + return f'{result.get("token_type")} {result.get("access_token")}' + + else: + raise ValidationError(_("{reason}: Unable to connect to API.").format(reason=response.reason)) + + def get_header_for_body(self, social_registry_version, today_isoformat, message_id): + sender_id = self.env["ir.config_parameter"].sudo().get_param("web.base.url") or "" + receiver_id = "Social Registry" + return { + "version": "1.0.0", + "message_id": message_id, + "message_ts": today_isoformat, + "action": "search", + "sender_id": sender_id, + "sender_uri": "", + "receiver_id": receiver_id, + "total_count": 0, + } + + def get_graphql_query(self): + query = self.query.strip() + + graphql_query = query[0:-1] + "totalRegistrantCount }" + _logger.debug(query) + + if self.target_registry: + index = graphql_query.find("(") + 1 + is_group = str(self.target_registry == "group").lower() + if not index: + get_registrants_index = graphql_query.find("getRegistrants") + 14 + graphql_query = ( + graphql_query[:get_registrants_index] + "()" + graphql_query[get_registrants_index:] + ) + index = graphql_query.find("(") + 1 + + graphql_query = graphql_query[:index] + f"isGroup: {is_group}" + graphql_query[index:] + + else: + graphql_query = graphql_query[:index] + f"isGroup: {is_group}," + graphql_query[index:] + + if self.last_sync_date: + index = graphql_query.find("(") + 1 + if not index: + get_registrants_index = graphql_query.find("getRegistrants") + 14 + graphql_query = ( + graphql_query[:get_registrants_index] + "()" + graphql_query[get_registrants_index:] + ) + index = graphql_query.find("(") + 1 + graphql_query = ( + graphql_query[:index] + + f'lastSyncDate: "{self.last_sync_date.strftime("%Y-%m-%dT%H:%M:%S.000Z")}"' + + graphql_query[index:] + ) + + else: + graphql_query = ( + graphql_query[:index] + + f'lastSyncDate: "{self.last_sync_date.strftime("%Y-%m-%dT%H:%M:%S.000Z")}",' + + graphql_query[index:] + ) + + _logger.debug("updated graphql query", graphql_query) + return graphql_query.strip() + + def get_search_request(self, reference_id, today_isoformat): + search_requests = { + "reference_id": reference_id, + "timestamp": today_isoformat, + "search_criteria": { + "reg_type": "G2P:RegistryType:Individual", + "query_type": "graphql", + "query": self.get_graphql_query(), + }, + } + + return search_requests + + def get_message(self, today_isoformat, transaction_id, reference_id): + # Define Search Requests + search_request = self.get_search_request(reference_id, today_isoformat) + + return { + "transaction_id": transaction_id, + "search_request": [search_request], + } + + def get_data(self, signature, header, message): + return { + "sinature": signature, + "header": header, + "message": message, + } + + def get_partner_and_clean_identifier(self, identifiers): + clean_identifiers = [] + partner_id = None + + # get existing record if there's any + for identifier in identifiers: + identifier_type = identifier.get("idTypeAsStr", "") + identifier_value = identifier.get("value", "") + if identifier_type and identifier_value: + # Check if identifier type is already created. Create record if no existing identifier type + id_type = self.env["g2p.id.type"].search([("name", "=", identifier_type)], limit=1) + if not id_type: + id_type = self.env["g2p.id.type"].create({"name": identifier_type}) + + clean_identifiers.append({"id_type": id_type, "value": identifier_value}) + + if not partner_id: + reg_id = self.env["g2p.reg.id"].search( + [ + ("id_type", "=", id_type.id), + ("value", "=", identifier_value), + ], + limit=1, + ) + if reg_id: + partner_id = reg_id.partner_id + + return partner_id, clean_identifiers + + def get_individual_data(self, record): + vals = dict_to_snake(record) + return vals + + def get_member_kind(self, data): + # TODO: Kind will be in List + kind_str = data.get("kind").get("name") if data.get("kind") else None + + kind = self.env["g2p.group.membership.kind"].search([("name", "=", kind_str)], limit=1) + + if not kind: + return None + + return kind + + def get_member_relationship(self, individual, data): + # TODO: Add relationship logic + res = None + return res + + def update_reg_id(self, partner_data): + if "reg_ids" in partner_data: + partner_data["reg_ids"] = [ + ( + 0, + 0, + { + "id_type": self.env["g2p.id.type"] + .sudo() + .search([("name", "=", reg_id.get("id_type").get("name"))], limit=1) + .id, + "value": reg_id.get("value"), + "expiry_date": reg_id.get("expiry_date"), + "status": reg_id.get("status"), + "description": reg_id.get("description"), + }, + ) + for reg_id in partner_data["reg_ids"] + ] + + return partner_data + + def create_or_update_registrant(self, partner_id, partner_data): + partner_data.update({"is_registrant": True}) + + # TODO: Check whether phone number already exist + if "phone_number_ids" in partner_data: + partner_data["phone_number_ids"] = [ + ( + 0, + 0, + { + "phone_no": phone.get("phone_no", None), + "date_collected": phone.get("date_collected", None), + "disabled": phone.get("disabled", None), + }, + ) + for phone in partner_data["phone_number_ids"] + ] + + if "reg_ids" in partner_data: + partner_data["reg_ids"] = [] + + if "group_membership_ids" in partner_data and self.target_registry == "group": + individual_ids = [] + relationships_ids = [] + for individual_mem in partner_data.get("group_membership_ids"): + individual_data = individual_mem.get("individual") + # TODO: Handle the phone number logic for group members + individual_data.update({"is_registrant": True, "phone_number_ids": []}) + + update_individual_data = self.update_reg_id(individual_data) + + individual = self.env["res.partner"].sudo().create(update_individual_data) + if individual: + kind = self.get_member_kind(individual_mem) + individual_data = {"individual": individual.id} + if kind: + individual_data["kind"] = [(4, kind.id)] + + relationship = self.get_member_relationship(individual.id, individual_mem) + + if relationship: + relationships_ids.append((0, 0, relationship)) + + individual_ids.append((0, 0, individual_data)) + + partner_data["related_1_ids"] = relationships_ids + partner_data["group_membership_ids"] = individual_ids + + if partner_id: + partner_id.write(partner_data) + else: + partner_id = self.env["res.partner"].create(partner_data) + + return partner_id + + def create_registrant_id(self, clean_identifiers, partner_id): + for clean_identifier in clean_identifiers: + partner_reg_id = self.env["g2p.reg.id"].search( + [ + ("id_type", "=", clean_identifier["id_type"].id), + ("partner_id", "=", partner_id.id), + ] + ) + if not partner_reg_id: + reg_data = { + "id_type": clean_identifier["id_type"].id, + "partner_id": partner_id.id, + "value": clean_identifier["value"], + } + self.env["g2p.reg.id"].create(reg_data) + return + + def assign_registrant_to_program(self, partner_id): + program_membership = self.env["g2p.program_membership"] + + if self.target_program and not program_membership.search( + [("partner_id", "=", partner_id.id), ("program_id", "=", self.target_program.id)], + limit=1, + ): + program_membership.create({"partner_id": partner_id.id, "program_id": self.target_program.id}) + + return + + def process_record(self, record): + identifiers = record.get("regIds", []) + ( + partner_id, + clean_identifiers, + ) = self.get_partner_and_clean_identifier(identifiers) + + if partner_id: + is_created = False + else: + is_created = True + + # Instantiate individual data + partner_data = self.get_individual_data(record) + + partner_data.update({"data_source_id": self.data_source_id.id}) + + # Create or Update registrant + partner_id = self.create_or_update_registrant(partner_id, partner_data) + + # Check and Create Registrant ID + self.create_registrant_id(clean_identifiers, partner_id) + + # Assign registrant into program + self.assign_registrant_to_program(partner_id) + + # Create Social Registry Imported Individuals + social_registry_imported_individuals = self.env["g2p.social.registry.imported.registrants"] + if not social_registry_imported_individuals.search( + [ + ("fetch_social_registry_id", "=", self.id), + ("registrant_id", "=", partner_id.id), + ], + limit=1, + ): + social_registry_imported_individuals.create( + { + "fetch_social_registry_id": self.id, + "registrant_id": partner_id.id, + "is_group": partner_id.is_group, + "is_created": is_created, + "is_updated": not is_created, + } + ) + + else: + imported_registrant = social_registry_imported_individuals.search( + [ + ("fetch_social_registry_id", "=", self.id), + ("registrant_id", "=", partner_id.id), + ], + limit=1, + ) + + imported_registrant.update({"is_updated": True}) + + return partner_id + + def process_registrants(self, registrants): + for record in registrants: + identifiers = record.get("regIds", []) + + if self.import_registrant_without_id or identifiers: + self.process_record(record) + + def process_registrants_async(self, registrants, count): + max_registrant = int( + self.env["ir.config_parameter"] + .sudo() + .get_param("g2p_import_social_registry.max_registrants_count_job_queue") + ) + _logger.warning("Fetching Registrant Asynchronously!") + jobs = [] + for i in range(0, count, max_registrant): + jobs.append(self.delayable().process_registrants(registrants[i : i + max_registrant])) + main_job = group(*jobs) + main_job.delay() + + def fetch_social_registry_beneficiary(self): + config_parameters = self.env["ir.config_parameter"].sudo() + today_isoformat = datetime.now(timezone.utc).isoformat() + social_registry_version = config_parameters.get_param("social_registry_version") + max_registrant = int( + config_parameters.get_param("g2p_import_social_registry.max_registrants_count_job_queue") + ) + + message_id = str(uuid.uuid4()) + transaction_id = str(uuid.uuid4()) + reference_id = str(uuid.uuid4()) + + # Define Data Source + paths = self.get_data_source_paths() + + # Define Social Registry auth url + + full_social_registry_auth_url = self.get_social_registry_auth_url(paths) + + # Retrieve auth token + + auth_token = self.get_auth_token(full_social_registry_auth_url) + + # Define Social Registry search url + full_social_registry_search_url = self.get_social_registry_search_url(paths) + + # Define header + header = self.get_header_for_body( + social_registry_version, + today_isoformat, + message_id, + ) + + # Define message + message = self.get_message( + today_isoformat, + transaction_id=transaction_id, + reference_id=reference_id, + ) + + signature = "" + + # Define data + data = self.get_data( + signature, + header, + message, + ) + + data = json.dumps(data) + + # POST Request + response = requests.post( + full_social_registry_search_url, + data=data, + headers={"Authorization": auth_token}, + timeout=constants.REQUEST_TIMEOUT, + ) + + if not response.ok: + _logger.error("Social Registry Search API response: %s", response.text) + response.raise_for_status() + + sticky = False + + # Process response + if response.ok: + kind = "success" + message = _("Successfully Imported Social Registry Beneficiaries") + + search_responses = response.json().get("message", {}).get("search_response", []) + if not search_responses: + kind = "warning" + message = _("No imported beneficiary") + + for search_response in search_responses: + reg_record = search_response.get("data", {}).get("reg_records", []) + registrants = reg_record.get("getRegistrants", []) + total_partners_count = reg_record.get("totalRegistrantCount", "") + + if total_partners_count: + if total_partners_count < max_registrant: + self.process_registrants(registrants) + + else: + self.process_registrants_async(registrants, total_partners_count) + kind = "success" + message = _("Fetching from Social Registry Started Asynchronously.") + sticky = True + + else: + kind = "success" + message = _("No matching records found.") + + self.last_sync_date = fields.Datetime.now() + + else: + kind = "danger" + message = response.json().get("error", {}).get("message", "") + if not message: + message = _("{reason}: Unable to connect to API.").format(reason=response.reason) + + action = { + "type": "ir.actions.client", + "tag": "display_notification", + "params": { + "title": _("Social Registry"), + "message": message, + "sticky": sticky, + "type": kind, + "next": { + "type": "ir.actions.act_window_close", + }, + }, + } + return action diff --git a/g2p_social_registry_importer/models/imported_registrants.py b/g2p_social_registry_importer/models/imported_registrants.py new file mode 100644 index 00000000..c93127e6 --- /dev/null +++ b/g2p_social_registry_importer/models/imported_registrants.py @@ -0,0 +1,28 @@ +import logging + +from odoo import fields, models + +_logger = logging.getLogger(__name__) + + +class G2PSocialRegistryImportedRegistrants(models.Model): + _name = "g2p.social.registry.imported.registrants" + _description = "Social Registry Imported Registrants" + + fetch_social_registry_id = fields.Many2one( + "g2p.fetch.social.registry.beneficiary", + required=True, + auto_join=True, + ) + + registrant_id = fields.Many2one( + "res.partner", + required=True, + domain=[("is_group", "=", False), ("is_registrant", "=", True)], + auto_join=True, + ) + + is_group = fields.Boolean() + + is_created = fields.Boolean("Created?") + is_updated = fields.Boolean("Updated?") diff --git a/g2p_social_registry_importer/models/res_partner.py b/g2p_social_registry_importer/models/res_partner.py new file mode 100644 index 00000000..dc0bf30f --- /dev/null +++ b/g2p_social_registry_importer/models/res_partner.py @@ -0,0 +1,29 @@ +from odoo import api, fields, models + + +class OpenG2PRegistry(models.Model): + _inherit = "res.partner" + + data_source_id = fields.Many2one( + "spp.data.source", + readonly=True, + ) + + ind_is_imported_from_social_registry = fields.Boolean( + "Imported from Social Registry", + compute="_compute_ind_is_imported_from_social_registry", + ) + + social_registry_import_ids = fields.One2many( + "g2p.social.registry.imported.registrants", + "registrant_id", + "Social Registry Import", + ) + + @api.depends("social_registry_import_ids") + def _compute_ind_is_imported_from_social_registry(self): + for rec in self: + if rec.social_registry_import_ids: + rec.ind_is_imported_from_social_registry = True + else: + rec.ind_is_imported_from_social_registry = False diff --git a/g2p_social_registry_importer/pyproject.toml b/g2p_social_registry_importer/pyproject.toml new file mode 100644 index 00000000..4231d0cc --- /dev/null +++ b/g2p_social_registry_importer/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/g2p_social_registry_importer/security/ir.model.access.csv b/g2p_social_registry_importer/security/ir.model.access.csv new file mode 100644 index 00000000..fb34ee9b --- /dev/null +++ b/g2p_social_registry_importer/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_social_registry_beneficiary,G2P Fetch Social Registry Beneficiary Access,model_g2p_fetch_social_registry_beneficiary,,1,1,1,1 +access_social_registry_imported_individuals,G2P Social Registry Imported Beneficiary Access,model_g2p_social_registry_imported_registrants,,1,1,1,1 diff --git a/g2p_social_registry_importer/static/description/icon.png b/g2p_social_registry_importer/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_social_registry_importer/static/description/icon.png differ diff --git a/g2p_social_registry_importer/views/fetch_social_registry_beneficiary_views.xml b/g2p_social_registry_importer/views/fetch_social_registry_beneficiary_views.xml new file mode 100644 index 00000000..faa9a4fb --- /dev/null +++ b/g2p_social_registry_importer/views/fetch_social_registry_beneficiary_views.xml @@ -0,0 +1,64 @@ + + + + + fetch_social_registry_beneficiary_tree + g2p.fetch.social.registry.beneficiary + + + + + + + + + + fetch_social_registry_beneficiary_form + g2p.fetch.social.registry.beneficiary + +
+ + + + + + + + + + + + + + + + + +