From 23f9f5cb1787d57ecd2c1a7eb14a45fae8753757 Mon Sep 17 00:00:00 2001 From: braisab Date: Fri, 22 Oct 2021 21:55:04 +0200 Subject: [PATCH] [IMP]pms: added pay button in folio portal --- pms/controllers/pms_portal.py | 119 +++++++++++++++++++++++++++ pms/models/pms_folio.py | 75 +++++++++++++++++ pms/views/folio_portal_templates.xml | 113 +++++++++++++++++++++++++ 3 files changed, 307 insertions(+) diff --git a/pms/controllers/pms_portal.py b/pms/controllers/pms_portal.py index 0ecf0e989..34cc95b0a 100644 --- a/pms/controllers/pms_portal.py +++ b/pms/controllers/pms_portal.py @@ -4,6 +4,7 @@ from odoo import _, fields, http, tools from odoo.exceptions import AccessError, MissingError from odoo.http import request +from odoo.addons.payment.controllers.portal import PaymentProcessing from odoo.addons.portal.controllers.portal import CustomerPortal, pager as portal_pager @@ -26,10 +27,128 @@ class PortalFolio(CustomerPortal): def _folio_get_page_view_values(self, folio, access_token, **kwargs): values = {"folio": folio, "token": access_token} + payment_inputs = request.env["payment.acquirer"]._get_available_payment_input( + partner=folio.partner_id, company=folio.company_id + ) + is_public_user = request.env.user._is_public() + if is_public_user: + payment_inputs.pop("pms", None) + token_count = ( + request.env["payment.token"] + .sudo() + .search_count( + [ + ("acquirer_id.company_id", "=", folio.company_id.id), + ("partner_id", "=", folio.partner_id.id), + ] + ) + ) + values["existing_token"] = token_count > 0 + values.update(payment_inputs) + values["partner_id"] = ( + folio.partner_id if is_public_user else request.env.user.partner_id, + ) return self._get_page_view_values( folio, access_token, values, "my_folios_history", False, **kwargs ) + @http.route( + "/folio/pay//form_tx", type="json", auth="public", website=True + ) + def folio_pay_form( + self, acquirer_id, folio_id, save_token=False, access_token=None, **kwargs + ): + folio_sudo = request.env["pms.folio"].sudo().browse(folio_id) + if not folio_sudo: + return False + + try: + acquirer_id = int(acquirer_id) + except Exception: + return False + + if request.env.user._is_public(): + save_token = False # we avoid to create a token for the public user + + success_url = kwargs.get( + "success_url", + "%s?%s" % (folio_sudo.access_url, access_token if access_token else ""), + ) + vals = { + "acquirer_id": acquirer_id, + "return_url": success_url, + } + + if save_token: + vals["type"] = "form_save" + transaction = folio_sudo._create_payment_transaction(vals) + PaymentProcessing.add_payment_transaction(transaction) + if not transaction: + return False + tx_ids_list = set(request.session.get("__payment_tx_ids__", [])) | set( + transaction.ids + ) + request.session["__payment_tx_ids__"] = list(tx_ids_list) + + return transaction.render_invoice_button( + folio_sudo, + submit_txt=_("Pay & Confirm"), + render_values={ + "type": "form_save" if save_token else "form", + "alias_usage": _( + "If we store your payment information on our server, " + "subscription payments will be made automatically." + ), + }, + ) + + # @http.route( + # '/invoice/pay//s2s_token_tx', + # type='http', + # auth='public', + # website=True + # ) + # def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs): + # """ Use a token to perform a s2s transaction """ + # error_url = kwargs.get('error_url', '/my') + # access_token = kwargs.get('access_token') + # params = {} + # if access_token: + # params['access_token'] = access_token + # + # invoice_sudo = request.env['account.move'].sudo().browse(invoice_id).exists() + # if not invoice_sudo: + # params['error'] = 'pay_invoice_invalid_doc' + # return request.redirect(_build_url_w_params(error_url, params)) + # + # success_url = kwargs.get( + # 'success_url', + # "%s?%s" % ( + # invoice_sudo.access_url, + # url_encode({'access_token': access_token}) if access_token else '') + # ) + # try: + # token = request.env['payment.token'].sudo().browse(int(pm_id)) + # except (ValueError, TypeError): + # token = False + # token_owner = invoice_sudo.partner_id if \ + # request.env.user._is_public() else request.env.user.partner_id + # if not token or token.partner_id != token_owner: + # params['error'] = 'pay_invoice_invalid_token' + # return request.redirect(_build_url_w_params(error_url, params)) + # + # vals = { + # 'payment_token_id': token.id, + # 'type': 'server2server', + # 'return_url': _build_url_w_params(success_url, params), + # } + # + # tx = invoice_sudo._create_payment_transaction(vals) + # PaymentProcessing.add_payment_transaction(tx) + # + # params['success'] = 'pay_invoice' + # return request.redirect('/payment/process') + @http.route( ["/my/folios", "/my/folios/page/"], type="http", diff --git a/pms/models/pms_folio.py b/pms/models/pms_folio.py index 19438ba7d..bcbbb3e80 100644 --- a/pms/models/pms_folio.py +++ b/pms/models/pms_folio.py @@ -1955,3 +1955,78 @@ class PmsFolio(models.Model): } self.env["res.partner.id_number"].create(number_values) record.partner_id = partner + + def _create_payment_transaction(self, vals): + # Ensure the currencies are the same. + currency = self[0].currency_id + if any(folio.currency_id != currency for folio in self): + raise ValidationError( + _( + "A transaction can't be linked to folios having different currencies." + ) + ) + + # Ensure the partner are the same. + partner = self[0].partner_id + if any(folio.partner_id != partner for folio in self): + raise ValidationError( + _("A transaction can't be linked to folios having different partners.") + ) + + # Try to retrieve the acquirer. However, fallback to the token's acquirer. + acquirer_id = vals.get("acquirer_id") + acquirer = None + payment_token_id = vals.get("payment_token_id") + + if payment_token_id: + payment_token = self.env["payment.token"].sudo().browse(payment_token_id) + + # Check payment_token/acquirer matching or take the acquirer from token + if acquirer_id: + acquirer = self.env["payment.acquirer"].browse(acquirer_id) + if payment_token and payment_token.acquirer_id != acquirer: + raise ValidationError( + _("Invalid token found! Token acquirer %s != %s") + % (payment_token.acquirer_id.name, acquirer.name) + ) + if payment_token and payment_token.partner_id != partner: + raise ValidationError( + _("Invalid token found! Token partner %s != %s") + % (payment_token.partner.name, partner.name) + ) + else: + acquirer = payment_token.acquirer_id + + # Check an acquirer is there. + if not acquirer_id and not acquirer: + raise ValidationError( + _("A payment acquirer is required to create a transaction.") + ) + + if not acquirer: + acquirer = self.env["payment.acquirer"].browse(acquirer_id) + + # Check a journal is set on acquirer. + if not acquirer.journal_id: + raise ValidationError( + _("A journal must be specified for the acquirer %s.", acquirer.name) + ) + + if not acquirer_id and acquirer: + vals["acquirer_id"] = acquirer.id + + vals.update( + { + "amount": sum(self.mapped("amount_total")), + "currency_id": currency.id, + "partner_id": partner.id, + "folio_ids": [(6, 0, self.ids)], + } + ) + transaction = self.env["payment.transaction"].create(vals) + + # Process directly if payment_token + if transaction.payment_token_id: + transaction.s2s_do_transaction() + + return transaction diff --git a/pms/views/folio_portal_templates.xml b/pms/views/folio_portal_templates.xml index 174393b3a..be237460d 100644 --- a/pms/views/folio_portal_templates.xml +++ b/pms/views/folio_portal_templates.xml @@ -77,6 +77,116 @@ + + + + +