2016-06-27 12:38:08 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2018-07-17 09:33:56 +02:00
|
|
|
# Copyright 2017-2018 Fabien Bourgeois <fabien@yaltik.com>
|
2016-06-27 12:38:08 +02:00
|
|
|
#
|
|
|
|
# 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/>.
|
|
|
|
|
2017-05-01 17:49:21 +02:00
|
|
|
""" GOLEM activities related models """
|
|
|
|
|
2018-08-03 10:34:36 +02:00
|
|
|
import logging
|
2017-04-29 09:16:41 +02:00
|
|
|
from odoo import models, fields, api, _
|
2018-08-03 10:34:36 +02:00
|
|
|
_LOGGER = logging.getLogger(__name__)
|
2016-06-27 12:38:08 +02:00
|
|
|
|
2017-06-05 11:22:34 +02:00
|
|
|
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?')
|
2016-06-27 12:38:08 +02:00
|
|
|
|
2018-02-01 16:00:42 +01:00
|
|
|
|
2018-07-17 09:33:56 +02:00
|
|
|
class GolemActivityAudience(models.Model):
|
|
|
|
""" GOLEM Activity Audience """
|
|
|
|
_name = 'golem.activity.audience'
|
|
|
|
_description = 'GOLEM Activity Audience'
|
|
|
|
|
|
|
|
_sql_constraints = [('golem_activity_audience_name_uniq', 'UNIQUE (name)',
|
|
|
|
_('This activity audience name has already been used.'))]
|
|
|
|
|
|
|
|
name = fields.Char('Activity audience', required=True, translate=True)
|
|
|
|
|
|
|
|
|
2016-06-27 12:38:08 +02:00
|
|
|
class GolemActivity(models.Model):
|
2017-05-01 17:49:21 +02:00
|
|
|
""" GOLEM Activity """
|
2016-06-27 12:38:08 +02:00
|
|
|
_name = 'golem.activity'
|
|
|
|
_description = 'GOLEM Activity'
|
|
|
|
_inherit = 'mail.thread'
|
2016-10-10 16:25:55 +02:00
|
|
|
_inherits = {'product.template': 'product_id'}
|
2018-08-09 11:27:24 +02:00
|
|
|
_order = 'default_code, name, id'
|
2016-10-10 16:25:55 +02:00
|
|
|
_rec_name = 'full_name'
|
2016-07-08 21:49:21 +02:00
|
|
|
|
2016-10-10 16:25:55 +02:00
|
|
|
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)
|
2018-02-01 17:02:39 +01:00
|
|
|
is_fullseason = fields.Boolean('Is full season?',
|
2018-02-01 17:16:19 +01:00
|
|
|
compute='_compute_is_full_season')
|
2018-07-17 09:33:56 +02:00
|
|
|
location = fields.Char()
|
2018-07-20 10:09:24 +02:00
|
|
|
audience_id = fields.Many2one('golem.activity.audience', string='Audience',
|
|
|
|
index=True, auto_join=True)
|
2018-02-01 17:02:39 +01:00
|
|
|
|
2018-03-08 11:06:53 +01:00
|
|
|
@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
|
|
|
|
|
2018-02-01 17:02:39 +01:00
|
|
|
@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:
|
2018-02-01 17:16:19 +01:00
|
|
|
activity.is_fullseason = True
|
2016-10-10 16:25:55 +02:00
|
|
|
|
|
|
|
@api.depends('name', 'default_code')
|
|
|
|
def _compute_full_name(self):
|
|
|
|
""" Provide a better displayed name """
|
2017-05-01 17:49:21 +02:00
|
|
|
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
|
2016-10-10 16:25:55 +02:00
|
|
|
|
2016-07-10 07:39:38 +02:00
|
|
|
@api.model
|
2018-07-20 10:09:24 +02:00
|
|
|
def default_season(self):
|
2016-07-10 07:39:38 +02:00
|
|
|
""" Get default season """
|
|
|
|
domain = [('is_default', '=', True)]
|
|
|
|
return self.env['golem.season'].search(domain)
|
|
|
|
|
|
|
|
season_id = fields.Many2one('golem.season', string='Season', copy=False,
|
2018-07-20 10:09:24 +02:00
|
|
|
required=True, default=default_season,
|
|
|
|
index=True, auto_join=True,
|
2016-07-11 07:25:09 +02:00
|
|
|
ondelete='restrict')
|
2018-07-20 10:09:24 +02:00
|
|
|
is_default = fields.Boolean('Default season?',
|
|
|
|
compute='_compute_is_default',
|
|
|
|
search='_search_is_default')
|
2016-10-10 16:25:55 +02:00
|
|
|
|
|
|
|
@api.depends('season_id')
|
2018-07-20 10:09:24 +02:00
|
|
|
def _compute_is_default(self):
|
|
|
|
""" Checks if activity is active for default season """
|
|
|
|
default_season = self.default_season()
|
2017-05-01 17:49:21 +02:00
|
|
|
for activity in self:
|
2018-07-20 10:09:24 +02:00
|
|
|
activity.is_default = (default_season == activity.season_id)
|
|
|
|
|
|
|
|
@api.multi
|
|
|
|
def _search_is_default(self, operator, value):
|
|
|
|
""" Search function for is default """
|
|
|
|
if operator in ('in', '='):
|
|
|
|
operator = '=' if value else '!='
|
|
|
|
elif operator in ('not in', '!='):
|
|
|
|
operator = '!=' if value else '='
|
|
|
|
else:
|
|
|
|
err = _('Unsupported operator for defautl season search')
|
|
|
|
raise NotImplementedError(err)
|
|
|
|
return [('season_id', operator, self.default_season().id)]
|
2016-10-10 16:25:55 +02:00
|
|
|
|
2016-06-28 19:56:27 +02:00
|
|
|
animator_id = fields.Many2one('res.partner', string='Animator',
|
2018-07-20 10:09:24 +02:00
|
|
|
index=True, auto_join=True,
|
2016-06-27 17:53:10 +02:00
|
|
|
domain=[('is_company', '=', False)])
|
2017-06-05 11:22:34 +02:00
|
|
|
type_id = fields.Many2one('golem.activity.type', required=True, index=True,
|
2018-07-20 10:09:24 +02:00
|
|
|
auto_join=True, string='Type')
|
2017-06-05 11:22:34 +02:00
|
|
|
is_recurrent = fields.Boolean(related='type_id.is_recurrent')
|
2016-07-05 15:39:15 +02:00
|
|
|
date_start = fields.Date('Start date', copy=False)
|
2016-10-10 16:25:55 +02:00
|
|
|
date_stop = fields.Date('End date', copy=False)
|
|
|
|
|
|
|
|
@api.onchange('date_start')
|
2017-05-01 17:49:21 +02:00
|
|
|
def _onchange_date_start(self):
|
2016-10-10 16:25:55 +02:00
|
|
|
""" Sets end date to start date if no start date """
|
2017-05-01 17:49:21 +02:00
|
|
|
for activity in self:
|
|
|
|
if not activity.date_stop:
|
|
|
|
activity.date_stop = activity.date_start
|
2016-06-27 12:38:08 +02:00
|
|
|
|
2016-10-10 16:25:55 +02:00
|
|
|
@api.constrains('date_start', 'date_stop')
|
2016-06-27 12:38:08 +02:00
|
|
|
def _check_period(self):
|
2017-05-01 17:49:21 +02:00
|
|
|
""" Checks if end date if after start date """
|
|
|
|
for activity in self:
|
2018-02-27 18:49:08 +01:00
|
|
|
season = activity.season_id
|
2017-05-01 17:49:21 +02:00
|
|
|
if activity.date_start and activity.date_stop and \
|
|
|
|
activity.date_start > activity.date_stop:
|
2016-06-27 12:38:08 +02:00
|
|
|
raise models.ValidationError(_('Start of the period cannot be '
|
|
|
|
'after end of the period.'))
|
2018-02-27 18:49:08 +01:00
|
|
|
if season.date_start and season.date_start > activity.date_start:
|
2018-02-01 17:26:47 +01:00
|
|
|
msg = _(u'Activity start date can not be set before '
|
|
|
|
'linked season start.')
|
2018-01-29 22:55:36 +01:00
|
|
|
raise models.ValidationError(msg)
|
2018-02-27 18:49:08 +01:00
|
|
|
if season.date_end and season.date_end < activity.date_stop:
|
2018-02-01 17:26:47 +01:00
|
|
|
msg = _(u'Activity end date can not be set after '
|
2018-02-01 17:40:49 +01:00
|
|
|
'linked season end.')
|
2018-01-29 22:55:36 +01:00
|
|
|
raise models.ValidationError(msg)
|
2018-01-29 22:57:03 +01:00
|
|
|
|
2016-06-27 12:38:08 +02:00
|
|
|
@api.onchange('season_id')
|
2017-05-01 17:49:21 +02:00
|
|
|
def _onchange_season_dates(self):
|
2016-06-27 12:38:08 +02:00
|
|
|
""" Sets defaults dates according to season """
|
2017-05-01 17:49:21 +02:00
|
|
|
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
|
2016-06-27 12:38:08 +02:00
|
|
|
|
2016-10-10 16:25:55 +02:00
|
|
|
weekday = fields.Selection([('mon', _('Monday')),
|
|
|
|
('tue', _('Tuesday')),
|
|
|
|
('wed', _('Wednesday')),
|
|
|
|
('thu', _('Thursday')),
|
|
|
|
('fri', _('Friday')),
|
|
|
|
('sat', _('Saturday')),
|
|
|
|
('sun', _('Sunday'))], copy=False)
|
|
|
|
hour_start = fields.Float('Start time', copy=False)
|
2016-10-26 09:39:59 +02:00
|
|
|
hour_stop = fields.Float('Stop time', copy=False)
|
2018-08-09 15:47:57 +02:00
|
|
|
hour_start_display = fields.Char('Hour start',
|
|
|
|
compute='_compute_hour_start_display')
|
|
|
|
|
|
|
|
@api.depends('hour_start')
|
|
|
|
def _compute_hour_start_display(self):
|
|
|
|
""" Computes datetime from day hour start """
|
|
|
|
for activity in self:
|
|
|
|
activity.hour_start_display = (activity.hour_start if
|
|
|
|
activity.hour_start else u'')
|
2016-06-27 12:38:08 +02:00
|
|
|
|
2016-10-10 16:25:55 +02:00
|
|
|
@api.onchange('hour_start')
|
2017-05-01 17:49:21 +02:00
|
|
|
def _onchange_hour_start(self):
|
2016-10-10 16:25:55 +02:00
|
|
|
""" Sets end hour to start hour if no start hour """
|
2017-05-01 17:49:21 +02:00
|
|
|
for activity in self:
|
|
|
|
if activity.hour_start and not activity.hour_stop:
|
|
|
|
activity.hour_stop = activity.hour_start + 1
|
2016-10-10 16:25:55 +02:00
|
|
|
|
2016-10-26 09:39:59 +02:00
|
|
|
@api.constrains('hour_start', 'hour_stop')
|
2016-10-10 16:25:55 +02:00
|
|
|
def _check_hour_period(self):
|
|
|
|
""" Check if end hour if after start hour """
|
2017-05-01 17:49:21 +02:00
|
|
|
for activity in self:
|
|
|
|
if activity.hour_start > activity.hour_stop:
|
2016-10-10 16:25:55 +02:00
|
|
|
raise models.ValidationError(_('Start of the period cannot be '
|
|
|
|
'after end of the period.'))
|
|
|
|
|
|
|
|
|
|
|
|
class ProductTemplate(models.Model):
|
2017-05-01 17:49:21 +02:00
|
|
|
""" GOLEM Activity Product adaptations """
|
2016-10-10 16:25:55 +02:00
|
|
|
_inherit = 'product.template'
|
|
|
|
|
|
|
|
type = fields.Selection(default='service')
|
|
|
|
default_code = fields.Char(copy=True)
|
2017-06-20 16:41:22 +02:00
|
|
|
categ_id = fields.Many2one(copy=True)
|
2018-08-03 10:34:36 +02:00
|
|
|
|
|
|
|
|
|
|
|
class ProductCategory(models.Model):
|
|
|
|
""" Product Category adaptations """
|
|
|
|
_inherit = 'product.category'
|
|
|
|
|
|
|
|
property_account_income_categ_id = fields.Many2one(required=True)
|
|
|
|
property_account_expense_categ_id = fields.Many2one(required=True)
|