odex25_standard/odex25_sales/dev_membership/models/dev_membership.py

341 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'
membrship_level = fields.Many2one('membership.level',string='Membrship level',store=True,required=False,compute='_compute_membership_level')
name = fields.Char(string='Name', readonly=1)
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)
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", related="product_id.interval")
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')
@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)
@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('membership_fees')
def _check_subscription_fee(self):
for record in self:
if record.product_id.duration and record.membership_fees < record.product_id.list_price :
raise ValidationError(_('Membership fees cannot be less than the default value in Setting of membrship type.'))
# elif record.product_id.duration>1 and record.membership_fees*record.duration < record.product_id.list_price*record.duration :
# raise ValidationError(_('Membership fees cannot be less than the default value in Setting of membrship type.'))
@api.constrains('duration')
def _check_duration(self):
for record in self:
if record.duration < record.product_id.duration:
raise ValidationError(_('Duration cannot be less than the default value in Setting of membrship type.'))
@api.constrains('from_date')
def _check_from_date(self):
for rec in self:
if not rec.from_date >= datetime.now().date():
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.partner_id.gender != self.product_id.gender and self.product_id.gender != False:
raise ValidationError(_('Membership is only %s allowed') % self.product_id.gender)
self.state = 'confirm'
def action_active_membership(self):
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
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)
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)
return True
def cancell_membership_reminder_email_cron(self):
membership_pool = self.env['dev.membership']
tmpl_id = self.env.ref('dev_membership.dev_cancel_membership_expire')
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 tmpl_id and post_expiry_period:
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:
membership.write({
'state': 'cancel',
'cancel_reason': cancel_reason
})
tmpl_id.send_mail(membership.id, force_send=True)
return True
def cancell2_membership_reminder_email_cron(self):
membership_pool = self.env['dev.membership']
tmpl_id = self.env.ref('dev_membership.dev_cancel_membership_expire2')
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 tmpl_id and post_expiry_period:
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:
membership.write({
'state': 'cancel',
'cancel_reason': cancel_reason
})
tmpl_id.send_mail(membership.id, force_send=True)
return True
def cancell_membership_reminder_email_cron(self):
membership_pool = self.env['dev.membership']
tmpl_id = self.env.ref('dev_membership.dev_cancel_membership_expire')
post_expiry_period = self.env['ir.config_parameter'].get_param('dev_membership.post_expiry_period')
if tmpl_id:
date = self.to_date+ relativedelta(days=int(post_expiry_period))
membership_ids = membership_pool.search([('state', '=', 'expire'),
('to_date', '<=', date)])
for membership in membership_ids:
tmpl_id.send_mail(membership.id, force_send=True)
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:
date = datetime.now().date() + relativedelta(days=int(days_before_second))
membership_ids = membership_pool.search([('state', '=', 'active'),
('to_date', '<=', days_before_second)])
for membership in membership_ids:
tmpl_id.send_mail(membership.id, force_send=True)
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,
'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:
memberships = self.env['dev.membership'].search([('partner_id', '=', record.partner_id.id),('payment_state', 'in', ['paid','in_payment'])])
total_fees = sum(membership.membership_fees for membership in memberships)+record.membership_fees
total_duration = sum(membership.duration for membership in memberships)+record.duration
# البحث عن مستوى العضوية بناءً على إجمالي الرسوم
level_by_fees = self.env['membership.level'].search([
('min', '<=', total_fees),
('max', '>=', total_fees),('years', '<=',total_duration)
],order='sequence desc',limit=1)
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,
}