diff --git a/g2p_payment_g2p_connect/README.rst b/g2p_payment_g2p_connect/README.rst new file mode 100644 index 00000000..192a289c --- /dev/null +++ b/g2p_payment_g2p_connect/README.rst @@ -0,0 +1,57 @@ +==================================================== +OpenG2P Program Payment: G2P Connect Payment Manager +==================================================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:81c41f1c1bbf5c8bf43037f3238f41e7fc27ba59bccc9c6a52523920fe69b5ee + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/15.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/__init__.py b/g2p_payment_g2p_connect/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/g2p_payment_g2p_connect/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/g2p_payment_g2p_connect/__manifest__.py b/g2p_payment_g2p_connect/__manifest__.py new file mode 100644 index 00000000..874cf4c7 --- /dev/null +++ b/g2p_payment_g2p_connect/__manifest__.py @@ -0,0 +1,25 @@ +{ + "name": "OpenG2P Program Payment: G2P Connect Payment Manager", + "category": "G2P", + "version": "15.0.1.2.0", + "sequence": 1, + "author": "OpenG2P", + "website": "https://openg2p.org", + "license": "Other OSI approved licence", + "development_status": "Alpha", + "depends": [ + "base", + "g2p_registry_base", + "g2p_programs", + ], + "data": [ + "security/ir.model.access.csv", + "views/payment_manager_view.xml", + ], + "assets": {}, + "demo": [], + "images": [], + "application": True, + "installable": True, + "auto_install": False, +} diff --git a/g2p_payment_g2p_connect/models/__init__.py b/g2p_payment_g2p_connect/models/__init__.py new file mode 100644 index 00000000..d512317b --- /dev/null +++ b/g2p_payment_g2p_connect/models/__init__.py @@ -0,0 +1,2 @@ +# Part of OpenSPP. See LICENSE file for full copyright and licensing details. +from . import payment_manager diff --git a/g2p_payment_g2p_connect/models/payment_manager.py b/g2p_payment_g2p_connect/models/payment_manager.py new file mode 100644 index 00000000..1eb80513 --- /dev/null +++ b/g2p_payment_g2p_connect/models/payment_manager.py @@ -0,0 +1,156 @@ +# Part of OpenG2P. See LICENSE file for full copyright and licensing details. +import logging +from datetime import datetime + +import requests + +from odoo import _, api, fields, models + +_logger = logging.getLogger(__name__) + + +class PaymentManager(models.Model): + _inherit = "g2p.program.payment.manager" + + @api.model + def _selection_manager_ref_id(self): + selection = super()._selection_manager_ref_id() + new_manager = ( + "g2p.program.payment.manager.g2p.connect", + "G2P Connect Payment Manager", + ) + if new_manager not in selection: + selection.append(new_manager) + return selection + + +class G2PPaymentManagerG2PConnect(models.Model): + _name = "g2p.program.payment.manager.g2p.connect" + _inherit = [ + "g2p.program.payment.manager.default", + "mail.thread", + "mail.activity.mixin", + ] + _description = "G2P Connect Payment Manager" + + batch_tag_ids = fields.Many2many( + "g2p.payment.batch.tag", + "g2p_pay_batch_tag_pay_manager_g2p_connect", + string="Batch Tags", + ondelete="cascade", + ) + create_batch = fields.Boolean("Automatically Create Batch", default=True) + payee_id_type = fields.Selection( + [ + ("bank_acc_no", "Bank Account Number"), + ("bank_acc_iban", "IBAN"), + ("phone", "Phone"), + ("email", "Email"), + ("reg_id", "Registrant ID"), + ], + "Payee ID Field", + required=True, + ) + reg_id_type_for_payee_id = fields.Many2one( + "g2p.id.type", "Payee DFSP ID Type", required=False + ) + payment_endpoint_url = fields.Char("Payment Endpoint URL", required=True) + + api_timeout = fields.Integer("API Timeout", default=10) + + username = fields.Char(required=True) + password = fields.Char(required=True) + + payer_fa = fields.Char(string="Payer Financial Address", required=True) + payer_name = fields.Char(required=True) + locale = fields.Char(required=True) + + def _send_payments(self, batches): + _logger.info("DEBUG! send_payments Manager: G2P Connect.") + for batch in batches: + if batch.batch_has_started: + continue + batch.batch_has_started = True + batch_data = { + "signature": 'Signature: namespace="g2p", kidId="{sender_id}|{unique_key_id}|{algorithm}", algorithm="ed25519", created="1606970629", expires="1607030629", headers="(created) (expires) digest", signature="Base64(signing content)', + "header": { + "version": "1.0.0", + "message_id": "123", + "message_ts": "", + "action": "search", + "sender_id": "spp.example.org", + "sender_uri": "https://spp.example.org/{namespace}/callback/on-search", + "receiver_id": "pymts.example.org", + "total_count": 21800, + "is_msg_encrypted": False, + "meta": {}, + }, + "message": {"transaction_id": batch.name, "disbursements": []}, + } + headers = { + "Content-Type": "application/json", + } + for payment in batch.payment_ids: + batch_data["message"]["disbursements"].append( + { + "reference_id": payment.name, + "payer_fa": self.payer_fa, + "payee_fa": self._get_payee_fa(payment), + "amount": payment.amount_issued, + "scheduled_timestamp": "", + "payer_name": self.payer_name, + "payee_name": payment.partner_id.name, + "note": "string", + "purpose": self.program_id.name, + "instruction": "string", + "currency_code": payment.currency_id.name, + "locale": self.locale, + } + ) + try: + response = requests.post( + self.payment_endpoint_url, json=batch_data, headers=headers + ) + _logger.info("G2P Connect Disbursement response: %s", response.content) + response.raise_for_status() + + # TODO: Do Status check rather than hardcoding + for payment in batch.payment_ids: + payment.state = "sent" + payment.status = "paid" + payment.amount_paid = payment.amount_issued + payment.payment_datetime = datetime.utcnow() + + except Exception as e: + _logger.error( + "G2P Connect Payment Failed with unknown reason: %s", str(e) + ) + error_msg = "G2P Connect Payment Failed with unknown reason: " + str(e) + self.message_post( + body=error_msg, subject=_("G2P Connect Payment Disbursement") + ) + + # TODO: Compute status of disbursement from API + batch.batch_has_completed = True + + def _get_payee_fa(self, payment): + self.ensure_one() + payee_id_type = self.payee_id_type + if payee_id_type == "bank_acc_no": + # TODO: Compute which bank_acc_no to choose from bank account list + for bank_id in payment.partner_id.bank_ids: + return bank_id.acc_number + elif payee_id_type == "bank_acc_iban": + # TODO: Compute which iban to choose from bank account list + for bank_id in payment.partner_id.bank_ids: + return bank_id.iban + elif payee_id_type == "phone": + return payment.partner_id.phone + elif payee_id_type == "email": + return payment.partner_id.email + elif payee_id_type == "reg_id": + for reg_id in payment.partner_id.reg_ids: + if reg_id.id_type.id == self.reg_id_type_for_payee_id.id: + return reg_id.value + # TODO: Deal with no bank acc and/or ID type not matching any available IDs + return None diff --git a/g2p_payment_g2p_connect/readme/DESCRIPTION.rst b/g2p_payment_g2p_connect/readme/DESCRIPTION.rst new file mode 100644 index 00000000..981b7516 --- /dev/null +++ b/g2p_payment_g2p_connect/readme/DESCRIPTION.rst @@ -0,0 +1 @@ +G2P Connect Payment Manager diff --git a/g2p_payment_g2p_connect/security/ir.model.access.csv b/g2p_payment_g2p_connect/security/ir.model.access.csv new file mode 100644 index 00000000..f4e896be --- /dev/null +++ b/g2p_payment_g2p_connect/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_payment_manager_g2p_connect_admin,G2P Connect Payment Manager Admin,g2p_payment_g2p_connect.model_g2p_program_payment_manager_g2p_connect,g2p_registry_base.group_g2p_admin,1,1,1,1 +g2p_program_payment_manager_g2p_connect_program_manager,G2P Connect Payment Manager Program Manager,g2p_payment_g2p_connect.model_g2p_program_payment_manager_g2p_connect,g2p_programs.g2p_program_manager,1,1,1,0 +g2p_program_payment_manager_g2p_connect_program_validator,G2P Connect Payment Manager Program Validator,g2p_payment_g2p_connect.model_g2p_program_payment_manager_g2p_connect,g2p_programs.g2p_program_validator,1,0,0,0 diff --git a/g2p_payment_g2p_connect/static/description/icon.png b/g2p_payment_g2p_connect/static/description/icon.png new file mode 100644 index 00000000..5ecb429e Binary files /dev/null and b/g2p_payment_g2p_connect/static/description/icon.png differ diff --git a/g2p_payment_g2p_connect/static/description/index.html b/g2p_payment_g2p_connect/static/description/index.html new file mode 100644 index 00000000..87737bf9 --- /dev/null +++ b/g2p_payment_g2p_connect/static/description/index.html @@ -0,0 +1,415 @@ + + + + + + +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_g2p_connect/views/payment_manager_view.xml b/g2p_payment_g2p_connect/views/payment_manager_view.xml new file mode 100644 index 00000000..b3170c0c --- /dev/null +++ b/g2p_payment_g2p_connect/views/payment_manager_view.xml @@ -0,0 +1,103 @@ + + + + + view_payment_manager_g2p_connect_tree + g2p.program.payment.manager.g2p.connect + 1 + + + + + + + + + + + view_payment_manager_g2p_connect_form + g2p.program.payment.manager.g2p.connect + + primary + + + + + + + + + + + + + + + + + + + + + payment_manager_g2p_connect_filter + g2p.program.payment.manager.g2p.connect + + + + + + + + + + + + + + Payment Managers + ir.actions.act_window + g2p.program.payment.manager.g2p.connect + tree,form + + {} + [] + +

+ Add a Payment Manager! +

+ Click the create button to enter a new g2p connect payment manager. +

+
+
+ + + + tree + + + + + + + form + + + + + + +
diff --git a/setup/g2p_payment_g2p_connect/odoo/addons/g2p_payment_g2p_connect b/setup/g2p_payment_g2p_connect/odoo/addons/g2p_payment_g2p_connect new file mode 120000 index 00000000..1cc49beb --- /dev/null +++ b/setup/g2p_payment_g2p_connect/odoo/addons/g2p_payment_g2p_connect @@ -0,0 +1 @@ +../../../../g2p_payment_g2p_connect \ No newline at end of file diff --git a/setup/g2p_payment_g2p_connect/setup.py b/setup/g2p_payment_g2p_connect/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/g2p_payment_g2p_connect/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)