1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
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.
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.
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/>.
20 ##############################################################################
23 from osv import fields, osv
24 from tools.translate import _
31 class event_type(osv.osv):
36 _description = __doc__
38 'name': fields.char('Event type', size=64, required=True),
48 _description = __doc__
49 _inherit = 'crm.case.section'
52 def copy(self, cr, uid, id, default=None, context=None):
55 Copy record of Given id
56 @param self: The object pointer
57 @param cr: the current row, from the database cursor,
58 @param uid: the current user’s ID for security checks,
59 @param id: Id of Event Registration type record.
60 @param context: A standard dictionary for contextual values
63 return super(event, self).copy(cr, uid, id, default={'code': self.pool.get('ir.sequence').get(cr, uid, 'event.event'), 'state': 'draft'})
65 def button_draft(self, cr, uid, ids, context={}):
66 return self.write(cr, uid, ids, {'state': 'draft'})
68 def button_cancel(self, cr, uid, ids, context={}):
69 return self.write(cr, uid, ids, {'state': 'cancel'})
71 def button_done(self, cr, uid, ids, context={}):
72 return self.write(cr, uid, ids, {'state': 'done'})
74 def button_confirm(self, cr, uid, ids, context={}):
76 for eve in self.browse(cr, uid, ids):
77 if eve.mail_auto_confirm:
78 #send reminder that will confirm the event for all the people that were already confirmed
79 reg_ids = self.pool.get('event.registration').search(cr, uid,
80 [('event_id', '=', eve.id),
81 ('state', 'not in', ['draft', 'cancel'])])
83 self.pool.get('event.registration').mail_user_confirm(cr, uid, reg_ids)
85 return self.write(cr, uid, ids, {'state': 'confirm'})
87 def _get_register(self, cr, uid, ids, name, args, context=None):
90 Get Confirm or uncofirm register value.
91 @param self: The object pointer
92 @param cr: the current row, from the database cursor,
93 @param uid: the current user’s ID for security checks,
94 @param ids: List of Event registration type's id
95 @param name: List of function fields(register_current and register_prospect).
96 @param context: A standard dictionary for contextual values
97 @return: Dictionary of function fields value.
101 for event in self.browse(cr, uid, ids, context):
104 if name[0] == 'register_current':
106 query = """SELECT sum(r.nb_register)
107 from event_registration r
108 where state=%s and event_id=%s"""
110 cr.execute(query, (state, event.id,))
114 res[event.id][name[0]] = res2[0]
116 res[event.id][name[0]] = 0
120 def write(self, cr, uid, ids, vals, *args, **kwargs):
122 Writes values in one or several fields.
123 @param cr: the current row, from the database cursor,
124 @param uid: the current user’s ID for security checks,
125 @param ids: List of Event registration type's IDs
126 @param vals: dictionary with values to update.
130 res = super(event, self).write(cr, uid, ids, vals, *args, **kwargs)
131 if 'date_begin' in vals and vals['date_begin']:
132 for eve in self.browse(cr, uid, ids):
133 #change the deadlines of the registration linked to this event
134 reg_ids = self.pool.get('event.registration').search(cr, uid,
135 [('event_id', '=', eve.id)])
137 self.pool.get('event.registration').write(cr, uid, reg_ids,
138 {'date_deadline': vals['date_begin']})
140 #change the description of the registration linked to this event
141 if 'mail_auto_confirm' in vals:
142 if vals['mail_auto_confirm']:
143 if 'mail_confirm' not in vals:
144 for eve in self.browse(cr, uid, ids):
145 vals['mail_confirm'] = eve.mail_confirm
147 vals['mail_confirm'] = False
148 if 'mail_confirm' in vals:
149 for eve in self.browse(cr, uid, ids):
150 reg_ids = self.pool.get('event.registration').search(cr, uid,
151 [('event_id', '=', eve.id)])
153 self.pool.get('event.registration').write(cr, uid, reg_ids,
154 {'description': vals['mail_confirm']})
158 'type': fields.many2one('event.type', 'Type'),
159 'register_max': fields.integer('Maximum Registrations'),
160 'register_min': fields.integer('Minimum Registrations'),
161 'register_current': fields.function(_get_register, method=True, string='Confirmed Registrations', multi='register_current'),
162 'register_prospect': fields.function(_get_register, method=True, string='Unconfirmed Registrations', multi='register_prospect'),
163 'date_begin': fields.datetime('Beginning date', required=True),
164 'date_end': fields.datetime('Ending date', required=True),
165 'state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, required=True,
166 help='If event is created, the state is \'Draft\'.\n If event is confirmed for the particular dates the state is set to \'Confirmed\'.\
167 \nIf the event is over, the state is set to \'Done\'.\n If event is cancelled the state is set to \'Cancelled\'.'),
168 'mail_auto_registr': fields.boolean('Mail Auto Register', help='Check this box if you want to use the automatic mailing for new registration'),
169 'mail_auto_confirm': fields.boolean('Mail Auto Confirm', help='Check this box if you want ot use the automatic confirmation emailing or the reminder'),
170 'mail_registr': fields.text('Registration Email', help='This email will be sent when someone subscribes to the event.'),
171 '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."),
172 'product_id': fields.many2one('product.product', 'Product', required=True),
176 'state': lambda *args: 'draft',
177 'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'event.event'),
178 'user_id': lambda self, cr, uid, ctx: uid,
183 class event_registration(osv.osv):
185 """Event Registration"""
187 def check_confirm(self, cr, uid, ids, context):
190 Check confirm event register on given id.
191 @param cr: the current row, from the database cursor,
192 @param uid: the current user’s ID for security checks,
193 @param ids: List of Event registration's IDs
194 @param context: A standard dictionary for contextual values
195 @return: Dictionary value which open Confirm registration form.
198 mod_obj = self.pool.get('ir.model.data')
199 current_registration = self.browse(cr, uid, [ids[0]])[0]
200 total_confirmed = current_registration.event_id.register_current + current_registration.nb_register
201 if total_confirmed <= current_registration.event_id.register_max or current_registration.event_id.register_max == 0:
202 self.write(cr, uid, [ids[0]], {'state': 'open'}, context=context)
203 self._history(cr, uid, [ids[0]], 'Open', history=True)
204 self.mail_user(cr, uid, [ids[0]])
207 model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'view_event_confirm_registration')], context=context)
208 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
209 context.update({'reg_id': ids[0]})
211 'name': _('Confirm Registration'),
214 'view_mode': 'tree,form',
215 'res_model': 'event.confirm.registration',
216 'views': [(resource_id, 'form')],
217 'type': 'ir.actions.act_window',
222 def _history(self, cr, uid, ids, keyword, history=False, email=False, context={}):
225 Create value in mailgateway.message model.
226 @param cr: the current row, from the database cursor,
227 @param uid: the current user’s ID for security checks,
228 @param ids: List of Event registration's IDs
229 @param context: A standard dictionary for contextual values
233 for case in self.browse(cr, uid, ids):
237 'canal_id': case.canal_id.id,
240 obj = self.pool.get('mailgate.message')
241 obj.create(cr, uid, data, context=context)
244 def button_reg_close(self, cr, uid, ids, *args):
245 self.write(cr, uid, ids, {'state': 'done', })
246 self._history(cr, uid, ids, 'Done', history=True)
249 def button_reg_cancel(self, cr, uid, ids, *args):
250 self.write(cr, uid, ids, {'state': 'cancel', })
251 self._history(cr, uid, ids, 'Cancel', history=True)
254 def create(self, cr, uid, *args, **argv):
255 """ Overrides orm create method.
256 @param self: The object pointer
257 @param cr: the current row, from the database cursor,
258 @param uid: the current user’s ID for security checks,
259 @param *args: Fields value
260 @return : New created record Id.
263 event = self.pool.get('event.event').browse(cr, uid, args[0]['event_id'], None)
265 args[0]['date_deadline']= event.date_begin
266 args[0]['description']= event.mail_confirm
267 res = super(event_registration, self).create(cr, uid, *args, **argv)
269 self._history(cr, uid, [res], 'Created', history=True)
273 def write(self, cr, uid, *args, **argv):
275 if 'event_id' in args[1]:
276 event = self.pool.get('event.event').browse(cr, uid, args[1]['event_id'], None)
278 args[1]['date_deadline']= event.date_begin
279 args[1]['description']= event.mail_confirm
280 return super(event_registration, self).write(cr, uid, *args, **argv)
282 def mail_user_confirm(self, cr, uid, ids):
284 @param self: The object pointer
285 @param cr: the current row, from the database cursor,
286 @param uid: the current user’s ID for security checks,
287 @param ids: List of Event Registration's Id.
291 reg_ids = self.browse(cr, uid, ids)
292 for reg_id in reg_ids:
293 src = reg_id.event_id.reply_to or False
295 if reg_id.email_from:
296 dest += [reg_id.email_from]
298 dest += [reg_id.email_cc]
300 tools.email_send(src, dest, 'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, openobject_id = str(reg_id.id))
302 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'))
305 def mail_user(self, cr, uid, ids):
307 @param self: The object pointer
308 @param cr: the current row, from the database cursor,
309 @param uid: the current user’s ID for security checks,
310 @param ids: List of Event Registration's Id.
313 reg_ids = self.browse(cr, uid, ids)
315 for reg_id in reg_ids:
316 src = reg_id.event_id.reply_to or False
318 if reg_id.email_from:
319 dest += [reg_id.email_from]
321 dest += [reg_id.email_cc]
322 if reg_id.event_id.mail_auto_confirm or reg_id.event_id.mail_auto_registr:
324 if reg_id.event_id.state in ['draft', 'fixed', 'open', 'confirm', 'running'] and reg_id.event_id.mail_auto_registr:
325 tools.email_send(src, dest, 'Auto Registration: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_registr, openobject_id = str(reg_id.id))
326 if (reg_id.event_id.state in ['confirm', 'running']) and reg_id.event_id.mail_auto_confirm:
327 tools.email_send(src, dest, 'Auto Confirmation: '+'['+str(reg_id.id)+']'+' '+reg_id.name, reg_id.event_id.mail_confirm, openobject_id = str(reg_id.id))
329 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'))
332 def _create_invoice_lines(self, cr, uid, ids, vals):
334 """ Create account Invoice line for Registration Id.
335 @param self: The object pointer
336 @param cr: the current row, from the database cursor,
337 @param uid: the current user’s ID for security checks,
338 @param Ids: List of event registration's Id
339 @param vals: Create fields value
340 @return : New created record Id.
343 return self.pool.get('account.invoice.line').create(cr, uid, vals)
345 _name= 'event.registration'
346 _description = __doc__
347 _inherit = 'crm.meeting'
350 'email_cc': fields.text('Watchers Emails', size=252 , help="These \
351 people will receive a copy of the future communication between partner \
352 and users by email"),
353 'nb_register': fields.integer('Number of Registration', readonly=True, states={'draft': [('readonly', False)]}),
354 'event_id': fields.many2one('event.event', 'Event Related', required=True),
355 "partner_invoice_id": fields.many2one('res.partner', 'Partner Invoiced'),
356 "contact_id": fields.many2one('res.partner.contact', 'Partner Contact'), #TODO: filter only the contacts that have a function into the selected partner_id
357 "unit_price": fields.float('Unit Price'),
358 "badge_title": fields.char('Badge Title', size=128),
359 "badge_name": fields.char('Badge Name', size=128),
360 "badge_partner": fields.char('Badge Partner', size=128),
361 "invoice_label": fields.char("Label Invoice", size=128, required=True),
362 "tobe_invoiced": fields.boolean("To be Invoiced"),
363 "invoice_id": fields.many2one("account.invoice", "Invoice"),
364 'date_closed': fields.datetime('Closed', readonly=True),
365 'ref': fields.reference('Reference', selection=crm._links_get, size=128),
366 'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
367 'canal_id': fields.many2one('res.partner.canal', 'Channel', help="The channels represent the different communication modes available with the customer." \
368 " With each commercial opportunity, you can indicate the canall which is this opportunity source."),
369 'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
370 "the partner mentality in relation to our services.The scale has" \
371 "to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."),
375 'nb_register': lambda *a: 1,
376 'tobe_invoiced': lambda *a: True,
377 'name': lambda *a: 'Registration',
380 def onchange_badge_name(self, cr, uid, ids, badge_name):
385 data['name'] = 'Registration: ' + badge_name
386 return {'value': data}
388 def onchange_contact_id(self, cr, uid, ids, contact, partner):
394 contact_id = self.pool.get('res.partner.contact').browse(cr, uid, contact)
395 data['badge_name'] = contact_id.name
396 data['badge_title'] = contact_id.title
398 partner_addresses = self.pool.get('res.partner.address').search(cr, uid, [('partner_id', '=', partner)])
399 job_ids = self.pool.get('res.partner.job').search(cr, uid, [('contact_id', '=', contact), ('address_id', 'in', partner_addresses)])
401 data['email_from'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).email
402 d = self.onchange_badge_name(cr, uid, ids, data['badge_name'])
403 data.update(d['value'])
405 return {'value': data}
407 def onchange_event(self, cr, uid, ids, event_id, partner_invoice_id):
410 return {'value': {'unit_price': False, 'invoice_label': False}}
411 data_event = self.pool.get('event.event').browse(cr, uid, event_id)
413 if data_event.product_id:
414 if not partner_invoice_id:
415 unit_price=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id]
416 return {'value': {'unit_price': unit_price, 'invoice_label': data_event.product_id.name}}
417 data_partner = self.pool.get('res.partner').browse(cr, uid, partner_invoice_id)
418 context.update({'partner_id': data_partner})
419 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]
420 return {'value': {'unit_price': unit_price, 'invoice_label': data_event.product_id.name}}
422 return {'value': {'unit_price': False, 'invoice_label': False}}
425 def onchange_partner_id(self, cr, uid, ids, part, event_id, email=False):
428 data['badge_partner'] = data['contact_id'] = data['partner_invoice_id'] = data['email_from'] = data['badge_title'] = data['badge_name'] = False
430 return {'value': data}
431 data['partner_invoice_id']=part
432 # this calls onchange_partner_invoice_id
433 d = self.onchange_partner_invoice_id(cr, uid, ids, event_id, part)
434 # this updates the dictionary
435 data.update(d['value'])
436 addr = self.pool.get('res.partner').address_get(cr, uid, [part])
438 if addr.has_key('default'):
439 job_ids = self.pool.get('res.partner.job').search(cr, uid, [('address_id', '=', addr['default'])])
441 data['contact_id'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).contact_id.id
442 d = self.onchange_contact_id(cr, uid, ids, data['contact_id'], part)
443 data.update(d['value'])
444 partner_data = self.pool.get('res.partner').browse(cr, uid, part)
445 data['badge_partner'] = partner_data.name
446 return {'value': data}
448 def onchange_partner_invoice_id(self, cr, uid, ids, event_id, partner_invoice_id):
452 data['unit_price']=False
454 return {'value': data}
455 data_event = self.pool.get('event.event').browse(cr, uid, event_id)
457 if data_event.product_id:
458 if not partner_invoice_id:
459 data['unit_price']=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id]
460 return {'value': data}
461 data_partner = self.pool.get('res.partner').browse(cr, uid, partner_invoice_id)
462 context.update({'partner_id': data_partner})
463 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]
464 return {'value': data}
465 return {'value': data}
471 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: