diff --git a/__unported__/super_calendar/AUTHORS.txt b/__unported__/super_calendar/AUTHORS.txt deleted file mode 100644 index 7106ca0eb..000000000 --- a/__unported__/super_calendar/AUTHORS.txt +++ /dev/null @@ -1 +0,0 @@ -Lorenzo Battistini diff --git a/__unported__/super_calendar/__openerp__.py b/__unported__/super_calendar/__openerp__.py deleted file mode 100644 index 7be936373..000000000 --- a/__unported__/super_calendar/__openerp__.py +++ /dev/null @@ -1,88 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Copyright (C) 2012 Agile Business Group sagl () -# Copyright (C) 2012 Domsense srl () -# -# 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 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 . -# -############################################################################## -{ - 'name': "Super Calendar", - 'version': '0.1', - 'category': 'Generic Modules/Others', - 'summary': 'This module allows to create configurable calendars.', - 'description': """ -This module allows to create configurable calendars. - -Through the 'calendar configurator' object, you can specify which models have -to be merged in the super calendar. For each model, you have to define the -'description' and 'date_start' fields at least. Then you can define 'duration' -and the 'user_id' fields. - -The 'super.calendar' object contains the the merged calendars. The -'super.calendar' can be updated by 'ir.cron' or manually. - -Configuration -============= - -After installing the module you can go to - -Super calendar → Configuration → Configurators - -and create a new configurator. For instance, if you want to see meetings and -phone calls, you can create the following lines - -.. image:: http://planet.domsense.com/wp-content/uploads/2012/04/meetings.png - :width: 400 px - -.. image:: http://planet.domsense.com/wp-content/uploads/2012/04/phone_calls.png - :width: 400 px - -Then, you can use the ‘Generate Calendar’ button or wait for the scheduled -action (‘Generate Calendar Records’) to be run. - -When the calendar is generated, you can visualize it by the ‘super calendar’ main menu. - -Here is a sample monthly calendar: - -.. image:: http://planet.domsense.com/wp-content/uploads/2012/04/month_calendar.png - :width: 400 px - -And here is the weekly one: - -.. image:: http://planet.domsense.com/wp-content/uploads/2012/04/week_calendar.png - :width: 400 px - -As you can see, several filters are available. A typical usage consists in -filtering by ‘Configurator’ (if you have several configurators, -‘Scheduled calls and meetings’ can be one of them) and by your user. -Once you filtered, you can save the filter as ‘Advanced filter’ or even -add it to a dashboard. -""", - 'author': "Agile Business Group,Odoo Community Association (OCA)", - 'website': 'http://www.agilebg.com', - 'license': 'AGPL-3', - 'depends': ['base'], - "data": [ - 'super_calendar_view.xml', - 'cron_data.xml', - 'security/ir.model.access.csv', - ], - 'demo': [], - 'test': [], - 'installable': False, - 'application': True, - 'auto_install': False, -} diff --git a/__unported__/super_calendar/super_calendar.py b/__unported__/super_calendar/super_calendar.py deleted file mode 100644 index be1520252..000000000 --- a/__unported__/super_calendar/super_calendar.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Copyright (C) 2012 Agile Business Group sagl () -# Copyright (C) 2012 Domsense srl () -# -# 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 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 . -# -############################################################################## - -from openerp.osv import fields, orm -from openerp.tools.translate import _ -import logging -from mako.template import Template -from datetime import datetime -from openerp import tools -from openerp.tools.safe_eval import safe_eval - - -def _models_get(self, cr, uid, context=None): - obj = self.pool.get('ir.model') - ids = obj.search(cr, uid, []) - res = obj.read(cr, uid, ids, ['model', 'name'], context) - return [(r['model'], r['name']) for r in res] - - -class super_calendar_configurator(orm.Model): - _logger = logging.getLogger('super.calendar') - _name = 'super.calendar.configurator' - _columns = { - 'name': fields.char('Name', size=64, required=True), - 'line_ids': fields.one2many('super.calendar.configurator.line', 'configurator_id', 'Lines'), - } - - def generate_calendar_records(self, cr, uid, ids, context=None): - configurator_ids = self.search(cr, uid, []) - super_calendar_pool = self.pool.get('super.calendar') - - # removing old records - super_calendar_ids = super_calendar_pool.search(cr, uid, [], context=context) - super_calendar_pool.unlink(cr, uid, super_calendar_ids, context=context) - - for configurator in self.browse(cr, uid, configurator_ids, context): - for line in configurator.line_ids: - current_pool = self.pool.get(line.name.model) - current_record_ids = current_pool.search( - cr, - uid, - line.domain and safe_eval(line.domain) or [], - context=context) - - for current_record_id in current_record_ids: - current_record = current_pool.browse(cr, uid, current_record_id, context=context) - if (line.user_field_id and - current_record[line.user_field_id.name] and - current_record[line.user_field_id.name]._table_name != 'res.users'): - raise orm.except_orm( - _('Error'), - _("The 'User' field of record %s (%s) does not refer to res.users") - % (current_record[line.description_field_id.name], line.name.model)) - if (((line.description_field_id and current_record[line.description_field_id.name]) or - line.description_code) and - current_record[line.date_start_field_id.name]): - duration = False - if (not line.duration_field_id and - line.date_stop_field_id and - current_record[line.date_start_field_id.name] and - current_record[line.date_stop_field_id.name]): - date_start = datetime.strptime( - current_record[line.date_start_field_id.name], - tools.DEFAULT_SERVER_DATETIME_FORMAT - ) - date_stop = datetime.strptime( - current_record[line.date_stop_field_id.name], - tools.DEFAULT_SERVER_DATETIME_FORMAT - ) - duration = (date_stop - date_start).total_seconds() / 3600 - elif line.duration_field_id: - duration = current_record[line.duration_field_id.name] - if line.description_type != 'code': - name = current_record[line.description_field_id.name] - else: - parse_dict = {'o': current_record} - mytemplate = Template(line.description_code) - name = mytemplate.render(**parse_dict) - super_calendar_values = { - 'name': name, - 'model_description': line.description, - 'date_start': current_record[line.date_start_field_id.name], - 'duration': duration, - 'user_id': ( - line.user_field_id and - current_record[line.user_field_id.name] and - current_record[line.user_field_id.name].id or - False - ), - 'configurator_id': configurator.id, - 'res_id': line.name.model+','+str(current_record['id']), - 'model_id': line.name.id, - } - super_calendar_pool.create(cr, uid, super_calendar_values, context=context) - self._logger.info('Calendar generated') - return True - - -class super_calendar_configurator_line(orm.Model): - _name = 'super.calendar.configurator.line' - _columns = { - 'name': fields.many2one('ir.model', 'Model', required=True), - 'description': fields.char('Description', size=128, required=True), - 'domain': fields.char('Domain', size=512), - 'configurator_id': fields.many2one('super.calendar.configurator', 'Configurator'), - 'description_type': fields.selection([ - ('field', 'Field'), - ('code', 'Code'), - ], string="Description Type"), - 'description_field_id': fields.many2one( - 'ir.model.fields', 'Description field', - domain="[('model_id', '=', name),('ttype', '=', 'char')]"), - 'description_code': fields.text( - 'Description field', - help="Use '${o}' to refer to the involved object. E.g.: '${o.project_id.name}'" - ), - 'date_start_field_id': fields.many2one( - 'ir.model.fields', 'Start date field', - domain="['&','|',('ttype', '=', 'datetime'),('ttype', '=', 'date'),('model_id', '=', name)]", - required=True), - 'date_stop_field_id': fields.many2one( - 'ir.model.fields', 'End date field', - domain="['&',('ttype', '=', 'datetime'),('model_id', '=', name)]" - ), - 'duration_field_id': fields.many2one( - 'ir.model.fields', 'Duration field', - domain="['&',('ttype', '=', 'float'),('model_id', '=', name)]"), - 'user_field_id': fields.many2one( - 'ir.model.fields', 'User field', - domain="['&',('ttype', '=', 'many2one'),('model_id', '=', name)]"), - } - - -class super_calendar(orm.Model): - _name = 'super.calendar' - _columns = { - 'name': fields.char('Description', size=512, required=True), - 'model_description': fields.char('Model Description', size=128, required=True), - 'date_start': fields.datetime('Start date', required=True), - 'duration': fields.float('Duration'), - 'user_id': fields.many2one('res.users', 'User'), - 'configurator_id': fields.many2one('super.calendar.configurator', 'Configurator'), - 'res_id': fields.reference('Resource', selection=_models_get, size=128), - 'model_id': fields.many2one('ir.model', 'Model'), - } diff --git a/super_calendar/README.rst b/super_calendar/README.rst new file mode 100644 index 000000000..e0fbf7e0a --- /dev/null +++ b/super_calendar/README.rst @@ -0,0 +1,53 @@ +SUPER CALENDAR +============== + +This module allows to create configurable calendars. + +Through the 'calendar configurator' object, you can specify which models have +to be merged in the super calendar. For each model, you have to define the +'description' and 'date_start' fields at least. Then you can define 'duration' +and the 'user_id' fields. + +The 'super.calendar' object contains the the merged calendars. The +'super.calendar' can be updated by 'ir.cron' or manually. + +Configuration +============= + +After installing the module you can go to + +*Super calendar > Configuration > Configurators* + +and create a new configurator. For instance, if you want to see meetings and +phone calls, you can create the following lines + +Meetings: + +.. image:: super_calendar/static/description/meetings.png + :width: 400 px + +Phonecalls: + +.. image:: super_calendar/static/description/phone_calls.png + :width: 400 px + +Then, you can use the 'Generate Calendar' button or wait for the scheduled +action (‘Generate Calendar Records’) to be run. + +When the calendar is generated, you can visualize it by the 'super calendar' main menu. + +Here is a sample monthly calendar: + +.. image:: super_calendar/static/description/month_calendar.png + :width: 400 px + +And here is the weekly one: + +.. image:: super_calendar/static/description/week_calendar.png + :width: 400 px + +As you can see, several filters are available. A typical usage consists in +filtering by 'Configurator' (if you have several configurators, +'Scheduled calls and meetings' can be one of them) and by your user. +Once you filtered, you can save the filter as 'Advanced filter' or even +add it to a dashboard. diff --git a/__unported__/super_calendar/__init__.py b/super_calendar/__init__.py similarity index 97% rename from __unported__/super_calendar/__init__.py rename to super_calendar/__init__.py index 90402ead4..994b403d8 100644 --- a/__unported__/super_calendar/__init__.py +++ b/super_calendar/__init__.py @@ -18,4 +18,5 @@ # along with this program. If not, see . # ############################################################################## -import super_calendar + +from . import models diff --git a/super_calendar/__openerp__.py b/super_calendar/__openerp__.py new file mode 100644 index 000000000..295a41c55 --- /dev/null +++ b/super_calendar/__openerp__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (c) All rights reserved: +# (c) 2012 Agile Business Group sagl () +# Lorenzo Battistini +# (c) 2012 Domsense srl () +# (c) 2015 Anubía, soluciones en la nube,SL (http://www.anubia.es) +# Alejandro Santana +# +# 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 +# +############################################################################## +{ + 'name': 'Super Calendar', + 'version': '0.2', + 'category': 'Generic Modules/Others', + 'summary': 'This module allows to create configurable calendars.', + 'author': ('Agile Business Group, ' + 'Alejandro Santana , ' + 'Odoo Community Association (OCA)'), + 'website': 'http://www.agilebg.com', + 'license': 'AGPL-3', + 'depends': [ + 'base', + 'web_calendar', + ], + 'data': [ + 'views/super_calendar_view.xml', + 'data/cron_data.xml', + 'security/ir.model.access.csv', + ], + 'demo': [], + 'test': [], + 'installable': True, + 'application': True, + 'auto_install': False, +} diff --git a/__unported__/super_calendar/cron_data.xml b/super_calendar/data/cron_data.xml similarity index 100% rename from __unported__/super_calendar/cron_data.xml rename to super_calendar/data/cron_data.xml diff --git a/__unported__/super_calendar/i18n/it.po b/super_calendar/i18n/it.po similarity index 100% rename from __unported__/super_calendar/i18n/it.po rename to super_calendar/i18n/it.po diff --git a/__unported__/super_calendar/i18n/ru.po b/super_calendar/i18n/ru.po similarity index 100% rename from __unported__/super_calendar/i18n/ru.po rename to super_calendar/i18n/ru.po diff --git a/__unported__/super_calendar/i18n/super_calendar.pot b/super_calendar/i18n/super_calendar.pot similarity index 100% rename from __unported__/super_calendar/i18n/super_calendar.pot rename to super_calendar/i18n/super_calendar.pot diff --git a/super_calendar/models/__init__.py b/super_calendar/models/__init__.py new file mode 100644 index 000000000..86cc41632 --- /dev/null +++ b/super_calendar/models/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +################################################################ +# License, author and contributors information in: # +# __openerp__.py file at the root folder of this module. # +################################################################ + +from . import super_calendar diff --git a/super_calendar/models/super_calendar.py b/super_calendar/models/super_calendar.py new file mode 100644 index 000000000..1b284d728 --- /dev/null +++ b/super_calendar/models/super_calendar.py @@ -0,0 +1,235 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Odoo, Open Source Management Solution +# +# Copyright (c) All rights reserved: +# (c) 2012 Agile Business Group sagl () +# (c) 2012 Domsense srl () +# (c) 2015 Anubía, soluciones en la nube,SL (http://www.anubia.es) +# Alejandro Santana +# +# 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 +# +############################################################################## + +from openerp import models, fields, api +from openerp.tools.translate import _ +from mako.template import Template +from datetime import datetime +from openerp import tools +from openerp.tools.safe_eval import safe_eval +import logging + + +def _models_get(self): + model_obj = self.env['ir.model'] + model_ids = model_obj.search([]) + return [(model.model, model.name) for model in model_ids] + + +class super_calendar_configurator(models.Model): + _logger = logging.getLogger(__name__) + _name = 'super.calendar.configurator' + + name = fields.Char( + string='Name', + size=64, + required=True, + ) + line_ids = fields.One2many( + comodel_name='super.calendar.configurator.line', + inverse_name='configurator_id', + string='Lines', + ) + + @api.multi + def generate_calendar_records(self): + configurator_ids = self.search([]) + super_calendar_pool = self.env['super.calendar'] + + # Remove old records + super_calendar_ids = super_calendar_pool.search([]) + super_calendar_ids.unlink() + + # Rebuild all calendar records + for configurator in configurator_ids: + for line in configurator.line_ids: + current_pool = self.env[line.name.model] + domain = line.domain and safe_eval(line.domain) or [] + current_record_ids = current_pool.search(domain) + + for cur_rec in current_record_ids: + f_user = line.user_field_id and line.user_field_id.name + f_descr = (line.description_field_id and + line.description_field_id.name) + f_date_start = (line.date_start_field_id and + line.date_start_field_id.name) + f_date_stop = (line.date_stop_field_id and + line.date_stop_field_id.name) + f_duration = (line.duration_field_id and + line.duration_field_id.name) + if (f_user and + cur_rec[f_user] and + cur_rec[f_user]._model._name != 'res.users'): + raise orm.except_orm( + _('Error'), + _("The 'User' field of record %s (%s) " + "does not refer to res.users") + % (cur_rec[f_descr], line.name.model)) + + if (((f_descr and cur_rec[f_descr]) or + line.description_code) and + cur_rec[f_date_start]): + duration = False + if (not line.duration_field_id and + line.date_stop_field_id and + cur_rec[f_date_start] and + cur_rec[f_date_stop]): + date_start = datetime.strptime( + cur_rec[f_date_start], + tools.DEFAULT_SERVER_DATETIME_FORMAT + ) + date_stop = datetime.strptime( + cur_rec[f_date_stop], + tools.DEFAULT_SERVER_DATETIME_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) + + super_calendar_values = { + 'name': name, + 'model_description': line.description, + 'date_start': cur_rec[f_date_start], + 'duration': duration, + 'user_id': ( + f_user and + cur_rec[f_user] and + cur_rec[f_user].id or + False + ), + 'configurator_id': configurator.id, + 'res_id': line.name.model+','+str(cur_rec['id']), + 'model_id': line.name.id, + } + super_calendar_pool.create(super_calendar_values) + self._logger.info('Calendar generated') + return True + + +class super_calendar_configurator_line(models.Model): + _name = 'super.calendar.configurator.line' + + name = fields.Many2one( + comodel_name='ir.model', + string='Model', + required=True, + ) + description = fields.Char( + string='Description', + size=128, + required=True, + ) + domain = fields.Char( + string='Domain', + size=512, + ) + configurator_id = fields.Many2one( + comodel_name='super.calendar.configurator', + string='Configurator', + ) + description_type = fields.Selection( + [('field', 'Field'), + ('code', 'Code')], + string="Description Type", + ) + description_field_id = fields.Many2one( + comodel_name='ir.model.fields', + string='Description field', + domain="[('model_id', '=', name), ('ttype', '=', 'char')]", + ) + description_code = fields.Text( + string='Description field', + help=("Use '${o}' to refer to the involved object. " + "E.g.: '${o.project_id.name}'"), + ) + date_start_field_id = fields.Many2one( + comodel_name='ir.model.fields', + string='Start date field', + domain=("['&','|',('ttype', '=', 'datetime'),('ttype', '=', 'date')," + "('model_id', '=', name)]"), + required=True, + ) + date_stop_field_id = fields.Many2one( + comodel_name='ir.model.fields', + string='End date field', + domain="['&',('ttype', '=', 'datetime'),('model_id', '=', name)]" + ) + duration_field_id = fields.Many2one( + comodel_name='ir.model.fields', + string='Duration field', + domain="['&',('ttype', '=', 'float'), ('model_id', '=', name)]", + ) + user_field_id = fields.Many2one( + comodel_name='ir.model.fields', + string='User field', + domain="['&', ('ttype', '=', 'many2one'), ('model_id', '=', name)]", + ) + + +class super_calendar(models.Model): + _name = 'super.calendar' + + name = fields.Char( + string='Description', + size=512, + required=True, + ) + model_description = fields.Char( + string='Model Description', + size=128, + required=True, + ) + date_start = fields.Datetime( + string='Start date', + required=True, + ) + duration = fields.Float( + string='Duration' + ) + user_id = fields.Many2one( + comodel_name='res.users', + string='User', + ) + configurator_id = fields.Many2one( + comodel_name='super.calendar.configurator', + string='Configurator', + ) + res_id = fields.Reference( + selection=_models_get, + string='Resource', + size=128, + ) + model_id = fields.Many2one( + comodel_name='ir.model', + string='Model', + ) diff --git a/__unported__/super_calendar/security/ir.model.access.csv b/super_calendar/security/ir.model.access.csv similarity index 100% rename from __unported__/super_calendar/security/ir.model.access.csv rename to super_calendar/security/ir.model.access.csv diff --git a/super_calendar/static/description/meetings.png b/super_calendar/static/description/meetings.png new file mode 100644 index 000000000..bb359ec2a Binary files /dev/null and b/super_calendar/static/description/meetings.png differ diff --git a/super_calendar/static/description/month_calendar.png b/super_calendar/static/description/month_calendar.png new file mode 100644 index 000000000..5a3c8e863 Binary files /dev/null and b/super_calendar/static/description/month_calendar.png differ diff --git a/super_calendar/static/description/phone_calls.png b/super_calendar/static/description/phone_calls.png new file mode 100644 index 000000000..559654013 Binary files /dev/null and b/super_calendar/static/description/phone_calls.png differ diff --git a/super_calendar/static/description/week_calendar.png b/super_calendar/static/description/week_calendar.png new file mode 100644 index 000000000..f9384bbfa Binary files /dev/null and b/super_calendar/static/description/week_calendar.png differ diff --git a/__unported__/super_calendar/super_calendar_view.xml b/super_calendar/views/super_calendar_view.xml similarity index 69% rename from __unported__/super_calendar/super_calendar_view.xml rename to super_calendar/views/super_calendar_view.xml index 1b675a7d8..4a482736e 100644 --- a/__unported__/super_calendar/super_calendar_view.xml +++ b/super_calendar/views/super_calendar_view.xml @@ -2,7 +2,7 @@ - + super_calendar_configurator_tree @@ -24,24 +24,33 @@ +
- - - - - - - - - - - - -
- + super_calendar_tree @@ -81,16 +90,20 @@ super_calendar_form super.calendar -
- - - - - - - - - + + + + + + + + + + + + + +