summaryrefslogtreecommitdiff
path: root/addons/payment/models/account_payment.py
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/payment/models/account_payment.py
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/payment/models/account_payment.py')
-rw-r--r--addons/payment/models/account_payment.py123
1 files changed, 123 insertions, 0 deletions
diff --git a/addons/payment/models/account_payment.py b/addons/payment/models/account_payment.py
new file mode 100644
index 00000000..0a417478
--- /dev/null
+++ b/addons/payment/models/account_payment.py
@@ -0,0 +1,123 @@
+# coding: utf-8
+
+import datetime
+
+from odoo import _, api, fields, models
+from odoo.exceptions import ValidationError
+
+
+class AccountPayment(models.Model):
+ _inherit = 'account.payment'
+
+ payment_transaction_id = fields.Many2one('payment.transaction', string='Payment Transaction', readonly=True)
+ payment_token_id = fields.Many2one(
+ 'payment.token', string="Saved payment token",
+ domain="""[
+ (payment_method_code == 'electronic', '=', 1),
+ ('company_id', '=', company_id),
+ ('acquirer_id.capture_manually', '=', False),
+ ('acquirer_id.journal_id', '=', journal_id),
+ ('partner_id', 'in', related_partner_ids),
+ ]""",
+ help="Note that tokens from acquirers set to only authorize transactions (instead of capturing the amount) are not available.")
+ related_partner_ids = fields.Many2many('res.partner', compute='_compute_related_partners')
+
+ def _get_payment_chatter_link(self):
+ self.ensure_one()
+ return '<a href=# data-oe-model=account.payment data-oe-id=%d>%s</a>' % (self.id, self.name)
+
+ @api.depends('partner_id.commercial_partner_id.child_ids')
+ def _compute_related_partners(self):
+ for p in self:
+ p.related_partner_ids = (
+ p.partner_id
+ | p.partner_id.commercial_partner_id
+ | p.partner_id.commercial_partner_id.child_ids
+ )._origin
+
+ @api.onchange('partner_id', 'payment_method_id', 'journal_id')
+ def _onchange_set_payment_token_id(self):
+ if not (self.payment_method_code == 'electronic' and self.partner_id and self.journal_id):
+ self.payment_token_id = False
+ return
+
+ self.payment_token_id = self.env['payment.token'].search([
+ ('partner_id', 'in', self.related_partner_ids.ids),
+ ('acquirer_id.capture_manually', '=', False),
+ ('acquirer_id.journal_id', '=', self.journal_id.id),
+ ], limit=1)
+
+ def _prepare_payment_transaction_vals(self):
+ self.ensure_one()
+ return {
+ 'amount': self.amount,
+ 'reference': self.ref,
+ 'currency_id': self.currency_id.id,
+ 'partner_id': self.partner_id.id,
+ 'partner_country_id': self.partner_id.country_id.id,
+ 'payment_token_id': self.payment_token_id.id,
+ 'acquirer_id': self.payment_token_id.acquirer_id.id,
+ 'payment_id': self.id,
+ 'type': 'server2server',
+ }
+
+ def _create_payment_transaction(self, vals=None):
+ for pay in self:
+ if pay.payment_transaction_id:
+ raise ValidationError(_('A payment transaction already exists.'))
+ elif not pay.payment_token_id:
+ raise ValidationError(_('A token is required to create a new payment transaction.'))
+
+ transactions = self.env['payment.transaction']
+ for pay in self:
+ transaction_vals = pay._prepare_payment_transaction_vals()
+
+ if vals:
+ transaction_vals.update(vals)
+
+ transaction = self.env['payment.transaction'].create(transaction_vals)
+ transactions += transaction
+
+ # Link the transaction to the payment.
+ pay.payment_transaction_id = transaction
+
+ return transactions
+
+ def action_validate_invoice_payment(self):
+ res = super(AccountPayment, self).action_validate_invoice_payment()
+ self.mapped('payment_transaction_id').filtered(lambda x: x.state == 'done' and not x.is_processed)._post_process_after_done()
+ return res
+
+ def action_post(self):
+ # Post the payments "normally" if no transactions are needed.
+ # If not, let the acquirer updates the state.
+ # __________ ______________
+ # | Payments | | Transactions |
+ # |__________| |______________|
+ # || | |
+ # || | |
+ # || | |
+ # __________ no s2s required __\/______ s2s required | | s2s_do_transaction()
+ # | Posted |<-----------------| post() |---------------- |
+ # |__________| |__________|<----- |
+ # | |
+ # OR---------------
+ # __________ __________ |
+ # | Cancelled|<-----------------| cancel() |<-----
+ # |__________| |__________|
+
+ payments_need_trans = self.filtered(lambda pay: pay.payment_token_id and not pay.payment_transaction_id)
+ transactions = payments_need_trans._create_payment_transaction()
+
+ res = super(AccountPayment, self - payments_need_trans).action_post()
+
+ transactions.s2s_do_transaction()
+
+ # Post payments for issued transactions.
+ transactions._post_process_after_done()
+ payments_trans_done = payments_need_trans.filtered(lambda pay: pay.payment_transaction_id.state == 'done')
+ super(AccountPayment, payments_trans_done).action_post()
+ payments_trans_not_done = payments_need_trans.filtered(lambda pay: pay.payment_transaction_id.state != 'done')
+ payments_trans_not_done.action_cancel()
+
+ return res