Lorenzo Battistini - Agile BG - Domsense
12 years ago
committed by
unknown
7 changed files with 395 additions and 0 deletions
-
1super_calendar/AUTHORS.txt
-
21super_calendar/__init__.py
-
76super_calendar/__openerp__.py
-
15super_calendar/cron_data.xml
-
4super_calendar/security/ir.model.access.csv
-
132super_calendar/super_calendar.py
-
146super_calendar/super_calendar_view.xml
@ -0,0 +1 @@ |
|||||
|
Lorenzo Battistini <lorenzo.battistini@agilebg.com> |
@ -0,0 +1,21 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>) |
||||
|
# Copyright (C) 2012 Domsense srl (<http://www.domsense.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 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 super_calendar |
@ -0,0 +1,76 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>) |
||||
|
# Copyright (C) 2012 Domsense srl (<http://www.domsense.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 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.1', |
||||
|
'category': 'Generic Modules/Others', |
||||
|
'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', |
||||
|
'website': 'http://www.agilebg.com', |
||||
|
'license': 'AGPL-3', |
||||
|
"depends" : ['base'], |
||||
|
"init_xml" : [], |
||||
|
"update_xml" : [ |
||||
|
'super_calendar_view.xml', |
||||
|
'cron_data.xml', |
||||
|
'security/ir.model.access.csv', |
||||
|
], |
||||
|
"demo_xml" : [], |
||||
|
"active": False, |
||||
|
"installable": True |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<openerp> |
||||
|
<data noupdate="1"> |
||||
|
<record model="ir.cron" id="generate_calendar_records_cron"> |
||||
|
<field name="name">Generate Calendar Records</field> |
||||
|
<field name="interval_number">10</field> |
||||
|
<field name="interval_type">minutes</field> |
||||
|
<field name="numbercall">-1</field> |
||||
|
<field name="doall" eval="False"></field> |
||||
|
<field eval="'super.calendar.configurator'" name="model"/> |
||||
|
<field eval="'generate_calendar_records'" name="function"/> |
||||
|
<field eval="'[[],{}]'" name="args"/> |
||||
|
</record> |
||||
|
</data> |
||||
|
</openerp> |
@ -0,0 +1,4 @@ |
|||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink |
||||
|
access_model_super_calendar_configurator,access_model_super_calendar_configurator,model_super_calendar_configurator,base.group_system,1,1,1,1 |
||||
|
access_model_super_calendar_configurator_line,access_model_super_calendar_configurator_line,model_super_calendar_configurator_line,base.group_system,1,1,1,1 |
||||
|
access_model_super_calendar,access_model_super_calendar,model_super_calendar,base.group_user,1,0,0,0 |
@ -0,0 +1,132 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
############################################################################## |
||||
|
# |
||||
|
# Copyright (C) 2012 Agile Business Group sagl (<http://www.agilebg.com>) |
||||
|
# Copyright (C) 2012 Domsense srl (<http://www.domsense.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 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.osv import fields, osv, orm |
||||
|
from openerp.tools.translate import _ |
||||
|
import logging |
||||
|
from mako.template import Template |
||||
|
from datetime import datetime |
||||
|
from openerp import tools |
||||
|
from openerp.tools import safe_eval as 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 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 osv.except_osv(_('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'), |
||||
|
} |
@ -0,0 +1,146 @@ |
|||||
|
<?xml version="1.0"?> |
||||
|
<openerp> |
||||
|
<data> |
||||
|
|
||||
|
<!-- configurator --> |
||||
|
|
||||
|
<record model="ir.ui.view" id="super_calendar_configurator_tree"> |
||||
|
<field name="name">super_calendar_configurator_tree</field> |
||||
|
<field name="model">super.calendar.configurator</field> |
||||
|
<field name="type">tree</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Configurators"> |
||||
|
<field name="name"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record model="ir.ui.view" id="super_calendar_configurator_form"> |
||||
|
<field name="name">super_calendar_configurator_form</field> |
||||
|
<field name="model">super.calendar.configurator</field> |
||||
|
<field name="type">form</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Configurator"> |
||||
|
<field name="name" select="1" colspan="2"/> |
||||
|
<newline/> |
||||
|
<field name="line_ids" nolabel="1" colspan="4"> |
||||
|
<tree string="Lines"> |
||||
|
<field name="name"/> |
||||
|
<field name="domain"/> |
||||
|
</tree> |
||||
|
<form string="Line"> |
||||
|
<field name="name"/> |
||||
|
<field name="description"/> |
||||
|
<field name="domain"/> |
||||
|
<field name="date_start_field_id"/> |
||||
|
<field name="duration_field_id"/> |
||||
|
<field name="date_stop_field_id" attrs="{'readonly':[('duration_field_id','!=',False)]}"/> |
||||
|
<field name="user_field_id"/> |
||||
|
<separator string="Description" colspan="4" /> |
||||
|
<field name="description_type"/> |
||||
|
<newline/> |
||||
|
<field name="description_field_id" attrs="{'required':[('description_type','!=','code')], 'invisible':[('description_type','==','code')]}"/> |
||||
|
<group colspan="4" col="1" attrs="{'invisible':[('description_type','!=','code')]}"> |
||||
|
<label string="Use '${o}' to refer to the involved object. E.g.: '${o.project_id.name}'" /> |
||||
|
<field name="description_code" nolabel="1" attrs="{'required':[('description_type','==','code')]}"/> |
||||
|
</group> |
||||
|
</form> |
||||
|
</field> |
||||
|
<newline/> |
||||
|
<button name="generate_calendar_records" string="Generate Calendar" type="object" icon="gtk-go-forward" colspan="2"/> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.actions.act_window" id="super_calendar_configurator"> |
||||
|
<field name="name">Calendar Configurators</field> |
||||
|
<field name="res_model">super.calendar.configurator</field> |
||||
|
<field name="view_type">form</field> |
||||
|
<field name="view_mode">tree,form</field> |
||||
|
<field name="view_id" ref="super_calendar_configurator_tree"/> |
||||
|
</record> |
||||
|
|
||||
|
<!-- calendar --> |
||||
|
|
||||
|
<record model="ir.ui.view" id="super_calendar_tree"> |
||||
|
<field name="name">super_calendar_tree</field> |
||||
|
<field name="model">super.calendar</field> |
||||
|
<field name="type">tree</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<tree string="Calendar"> |
||||
|
<field name="name"/> |
||||
|
<field name="date_start"/> |
||||
|
<!--<field name="date_stop"/>--> |
||||
|
<field name="duration"/> |
||||
|
<field name="user_id"/> |
||||
|
<field name="configurator_id"/> |
||||
|
<field name="model_id"/> |
||||
|
<field name="model_description"/> |
||||
|
</tree> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record model="ir.ui.view" id="super_calendar_form"> |
||||
|
<field name="name">super_calendar_form</field> |
||||
|
<field name="model">super.calendar</field> |
||||
|
<field name="type">form</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<form string="Configurator"> |
||||
|
<field name="name" readonly="1"/> |
||||
|
<field name="date_start" readonly="1"/> |
||||
|
<!--<field name="date_stop" readonly="1"/>--> |
||||
|
<field name="duration" readonly="1"/> |
||||
|
<field name="user_id" readonly="1"/> |
||||
|
<field name="configurator_id" readonly="1"/> |
||||
|
<field name="model_id" readonly="1"/> |
||||
|
<field name="model_description" readonly="1"/> |
||||
|
<field name="res_id"/> |
||||
|
</form> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record model="ir.ui.view" id="super_calendar"> |
||||
|
<field name="name">super_calendar</field> |
||||
|
<field name="model">super.calendar</field> |
||||
|
<field name="type">calendar</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<calendar string="Calendar" color="model_description" date_start="date_start" date_delay="duration"> |
||||
|
<field name="name"/> |
||||
|
</calendar> |
||||
|
</field> |
||||
|
</record> |
||||
|
<record model="ir.ui.view" id="super_calendar_search"> |
||||
|
<field name="name">super_calendar_search</field> |
||||
|
<field name="model">super.calendar</field> |
||||
|
<field name="type">search</field> |
||||
|
<field name="arch" type="xml"> |
||||
|
<search string="Search Calendar" > |
||||
|
<field name="name"/> |
||||
|
<field name="configurator_id" select="1"/> |
||||
|
<field name="model_id" select="1"/> |
||||
|
<field name="model_description" select="1"/> |
||||
|
<field name="user_id" widget="selection" > |
||||
|
<filter domain="[('user_id','=',uid)]" help="My Items" icon="terp-personal"/> |
||||
|
</field> |
||||
|
<newline/> |
||||
|
<group expand="0" string="Extended Filters..." colspan="4" col="8"> |
||||
|
<field name="date_start" /> |
||||
|
<!--<field name="date_stop" />--> |
||||
|
<field name="duration" /> |
||||
|
</group> |
||||
|
</search> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record model="ir.actions.act_window" id="super_calendar_action"> |
||||
|
<field name="name">Super Calendar</field> |
||||
|
<field name="res_model">super.calendar</field> |
||||
|
<field name="view_type">form</field> |
||||
|
<field name="view_mode">calendar,tree,form</field> |
||||
|
<field name="view_id" ref="super_calendar"/> |
||||
|
</record> |
||||
|
|
||||
|
<menuitem id="super_calendar_menu" name="Super Calendar" action="super_calendar_action"/> |
||||
|
<menuitem id="super_calendar_calendar" name="Calendar" parent="super_calendar_menu" /> |
||||
|
<menuitem id="super_calendar_calendar_calendar" name="Calendar" parent="super_calendar_calendar" action="super_calendar_action"/> |
||||
|
<menuitem id="super_calendar_configuration" name="Configuration" parent="super_calendar_menu" /> |
||||
|
<menuitem id="super_calendar_configurators" name="Configurators" parent="super_calendar_configuration" action="super_calendar_configurator"/> |
||||
|
</data> |
||||
|
</openerp> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue