Merge branch 'master' of https://github.com/odoo/odoo
[odoo/odoo.git] / addons / website_event / controllers / main.py
1 # -*- coding: utf-8 -*-
2
3 import time
4 import werkzeug.urls
5 from datetime import datetime, timedelta
6 from dateutil.relativedelta import relativedelta
7 from collections import OrderedDict
8
9 from openerp import http
10 from openerp import tools, SUPERUSER_ID
11 from openerp.addons.website.models.website import slug
12 from openerp.http import request
13 from openerp.tools.translate import _
14
15
16 class website_event(http.Controller):
17     @http.route(['/event', '/event/page/<int:page>'], type='http', auth="public", website=True)
18     def events(self, page=1, **searches):
19         cr, uid, context = request.cr, request.uid, request.context
20         event_obj = request.registry['event.event']
21         type_obj = request.registry['event.type']
22         country_obj = request.registry['res.country']
23
24         searches.setdefault('date', 'all')
25         searches.setdefault('type', 'all')
26         searches.setdefault('country', 'all')
27
28         domain_search = {}
29
30         def sdn(date):
31             return date.replace(hour=23, minute=59, second=59).strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
32
33         def sd(date):
34             return date.strftime(tools.DEFAULT_SERVER_DATETIME_FORMAT)
35         today = datetime.today()
36         dates = [
37             ['all', _('Next Events'), [("date_end", ">", sd(today))], 0],
38             ['today', _('Today'), [
39                 ("date_end", ">", sd(today)),
40                 ("date_begin", "<", sdn(today))],
41                 0],
42             ['week', _('This Week'), [
43                 ("date_end", ">=", sd(today + relativedelta(days=-today.weekday()))),
44                 ("date_begin", "<", sdn(today + relativedelta(days=6-today.weekday())))],
45                 0],
46             ['nextweek', _('Next Week'), [
47                 ("date_end", ">=", sd(today + relativedelta(days=7-today.weekday()))),
48                 ("date_begin", "<", sdn(today + relativedelta(days=13-today.weekday())))],
49                 0],
50             ['month', _('This month'), [
51                 ("date_end", ">=", sd(today.replace(day=1))),
52                 ("date_begin", "<", (today.replace(day=1) + relativedelta(months=1)).strftime('%Y-%m-%d 00:00:00'))],
53                 0],
54             ['nextmonth', _('Next month'), [
55                 ("date_end", ">=", sd(today.replace(day=1) + relativedelta(months=1))),
56                 ("date_begin", "<", (today.replace(day=1) + relativedelta(months=2)).strftime('%Y-%m-%d 00:00:00'))],
57                 0],
58             ['old', _('Old Events'), [
59                 ("date_end", "<", today.strftime('%Y-%m-%d 00:00:00'))],
60                 0],
61         ]
62
63         # search domains
64         # TDE note: WTF ???
65         current_date = None
66         current_type = None
67         current_country = None
68         for date in dates:
69             if searches["date"] == date[0]:
70                 domain_search["date"] = date[2]
71                 if date[0] != 'all':
72                     current_date = date[1]
73         if searches["type"] != 'all':
74             current_type = type_obj.browse(cr, uid, int(searches['type']), context=context)
75             domain_search["type"] = [("type", "=", int(searches["type"]))]
76
77         if searches["country"] != 'all' and searches["country"] != 'online':
78             current_country = country_obj.browse(cr, uid, int(searches['country']), context=context)
79             domain_search["country"] = ['|', ("country_id", "=", int(searches["country"])), ("country_id", "=", False)]
80         elif searches["country"] == 'online':
81             domain_search["country"] = [("country_id", "=", False)]
82
83         def dom_without(without):
84             domain = [('state', "in", ['draft', 'confirm', 'done'])]
85             for key, search in domain_search.items():
86                 if key != without:
87                     domain += search
88             return domain
89
90         # count by domains without self search
91         for date in dates:
92             if date[0] != 'old':
93                 date[3] = event_obj.search(
94                     request.cr, request.uid, dom_without('date') + date[2],
95                     count=True, context=request.context)
96
97         domain = dom_without('type')
98         types = event_obj.read_group(
99             request.cr, request.uid, domain, ["id", "type"], groupby="type",
100             orderby="type", context=request.context)
101         type_count = event_obj.search(request.cr, request.uid, domain,
102                                       count=True, context=request.context)
103         types.insert(0, {
104             'type_count': type_count,
105             'type': ("all", _("All Categories"))
106         })
107
108         domain = dom_without('country')
109         countries = event_obj.read_group(
110             request.cr, request.uid, domain, ["id", "country_id"],
111             groupby="country_id", orderby="country_id", context=request.context)
112         country_id_count = event_obj.search(request.cr, request.uid, domain,
113                                             count=True, context=request.context)
114         countries.insert(0, {
115             'country_id_count': country_id_count,
116             'country_id': ("all", _("All Countries"))
117         })
118
119         step = 10  # Number of events per page
120         event_count = event_obj.search(
121             request.cr, request.uid, dom_without("none"), count=True,
122             context=request.context)
123         pager = request.website.pager(
124             url="/event",
125             url_args={'date': searches.get('date'), 'type': searches.get('type'), 'country': searches.get('country')},
126             total=event_count,
127             page=page,
128             step=step,
129             scope=5)
130
131         order = 'website_published desc, date_begin'
132         if searches.get('date', 'all') == 'old':
133             order = 'website_published desc, date_begin desc'
134         obj_ids = event_obj.search(
135             request.cr, request.uid, dom_without("none"), limit=step,
136             offset=pager['offset'], order=order, context=request.context)
137         events_ids = event_obj.browse(request.cr, request.uid, obj_ids,
138                                       context=request.context)
139
140         values = {
141             'current_date': current_date,
142             'current_country': current_country,
143             'current_type': current_type,
144             'event_ids': events_ids,
145             'dates': dates,
146             'types': types,
147             'countries': countries,
148             'pager': pager,
149             'searches': searches,
150             'search_path': "?%s" % werkzeug.url_encode(searches),
151         }
152
153         return request.website.render("website_event.index", values)
154
155     @http.route(['/event/<model("event.event"):event>/page/<path:page>'], type='http', auth="public", website=True)
156     def event_page(self, event, page, **post):
157         values = {
158             'event': event,
159             'main_object': event
160         }
161
162         if '.' not in page:
163             page = 'website_event.%s' % page
164
165         return request.website.render(page, values)
166
167     @http.route(['/event/<model("event.event"):event>'], type='http', auth="public", website=True)
168     def event(self, event, **post):
169         if event.menu_id and event.menu_id.child_id:
170             target_url = event.menu_id.child_id[0].url
171         else:
172             target_url = '/event/%s/register' % str(event.id)
173         if post.get('enable_editor') == '1':
174             target_url += '?enable_editor=1'
175         return request.redirect(target_url)
176
177     @http.route(['/event/<model("event.event"):event>/register'], type='http', auth="public", website=True)
178     def event_register(self, event, **post):
179         values = {
180             'event': event,
181             'main_object': event,
182             'range': range,
183         }
184         return request.website.render("website_event.event_description_full", values)
185
186     @http.route('/event/add_event', type='http', auth="user", methods=['POST'], website=True)
187     def add_event(self, event_name="New Event", **kwargs):
188         return self._add_event(event_name, request.context, **kwargs)
189
190     def _add_event(self, event_name=None, context={}, **kwargs):
191         if not event_name:
192             event_name = _("New Event")
193         Event = request.registry.get('event.event')
194         date_begin = datetime.today() + timedelta(days=(14))
195         vals = {
196             'name': event_name,
197             'date_begin': date_begin.strftime('%Y-%m-%d'),
198             'date_end': (date_begin + timedelta(days=(1))).strftime('%Y-%m-%d'),
199             'seats_available': 1000,
200         }
201         event_id = Event.create(request.cr, request.uid, vals, context=context)
202         event = Event.browse(request.cr, request.uid, event_id, context=context)
203         return request.redirect("/event/%s/register?enable_editor=1" % slug(event))
204
205     def get_formated_date(self, event):
206         start_date = datetime.strptime(event.date_begin, tools.DEFAULT_SERVER_DATETIME_FORMAT).date()
207         end_date = datetime.strptime(event.date_end, tools.DEFAULT_SERVER_DATETIME_FORMAT).date()
208         return ('%s %s%s') % (start_date.strftime("%b"), start_date.strftime("%e"), (end_date != start_date and ("-"+end_date.strftime("%e")) or ""))
209
210     @http.route('/event/get_country_event_list', type='http', auth='public', website=True)
211     def get_country_events(self, **post):
212         cr, uid, context, event_ids = request.cr, request.uid, request.context, []
213         country_obj = request.registry['res.country']
214         event_obj = request.registry['event.event']
215         country_code = request.session['geoip'].get('country_code')
216         result = {'events': [], 'country': False}
217         if country_code:
218             country_ids = country_obj.search(cr, uid, [('code', '=', country_code)], context=context)
219             event_ids = event_obj.search(cr, uid, ['|', ('address_id', '=', None), ('country_id.code', '=', country_code), ('date_begin', '>=', time.strftime('%Y-%m-%d 00:00:00')), ('state', '=', 'confirm')], order="date_begin", context=context)
220         if not event_ids:
221             event_ids = event_obj.search(cr, uid, [('date_begin', '>=', time.strftime('%Y-%m-%d 00:00:00')), ('state', '=', 'confirm')], order="date_begin", context=context)
222         for event in event_obj.browse(cr, uid, event_ids, context=context)[:6]:
223             if country_code and event.country_id.code == country_code:
224                 result['country'] = country_obj.browse(cr, uid, country_ids[0], context=context)
225             result['events'].append({
226                 "date": self.get_formated_date(event),
227                 "event": event,
228                 "url": event.website_url})
229         return request.website.render("website_event.country_events_list", result)
230
231     def _process_tickets_details(self, data):
232         nb_register = int(data.get('nb_register-0', 0))
233         if nb_register:
234             return [{'id': 0, 'name': 'Subscription', 'quantity': nb_register, 'price': 0}]
235         return []
236
237     @http.route(['/event/<model("event.event"):event>/registration/new'], type='json', auth="public", methods=['POST'], website=True)
238     def registration_new(self, event, **post):
239         tickets = self._process_tickets_details(post)
240         if not tickets:
241             return request.redirect("/event/%s" % slug(event))
242         return request.website._render("website_event.registration_attendee_details", {'tickets': tickets, 'event': event})
243
244     def _process_registration_details(self, details):
245         ''' Process data posted from the attendee details form. '''
246         registrations = {}
247         for key, value in details.iteritems():
248             counter, field_name = key.split('-', 1)
249             registrations.setdefault(counter, dict())[field_name] = value
250         return registrations.values()
251
252     @http.route(['/event/<model("event.event"):event>/registration/confirm'], type='http', auth="public", methods=['POST'], website=True)
253     def registration_confirm(self, event, **post):
254         cr, uid, context = request.cr, request.uid, request.context
255         Registration = request.registry['event.registration']
256         registrations = self._process_registration_details(post)
257
258         registration_ids = []
259         user = request.registry.get('res.users').browse(cr, uid, uid, context=context)
260         for registration in registrations:
261             registration_ids.append(
262                 Registration.create(cr, SUPERUSER_ID, {
263                     'name': registration.get('name', user.name),
264                     'phone': registration.get('phone', user.phone),
265                     'email': registration.get('email', user.email),
266                     'partner_id': user.partner_id.id,
267                     'event_id': event.id,
268                 }, context=context))
269
270         attendees = Registration.browse(cr, uid, registration_ids, context=context)
271         return request.website.render("website_event.registration_complete", {
272             'attendees': attendees,
273             'event': event,
274         })