Files
Odoo-Modules/fusion_poynt/models/account_move.py
gsinghpal e71bc503f9 changes
2026-02-25 09:40:41 -05:00

204 lines
7.0 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import base64
from odoo import _, api, fields, models
from odoo.exceptions import UserError
class AccountMove(models.Model):
_inherit = 'account.move'
poynt_refunded = fields.Boolean(
string="Refunded via Poynt",
readonly=True,
copy=False,
default=False,
)
poynt_refund_count = fields.Integer(
string="Poynt Refund Count",
compute='_compute_poynt_refund_count',
)
has_poynt_receipt = fields.Boolean(
string="Has Poynt Receipt",
compute='_compute_has_poynt_receipt',
)
@api.depends('reversal_move_ids')
def _compute_poynt_refund_count(self):
for move in self:
if move.move_type == 'out_invoice':
move.poynt_refund_count = len(move.reversal_move_ids.filtered(
lambda r: r.poynt_refunded
))
else:
move.poynt_refund_count = 0
def _compute_has_poynt_receipt(self):
for move in self:
move.has_poynt_receipt = bool(move._get_poynt_transaction_for_receipt())
def action_view_poynt_refunds(self):
"""Open the credit notes linked to this invoice that were refunded via Poynt."""
self.ensure_one()
refund_moves = self.reversal_move_ids.filtered(lambda r: r.poynt_refunded)
action = {
'name': _("Poynt Refunds"),
'type': 'ir.actions.act_window',
'res_model': 'account.move',
'view_mode': 'list,form',
'domain': [('id', 'in', refund_moves.ids)],
'context': {'default_move_type': 'out_refund'},
}
if len(refund_moves) == 1:
action['view_mode'] = 'form'
action['res_id'] = refund_moves.id
return action
def _get_poynt_transaction_for_receipt(self):
"""Find the Poynt transaction linked to this invoice or credit note."""
self.ensure_one()
domain = [
('provider_id.code', '=', 'poynt'),
('poynt_transaction_id', '!=', False),
('state', '=', 'done'),
]
if self.move_type == 'out_invoice':
domain.append(('invoice_ids', 'in', self.ids))
elif self.move_type == 'out_refund':
domain += [
('operation', '=', 'refund'),
('invoice_ids', 'in', self.ids),
]
else:
return self.env['payment.transaction']
return self.env['payment.transaction'].sudo().search(
domain, order='id desc', limit=1,
)
def action_resend_poynt_receipt(self):
"""Resend the Poynt payment/refund receipt email to the customer."""
self.ensure_one()
tx = self._get_poynt_transaction_for_receipt()
if not tx:
raise UserError(_(
"No completed Poynt transaction found for this document."
))
template = self.env.ref(
'fusion_poynt.mail_template_poynt_receipt',
raise_if_not_found=False,
)
if not template:
raise UserError(_("Receipt email template not found."))
report = self.env.ref(
'fusion_poynt.action_report_poynt_receipt',
raise_if_not_found=False,
)
attachment_ids = []
if report:
pdf_content, _content_type = report.sudo()._render_qweb_pdf(
report_ref='fusion_poynt.action_report_poynt_receipt',
res_ids=tx.ids,
)
prefix = "Refund_Receipt" if self.move_type == 'out_refund' else "Payment_Receipt"
filename = f"{prefix}_{tx.reference}.pdf"
att = self.env['ir.attachment'].create({
'name': filename,
'type': 'binary',
'datas': base64.b64encode(pdf_content),
'res_model': self._name,
'res_id': self.id,
'mimetype': 'application/pdf',
})
attachment_ids = [att.id]
template.send_mail(tx.id, force_send=True)
is_refund = self.move_type == 'out_refund'
label = _("Refund") if is_refund else _("Payment")
self.message_post(
body=_(
"%(label)s receipt resent to %(email)s.",
label=label,
email=tx.partner_id.email,
),
message_type='notification',
subtype_xmlid='mail.mt_note',
attachment_ids=attachment_ids,
)
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': _("Receipt Sent"),
'message': _("The receipt has been sent to %s.",
tx.partner_id.email),
'type': 'success',
'sticky': False,
},
}
def action_open_poynt_payment_wizard(self):
"""Open the Poynt payment collection wizard for this invoice."""
self.ensure_one()
return {
'name': _("Collect Poynt Payment"),
'type': 'ir.actions.act_window',
'res_model': 'poynt.payment.wizard',
'view_mode': 'form',
'target': 'new',
'context': {
'active_model': 'account.move',
'active_id': self.id,
},
}
def action_open_poynt_refund_wizard(self):
"""Open the Poynt refund wizard for this credit note."""
self.ensure_one()
return {
'name': _("Refund via Poynt"),
'type': 'ir.actions.act_window',
'res_model': 'poynt.refund.wizard',
'view_mode': 'form',
'target': 'new',
'context': {
'active_model': 'account.move',
'active_id': self.id,
},
}
def _get_original_poynt_transaction(self):
"""Find the Poynt payment transaction from the reversed invoice.
For credit notes created via the "Reverse" action, the
``reversed_entry_id`` links back to the original invoice.
We look for a confirmed Poynt transaction on that invoice.
"""
self.ensure_one()
origin_invoice = self.reversed_entry_id
if not origin_invoice:
return self.env['payment.transaction']
tx = self.env['payment.transaction'].sudo().search([
('invoice_ids', 'in', origin_invoice.ids),
('state', '=', 'done'),
('provider_id.code', '=', 'poynt'),
('poynt_transaction_id', '!=', False),
('poynt_voided', '=', False),
], order='id desc', limit=1)
if not tx:
tx = self.env['payment.transaction'].sudo().search([
('invoice_ids', 'in', origin_invoice.ids),
('state', 'in', ('done', 'cancel')),
('provider_id.code', '=', 'poynt'),
('poynt_transaction_id', '!=', False),
], order='id desc', limit=1)
return tx