373 lines
17 KiB
Python
373 lines
17 KiB
Python
# -*- coding: utf-8 -*-
|
|
##############################################################################
|
|
#
|
|
# OpenERP, Open Source Management Solution
|
|
# Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (<http://www.devintellecs.com>).
|
|
#
|
|
# For Module Support : devintelle@gmail.com or Skype : devintelle
|
|
#
|
|
##############################################################################
|
|
|
|
from odoo import fields, models, api, _
|
|
from datetime import datetime
|
|
from dateutil.relativedelta import relativedelta
|
|
from odoo.exceptions import UserError, ValidationError
|
|
|
|
|
|
class DevMembership(models.Model):
|
|
_name = 'dev.membership'
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
_description = 'Dev Membership'
|
|
_order = 'name desc'
|
|
|
|
|
|
name = fields.Char(string='Name')
|
|
date = fields.Date(string="Request Date", tracking=3, required=1, default=lambda self: datetime.now().date())
|
|
from_date = fields.Date(string="Membership From Date", tracking=3, required=1, default=lambda *a: (datetime.now().date()))
|
|
to_date = fields.Date(string="Membership To Date", tracking=3)
|
|
request_date = fields.Date(string="Cancell Date", tracking=3,readonly=1)
|
|
partner_id = fields.Many2one('res.partner', string="Partner", domain="[('is_member', '=', True)]", tracking=2, required=1)
|
|
id_no = fields.Char(string='Identification Number',related='partner_id.identification_number',store=True)
|
|
phone = fields.Char(string='Phone',related='partner_id.phone',store=True)
|
|
email = fields.Char(string='Email',related='partner_id.email',store=True)
|
|
product_id = fields.Many2one('product.product', string="Membership Product", domain="[('is_membership', '=', True)]", tracking=2, required=1)
|
|
membership_fees = fields.Float(string="Membership Fees")
|
|
is_free = fields.Boolean(string="Is Free",related="product_id.is_free",)
|
|
company_id = fields.Many2one('res.company', string="Company", default=lambda self: self.env.company, required=1, tracking=3)
|
|
duration = fields.Integer(string="Duration",)
|
|
description = fields.Text(string="Description", related="product_id.description", readonly=False)
|
|
interval = fields.Selection(string="Interval", selection=([
|
|
('days', 'Days'),
|
|
('month', 'Month'),
|
|
('year', 'Year')]), default='year',required=1)
|
|
payment_state = fields.Selection(string='Payment State',related='invoice_id.payment_state')
|
|
state = fields.Selection(string="State", selection=([
|
|
('draft', 'Draft'),
|
|
('confirm', 'Confirm'),
|
|
('active', 'Active'),
|
|
('expire', 'Expire'),
|
|
('cancel', 'Cancel')]), default='draft', tracking=1)
|
|
membership_id = fields.Many2one('dev.membership', string='Renew Membership')
|
|
invoice_id = fields.Many2one('account.move', string='Invoice')
|
|
user_id = fields.Many2one('res.users', string='Resposible', default=lambda self:self.env.user)
|
|
cancel_reasone = fields.Many2one('cancellation.reason',string='Cancel Membership Reason')
|
|
membrship_level = fields.Many2one('membership.level', string='Membrship level',store=True,required=False,compute='_compute_membership_level')
|
|
|
|
|
|
@api.onchange('product_id')
|
|
def _onchange_membership_type(self):
|
|
if self.product_id:
|
|
if self.product_id.is_free:
|
|
self.membership_fees = 0
|
|
else:
|
|
self.membership_fees = self.product_id.list_price
|
|
self.duration = self.product_id.duration
|
|
self.interval = self.product_id.interval
|
|
|
|
|
|
@api.onchange('duration')
|
|
def _onchange_duration(self):
|
|
if self.duration and self.interval and self.membership_fees:
|
|
self.membership_fees = self.duration * self.product_id.list_price
|
|
|
|
|
|
|
|
|
|
|
|
@api.constrains('from_date')
|
|
def _check_from_date(self):
|
|
for rec in self:
|
|
if not rec.from_date >= datetime.now().date():
|
|
pass
|
|
# raise ValidationError("Membership date should be greater than or equal to today's date!!")
|
|
|
|
def make_activity_group(self):
|
|
# templet_id = self.env.ref('dev_membership.template_membership_cancell')
|
|
# templet2_id = self.env.ref('dev_membership.template_membership_cancell2')
|
|
date_deadline = fields.Date.today()
|
|
note=_('Membership %s is Cancelled') % self.name
|
|
|
|
summary = _("Membership Cancellation")
|
|
self.sudo().activity_schedule(
|
|
'mail.mail_activity_data_todo', date_deadline,
|
|
note=note,
|
|
user_id=self.partner_id.user_id.id,
|
|
res_id=self.id,
|
|
summary=summary
|
|
)
|
|
self.sudo().activity_schedule(
|
|
'mail.mail_activity_data_todo', date_deadline,
|
|
note=note,
|
|
user_id=self.user_id.id,
|
|
res_id=self.id,
|
|
summary=summary
|
|
)
|
|
|
|
@api.constrains('partner_id', 'from_date')
|
|
def _check_if_membership_exists(self):
|
|
membership_obj = self.env['dev.membership'].search([('partner_id.id', '=', self.partner_id.id), ('state', 'in', ['draft', 'active', 'confirm']), ('id', '!=', self.id)])
|
|
if membership_obj:
|
|
for rec in self:
|
|
for membership in membership_obj:
|
|
if rec.from_date < membership.to_date:
|
|
raise ValidationError(
|
|
_("You already have a membership from '%s' to '%s' !!!!") % (membership.from_date, membership.to_date))
|
|
|
|
@api.onchange('from_date', 'product_id', 'duration','interval')
|
|
def onchange_from_date(self):
|
|
if self.from_date and self.product_id:
|
|
if self.interval == 'year':
|
|
self.to_date = self.from_date + relativedelta(years=+self.duration) - relativedelta(days=1)
|
|
elif self.interval == 'month':
|
|
self.to_date = self.from_date + relativedelta(months=+self.duration) - relativedelta(days=1)
|
|
elif self.interval == 'days':
|
|
self.to_date = self.from_date + relativedelta(days=+self.duration)
|
|
def action_confirm_membership(self):
|
|
if self.product_id.nationality_ids:
|
|
if self.partner_id.nationality_id not in self.product_id.nationality_ids:
|
|
raise ValidationError(_("The member's nationality does not meet the membership requirements"))
|
|
if self.product_id.age > 0 and self.partner_id.age < self.product_id.age:
|
|
raise ValidationError(_('The member must be at least %s years old.') % self.product_id.age)
|
|
if self.product_id.max_age > 0 and self.partner_id.age > self.product_id.max_age:
|
|
raise ValidationError(_('The member must not be more than %s years old.') % self.product_id.max_age)
|
|
if self.product_id.gender and self.partner_id.gender != self.product_id.gender:
|
|
raise ValidationError(_('Membership is only %s allowed') % self.product_id.gender)
|
|
|
|
if self.membership_fees < (self.product_id.list_price * self.duration):
|
|
raise ValidationError(
|
|
_("Membership fees cannot be less than %s .") % (self.product_id.list_price * self.duration,))
|
|
if self.duration < self.product_id.duration:
|
|
raise ValidationError(
|
|
_("Duration cannot be less than the default value in Setting of membrship type.%s'") % self.product_id.duration)
|
|
self.state = 'confirm'
|
|
|
|
def action_active_membership(self):
|
|
# Search for the last membership of the partner
|
|
last_membership = self.env['dev.membership'].search([
|
|
('partner_id', '=', self.partner_id.id),
|
|
('state', '=', 'cancel')
|
|
], limit=1, order="to_date desc")
|
|
# Handle sequence generation for new or renewed memberships
|
|
sequence_code = 'membership.no.sequence'
|
|
if not self.invoice_id and not self.is_free:
|
|
raise ValidationError(_('Please Create Membership Invoice'))
|
|
if self.invoice_id.payment_state not in ['paid','in_payment'] and not self.is_free:
|
|
raise ValidationError(_('Membership Invoice is not paid.\nPlease pay the membership invoice and activate the membership.'))
|
|
else:
|
|
# Assuming you have a field to track payment state
|
|
self.payment_state = self.invoice_id.payment_state
|
|
if not self.partner_id.membrship_no or last_membership:
|
|
# Generate new sequence number if it's the first membership or it's a renewal after cancellation
|
|
self.partner_id.membrship_no = self.env['ir.sequence'].next_by_code(sequence_code) or _('New')
|
|
# else:
|
|
# if self.state=='confirm':
|
|
# self.partner_id.membrship_no = self.env['ir.sequence'].next_by_code(sequence_code) or _('New')
|
|
self.state = 'active'
|
|
self.partner_id.product_id = self.product_id.id
|
|
if not self.partner_id.join_date:
|
|
self.partner_id.join_date = self.from_date
|
|
if not self.partner_id.membrship_level:
|
|
self.partner_id.membrship_level = self.membrship_level
|
|
if not self.partner_id.memebership_end_date:
|
|
self.partner_id.memebership_end_date = self.to_date
|
|
|
|
|
|
def action_cancel_membership(self):
|
|
self.state = 'cancel'
|
|
|
|
def action_set_to_draft(self):
|
|
self.state = 'draft'
|
|
|
|
@api.model
|
|
def create(self, vals):
|
|
res = super(DevMembership, self).create(vals)
|
|
sequence = self.env['ir.sequence'].next_by_code('seq.dev.membership') or 'New'
|
|
res.name = sequence
|
|
return res
|
|
|
|
def unlink(self):
|
|
for rec in self:
|
|
if rec.state not in ('draft', 'cancel'):
|
|
raise UserError("You are not allowed to delete this record!!")
|
|
return super(DevMembership, self).unlink()
|
|
|
|
def membership_send_by_mail(self):
|
|
self.ensure_one()
|
|
template_id = self.env['ir.model.data'].xmlid_to_res_id('dev_membership.template_membership', raise_if_not_found=False)
|
|
ctx = {
|
|
'default_model': 'dev.membership',
|
|
'default_res_id': self.ids[0],
|
|
'default_use_template': bool(template_id),
|
|
'default_template_id': template_id,
|
|
'default_composition_mode': 'comment',
|
|
'force_email': True,
|
|
}
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'view_mode': 'form',
|
|
'res_model': 'mail.compose.message',
|
|
'views': [(False, 'form')],
|
|
'view_id': False,
|
|
'target': 'new',
|
|
'context': ctx,
|
|
}
|
|
|
|
def membership_auto_expire(self):
|
|
current_date = datetime.now().date()
|
|
membership_ids = self.env['dev.membership'].search([('state', '=', 'active'),
|
|
('to_date', '<=', current_date)])
|
|
template_id = self.env.ref('dev_membership.dev_membership_expired_mail_template')
|
|
for membership in membership_ids:
|
|
membership.state = 'expire'
|
|
#template_id.send_mail(membership.id, force_send=True)
|
|
if membership.user_id:
|
|
membership.message_post(
|
|
body=_("The Membership %s was expired on %s") % (membership.name,membership.to_date),
|
|
subject=_("Auto Expire Membership") ,
|
|
partner_ids=[membership.user_id.partner_id.id],
|
|
message_type='notification', #
|
|
author_id=self.env.user.partner_id.id,
|
|
)
|
|
|
|
def membership_reminder_email_cron(self):
|
|
membership_pool = self.env['dev.membership']
|
|
tmpl_id = self.env.ref('dev_membership.dev_membership_expire_reminder_mail_template')
|
|
days_before = self.env['ir.config_parameter'].get_param('dev_membership.days_before')
|
|
if tmpl_id:
|
|
date = datetime.now().date() + relativedelta(days=int(days_before))
|
|
membership_ids = membership_pool.search([('state', '=', 'active'),
|
|
('to_date', '=', date)])
|
|
|
|
for membership in membership_ids:
|
|
|
|
#tmpl_id.send_mail(membership.id, force_send=True)
|
|
|
|
if membership.user_id:
|
|
membership.message_post(
|
|
body=_("The Membership %s is about to expire on %s") % (membership.name,membership.to_date),
|
|
subject=_("Membership Expire Reminder") ,
|
|
partner_ids=[membership.user_id.partner_id.id],
|
|
message_type='notification',
|
|
author_id=self.env.user.partner_id.id,
|
|
)
|
|
|
|
def cancell2_membership_reminder_email_cron(self):
|
|
membership_pool = self.env['dev.membership']
|
|
post_expiry_period = self.env['ir.config_parameter'].get_param('dev_membership.post_expiry_period')
|
|
cancel_reason = self.env['ir.config_parameter'].get_param('dev_membership.cancellation_reason')
|
|
if post_expiry_period:
|
|
try:
|
|
post_expiry_period = int(post_expiry_period)
|
|
except ValueError:
|
|
post_expiry_period = 0
|
|
|
|
date = fields.Date.today() - relativedelta(days=int(post_expiry_period))
|
|
membership_ids = membership_pool.search([
|
|
('state', '=', 'expire'),
|
|
('to_date', '=', date),('membership_id','=',False)
|
|
])
|
|
for membership in membership_ids:
|
|
existing_cancel_request = self.env['membership.cancellation.request'].search([
|
|
('membership_id', '=', membership.id),
|
|
('state', '=', 'draft')
|
|
], limit=1)
|
|
if not existing_cancel_request:
|
|
self.env['membership.cancellation.request'].create({
|
|
'membership_id': membership.id,
|
|
'member_id': membership.partner_id.id,
|
|
'request_date': fields.Datetime.now(),
|
|
'state': 'draft',
|
|
'cancel_reason': cancel_reason
|
|
})
|
|
|
|
return True
|
|
|
|
def membership_secand_reminder_email_cron(self):
|
|
membership_pool = self.env['dev.membership']
|
|
tmpl_id = self.env.ref('dev_membership.dev_membership_expire_second_reminder_mail_template')
|
|
days_before_second = self.env['ir.config_parameter'].get_param('dev_membership.days_before_second')
|
|
if tmpl_id and days_before_second:
|
|
try:
|
|
days_before_second = int(days_before_second)
|
|
except ValueError:
|
|
days_before_second = 0
|
|
|
|
date = datetime.now().date() + relativedelta(days=days_before_second)
|
|
membership_ids = membership_pool.search([
|
|
('state', '=', 'active'),
|
|
('to_date', '=', date)
|
|
])
|
|
for membership in membership_ids:
|
|
#tmpl_id.send_mail(membership.id, force_send=True)
|
|
if membership.user_id:
|
|
membership.message_post(
|
|
body=_("The Membership %s is about to expire on %s") % (membership.name,membership.to_date),
|
|
subject=_("Membership Expire Reminder") ,
|
|
partner_ids=[membership.user_id.partner_id.id],
|
|
message_type='notification',
|
|
author_id=self.env.user.partner_id.id,
|
|
)
|
|
return True
|
|
|
|
def datetime_convert(self):
|
|
convert_date = self.to_date.strftime("%d-%m-%Y")
|
|
return convert_date
|
|
|
|
def create_membership_invoice(self):
|
|
vals= {'move_type': 'out_invoice',
|
|
'partner_id': self.partner_id.id,
|
|
'ref':self.name,
|
|
'invoice_line_ids': [
|
|
(0, None, {'product_id': self.product_id.id, 'quantity': 1, 'price_unit': self.membership_fees, 'tax_ids': [(6, 0, self.product_id.taxes_id.ids)]})
|
|
]
|
|
}
|
|
invoice_id = self.env['account.move'].create(vals)
|
|
self.invoice_id = invoice_id and invoice_id.id or False
|
|
|
|
|
|
@api.depends('membership_fees','duration')
|
|
def _compute_membership_level(self):
|
|
for record in self:
|
|
total_fees = record.membership_fees
|
|
total_duration = record.duration
|
|
memberships = self.env['dev.membership'].search([
|
|
('id', '!=', record.id),
|
|
('partner_id', '=', record.partner_id.id),
|
|
('to_date', '<', record.from_date),
|
|
('state', 'in', [['expire','active','cancel']])])
|
|
for membership in memberships:
|
|
total_fees += membership.membership_fees
|
|
total_duration += membership.duration
|
|
level_by_fees = self.env['membership.level'].search([ ('min', '<=', total_fees),('years', '<=', total_duration)], limit=1, order='sequence desc')
|
|
if level_by_fees:
|
|
record.membrship_level = level_by_fees
|
|
|
|
def view_invoice(self):
|
|
if self.invoice_id:
|
|
ctx = dict(create=False)
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': 'Invoice',
|
|
'res_model': 'account.move',
|
|
'domain': [('id', '=', self.invoice_id.id)],
|
|
'view_mode': 'tree,form',
|
|
'target': 'current',
|
|
'context': ctx,
|
|
}
|
|
|
|
|
|
def view_membership(self):
|
|
if self.membership_id:
|
|
ctx = dict(create=False)
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': 'Membership',
|
|
'res_model': 'dev.membership',
|
|
'domain': [('id', '=', self.membership_id.id)],
|
|
'view_mode': 'tree,form',
|
|
'target': 'current',
|
|
'context': ctx,
|
|
}
|
|
|
|
|