Files
Odoo-Modules/fusion_rental/wizard/manual_renewal_wizard.py
gsinghpal 14fe9ab716 feat: hide authorizer for rental orders, auto-set sale type
Rental orders no longer show the "Authorizer Required?" question or
the Authorizer field. The sale type is automatically set to 'Rentals'
when creating or confirming a rental order. Validation logic also
skips authorizer checks for rental sale type.

Made-with: Cursor
2026-02-25 23:33:23 -05:00

202 lines
6.4 KiB
Python

import logging
from datetime import timedelta
from odoo import _, api, fields, models
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class ManualRenewalWizard(models.TransientModel):
_name = 'manual.renewal.wizard'
_description = 'Manual Rental Renewal Wizard'
order_id = fields.Many2one(
'sale.order',
string="Rental Order",
required=True,
readonly=True,
)
partner_id = fields.Many2one(
related='order_id.partner_id',
string="Customer",
)
current_start_date = fields.Datetime(
string="Current Start Date",
readonly=True,
)
current_return_date = fields.Datetime(
string="Current Return Date",
readonly=True,
)
new_start_date = fields.Datetime(
string="New Start Date",
required=True,
)
new_return_date = fields.Datetime(
string="New Return Date",
required=True,
)
amount_preview = fields.Float(
string="Estimated Renewal Amount",
compute='_compute_amount_preview',
)
payment_token_id = fields.Many2one(
'payment.token',
string="Card on File",
domain="[('partner_id', '=', partner_id)]",
help="Select a stored card to charge automatically. "
"Leave empty to open the manual payment wizard.",
)
use_card_on_file = fields.Boolean(
string="Charge Card on File",
default=False,
compute='_compute_use_card_on_file',
store=True,
readonly=False,
)
previous_start_date = fields.Datetime(
string="Previous Start (rollback)",
readonly=True,
)
previous_return_date = fields.Datetime(
string="Previous Return (rollback)",
readonly=True,
)
renewal_invoice_id = fields.Many2one(
'account.move',
string="Renewal Invoice",
readonly=True,
)
renewal_log_id = fields.Many2one(
'rental.renewal.log',
string="Renewal Log",
readonly=True,
)
@api.depends('order_id', 'new_start_date', 'new_return_date')
def _compute_amount_preview(self):
for wizard in self:
if wizard.order_id:
wizard.amount_preview = wizard.order_id._get_renewal_amount()
else:
wizard.amount_preview = 0.0
@api.depends('payment_token_id')
def _compute_use_card_on_file(self):
for wizard in self:
wizard.use_card_on_file = bool(wizard.payment_token_id)
def action_confirm_renewal(self):
"""Confirm the manual renewal: extend dates, create invoice, and collect payment."""
self.ensure_one()
order = self.order_id
if not order.is_rental_order:
raise UserError(_("This is not a rental order."))
if self.new_return_date <= self.new_start_date:
raise UserError(_("New return date must be after the new start date."))
old_start = order.rental_start_date
old_return = order.rental_return_date
self.write({
'previous_start_date': old_start,
'previous_return_date': old_return,
})
order.write({
'rental_start_date': self.new_start_date,
'rental_return_date': self.new_return_date,
})
order._recompute_rental_prices()
invoice = order._create_renewal_invoice()
if not invoice:
raise UserError(_("Could not create renewal invoice."))
renewal_log = self.env['rental.renewal.log'].create({
'order_id': order.id,
'renewal_number': order.rental_renewal_count + 1,
'previous_start_date': old_start,
'previous_return_date': old_return,
'new_start_date': self.new_start_date,
'new_return_date': self.new_return_date,
'invoice_id': invoice.id,
'renewal_type': 'manual',
'state': 'draft',
'payment_status': 'pending',
})
self.write({
'renewal_invoice_id': invoice.id,
'renewal_log_id': renewal_log.id,
})
order.write({
'rental_renewal_count': order.rental_renewal_count + 1,
'rental_reminder_sent': False,
})
if self.use_card_on_file and self.payment_token_id:
invoice.action_post()
ok = order._collect_token_payment_for_invoice(invoice)
if ok:
renewal_log.write({
'state': 'done',
'payment_status': 'paid',
})
order._send_invoice_with_receipt(invoice, 'renewal')
order._send_renewal_confirmation_email(renewal_log, True)
return {'type': 'ir.actions.act_window_close'}
else:
renewal_log.write({
'state': 'done',
'payment_status': 'failed',
})
order._send_renewal_confirmation_email(renewal_log, False)
order._notify_staff_manual_payment(invoice)
return {'type': 'ir.actions.act_window_close'}
invoice.action_post()
renewal_log.write({'state': 'done'})
order._send_renewal_confirmation_email(renewal_log, False)
inv = invoice.with_user(self.env.user)
return inv.action_open_poynt_payment_wizard()
def action_cancel_renewal(self):
"""Cancel the renewal: revert dates and void the invoice."""
self.ensure_one()
order = self.order_id
if self.renewal_invoice_id:
inv = self.renewal_invoice_id
if inv.state == 'posted' and inv.payment_state in ('not_paid', 'partial'):
inv.button_draft()
if inv.state == 'draft':
inv.button_cancel()
if self.previous_start_date and self.previous_return_date:
order.write({
'rental_start_date': self.previous_start_date,
'rental_return_date': self.previous_return_date,
})
order._recompute_rental_prices()
if self.renewal_log_id:
self.renewal_log_id.write({
'state': 'failed',
'payment_status': 'failed',
'notes': 'Cancelled by user.',
})
if order.rental_renewal_count > 0:
order.rental_renewal_count -= 1
order.message_post(body=_("Manual renewal cancelled and reverted."))
return {'type': 'ir.actions.act_window_close'}