super_calendar_configurator.py 6.88 KB
Newer Older
François C. committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
# -*- coding: utf-8 -*-
##############################################################################
#
#    Odoo, Open Source Management Solution
#
#    Copyright (c) All rights reserved:
#        (c) 2012      Agile Business Group sagl (<http://www.agilebg.com>)
#        (c) 2012      Domsense srl (<http://www.domsense.com>)
#        (c) 2015      Anubía, soluciones en la nube,SL (http://www.anubia.es)
#                      Alejandro Santana <alejandrosantana@anubia.es>
#        (c) 2015      Savoir-faire Linux <http://www.savoirfairelinux.com>)
#                      Agathe Mollé <agathe.molle@savoirfairelinux.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
#
##############################################################################

import logging
from datetime import datetime
from pytz import timezone, utc
from mako.template import Template
from openerp import _, api, exceptions, fields, models, tools
from openerp.tools.safe_eval import safe_eval


_logger = logging.getLogger(__name__)


class SuperCalendarConfigurator(models.Model):
    _name = 'super.calendar.configurator'

    name = fields.Char(
        string='Name',
        required=True,
    )
    line_ids = fields.One2many(
        comodel_name='super.calendar.configurator.line',
        inverse_name='configurator_id',
        string='Lines',
    )

    def _clear_super_calendar_records(self):
        """
        Remove old super_calendar records
        """
        super_calendar_pool = self.env['super.calendar']
        super_calendar_list = super_calendar_pool.search([])
        super_calendar_list.unlink()

    @api.multi
    def generate_calendar_records(self):
        """
        At every CRON execution, every 'super calendar' data is deleted and
        regenerated again.
        """

        # Remove old records
        self._clear_super_calendar_records()

        # Rebuild all calendar records
        configurator_list = self.search([])
        for configurator in configurator_list:
            for line in configurator.line_ids:
                configurator._generate_record_from_line(line)
        _logger.info('Calendar generated')
        return True

    @api.multi
    def _generate_record_from_line(self, line):
        """
        Create super_calendar records from super_calendar_configurator_line
        objects.
        """
        super_calendar_pool = self.env['super.calendar']
        values = self._get_record_values_from_line(line)
        for record in values:
            super_calendar_pool.create(values[record])

    @api.multi
    def _get_record_values_from_line(self, line):
        """
        Get super_calendar fields values from super_calendar_configurator_line
        objects.
        Check if the User value is a res.users.
        """
        res = {}
        current_pool = self.env[line.name.model]
        domain = line.domain and safe_eval(line.domain) or []
        current_record_list = current_pool.search(domain)
        for cur_rec in current_record_list:
            f_user = line.user_field_id.name
            f_descr = line.description_field_id.name
            f_date_start = line.date_start_field_id.name
            f_date_stop = line.date_stop_field_id.name
            f_duration = line.duration_field_id.name

            # Check if f_user refer to a res.users
            if (f_user and cur_rec[f_user] and
                    cur_rec[f_user]._model._name != 'res.users'):
                raise exceptions.ValidationError(
                    _("The 'User' field of record %s (%s) "
                      "does not refer to res.users")
                    % (cur_rec[f_descr], line.name.model))

            if ((cur_rec[f_descr] or line.description_code) and
                    cur_rec[f_date_start]):
                duration = False

                if line.date_start_field_id.ttype == 'date':
                    date_format = tools.DEFAULT_SERVER_DATE_FORMAT
                else:
                    date_format = tools.DEFAULT_SERVER_DATETIME_FORMAT
                date_start = datetime.strptime(
                    cur_rec[f_date_start], date_format
                )

                if (not line.duration_field_id and
                        line.date_stop_field_id and
                        cur_rec[f_date_start] and
                        cur_rec[f_date_stop]):
                    if line.date_stop_field_id.ttype == 'date':
                        date_format = tools.DEFAULT_SERVER_DATE_FORMAT
                    else:
                        date_format = tools.DEFAULT_SERVER_DATETIME_FORMAT
                    date_stop = datetime.strptime(
                        cur_rec[f_date_stop], date_format
                    )
                    date_diff = (date_stop - date_start)
                    duration = date_diff.total_seconds() / 3600

                elif line.duration_field_id:
                    duration = cur_rec[f_duration]

                if line.description_type != 'code':
                    name = cur_rec[f_descr]
                else:
                    parse_dict = {'o': cur_rec}
                    mytemplate = Template(line.description_code)
                    name = mytemplate.render(**parse_dict)

                # Convert date_start to UTC timezone if it is a date field
                # in order to be stored in UTC in the database
                if line.date_start_field_id.ttype == 'date':
                    tz = timezone(self._context.get('tz')
                                  or self.env.user.tz
                                  or 'UTC')
                    local_date_start = tz.localize(date_start)
                    utc_date_start = local_date_start.astimezone(utc)
                    date_start = utc_date_start
                date_start = datetime.strftime(
                    date_start,
                    tools.DEFAULT_SERVER_DATETIME_FORMAT
                )

                super_calendar_values = {
                    'name': name,
                    'date_start': date_start,
                    'duration': duration,
                    'user_id': (f_user and cur_rec[f_user].id),
                    'configurator_id': self.id,
                    'res_id': line.name.model + ',' + str(cur_rec['id']),
                    'model_id': line.name.id,
                }
                res[cur_rec] = super_calendar_values
        return res