You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
7.5 KiB
160 lines
7.5 KiB
# -*- coding: utf-8 -*-
|
|
from odoo import api, fields, models, _
|
|
from odoo.exceptions import UserError
|
|
from datetime import date, timedelta
|
|
|
|
|
|
class GymMembershipExtendWizard(models.TransientModel):
|
|
"""Wizard to extend gym membership"""
|
|
_name = 'gym.membership.extend.wizard'
|
|
_description = 'Extend Gym Membership Wizard'
|
|
|
|
membership_id = fields.Many2one('gym.membership', string='Membership', required=True)
|
|
member_id = fields.Many2one('res.partner', string='Member', required=True)
|
|
current_end_date = fields.Date(string='Current End Date', related='membership_id.effective_end_date')
|
|
extension_type = fields.Selection([
|
|
('same_plan', 'Extend with Same Plan Duration'),
|
|
('custom_days', 'Custom Number of Days'),
|
|
('new_plan', 'Change to New Membership Plan')
|
|
], string='Extension Type', required=True, default='same_plan')
|
|
same_plan_duration = fields.Integer(string='Plan Duration (Days)', compute='_compute_same_plan_duration',
|
|
store=True)
|
|
custom_days = fields.Integer(string='Number of Days to Extend', default=30)
|
|
new_membership_plan_id = fields.Many2one('product.product', string='New Membership Plan',
|
|
domain="[('membership_date_from', '!=', False)]")
|
|
new_plan_duration = fields.Integer(string='New Plan Duration (Days)')
|
|
extension_days = fields.Integer(string='Total Extension Days', compute='_compute_extension_details', store=True)
|
|
new_end_date = fields.Date(string='New End Date', compute='_compute_extension_details', store=True)
|
|
extension_amount = fields.Float(string='Extension Amount', compute='_compute_extension_details', store=True)
|
|
notes = fields.Text(string='Notes')
|
|
|
|
@api.depends('membership_id.membership_duration')
|
|
def _compute_same_plan_duration(self):
|
|
"""Compute the same plan duration from membership"""
|
|
for wizard in self:
|
|
wizard.same_plan_duration = wizard.membership_id.membership_duration or 0
|
|
|
|
@api.depends('extension_type', 'custom_days', 'new_membership_plan_id', 'same_plan_duration')
|
|
def _compute_extension_details(self):
|
|
"""Compute extension days, new end date and amount"""
|
|
for wizard in self:
|
|
extension_days = 0
|
|
extension_amount = 0.0
|
|
|
|
if wizard.extension_type == 'same_plan':
|
|
if wizard.membership_id.membership_scheme_id:
|
|
original_plan = wizard.membership_id.membership_scheme_id
|
|
if original_plan.membership_date_from and original_plan.membership_date_to:
|
|
extension_days = (original_plan.membership_date_to - original_plan.membership_date_from).days
|
|
extension_amount = original_plan.list_price
|
|
|
|
elif wizard.extension_type == 'custom_days':
|
|
extension_days = wizard.custom_days
|
|
if wizard.membership_id.membership_scheme_id and extension_days > 0:
|
|
original_plan = wizard.membership_id.membership_scheme_id
|
|
if original_plan.membership_date_from and original_plan.membership_date_to:
|
|
original_days = (original_plan.membership_date_to - original_plan.membership_date_from).days
|
|
if original_days > 0:
|
|
daily_rate = original_plan.list_price / original_days
|
|
extension_amount = daily_rate * extension_days
|
|
|
|
elif wizard.extension_type == 'new_plan':
|
|
if wizard.new_membership_plan_id:
|
|
new_plan = wizard.new_membership_plan_id
|
|
if new_plan.membership_date_from and new_plan.membership_date_to:
|
|
extension_days = (new_plan.membership_date_to - new_plan.membership_date_from).days
|
|
extension_amount = new_plan.list_price
|
|
|
|
wizard.extension_days = extension_days
|
|
wizard.extension_amount = extension_amount
|
|
|
|
if wizard.current_end_date and extension_days > 0:
|
|
wizard.new_end_date = wizard.current_end_date + timedelta(days=extension_days)
|
|
else:
|
|
wizard.new_end_date = wizard.current_end_date
|
|
|
|
@api.onchange('new_membership_plan_id')
|
|
def _onchange_new_membership_plan_id(self):
|
|
"""Update new plan duration when plan changes"""
|
|
if self.new_membership_plan_id:
|
|
plan = self.new_membership_plan_id
|
|
if plan.membership_date_from and plan.membership_date_to:
|
|
self.new_plan_duration = (plan.membership_date_to - plan.membership_date_from).days
|
|
|
|
def action_extend_membership(self):
|
|
"""Process the membership extension"""
|
|
self.ensure_one()
|
|
|
|
if self.extension_days <= 0:
|
|
raise UserError(_('Extension days must be greater than 0.'))
|
|
|
|
if self.extension_amount <= 0:
|
|
raise UserError(_('Extension amount must be greater than 0.'))
|
|
|
|
sale_order = self._create_extension_sale_order()
|
|
|
|
self.membership_id.complete_extension(
|
|
days_extended=self.extension_days,
|
|
extension_amount=self.extension_amount,
|
|
sale_order_id=sale_order.id
|
|
)
|
|
|
|
if self.extension_type == 'new_plan' and self.new_membership_plan_id:
|
|
self.membership_id.membership_scheme_id = self.new_membership_plan_id.id
|
|
|
|
return {
|
|
'name': _('Extension Sale Order'),
|
|
'type': 'ir.actions.act_window',
|
|
'res_model': 'sale.order',
|
|
'res_id': sale_order.id,
|
|
'view_mode': 'form',
|
|
'target': 'current',
|
|
}
|
|
|
|
def _create_extension_sale_order(self):
|
|
"""Create sale order for membership extension using a service product"""
|
|
|
|
extension_product = self._get_or_create_extension_service_product()
|
|
|
|
if self.extension_type == 'new_plan' and self.new_membership_plan_id:
|
|
product_name = f"Membership Extension - {self.new_membership_plan_id.name} ({self.extension_days} days)"
|
|
elif self.extension_type == 'same_plan':
|
|
product_name = f"Membership Extension - {self.membership_id.membership_scheme_id.name} ({self.extension_days} days)"
|
|
else:
|
|
product_name = f"Membership Extension - {self.extension_days} days"
|
|
|
|
sale_order_vals = {
|
|
'partner_id': self.member_id.id,
|
|
'date_order': fields.Datetime.now(),
|
|
'origin': f'Extension of {self.membership_id.reference}',
|
|
'order_line': [(0, 0, {
|
|
'product_id': extension_product.id,
|
|
'name': product_name,
|
|
'product_uom_qty': 1,
|
|
'price_unit': self.extension_amount,
|
|
})]
|
|
}
|
|
|
|
sale_order = self.env['sale.order'].create(sale_order_vals)
|
|
return sale_order
|
|
|
|
def _get_or_create_extension_service_product(self):
|
|
"""Get or create a generic service product for extensions (NOT a membership product)"""
|
|
|
|
extension_product = self.env['product.product'].search([
|
|
('name', '=', 'Membership Extension Service'),
|
|
('type', '=', 'service'),
|
|
('membership_date_from', '=', False),
|
|
('membership_date_to', '=', False)
|
|
], limit=1)
|
|
|
|
if not extension_product:
|
|
extension_product = self.env['product.product'].create({
|
|
'name': 'Membership Extension Service',
|
|
'type': 'service',
|
|
'list_price': 0.0,
|
|
'sale_ok': True,
|
|
'purchase_ok': False,
|
|
})
|
|
|
|
return extension_product
|