[IMP] event: refactored event form view. Usability reviews
[odoo/odoo.git] / addons / website_event_track / models / event.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 from openerp.osv import fields, osv
23 from openerp.tools.translate import _
24 from openerp.addons.website.models.website import slug
25
26 import pytz
27
28 class event_track_tag(osv.osv):
29     _name = "event.track.tag"
30     _order = 'name'
31     _columns = {
32         'name': fields.char('Event Track Tag', translate=True)
33     }
34
35 class event_tag(osv.osv):
36     _name = "event.tag"
37     _order = 'name'
38     _columns = {
39         'name': fields.char('Event Tag', translate=True)
40     }
41
42 #
43 # Tracks: conferences
44 #
45
46 class event_track_stage(osv.osv):
47     _name = "event.track.stage"
48     _order = 'sequence'
49     _columns = {
50         'name': fields.char('Track Stage', translate=True),
51         'sequence': fields.integer('Sequence')
52     }
53     _defaults = {
54         'sequence': 0
55     }
56
57
58 class event_track_location(osv.osv):
59     _name = "event.track.location"
60     _columns = {
61         'name': fields.char('Track Rooms')
62     }
63
64 class event_track(osv.osv):
65     _name = "event.track"
66     _description = 'Event Tracks'
67     _order = 'priority, date'
68     _inherit = ['mail.thread', 'ir.needaction_mixin', 'website.seo.metadata']
69
70     def _website_url(self, cr, uid, ids, field_name, arg, context=None):
71         res = dict.fromkeys(ids, '')
72         for track in self.browse(cr, uid, ids, context=context):
73             res[track.id] = "/event/%s/track/%s" % (slug(track.event_id), slug(track))
74         return res
75
76     _columns = {
77         'name': fields.char('Track Title', required=True, translate=True),
78         'user_id': fields.many2one('res.users', 'Responsible'),
79         'speaker_ids': fields.many2many('res.partner', string='Speakers'),
80         'tag_ids': fields.many2many('event.track.tag', string='Tags'),
81         'stage_id': fields.many2one('event.track.stage', 'Stage'),
82         'description': fields.html('Track Description', translate=True),
83         'date': fields.datetime('Track Date'),
84         'duration': fields.float('Duration', digits=(16,2)),
85         'location_id': fields.many2one('event.track.location', 'Location'),
86         'event_id': fields.many2one('event.event', 'Event', required=True),
87         'color': fields.integer('Color Index'),
88         'priority': fields.selection([('3','Low'),('2','Medium (*)'),('1','High (**)'),('0','Highest (***)')], 'Priority', required=True),
89         'website_published': fields.boolean('Available in the website', copy=False),
90         'website_url': fields.function(_website_url, string="Website url", type="char"),
91         'image': fields.related('speaker_ids', 'image', type='binary', readonly=True)
92     }
93     def set_priority(self, cr, uid, ids, priority, context={}):
94         return self.write(cr, uid, ids, {'priority' : priority})
95
96     def _default_stage_id(self, cr, uid, context={}):
97         stage_obj = self.pool.get('event.track.stage')
98         ids = stage_obj.search(cr, uid, [], context=context)
99         return ids and ids[0] or False
100
101     _defaults = {
102         'user_id': lambda self, cr, uid, ctx: uid,
103         'website_published': lambda self, cr, uid, ctx: False,
104         'duration': lambda *args: 1.5,
105         'stage_id': _default_stage_id,
106         'priority': '2'
107     }
108
109     def _read_group_stage_ids(self, cr, uid, ids, domain, read_group_order=None, access_rights_uid=None, context=None):
110         stage_obj = self.pool.get('event.track.stage')
111         result = stage_obj.name_search(cr, uid, '', context=context)
112         return result, {}
113
114     _group_by_full = {
115         'stage_id': _read_group_stage_ids,
116     }
117
118     def open_track_speakers_list(self, cr, uid, track_id, context=None):
119         track_id = self.browse(cr, uid, track_id, context=context)
120         return {
121             'name':_('Speakers'),
122             'domain': [('id', 'in',[partner.id for partner in track_id.speaker_ids])],
123             'view_type': 'form',
124             'view_mode': 'kanban,form',
125             'res_model': 'res.partner',
126             'view_id':False,
127             'type': 'ir.actions.act_window',
128         }
129
130 #
131 # Events
132 #
133 class event_event(osv.osv):
134     _inherit = "event.event"
135
136     def _list_tz(self,cr,uid, context=None):
137         # put POSIX 'Etc/*' entries at the end to avoid confusing users - see bug 1086728
138         return [(tz,tz) for tz in sorted(pytz.all_timezones, key=lambda tz: tz if not tz.startswith('Etc/') else '_')]
139
140     def _count_tracks(self, cr, uid, ids, field_name, arg, context=None):
141         return {
142             event.id: len(event.track_ids)
143             for event in self.browse(cr, uid, ids, context=context)
144         }
145
146     def _count_sponsor(self, cr, uid, ids, field_name, arg, context=None):
147         return {
148             event.id: len(event.sponsor_ids)
149             for event in self.browse(cr, uid, ids, context=context)
150         }
151
152     def _get_tracks_tag_ids(self, cr, uid, ids, field_names, arg=None, context=None):
153         res = dict((res_id, []) for res_id in ids)
154         for event in self.browse(cr, uid, ids, context=context):
155             for track in event.track_ids:
156                 res[event.id] += [tag.id for tag in track.tag_ids]
157             res[event.id] = list(set(res[event.id]))
158         return res
159
160     _columns = {
161         'tag_ids': fields.many2many('event.tag', string='Tags'),
162         'track_ids': fields.one2many('event.track', 'event_id', 'Tracks', copy=True),
163         'sponsor_ids': fields.one2many('event.sponsor', 'event_id', 'Sponsorships', copy=True),
164         'blog_id': fields.many2one('blog.blog', 'Event Blog'),
165         'show_track_proposal': fields.boolean('Talks Proposals'),
166         'show_tracks': fields.boolean('Multiple Tracks'),
167         'show_blog': fields.boolean('News'),
168         'count_tracks': fields.function(_count_tracks, type='integer', string='Tracks'),
169         'tracks_tag_ids': fields.function(_get_tracks_tag_ids, type='one2many', relation='event.track.tag', string='Tags of Tracks'),
170         'allowed_track_tag_ids': fields.many2many('event.track.tag', string='Accepted Tags', help="List of available tags for track proposals."),
171         'count_sponsor': fields.function(_count_sponsor, type='integer', string='Sponsors'),
172     }
173
174     _defaults = {
175         'show_track_proposal': False,
176         'show_tracks': False,
177         'show_blog': False,
178     }
179
180     def _get_new_menu_pages(self, cr, uid, event, context=None):
181         context = context or {}
182         result = super(event_event, self)._get_new_menu_pages(cr, uid, event, context=context)
183         if event.show_tracks:
184             result.append( (_('Talks'), '/event/%s/track' % slug(event)))
185             result.append( (_('Agenda'), '/event/%s/agenda' % slug(event)))
186         if event.blog_id:
187             result.append( (_('News'), '/blogpost'+slug(event.blog_ig)))
188         if event.show_track_proposal:
189             result.append( (_('Talk Proposals'), '/event/%s/track_proposal' % slug(event)))
190         return result
191
192 #
193 # Sponsors
194 #
195
196 class event_sponsors_type(osv.osv):
197     _name = "event.sponsor.type"
198     _order = "sequence"
199     _columns = {
200         "name": fields.char('Sponsor Type', required=True, translate=True),
201         "sequence": fields.integer('Sequence')
202     }
203
204 class event_sponsors(osv.osv):
205     _name = "event.sponsor"
206     _order = "sequence"
207     _columns = {
208         'event_id': fields.many2one('event.event', 'Event', required=True),
209         'sponsor_type_id': fields.many2one('event.sponsor.type', 'Sponsoring Type', required=True),
210         'partner_id': fields.many2one('res.partner', 'Sponsor/Customer', required=True),
211         'url': fields.text('Sponsor Website'),
212         'sequence': fields.related('sponsor_type_id', 'sequence', string='Sequence', store=True),
213         'image_medium': fields.related('partner_id', 'image_medium', string='Logo', type='binary')
214     }
215
216     def has_access_to_partner(self, cr, uid, ids, context=None):
217         partner_ids = [sponsor.partner_id.id for sponsor in self.browse(cr, uid, ids, context=context)]
218         return len(partner_ids) == self.pool.get("res.partner").search(cr, uid, [("id", "in", partner_ids)], count=True, context=context)
219