201 lines
6.9 KiB
Python
201 lines
6.9 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'
|
|
|
|
clover_refunded = fields.Boolean(
|
|
string="Refunded via Clover",
|
|
readonly=True,
|
|
copy=False,
|
|
default=False,
|
|
)
|
|
clover_refund_count = fields.Integer(
|
|
string="Clover Refund Count",
|
|
compute='_compute_clover_refund_count',
|
|
)
|
|
has_clover_receipt = fields.Boolean(
|
|
string="Has Clover Receipt",
|
|
compute='_compute_has_clover_receipt',
|
|
)
|
|
clover_provider_enabled = fields.Boolean(
|
|
string="Clover Provider Enabled",
|
|
compute='_compute_clover_provider_enabled',
|
|
)
|
|
|
|
@api.depends('reversal_move_ids')
|
|
def _compute_clover_refund_count(self):
|
|
for move in self:
|
|
if move.move_type == 'out_invoice':
|
|
move.clover_refund_count = len(move.reversal_move_ids.filtered(
|
|
lambda r: r.clover_refunded
|
|
))
|
|
else:
|
|
move.clover_refund_count = 0
|
|
|
|
def _compute_has_clover_receipt(self):
|
|
for move in self:
|
|
move.has_clover_receipt = bool(move._get_clover_transaction_for_receipt())
|
|
|
|
def _compute_clover_provider_enabled(self):
|
|
provider = self.env['payment.provider'].sudo().search([
|
|
('code', '=', 'clover'),
|
|
('state', 'in', ('enabled', 'test')),
|
|
], limit=1)
|
|
enabled = bool(provider)
|
|
for move in self:
|
|
move.clover_provider_enabled = enabled
|
|
|
|
def action_view_clover_refunds(self):
|
|
"""Open the credit notes linked to this invoice that were refunded via Clover."""
|
|
self.ensure_one()
|
|
refund_moves = self.reversal_move_ids.filtered(lambda r: r.clover_refunded)
|
|
action = {
|
|
'name': _("Clover 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_clover_transaction_for_receipt(self):
|
|
"""Find the Clover transaction linked to this invoice or credit note."""
|
|
self.ensure_one()
|
|
domain = [
|
|
('provider_id.code', '=', 'clover'),
|
|
('clover_charge_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_clover_receipt(self):
|
|
"""Resend the Clover payment/refund receipt email to the customer."""
|
|
self.ensure_one()
|
|
tx = self._get_clover_transaction_for_receipt()
|
|
if not tx:
|
|
raise UserError(_(
|
|
"No completed Clover transaction found for this document."
|
|
))
|
|
|
|
template = self.env.ref(
|
|
'fusion_clover.mail_template_clover_receipt',
|
|
raise_if_not_found=False,
|
|
)
|
|
if not template:
|
|
raise UserError(_("Receipt email template not found."))
|
|
|
|
report = self.env.ref(
|
|
'fusion_clover.action_report_clover_receipt',
|
|
raise_if_not_found=False,
|
|
)
|
|
attachment_ids = []
|
|
if report:
|
|
pdf_content, _content_type = report.sudo()._render_qweb_pdf(
|
|
report_ref='fusion_clover.action_report_clover_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_clover_payment_wizard(self):
|
|
"""Open the Clover payment collection wizard for this invoice."""
|
|
self.ensure_one()
|
|
return {
|
|
'name': _("Collect Clover Payment"),
|
|
'type': 'ir.actions.act_window',
|
|
'res_model': 'clover.payment.wizard',
|
|
'view_mode': 'form',
|
|
'target': 'new',
|
|
'context': {
|
|
'active_model': 'account.move',
|
|
'active_id': self.id,
|
|
},
|
|
}
|
|
|
|
def action_open_clover_refund_wizard(self):
|
|
"""Open the Clover refund wizard for this credit note."""
|
|
self.ensure_one()
|
|
return {
|
|
'name': _("Refund via Clover"),
|
|
'type': 'ir.actions.act_window',
|
|
'res_model': 'clover.refund.wizard',
|
|
'view_mode': 'form',
|
|
'target': 'new',
|
|
'context': {
|
|
'active_model': 'account.move',
|
|
'active_id': self.id,
|
|
},
|
|
}
|
|
|
|
def _get_original_clover_transaction(self):
|
|
"""Find the Clover payment transaction from the reversed invoice."""
|
|
self.ensure_one()
|
|
origin_invoice = self.reversed_entry_id
|
|
if not origin_invoice:
|
|
return self.env['payment.transaction']
|
|
|
|
return self.env['payment.transaction'].sudo().search([
|
|
('invoice_ids', 'in', origin_invoice.ids),
|
|
('state', '=', 'done'),
|
|
('provider_id.code', '=', 'clover'),
|
|
('clover_charge_id', '!=', False),
|
|
], order='id desc', limit=1)
|