135 lines
6.5 KiB
Python
135 lines
6.5 KiB
Python
|
# -*- coding: utf-8 -*-
|
||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||
|
|
||
|
from odoo import http, _
|
||
|
from odoo.exceptions import ValidationError
|
||
|
from odoo.http import request
|
||
|
from odoo.tools.json import scriptsafe as json_safe
|
||
|
|
||
|
from odoo.addons.payment import utils as payment_utils
|
||
|
from odoo.addons.payment.controllers import portal as payment_portal
|
||
|
|
||
|
|
||
|
class PaymentPortal(payment_portal.PaymentPortal):
|
||
|
@http.route('/donation/pay', type='http', methods=['GET', 'POST'], auth='public', website=True, sitemap=False)
|
||
|
def donation_pay(self, **kwargs):
|
||
|
""" Behaves like PaymentPortal.payment_pay but for donation
|
||
|
|
||
|
:param dict kwargs: As the parameters of in payment_pay, with the additional:
|
||
|
- str donation_options: The options settled in the donation snippet
|
||
|
- str donation_descriptions: The descriptions for all prefilled amounts
|
||
|
:return: The rendered donation form
|
||
|
:rtype: str
|
||
|
:raise: werkzeug.exceptions.NotFound if the access token is invalid
|
||
|
"""
|
||
|
kwargs['is_donation'] = True
|
||
|
kwargs['currency_id'] = self._cast_as_int(kwargs.get('currency_id')) or request.env.company.currency_id.id
|
||
|
kwargs['amount'] = self._cast_as_float(kwargs.get('amount')) or 25.0
|
||
|
kwargs['donation_options'] = kwargs.get('donation_options', json_safe.dumps(dict(customAmount="freeAmount")))
|
||
|
|
||
|
if request.env.user._is_public():
|
||
|
kwargs['partner_id'] = request.env.user.partner_id.id
|
||
|
kwargs['access_token'] = payment_utils.generate_access_token(kwargs['partner_id'], kwargs['amount'], kwargs['currency_id'])
|
||
|
|
||
|
return self.payment_pay(**kwargs)
|
||
|
|
||
|
@http.route('/donation/transaction/<minimum_amount>', type='json', auth='public', website=True, sitemap=False)
|
||
|
def donation_transaction(self, amount, currency_id, partner_id, access_token, minimum_amount=0, **kwargs):
|
||
|
if float(amount) < float(minimum_amount):
|
||
|
raise ValidationError(_('Donation amount must be at least %.2f.', float(minimum_amount)))
|
||
|
use_public_partner = request.env.user._is_public() or not partner_id
|
||
|
if use_public_partner:
|
||
|
details = kwargs['partner_details']
|
||
|
if not details.get('name'):
|
||
|
raise ValidationError(_('Name is required.'))
|
||
|
if not details.get('email'):
|
||
|
raise ValidationError(_('Email is required.'))
|
||
|
if not details.get('country_id'):
|
||
|
raise ValidationError(_('Country is required.'))
|
||
|
partner_id = request.website.user_id.partner_id.id
|
||
|
del kwargs['partner_details']
|
||
|
else:
|
||
|
partner_id = request.env.user.partner_id.id
|
||
|
|
||
|
self._validate_transaction_kwargs(kwargs, additional_allowed_keys=(
|
||
|
'donation_comment', 'donation_recipient_email', 'partner_details', 'reference_prefix'
|
||
|
))
|
||
|
if use_public_partner:
|
||
|
kwargs['custom_create_values'] = {'tokenize': False}
|
||
|
tx_sudo = self._create_transaction(
|
||
|
amount=amount, currency_id=currency_id, partner_id=partner_id, **kwargs
|
||
|
)
|
||
|
tx_sudo.is_donation = True
|
||
|
if use_public_partner:
|
||
|
tx_sudo.update({
|
||
|
'partner_name': details['name'],
|
||
|
'partner_email': details['email'],
|
||
|
'partner_country_id': int(details['country_id']),
|
||
|
})
|
||
|
elif not tx_sudo.partner_country_id:
|
||
|
tx_sudo.partner_country_id = int(kwargs['partner_details']['country_id'])
|
||
|
# the user can change the donation amount on the payment page,
|
||
|
# therefor we need to recompute the access_token
|
||
|
access_token = payment_utils.generate_access_token(
|
||
|
tx_sudo.partner_id.id, tx_sudo.amount, tx_sudo.currency_id.id
|
||
|
)
|
||
|
self._update_landing_route(tx_sudo, access_token)
|
||
|
|
||
|
# Send a notification to warn that a donation has been made
|
||
|
recipient_email = kwargs['donation_recipient_email']
|
||
|
comment = kwargs['donation_comment']
|
||
|
tx_sudo._send_donation_email(True, comment, recipient_email)
|
||
|
|
||
|
return tx_sudo._get_processing_values()
|
||
|
|
||
|
def _get_extra_payment_form_values(
|
||
|
self, donation_options=None, donation_descriptions=None, is_donation=False, **kwargs
|
||
|
):
|
||
|
rendering_context = super()._get_extra_payment_form_values(
|
||
|
donation_options=donation_options,
|
||
|
donation_descriptions=donation_descriptions,
|
||
|
is_donation=is_donation,
|
||
|
**kwargs,
|
||
|
)
|
||
|
if is_donation:
|
||
|
user_sudo = request.env.user
|
||
|
logged_in = not user_sudo._is_public()
|
||
|
# If the user is logged in, take their partner rather than the partner set in the params.
|
||
|
# This is something that we want, since security rules are based on the partner, and created
|
||
|
# tokens should not be assigned to the public user. This should have no impact on the
|
||
|
# transaction itself besides making reconciliation possibly more difficult (e.g. The
|
||
|
# transaction and invoice partners are different).
|
||
|
partner_sudo = user_sudo.partner_id
|
||
|
partner_details = {}
|
||
|
if logged_in:
|
||
|
partner_details = {
|
||
|
'name': partner_sudo.name,
|
||
|
'email': partner_sudo.email,
|
||
|
'country_id': partner_sudo.country_id.id,
|
||
|
}
|
||
|
|
||
|
countries = request.env['res.country'].sudo().search([])
|
||
|
descriptions = request.httprequest.form.getlist('donation_descriptions')
|
||
|
|
||
|
donation_options = json_safe.loads(donation_options) if donation_options else {}
|
||
|
donation_amounts = json_safe.loads(donation_options.get('donationAmounts', '[]'))
|
||
|
|
||
|
rendering_context.update({
|
||
|
'is_donation': True,
|
||
|
'partner': partner_sudo,
|
||
|
'submit_button_label': _("Donate"),
|
||
|
'transaction_route': '/donation/transaction/%s' % donation_options.get('minimumAmount', 0),
|
||
|
'partner_details': partner_details,
|
||
|
'error': {},
|
||
|
'countries': countries,
|
||
|
'donation_options': donation_options,
|
||
|
'donation_amounts': donation_amounts,
|
||
|
'donation_descriptions': descriptions,
|
||
|
})
|
||
|
return rendering_context
|
||
|
|
||
|
def _get_payment_page_template_xmlid(self, **kwargs):
|
||
|
if kwargs.get('is_donation'):
|
||
|
return 'website_payment.donation_pay'
|
||
|
return super()._get_payment_page_template_xmlid(**kwargs)
|