GOLEM/golem_activity/models/golem_activity.py

293 lines
12 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2017 Fabien Bourgeois <fabien@yaltik.com>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
""" GOLEM activities related models """
import collections
from datetime import datetime, timedelta
from dateutil import parser
#from dateutil import rrule
from dateutil.rrule import WEEKLY, rrule
from dateutil.relativedelta import relativedelta
from odoo import models, fields, api, _
from datetime import timedelta
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
#from dateutil import rrule
#from dateutil.rrule import rrule
#from dateutil.rrule import rrule
class GolemActivityType(models.Model):
""" GOLEM Activity Type """
_name = 'golem.activity.type'
_description = 'GOLEM Activity Type'
_sql_constraints = [('golem_activity_type_name_uniq', 'UNIQUE (name)',
_('This activity type name has already been used.'))]
name = fields.Char('Activity type', required=True, translate=True)
is_recurrent = fields.Boolean('Is recurrent?')
class GolemActivity(models.Model):
""" GOLEM Activity """
_name = 'golem.activity'
_description = 'GOLEM Activity'
_inherit = 'mail.thread'
_inherits = {'product.template': 'product_id'}
_rec_name = 'full_name'
product_id = fields.Many2one('product.template', required=True,
ondelete='cascade')
image = fields.Binary(help='This field holds the image used as image for '
'the activity.')
full_name = fields.Char('Name', compute='_compute_full_name', store=True,
index=True)
is_fullseason = fields.Boolean('Is full season?',
compute='_compute_is_full_season')
@api.onchange('is_fullseason')
def onchange_fullseason(self):
""" Sets dates as season ones if needed """
for activity in self:
if activity.is_fullseason:
if activity.season_id.date_start:
activity.date_start = activity.season_id.date_start
if activity.season_id.date_end:
activity.date_stop = activity.season_id.date_end
@api.depends('date_start', 'date_stop')
def _compute_is_full_season(self):
""" Display date for is full season """
for activity in self:
if activity.date_start == activity.season_id.date_start and \
activity.date_stop == activity.season_id.date_end:
activity.is_fullseason = True
@api.depends('name', 'default_code')
def _compute_full_name(self):
""" Provide a better displayed name """
for activity in self:
full_name = unicode(activity.name)
if activity.default_code:
full_name = u'[{}] {}'.format(activity.default_code, full_name)
activity.full_name = full_name
@api.model
def _default_season(self):
""" Get default season """
domain = [('is_default', '=', True)]
return self.env['golem.season'].search(domain)
season_id = fields.Many2one('golem.season', string='Season', copy=False,
required=True, default=_default_season,
ondelete='restrict')
is_current = fields.Boolean('Current season?', store=True, default=False,
compute='compute_is_current')
@api.depends('season_id')
def compute_is_current(self):
""" Checks if activity is active for current season """
default_season = self._default_season()
for activity in self:
activity.is_current = (default_season == activity.season_id)
animator_id = fields.Many2one('res.partner', string='Animator',
domain=[('is_company', '=', False)])
categ_id = fields.Many2one('product.category',
help='Select category for the current activity')
type_id = fields.Many2one('golem.activity.type', required=True, index=True,
string='Type')
is_recurrent = fields.Boolean(related='type_id.is_recurrent')
date_start = fields.Date('Start date', copy=False)
date_stop = fields.Date('End date', copy=False)
@api.onchange('date_start')
def _onchange_date_start(self):
""" Sets end date to start date if no start date """
for activity in self:
if not activity.date_stop:
activity.date_stop = activity.date_start
@api.constrains('date_start', 'date_stop')
def _check_period(self):
""" Checks if end date if after start date """
for activity in self:
season = activity.season_id
if activity.date_start and activity.date_stop and \
activity.date_start > activity.date_stop:
raise models.ValidationError(_('Start of the period cannot be '
'after end of the period.'))
if season.date_start and season.date_start > activity.date_start:
msg = _(u'Activity start date can not be set before '
'linked season start.')
raise models.ValidationError(msg)
if season.date_end and season.date_end < activity.date_stop:
msg = _(u'Activity end date can not be set after '
'linked season end.')
raise models.ValidationError(msg)
@api.onchange('season_id')
def _onchange_season_dates(self):
""" Sets defaults dates according to season """
for activity in self:
if activity.season_id:
if not activity.date_start:
activity.date_start = activity.season_id.date_start
if not activity.date_stop:
activity.date_stop = activity.season_id.date_end
weekday = fields.Selection([(0, _('Monday')),
(1, _('Tuesday')),
(2, _('Wednesday')),
(3, _('Thursday')),
(4, _('Friday')),
(5, _('Saturday')),
(6, _('Sunday'))], copy=False)
hour_start = fields.Float('Start time', copy=False)
hour_stop = fields.Float('Stop time', copy=False)
@api.onchange('hour_start')
def _onchange_hour_start(self):
""" Sets end hour to start hour if no start hour """
for activity in self:
if activity.hour_start and not activity.hour_stop:
activity.hour_stop = activity.hour_start + 1
@api.constrains('hour_start', 'hour_stop')
def _check_hour_period(self):
""" Check if end hour if after start hour """
for activity in self:
if activity.hour_start > activity.hour_stop:
raise models.ValidationError(_('Start of the period cannot be '
'after end of the period.'))
###########################################
##########################################
@api.multi
def read(self, fields=None, load='_classic_read'):
#print '________________________'
#print self.ids
fields2 = fields and fields[:] or None
select = map(lambda x: (x, self.calendar_id2real_id(x)), self.ids)
print select
real_events = self.browse([real_id for calendar_id, real_id in select])
#verify that attribute of real id is working after next statement
real_data = super(GolemActivity, real_events).read(fields=fields2, load=load)
real_data = dict((d['id'], d) for d in real_data)
#print '------------------------------------'
#print real_data
#print '------------------------------------'
#print real_events
#print '------------------------------------'
result = []
for calendar_id, real_id in select:
res = real_data[real_id].copy()
date_start = str(calendar_id).split('_')
if len(date_start) == 2:
dt = datetime.strptime(date_start[1],DEFAULT_SERVER_DATETIME_FORMAT).date()# "%y-%m-%d %H:%M:%S")
res['date_start'] = str(dt)
res['id'] = calendar_id
#res['date_start'] = date_start[1]
result.append(res)
return result
"""print res
print '_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_'
print calendar_id
print '_*_*_*_*_*_*_*_*_*_*_*_*_*_*_*_'
print real_id"""
#ls = self.calendar_id2real_id(calendar_id, with_date=res and res.get('duration', 0) > 0 and res.get('duration') or 1)
"""for calendar_id, real_id in select:
print calendar_id
print real_id"""
#for id in self.ids:
# print self.env['golem.activity'].browse(id)
#return super(GolemActivity, self).read(self, fields=None, load='_classic_read')
@api.multi
def calendar_id2real_id(self, calendar_id=None):
if calendar_id and isinstance(calendar_id, (basestring)):
res = filter(None, calendar_id.split('_'))
if len(res) == 2:
real_id = res[0]
return int(real_id)
return calendar_id and int(calendar_id) or calendar_id
@api.multi
def real_id2calendar_id(self, record_id):
""" convert Real Id to Calendar ID """
activity = self.env['golem.activity'].browse(record_id)
date_start = fields.Date.from_string(activity.date_start)
date_stop = fields.Date.from_string(activity.date_stop)
weekday = 0#date_start.weekday()
if activity.weekday:
weekday = activity.weekday
print '_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-'
print weekday
list_date = list(rrule(freq=WEEKLY, dtstart=date_start, until=date_stop, byweekday=weekday))
calendar_ids = []
for date in list_date:
calendar_ids.append('%s_%s' % (record_id, date))
print '_______________________________________________'
print calendar_ids
return calendar_ids
@api.multi
def get_recurrent_ids(self):
result = []
for activity in self:
print '___________________tktk______'
#if not meeting.recurrency or not meeting.rrule:
if activity.is_recurrent:
result += activity.real_id2calendar_id(activity.id)
else:
result.append(activity.id)
return result
@api.model
def search(self, args, offset=0, limit=0, order=None, count=False):
activities = super(GolemActivity, self).search(args, offset=0, limit=0, order=None, count=False)
activities = self.browse(activities.get_recurrent_ids())
return activities
class ProductTemplate(models.Model):
""" GOLEM Activity Product adaptations """
_inherit = 'product.template'
type = fields.Selection(default='service')
default_code = fields.Char(copy=True)
categ_id = fields.Many2one(copy=True)