1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
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.
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.
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/>.
21 ##############################################################################
23 from osv import fields, osv
28 from tools.translate import _
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)
38 'user_id': lambda self,cr,uid,context: uid,
42 class event_type(osv.osv):
44 _description= 'Event type'
46 'name': fields.char('Event type', size=64, required=True),
52 _description = 'Event'
53 _inherits = {'crm.case.section': 'section_id'}
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'})
59 def button_draft(self, cr, uid, ids, context={}):
60 return self.write(cr, uid, ids, {'state':'draft'})
62 def button_cancel(self, cr, uid, ids, context={}):
63 return self.write(cr, uid, ids, {'state':'cancel'})
65 def button_done(self, cr, uid, ids, context={}):
66 return self.write(cr, uid, ids, {'state':'done'})
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'])])
74 self.pool.get('event.registration').mail_user_confirm(cr, uid, reg_ids)
75 return self.write(cr, uid, ids, {'state':'confirm'})
77 def _get_register(self, cr, uid, ids, name, args, context=None):
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
84 res[event.id] = res2[0]
89 def _get_prospect(self, cr, uid, ids, name, args, context=None):
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
96 res[event.id] = res2[0]
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)])
108 self.pool.get('event.registration').write(cr, uid, reg_ids, {'date_deadline':vals['date_begin']})
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
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)])
122 self.pool.get('event.registration').write(cr, uid, reg_ids, {'description':vals['mail_confirm']})
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),
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,
150 class event_registration(osv.osv):
152 def _history(self, cr, uid,ids,keyword, history=False, email=False, context={}):
153 for case in self.browse(cr, uid, ids):
159 'canal_id': case.canal_id.id,
161 'case_id': case.case_id.id
163 obj = self.pool.get('crm.case.log')
164 obj.create(cr, uid, data, context)
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)
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)
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)
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)
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]
200 dest += [reg_id.email_cc]
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))
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'))
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]
213 dest += [reg_id.email_cc]
214 if reg_id.event_id.mail_auto_confirm or reg_id.event_id.mail_auto_registr:
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))
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'))
224 def _create_invoice_lines(self, cr, uid, ids, vals):
225 return self.pool.get('account.invoice.line').create(cr, uid,vals )
227 _name= 'event.registration'
228 _description = 'Event Registration'
229 _inherits = {'crm.case': 'case_id'}
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"),
245 'nb_register': lambda *a: 1,
246 'tobe_invoiced' : lambda *a: True,
247 'name': lambda *a: 'Registration',
248 'state': lambda *b: 'draft'
251 def onchange_badge_name(self, cr, uid, ids, badge_name):
255 data['name'] = 'Registration: ' + badge_name
256 return {'value':data}
258 def onchange_contact_id(self, cr, uid, ids, contact, partner):
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
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)])
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'])
273 return {'value':data}
275 def onchange_event(self, cr, uid, ids, event_id, partner_invoice_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}}
291 def onchange_partner_id(self, cr, uid, ids, part, event_id, email=False):
293 data['badge_partner'] = data['contact_id'] = data['partner_invoice_id'] = data['email_from'] = data['badge_title'] = data['badge_name'] = False
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])
303 if addr.has_key('default'):
304 job_ids = self.pool.get('res.partner.job').search(cr, uid, [('address_id','=',addr['default'])])
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}
313 def onchange_partner_invoice_id(self, cr, uid, ids, event_id, partner_invoice_id):
316 data['unit_price']=False
318 return {'value':data}
319 data_event = self.pool.get('event.event').browse(cr,uid,event_id)
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}
331 def onchange_categ_id(self, cr, uid, ids, categ, context={}):
334 cat = self.pool.get('crm.case.categ').browse(cr, uid, categ, context).probability
335 return {'value':{'probability':cat}}
337 def _map_ids(self,method,cr, uid, ids, *args, **argv):
338 case_data = self.browse(cr,uid,ids)
340 for case in case_data:
342 new_ids.append(case.case_id.id)
343 return getattr(self.pool.get('crm.case'),method)(cr, uid, new_ids, *args, **argv)
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)
374 class report_event_registration(osv.osv):
375 _name = "report.event.registration"
376 _description = "Events on registrations"
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'),
388 create or replace view report_event_registration as (
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
398 event_event e,crm_case_section c
403 report_event_registration()
405 class report_event_type_registration(osv.osv):
406 _name = "report.event.type.registration"
407 _description = "Event type on registration"
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),
417 create or replace view report_event_type_registration as (
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
427 crm_case_section c1 on (e.section_id=c1.id)
429 event_type t on (e.type=t.id)
434 report_event_type_registration()
437 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: