[IMP] event: french translations
[odoo/odoo.git] / addons / event / event.py
1 # -*- encoding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
6 #    $Id$
7 #
8 #    This program is free software: you can redistribute it and/or modify
9 #    it under the terms of the GNU General Public License as published by
10 #    the Free Software Foundation, either version 3 of the License, or
11 #    (at your option) any later version.
12 #
13 #    This program is distributed in the hope that it will be useful,
14 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
15 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 #    GNU General Public License for more details.
17 #
18 #    You should have received a copy of the GNU General Public License
19 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 ##############################################################################
22
23 from osv import fields, osv
24 import time
25 import netsvc
26 import pooler
27 import tools
28 from tools.translate import _
29
30 class crm_case_log(osv.osv):
31     _inherit = 'crm.case.log'
32     _description = 'crm.case.log'
33     def create(self, cr, uid, vals, *args, **kwargs):
34             if not 'name' in vals:
35                 vals['name']='Historize'
36             return super(osv.osv,self).create(cr, uid, vals, *args, **kwargs)
37     _defaults = {
38         'user_id': lambda self,cr,uid,context: uid,
39     }
40 crm_case_log()
41
42 class event_type(osv.osv):
43     _name = 'event.type'
44     _description= 'Event type'
45     _columns = {
46         'name': fields.char('Event type', size=64, required=True),
47     }
48 event_type()
49
50 class event(osv.osv):
51     _name = 'event.event'
52     _description = 'Event'
53     _inherits = {'crm.case.section': 'section_id'}
54     _order = 'date_begin'
55
56     def copy(self, cr, uid, id, default=None, context=None):
57         return super(event, self).copy(cr, uid,id, default={'code': self.pool.get('ir.sequence').get(cr, uid, 'event.event'),'state':'draft'})
58
59     def button_draft(self, cr, uid, ids, context={}):
60         return self.write(cr, uid, ids, {'state':'draft'})
61
62     def button_cancel(self, cr, uid, ids, context={}):
63         return self.write(cr, uid, ids, {'state':'cancel'})
64
65     def button_done(self, cr, uid, ids, context={}):
66         return self.write(cr, uid, ids, {'state':'done'})
67
68     def button_confirm(self, cr, uid, ids, context={}):
69         for eve in self.browse(cr, uid, ids):
70             if eve.mail_auto_confirm:
71                 #send reminder that will confirm the event for all the people that were already confirmed
72                 reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id','=',eve.id),('state','not in',['draft','cancel'])])
73                 if reg_ids:
74                     self.pool.get('event.registration').mail_user_confirm(cr, uid, reg_ids)
75         return self.write(cr, uid, ids, {'state':'confirm'})
76
77     def _get_register(self, cr, uid, ids, name, args, context=None):
78         res={}
79         for event in self.browse(cr, uid, ids, context):
80             query = """select sum(nb_register) from crm_case c left join crm_case_section s on (c.section_id=s.id) right join event_event e on (e.section_id=s.id) right join event_registration r on (r.case_id=c.id) where e.section_id = %s and c.state in ('open','done')""" % event.section_id.id
81             cr.execute(query)
82             res2 = cr.fetchone()
83             if res2 and res2[0]:
84                 res[event.id] = res2[0]
85             else:
86                 res[event.id] = 0
87         return res
88
89     def _get_prospect(self, cr, uid, ids, name, args, context=None):
90         res={}
91         for event in self.browse(cr, uid, ids, context):
92             query = """select sum(nb_register) from crm_case c left join crm_case_section s on (c.section_id=s.id) right join event_event e on (e.section_id=s.id) right join event_registration r on (r.case_id=c.id) where e.section_id = %s and c.state = 'draft'""" % event.section_id.id
93             cr.execute(query)
94             res2 = cr.fetchone()
95             if res2 and res2[0]:
96                 res[event.id] = res2[0]
97             else:
98                 res[event.id] = 0
99         return res
100
101     def write(self, cr, uid, ids,vals, *args, **kwargs):
102         res = super(event,self).write(cr, uid, ids,vals, *args, **kwargs)
103         if 'date_begin' in vals and vals['date_begin']:
104             for eve in self.browse(cr, uid, ids):
105                 #change the deadlines of the registration linked to this event
106                 reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id','=',eve.id)])
107                 if reg_ids:
108                     self.pool.get('event.registration').write(cr, uid, reg_ids, {'date_deadline':vals['date_begin']})
109
110         #change the description of the registration linked to this event
111         if 'mail_auto_confirm' in vals:
112             if vals['mail_auto_confirm']:
113                 if 'mail_confirm' not in vals:
114                     for eve in self.browse(cr, uid, ids):
115                         vals['mail_confirm'] = eve.mail_confirm
116             else:
117                 vals['mail_confirm']=False
118         if 'mail_confirm' in vals:
119             for eve in self.browse(cr, uid, ids):
120                 reg_ids = self.pool.get('event.registration').search(cr, uid, [('event_id','=',eve.id)])
121                 if reg_ids:
122                     self.pool.get('event.registration').write(cr, uid, reg_ids, {'description':vals['mail_confirm']})
123         return res
124
125     _columns = {
126         'type': fields.many2one('event.type', 'Type'),
127         'section_id': fields.many2one('crm.case.section', 'Case section', required=True),
128         'register_max': fields.integer('Maximum Registrations'),
129         'register_min': fields.integer('Minimum Registrations'),
130         'register_current': fields.function(_get_register, method=True, string='Confirmed Registrations'),
131         'register_prospect': fields.function(_get_prospect, method=True, string='Unconfirmed Registrations'),
132         'date_begin': fields.datetime('Beginning date', required=True),
133         'date_end': fields.datetime('Ending date', required=True),
134         'state': fields.selection([('draft','Draft'),('confirm','Confirmed'),('done','Done'),('cancel','Canceled')], 'Status', readonly=True, required=True),
135         'mail_auto_registr':fields.boolean('Mail Auto Register',help='Check this box if you want to use the automatic mailing for new registration'),
136         'mail_auto_confirm':fields.boolean('Mail Auto Confirm',help='Check this box if you want ot use the automatic confirmation emailing or the reminder'),
137         'mail_registr':fields.text('Registration Email',help='This email will be sent when someone subscribes to the event.'),
138         'mail_confirm': fields.text('Confirmation Email', help="This email will be sent when the event gets confimed or when someone subscribes to a confirmed event. This is also the email sent to remind someone about the event."),
139         'product_id':fields.many2one('product.product','Product', required=True),
140     }
141
142     _defaults = {
143         'state': lambda *args: 'draft',
144         'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'event.event'),
145         'user_id': lambda self,cr,uid,ctx: uid,
146
147     }
148 event()
149
150 class event_registration(osv.osv):
151
152     def _history(self, cr, uid,ids,keyword, history=False, email=False, context={}):
153         for case in self.browse(cr, uid, ids):
154             if not case.case_id:
155                 return True
156             data = {
157                 'name': keyword,
158                 'som': case.som.id,
159                 'canal_id': case.canal_id.id,
160                 'user_id': uid,
161                 'case_id': case.case_id.id
162             }
163             obj = self.pool.get('crm.case.log')
164             obj.create(cr, uid, data, context)
165         return True
166
167     def button_reg_close(self, cr, uid, ids, *args):
168         self.write(cr, uid, ids, {'state':'done',})
169         self._history(cr, uid, ids, 'Done', history=True)
170         return True
171
172     def button_reg_cancel(self, cr, uid, ids, *args):
173         self.write(cr, uid, ids, {'state':'cancel',})
174         self._history(cr, uid, ids, 'Cancel', history=True)
175         return True
176
177     def create(self, cr, uid, *args, **argv):
178         event = self.pool.get('event.event').browse(cr, uid, args[0]['event_id'], None)
179         args[0]['section_id']= event.section_id.id
180         args[0]['date_deadline']= event.date_begin
181         args[0]['description']= event.mail_confirm
182         res = super(event_registration, self).create(cr, uid, *args, **argv)
183         self._history(cr, uid,[res], 'Created', history=True)
184         return res
185
186     def write(self, cr, uid, *args, **argv):
187         if 'event_id' in args[1]:
188             event = self.pool.get('event.event').browse(cr, uid, args[1]['event_id'], None)
189             args[1]['section_id']= event.section_id.id
190             args[1]['date_deadline']= event.date_begin
191             args[1]['description']= event.mail_confirm
192         return super(event_registration, self).write(cr, uid, *args, **argv)
193
194     def mail_user_confirm(self,cr,uid,ids):
195         reg_ids=self.browse(cr,uid,ids)
196         for reg_id in reg_ids:
197             src = reg_id.event_id.reply_to or False
198             dest = [reg_id.email_from]
199             if reg_id.email_cc:
200                 dest += [reg_id.email_cc]
201             if dest and src:
202                 tools.email_send(src, dest,'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, tinycrm = str(reg_id.case_id.id))
203             if not src:
204                 raise osv.except_osv(_('Error!'), _('You must define a reply-to address in order to mail the participant. You can do this in the Mailing tab of your event. Note that this is also the place where you can configure your event to not send emails automaticly while registering'))
205         return False
206
207     def mail_user(self,cr,uid,ids):
208         reg_ids=self.browse(cr,uid,ids)
209         for reg_id in reg_ids:
210             src = reg_id.event_id.reply_to or False
211             dest = [reg_id.email_from]
212             if reg_id.email_cc:
213                 dest += [reg_id.email_cc]
214             if reg_id.event_id.mail_auto_confirm or reg_id.event_id.mail_auto_registr:
215                 if dest and src:
216                     if reg_id.event_id.state in ['draft', 'fixed', 'open','confirm','running'] and reg_id.event_id.mail_auto_registr:
217                         tools.email_send(src, dest,'Auto Registration: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_registr, tinycrm = str(reg_id.case_id.id))
218                     if (reg_id.event_id.state in ['confirm','running']) and reg_id.event_id.mail_auto_confirm:
219                         tools.email_send(src, dest,'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, tinycrm = str(reg_id.case_id.id))
220                 if not src:
221                     raise osv.except_osv(_('Error!'), _('You must define a reply-to address in order to mail the participant. You can do this in the Mailing tab of your event. Note that this is also the place where you can configure your event to not send emails automaticly while registering'))
222         return False
223
224     def _create_invoice_lines(self, cr, uid, ids, vals):
225         return self.pool.get('account.invoice.line').create(cr, uid,vals )
226
227     _name= 'event.registration'
228     _description = 'Event Registration'
229     _inherits = {'crm.case': 'case_id'}
230     _columns = {
231         'case_id':fields.many2one('crm.case','Case'),
232         'nb_register': fields.integer('Number of Registration', readonly=True, states={'draft':[('readonly',False)]}),
233         'event_id':fields.many2one('event.event', 'Event Related', required=True),
234         "partner_invoice_id":fields.many2one('res.partner', 'Partner Invoiced'),
235         "contact_id":fields.many2one('res.partner.contact', 'Partner Contact'), #TODO: filter only the contacts that have a function into the selected partner_id
236         "unit_price": fields.float('Unit Price'),
237         "badge_title":fields.char('Badge Title',size=128),
238         "badge_name":fields.char('Badge Name',size=128),
239         "badge_partner":fields.char('Badge Partner',size=128),
240         "invoice_label":fields.char("Label Invoice",size=128,required=True),
241         "tobe_invoiced":fields.boolean("To be Invoiced"),
242         "invoice_id":fields.many2one("account.invoice","Invoice"),
243     }
244     _defaults = {
245         'nb_register': lambda *a: 1,
246         'tobe_invoiced' : lambda *a: True,
247         'name': lambda *a: 'Registration',
248         'state': lambda *b: 'draft'
249     }
250
251     def onchange_badge_name(self, cr, uid, ids, badge_name):
252         data ={}
253         if not badge_name:
254             return data
255         data['name'] = 'Registration: ' + badge_name
256         return {'value':data}
257
258     def onchange_contact_id(self, cr, uid, ids, contact, partner):
259         data ={}
260         if not contact:
261             return data
262         contact_id = self.pool.get('res.partner.contact').browse(cr, uid, contact)
263         data['badge_name'] = contact_id.name
264         data['badge_title'] = contact_id.title
265         if partner:
266             partner_addresses = self.pool.get('res.partner.address').search(cr, uid, [('partner_id','=',partner)])
267             job_ids = self.pool.get('res.partner.job').search(cr, uid, [('contact_id','=',contact),('address_id','in',partner_addresses)])
268             if job_ids:
269                 data['email_from'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).email
270         d = self.onchange_badge_name(cr, uid, ids,data['badge_name'])
271         data.update(d['value'])
272
273         return {'value':data}
274
275     def onchange_event(self, cr, uid, ids, event_id, partner_invoice_id):
276         context={}
277         if not event_id:
278             return {'value':{'unit_price' : False ,'invoice_label' : False }}
279         data_event =  self.pool.get('event.event').browse(cr,uid,event_id)
280         if data_event.product_id:
281             if not partner_invoice_id:
282                 unit_price=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id],context=context)[data_event.product_id.id]
283                 return {'value':{'unit_price' : unit_price , 'invoice_label' : data_event.product_id.name}}
284             data_partner = self.pool.get('res.partner').browse(cr,uid,partner_invoice_id)
285             context.update({'partner_id':data_partner})
286             unit_price = self.pool.get('product.product')._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist':data_partner.property_product_pricelist.id})[data_event.product_id.id]
287             return {'value':{'unit_price' :unit_price , 'invoice_label' : data_event.product_id.name}}
288         return {'value':{'unit_price' : False,'invoice_label' : False}}
289
290
291     def onchange_partner_id(self, cr, uid, ids, part, event_id, email=False):
292         data={}
293         data['badge_partner'] = data['contact_id'] = data['partner_invoice_id'] = data['email_from'] = data['badge_title'] = data['badge_name'] = False
294         if not part:
295             return {'value':data}
296         data['partner_invoice_id']=part
297         # this calls onchange_partner_invoice_id
298         d = self.onchange_partner_invoice_id(cr, uid, ids, event_id,part)
299         # this updates the dictionary
300         data.update(d['value'])
301         addr = self.pool.get('res.partner').address_get(cr, uid, [part])
302         if addr:
303             if addr.has_key('default'):
304                 job_ids = self.pool.get('res.partner.job').search(cr, uid, [('address_id','=',addr['default'])])
305                 if job_ids:
306                     data['contact_id'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).contact_id.id
307                     d = self.onchange_contact_id(cr, uid, ids, data['contact_id'],part)
308                     data.update(d['value'])
309         partner_data = self.pool.get('res.partner').browse(cr, uid, part)
310         data['badge_partner'] = partner_data.name
311         return {'value':data}
312
313     def onchange_partner_invoice_id(self, cr, uid, ids, event_id, partner_invoice_id):
314         data={}
315         context={}
316         data['unit_price']=False
317         if not event_id:
318             return {'value':data}
319         data_event =  self.pool.get('event.event').browse(cr,uid,event_id)
320
321         if data_event.product_id:
322             if not partner_invoice_id:
323                 data['unit_price']=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id],context=context)[data_event.product_id.id]
324                 return {'value':data}
325             data_partner = self.pool.get('res.partner').browse(cr,uid,partner_invoice_id)
326             context.update({'partner_id':data_partner})
327             data['unit_price'] = self.pool.get('product.product')._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist':data_partner.property_product_pricelist.id})[data_event.product_id.id]
328             return {'value':data}
329         return {'value':data}
330
331     def onchange_categ_id(self, cr, uid, ids, categ, context={}):
332         if not categ:
333             return {'value':{}}
334         cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
335         return {'value':{'probability':cat}}
336
337     def _map_ids(self,method,cr, uid, ids, *args, **argv):
338         case_data = self.browse(cr,uid,ids)
339         new_ids=[]
340         for case in case_data:
341             if case.case_id:
342                 new_ids.append(case.case_id.id)
343         return getattr(self.pool.get('crm.case'),method)(cr, uid, new_ids, *args, **argv)
344
345
346     def case_close(self,cr, uid, ids, *args, **argv):
347         return self._map_ids('case_close',cr,uid,ids,*args,**argv)
348     def case_escalate(self,cr, uid, ids, *args, **argv):
349         return self._map_ids('case_escalate',cr,uid,ids,*args,**argv)
350     def case_open(self,cr, uid, ids, *args, **argv):
351         return self._map_ids('case_open',cr,uid,ids,*args,**argv)
352     def case_cancel(self,cr, uid, ids, *args, **argv):
353         return self._map_ids('case_cancel',cr,uid,ids,*args,**argv)
354     def case_pending(self,cr, uid, ids, *args, **argv):
355         return self._map_ids('case_pending',cr,uid,ids,*args,**argv)
356     def case_reset(self,cr, uid, ids, *args, **argv):
357         return self._map_ids('case_reset',cr,uid,ids,*args,**argv)
358     def case_log(self,cr, uid, ids, *args, **argv):
359         return self._map_ids('case_log',cr,uid,ids,*args,**argv)
360     def case_log_reply(self,cr, uid, ids, *args, **argv):
361         return self._map_ids('case_log_reply',cr,uid,ids,*args,**argv)
362     def add_reply(self,cr, uid, ids, *args, **argv):
363         return self._map_ids('add_reply',cr,uid,ids,*args,**argv)
364     def remind_partner(self,cr, uid, ids, *args, **argv):
365         return self._map_ids('remind_partner',cr,uid,ids,*args,**argv)
366     def remind_user(self,cr, uid, ids, *args, **argv):
367         return self._map_ids('remind_user',cr,uid,ids,*args,**argv)
368
369
370 event_registration()
371
372
373
374 class report_event_registration(osv.osv):
375     _name = "report.event.registration"
376     _description = "Events on registrations"
377     _auto = False
378     _columns = {
379         'name': fields.char('Event',size=20),
380         'date_begin': fields.datetime('Beginning date', required=True),
381         'date_end': fields.datetime('Ending date', required=True),
382         'draft_state': fields.integer('Draft Registration',size=20),
383         'confirm_state': fields.integer('Confirm Registration',size=20),
384         'register_max': fields.integer('Maximum Registrations'),
385     }
386     def init(self, cr):
387         cr.execute("""
388             create or replace view report_event_registration as (
389                 select
390                 e.id as id,
391                 c.name as name,
392                 e.date_begin as date_begin,
393                 e.date_end as date_end,
394                 (SELECT sum(nb_register) FROM event_registration x , crm_case c  WHERE x.case_id=c.id and c.section_id=e.section_id and state in ('draft')) as draft_state,
395                 (SELECT sum(nb_register) FROM event_registration x , crm_case c  WHERE x.case_id=c.id and c.section_id=e.section_id and state in ('open')) as confirm_state,
396                 e.register_max as register_max
397                 from
398                 event_event e,crm_case_section c
399                 where
400                 e.section_id=c.id
401                 )""")
402
403 report_event_registration()
404
405 class report_event_type_registration(osv.osv):
406     _name = "report.event.type.registration"
407     _description = "Event type on registration"
408     _auto = False
409     _columns = {
410         'name': fields.char('Event Type',size=20),
411         'nbevent':fields.integer('Number Of Events'),
412         'draft_state': fields.integer('Draft Registrations',size=20),
413         'confirm_state': fields.integer('Confirm Registrations',size=20),
414         }
415     def init(self, cr):
416         cr.execute("""
417             create or replace view report_event_type_registration as (
418                 select
419                 count(t.id) as id,
420                 t.name as name,
421                 (select sum(nb_register) from event_registration r , crm_case c , event_event e  where c.section_id=e.section_id and r.case_id=c.id and c.state='draft' and e.type=t.id ) as draft_state ,
422                 (select sum(nb_register) from event_registration r , crm_case c , event_event e  where c.section_id=e.section_id and r.case_id=c.id and c.state='open' and e.type=t.id ) as  confirm_state,
423                 count(t.id) as nbevent
424                 from
425                     event_event e
426                 inner join
427                     crm_case_section c1 on (e.section_id=c1.id)
428                 inner join
429                     event_type t on (e.type=t.id)
430                 group by
431                     t.name,t.id
432
433             )""")
434 report_event_type_registration()
435
436
437 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
438