forked from Yaltik/golem
305 lines
12 KiB
Python
305 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 '_________read call _______________'
|
|
print 'load'
|
|
print load
|
|
print self.ids
|
|
fields2 = fields and fields[:] or None
|
|
select = map(lambda x: (x, self.calendar_id2real_id(x)), self.ids)
|
|
print '_____________________<<'
|
|
print select
|
|
print '>>_____________________'
|
|
real_events = self.browse([real_id for calendar_id, real_id in select])
|
|
#print real_events
|
|
#print " calendar_id n:1 : "+ str(calendar_id)
|
|
#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 real_data
|
|
result = []
|
|
#print " calendar_id n:3 : "+ str(calendar_id)
|
|
for calendar_id, real_id in select:
|
|
#print "cal"
|
|
#print calendar_id
|
|
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['date_stop'] = str(dt)
|
|
#print " calendar_id n:4 : "+ str(calendar_id)
|
|
res['id'] = calendar_id
|
|
|
|
|
|
#res['date_start'] = date_start[1]
|
|
result.append(res)
|
|
#print 'resuuuuuuuuuuuuuult'
|
|
#print result
|
|
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 get_metadata(self):
|
|
real = self.browse(set({x: self.calendar_id2real_id(x) for x in self.ids}.values()))
|
|
return super(GolemActivity, real).get_metadata()
|
|
@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())
|
|
#print "àààààààààààààààààààààààààààààààààààààààà"
|
|
#print activities.mapped('id')
|
|
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)
|