from odoo import models, fields, api,_
|
|
from odoo.exceptions import UserError, ValidationError,Warning
|
|
from psycopg2 import sql, DatabaseError
|
|
from datetime import datetime
|
|
|
|
from werkzeug import utils
|
|
import base64
|
|
|
|
class PaymentTransaction(models.Model):
|
|
_inherit = 'payment.transaction'
|
|
|
|
donation_ids = fields.Many2many('donation.donation', 'donation_transaction_rel', 'transaction_id', 'donation_id',
|
|
string='Donations', copy=False, readonly=True)
|
|
|
|
def render_donation_button(self, donation, submit_txt=None, render_values=None):
|
|
values = {
|
|
'partner_id': donation.partner_id.id,
|
|
'type': self.type,
|
|
}
|
|
if render_values:
|
|
values.update(render_values)
|
|
# Not very elegant to do that here but no choice regarding the design.
|
|
self._log_payment_transaction_sent()
|
|
return self.acquirer_id.with_context(submit_class='btn btn-primary', submit_txt=submit_txt or _('Pay Now')).sudo().render(
|
|
self.reference,
|
|
donation.amount_total,
|
|
donation.currency_id.id,
|
|
values=values,
|
|
)
|
|
|
|
class DonationDonation(models.Model):
|
|
_inherit = 'donation.donation'
|
|
|
|
|
|
|
|
def _get_payment_type(self, tokenize=False):
|
|
self.ensure_one()
|
|
return 'form_save' if tokenize else 'form'
|
|
|
|
def _create_payment_transaction(self, vals):
|
|
'''Similar to self.env['payment.transaction'].create(vals) but the values are filled with the
|
|
current donation fields (e.g. the partner or the currency).
|
|
:param vals: The values to create a new payment.transaction.
|
|
:return: The newly created payment.transaction record.
|
|
'''
|
|
# Ensure the currencies are the same.
|
|
currency = self[0].currency_id
|
|
# if any(so.pricelist_id.currency_id != currency for so in self):
|
|
# raise ValidationError(_('A transaction can\'t be linked to sales orders having different currencies.'))
|
|
|
|
# Ensure the partner are the same.
|
|
partner = self[0].partner_id
|
|
if any(so.partner_id != partner for so in self):
|
|
raise ValidationError(_('A transaction can\'t be linked to sales orders having different partners.'))
|
|
|
|
# Try to retrieve the acquirer. However, fallback to the token's acquirer.
|
|
acquirer_id = vals.get('acquirer_id')
|
|
acquirer = False
|
|
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,
|
|
'donation_ids': [(6, 0, self.ids)],
|
|
'type': self[0]._get_payment_type(vals.get('type')=='form_save'),
|
|
})
|
|
|
|
|
|
transaction = self.env['payment.transaction'].create(vals)
|
|
|
|
|
|
# Process directly if payment_token
|
|
if transaction.payment_token_id:
|
|
transaction.s2s_do_transaction()
|
|
|
|
return transaction
|