[IMP]: event: usability Improvement and Improve make invoice wizard.
[odoo/odoo.git] / addons / event / 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 crm import crm
23 from osv import fields, osv
24 from tools.translate import _
25 import netsvc
26 import pooler
27 import time
28 import tools
29
30
31 class event_type(osv.osv):
32     
33     """ Event Type """
34     
35     _name = 'event.type'
36     _description = __doc__
37     _columns = {
38         'name': fields.char('Event type', size=64, required=True), 
39     }
40     
41 event_type()
42
43 class event(osv.osv):
44     
45     """Event"""
46     
47     _name = 'event.event'
48     _description = __doc__
49     _inherit = 'crm.case.section'
50     _order = 'date_begin'
51
52     def copy(self, cr, uid, id, default=None, context=None):
53         
54         """
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
61         """
62         
63         return super(event, self).copy(cr, uid, id, default={'code': self.pool.get('ir.sequence').get(cr, uid, 'event.event'), 'state': 'draft'})
64
65     def button_draft(self, cr, uid, ids, context={}):
66         return self.write(cr, uid, ids, {'state': 'draft'})
67
68     def button_cancel(self, cr, uid, ids, context={}):
69         return self.write(cr, uid, ids, {'state': 'cancel'})
70
71     def button_done(self, cr, uid, ids, context={}):
72         return self.write(cr, uid, ids, {'state': 'done'})
73
74     def button_confirm(self, cr, uid, ids, context={}):
75         
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'])])
82                 if reg_ids:
83                     self.pool.get('event.registration').mail_user_confirm(cr, uid, reg_ids)
84                     
85         return self.write(cr, uid, ids, {'state': 'confirm'})
86     
87     
88     
89     
90     
91
92     def _get_register(self, cr, uid, ids, name, args, context=None):
93         
94         """
95         Get Confirm or uncofirm register value. 
96         @param self: The object pointer
97         @param cr: the current row, from the database cursor,
98         @param uid: the current user’s ID for security checks,
99         @param ids: List of Event registration type's id
100         @param name: List of function fields(register_current and register_prospect).
101         @param context: A standard dictionary for contextual values
102         @return: Dictionary of function fields value. 
103         """
104         
105         res = {}
106         for event in self.browse(cr, uid, ids, context):
107             res[event.id] = {}
108             state = 'draft'
109             if name[0] == 'register_current':
110                 state = 'open'
111             query = """SELECT sum(r.nb_register) 
112                         from event_registration r 
113                         where state=%s and event_id=%s"""
114
115             cr.execute(query, (state, event.id,))
116             res2 = cr.fetchone()
117             
118             if res2 and res2[0]:
119                 res[event.id][name[0]] = res2[0]
120             else:
121                 res[event.id][name[0]] = 0
122                
123         return res
124
125     def write(self, cr, uid, ids, vals, *args, **kwargs):
126         """
127         Writes values in one or several fields.
128         @param cr: the current row, from the database cursor,
129         @param uid: the current user’s ID for security checks,
130         @param ids: List of Event registration type's IDs
131         @param vals: dictionary with values to update.
132         @return: True
133         """
134         res = super(event, self).write(cr, uid, ids, vals, *args, **kwargs)
135         
136         if 'date_begin' in vals and vals['date_begin']:
137             
138             for eve in self.browse(cr, uid, ids):
139                 #change the deadlines of the registration linked to this event
140                 reg_ids = self.pool.get('event.registration').search(cr, uid, 
141                                                                      [('event_id', '=', eve.id)])
142                 if reg_ids:
143                     self.pool.get('event.registration').write(cr, uid, reg_ids, 
144                                                               {'date_deadline': vals['date_begin']})
145
146         #change the description of the registration linked to this event
147         if 'mail_auto_confirm' in vals:
148             if vals['mail_auto_confirm']:
149                 if 'mail_confirm' not in vals:
150                     for eve in self.browse(cr, uid, ids):
151                         vals['mail_confirm'] = eve.mail_confirm
152             else:
153                 vals['mail_confirm'] = False
154         if 'mail_confirm' in vals:
155             for eve in self.browse(cr, uid, ids):
156                 reg_ids = self.pool.get('event.registration').search(cr, uid, 
157                                                                      [('event_id', '=', eve.id)])
158                 if reg_ids:
159                     self.pool.get('event.registration').write(cr, uid, reg_ids, 
160                                                               {'description': vals['mail_confirm']})
161         return res
162
163     _columns = {
164         'type': fields.many2one('event.type', 'Type'), 
165         'register_max': fields.integer('Maximum Registrations'), 
166         'register_min': fields.integer('Minimum Registrations'), 
167         'register_current': fields.function(_get_register, method=True, string='Confirmed Registrations', multi='register_current'), 
168         'register_prospect': fields.function(_get_register, method=True, string='Unconfirmed Registrations', multi='register_prospect'), 
169         'date_begin': fields.datetime('Beginning date', required=True), 
170         'date_end': fields.datetime('Ending date', required=True), 
171         'state': fields.selection([('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', readonly=True, required=True, 
172                                   help='If event is created, the state is \'Draft\'.\n If event is confirmed for the particular dates the state is set to \'Confirmed\'.\
173                                   \nIf the event is over, the state is set to \'Done\'.\n If event is cancelled the state is set to \'Cancelled\'.'), 
174         'mail_auto_registr': fields.boolean('Mail Auto Register', help='Check this box if you want to use the automatic mailing for new registration'), 
175         'mail_auto_confirm': fields.boolean('Mail Auto Confirm', help='Check this box if you want ot use the automatic confirmation emailing or the reminder'), 
176         'mail_registr': fields.text('Registration Email', help='This email will be sent when someone subscribes to the event.'), 
177         '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."), 
178         'product_id': fields.many2one('product.product', 'Product', required=True),
179         'note': fields.text('Notes')
180     }
181
182     _defaults = {
183         'state': lambda *args: 'draft', 
184 #        'code': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'event.event'), 
185         'user_id': lambda self, cr, uid, ctx: uid, 
186     }
187
188 event()
189
190 class event_registration(osv.osv):
191     
192     """Event Registration"""
193
194     def _make_invoice(self, cr, uid, reg, lines, context=None):
195         
196         if context is None:
197             context = {}
198         inv_obj = self.pool.get('account.invoice')
199
200         obj_lines = self.pool.get('account.invoice.line')
201         
202         val_invoice = inv_obj.onchange_partner_id(cr, uid, [], 'out_invoice', reg.partner_invoice_id.id, False, False)
203             
204         val_invoice['value'].update({'partner_id': reg.partner_invoice_id.id})
205         partner_address_id = val_invoice['value']['address_invoice_id']
206         value = obj_lines.product_id_change(cr, uid, [], reg.event_id.product_id.id, uom =False, partner_id=reg.partner_invoice_id.id, fposition_id=reg.partner_invoice_id.property_account_position.id)
207         
208         l = obj_lines.read(cr, uid, lines)
209         
210         val_invoice['value'].update({
211                 'origin': reg.event_product, 
212                 'reference': False, 
213                 'invoice_line': [(6, 0, lines)], 
214                 'comment': "", 
215             })
216         inv_id = inv_obj.create(cr, uid, val_invoice['value'])
217         
218         self._history(cr, uid, [reg], _('Invoiced'))
219 #
220         inv_obj.button_compute(cr, uid, [inv_id])
221         return inv_id
222
223     def action_invoice_create(self, cr, uid, ids, grouped=False, date_inv = False):
224
225         res = False
226         invoices = {}
227         tax_ids=[]
228         
229         obj_reg = self.pool.get('event.registration')
230         obj_lines = self.pool.get('account.invoice.line')
231         inv_obj = self.pool.get('account.invoice')
232
233         context = {}
234         # If date was specified, use it as date invoiced, usefull when invoices are generated this month and put the
235         # last day of the last month as invoice date
236         if date_inv:
237             context['date_inv'] = date_inv
238        
239         obj_event_reg = self.pool.get('event.registration')
240         obj_lines = self.pool.get('account.invoice.line')
241         inv_obj = self.pool.get('account.invoice')
242         data_event_reg = obj_event_reg.browse(cr, uid, ids, context=context)
243
244         for reg in data_event_reg:
245             
246             val_invoice = inv_obj.onchange_partner_id(cr, uid, [], 'out_invoice', reg.partner_invoice_id.id, False, False)
247             
248             val_invoice['value'].update({'partner_id': reg.partner_invoice_id.id})
249             partner_address_id = val_invoice['value']['address_invoice_id']
250                 
251             if not partner_address_id:
252                raise osv.except_osv(_('Error !'),
253                         _("Registered partner doesn't have an address to make the invoice."))
254                                 
255             value = obj_lines.product_id_change(cr, uid, [], reg.event_id.product_id.id, uom =False, partner_id=reg.partner_invoice_id.id, fposition_id=reg.partner_invoice_id.property_account_position.id)
256             data_product = self.pool.get('product.product').browse(cr, uid, [reg.event_id.product_id.id])
257             for tax in data_product[0].taxes_id:
258                 tax_ids.append(tax.id)
259
260             vals = value['value']
261             c_name = reg.contact_id and ('-' + self.pool.get('res.partner.contact').name_get(cr, uid, [reg.contact_id.id])[0][1]) or ''
262             vals.update({
263                 'name': reg.event_product + '-' + c_name, 
264                 'price_unit': reg.unit_price, 
265                 'quantity': reg.nb_register, 
266                 'product_id':reg.event_id.product_id.id, 
267                 'invoice_line_tax_id': [(6, 0, tax_ids)], 
268             })
269             inv_line_ids = obj_event_reg._create_invoice_lines(cr, uid, [reg.id], vals)
270             invoices.setdefault(reg.partner_id.id, []).append((reg, inv_line_ids))
271            
272         for val in invoices.values():
273             if grouped:
274                 res = self._make_invoice(cr, uid, val[0][0], [v for k , v in val], context=context)
275                 
276                 for k , v in val:
277                     self.write(cr, uid, [k.id], {'state': 'done', 'invoice_id': res})
278                     
279             else:
280                for k , v in val:
281                    res = self._make_invoice(cr, uid, k, [v], context=context)
282                    self.write(cr, uid, [k.id], {'state': 'done', 'invoice_id': res})
283                 #res = self._make_invoice(cr, uid, val[0][0], m, context=context)       
284         return res
285
286     def check_confirm(self, cr, uid, ids, context):
287         
288         """
289         Check confirm event register on given id.
290         @param cr: the current row, from the database cursor,
291         @param uid: the current user’s ID for security checks,
292         @param ids: List of Event registration's IDs
293         @param context: A standard dictionary for contextual values
294         @return: Dictionary value which open Confirm registration form.
295         """
296         registration_obj = self.browse(cr, uid, ids)
297         self._history(cr, uid, registration_obj, _('Open'))
298         mod_obj = self.pool.get('ir.model.data')
299         
300         for current_registration in registration_obj: 
301             
302             total_confirmed = current_registration.event_id.register_current + current_registration.nb_register
303             if total_confirmed <= current_registration.event_id.register_max or current_registration.event_id.register_max == 0:
304                 self.write(cr, uid, ids, {'state': 'open'}, context=context)
305                 self.mail_user(cr, uid, ids)
306             
307                 return True
308             else:
309                 model_data_ids = mod_obj.search(cr, uid, [('model', '=', 'ir.ui.view'), ('name', '=', 'view_event_confirm_registration')], context=context)
310                 resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id']
311                 for id in ids:
312                     context.update({'reg_id': id})
313                 
314                 return {
315                     'name': _('Confirm Registration'), 
316                     'context': context, 
317                     'view_type': 'form', 
318                     'view_mode': 'tree,form', 
319                     'res_model': 'event.confirm.registration', 
320                     'views': [(resource_id, 'form')], 
321                     'type': 'ir.actions.act_window', 
322                     'target': 'new', 
323                     'nodestroy': True
324                 }
325
326     def _history(self, cr, uid, cases, keyword, history=False, subject=None, email=False, details=None, email_from=False, message_id=False, attach=[], context={}):
327         mailgate_pool = self.pool.get('mailgate.thread')
328         return mailgate_pool._history(cr, uid, cases, keyword, history=history,\
329                                        subject=subject, email=email, \
330                                        details=details, email_from=email_from,\
331                                        message_id=message_id, attach=attach, \
332                                        context=context)
333
334     def button_reg_close(self, cr, uid, ids, *args):
335         
336         cases = self.browse(cr, uid, ids) 
337         self._history(cr, uid, cases, _('Done'))
338         self.write(cr, uid, ids, {'state': 'done', 'date_closed': time.strftime('%Y-%m-%d %H:%M:%S')})
339         return True
340     
341     def button_reg_cancel(self, cr, uid, ids, *args):
342         
343         cases = self.browse(cr, uid, ids)
344         self._history(cr, uid, cases, _('Cancel'))
345         self.write(cr, uid, ids, {'state': 'cancel'})
346         return True
347
348     def create(self, cr, uid, *args, **argv):
349         """ Overrides orm create method.
350         @param self: The object pointer
351         @param cr: the current row, from the database cursor,
352         @param uid: the current user’s ID for security checks,
353         @param *args: Fields value
354         @return : New created record Id.
355         """
356
357         event = self.pool.get('event.event').browse(cr, uid, args[0]['event_id'], None)
358         
359         args[0]['date_deadline']= event.date_begin
360         args[0]['description']= event.mail_confirm
361         res = super(event_registration, self).create(cr, uid, *args, **argv)
362         cases = self.browse(cr, uid, [res])
363         self._history(cr, uid, cases, _('Created'))
364         return res
365
366     def write(self, cr, uid, *args, **argv):
367     
368         if 'event_id' in args[1]:
369             event = self.pool.get('event.event').browse(cr, uid, args[1]['event_id'], None)
370            
371             args[1]['date_deadline']= event.date_begin
372             args[1]['description']= event.mail_confirm
373         return super(event_registration, self).write(cr, uid, *args, **argv)
374     
375
376     def remind_partner(self, cr, uid, ids, context={}, attach=False):
377
378         """
379         @param self: The object pointer
380         @param cr: the current row, from the database cursor,
381         @param uid: the current user’s ID for security checks,
382         @param ids: List of Remind Partner's IDs
383         @param context: A standard dictionary for contextual values
384
385         """
386         return self.remind_user(cr, uid, ids, context, attach,
387                 destination=False)
388         
389             
390     def remind_user(self, cr, uid, ids, context={}, attach=False,destination=True):
391
392         """
393         @param self: The object pointer
394         @param cr: the current row, from the database cursor,
395         @param uid: the current user’s ID for security checks,
396         @param ids: List of Remind user's IDs
397         @param context: A standard dictionary for contextual values
398         """
399         
400         for case in self.browse(cr, uid, ids):
401             
402             if not case.event_id.reply_to:
403                 raise osv.except_osv(_('Error!'), ("Reply To is not specified for selected Event"))
404             if not case.email_from:
405                 raise osv.except_osv(_('Error!'), ("Partner Email is not specified in Registration"))
406             if case.event_id.reply_to and case.email_from:
407                 src = case.email_from
408                 dest = case.event_id.reply_to
409                 body = ""
410                 body = case.description
411                 if not destination:
412                     src, dest = dest, src
413                     if body and case.user_id.signature:
414                         body += '\n\n%s' % (case.user_id.signature)
415
416                 body = self.format_body(body)
417                 dest = [dest]
418
419                 attach_to_send = None
420
421                 if attach:
422                     attach_ids = self.pool.get('ir.attachment').search(cr, uid, [('res_model', '=', 'mailgate.thread'), ('res_id', '=', case.id)])
423                     attach_to_send = self.pool.get('ir.attachment').read(cr, uid, attach_ids, ['datas_fname','datas'])
424                     attach_to_send = map(lambda x: (x['datas_fname'], base64.decodestring(x['datas'])), attach_to_send)
425
426                 # Send an email
427                 flag = tools.email_send(
428                     src,
429                     dest,
430                     "Reminder: [%s] %s" % (str(case.id), case.name,),
431                     body,
432                     reply_to = case.event_id.reply_to,
433                     openobject_id=str(case.id),
434                     attach=attach_to_send
435                 )
436                 self._history(cr, uid, [case], _('Send'), history=True, email=dest, details=body, email_from=src)
437                 
438                 #if flag:
439                 #    raise osv.except_osv(_('Email!'),("Email Successfully Sent"))
440                 #else:
441                 #    raise osv.except_osv(_('Email Fail!'),("Email is not sent successfully"))
442         return True     
443
444     def mail_user_confirm(self, cr, uid, ids):
445         """
446         @param self: The object pointer
447         @param cr: the current row, from the database cursor,
448         @param uid: the current user’s ID for security checks,
449         @param ids: List of Event Registration's Id.
450         @return : False
451         """
452         reg_ids = self.browse(cr, uid, ids)
453         for reg_id in reg_ids:
454             src = reg_id.event_id.reply_to or False
455             dest = []
456             if reg_id.email_from:
457                 dest += [reg_id.email_from]
458             if reg_id.email_cc:
459                 dest += [reg_id.email_cc]
460             if dest and src:
461                     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))
462             if not src:
463                 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'))
464
465         return False
466
467     def mail_user(self, cr, uid, ids):
468         """
469         @param self: The object pointer
470         @param cr: the current row, from the database cursor,
471         @param uid: the current user’s ID for security checks,
472         @param ids: List of Event Registration's Id.
473         @return : False
474         """
475         reg_ids = self.browse(cr, uid, ids)
476         
477         for reg_id in reg_ids:
478             src = reg_id.event_id.reply_to or False
479             dest = []
480             if reg_id.email_from:
481                 dest += [reg_id.email_from]
482             if reg_id.email_cc:
483                 dest += [reg_id.email_cc]
484             if reg_id.event_id.mail_auto_confirm or reg_id.event_id.mail_auto_registr:
485                 if dest and src:
486                     if reg_id.event_id.state in ['draft', 'fixed', 'open', 'confirm', 'running'] and reg_id.event_id.mail_auto_registr:
487                         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))
488                     if (reg_id.event_id.state in ['confirm', 'running']) and reg_id.event_id.mail_auto_confirm:
489                         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))
490                 if not src:
491                     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'))
492         return False
493
494     def _create_invoice_lines(self, cr, uid, ids, vals):
495         
496         """ Create account Invoice line for Registration Id.
497         @param self: The object pointer
498         @param cr: the current row, from the database cursor,
499         @param uid: the current user’s ID for security checks,
500         @param Ids: List of event registration's Id
501         @param vals: Create fields value
502         @return : New created record Id.
503         """
504         
505         return self.pool.get('account.invoice.line').create(cr, uid, vals)
506
507     _name= 'event.registration'
508     _description = __doc__
509     _inherit = 'crm.meeting'
510
511     _columns = {
512         'email_cc': fields.text('CC', size=252 , help="These \
513 people will receive a copy of the future communication between partner \
514 and users by email"), 
515         'nb_register': fields.integer('Number of Registration', readonly=True, states={'draft': [('readonly', False)]}), 
516         'event_id': fields.many2one('event.event', 'Event Related', required=True), 
517         "partner_invoice_id": fields.many2one('res.partner', 'Partner Invoiced'), 
518         "contact_id": fields.many2one('res.partner.contact', 'Partner Contact'), #TODO: filter only the contacts that have a function into the selected partner_id
519         "unit_price": fields.float('Unit Price'), 
520         "badge_title": fields.char('Badge Title', size=128), 
521         "badge_name": fields.char('Badge Name', size=128), 
522         "badge_partner": fields.char('Badge Partner', size=128), 
523         "event_product": fields.char("Product Name", size=128, required=True), 
524         "tobe_invoiced": fields.boolean("To be Invoiced"), 
525         "invoice_id": fields.many2one("account.invoice", "Invoice"), 
526         'date_closed': fields.datetime('Closed', readonly=True), 
527         'ref': fields.reference('Reference', selection=crm._links_get, size=128), 
528         'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128), 
529         'canal_id': fields.many2one('res.partner.canal', 'Channel', help="The channels represent the different communication modes available with the customer." \
530                                                                         " With each commercial opportunity, you can indicate the canall which is this opportunity source."), 
531         'som': fields.many2one('res.partner.som', 'State of Mind', help="The minds states allow to define a value scale which represents" \
532                                                                        "the partner mentality in relation to our services.The scale has" \
533                                                                        "to be created with a factor for each level from 0 (Very dissatisfied) to 10 (Extremely satisfied)."), 
534     }
535     
536     _defaults = {
537         'nb_register': lambda *a: 1, 
538         'tobe_invoiced': lambda *a: True, 
539         'name': lambda *a: 'Registration', 
540     }
541
542     def onchange_badge_name(self, cr, uid, ids, badge_name):
543         
544         data ={}
545         if not badge_name:
546             return data
547         data['name'] = 'Registration: ' + badge_name
548         return {'value': data}
549
550     def onchange_contact_id(self, cr, uid, ids, contact, partner):
551         
552         data ={}
553         if not contact:
554             return data
555
556         contact_id = self.pool.get('res.partner.contact').browse(cr, uid, contact)
557         data['badge_name'] = contact_id.name
558         data['badge_title'] = contact_id.title
559         if partner:
560             partner_addresses = self.pool.get('res.partner.address').search(cr, uid, [('partner_id', '=', partner)])
561             job_ids = self.pool.get('res.partner.job').search(cr, uid, [('contact_id', '=', contact), ('address_id', 'in', partner_addresses)])
562             if job_ids:
563                 data['email_from'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).email
564         d = self.onchange_badge_name(cr, uid, ids, data['badge_name'])
565         data.update(d['value'])
566         return {'value': data}
567
568     def onchange_event(self, cr, uid, ids, event_id, partner_invoice_id):
569         context={}
570         if not event_id:
571             return {'value': {'unit_price': False, 'event_product': False}}
572         data_event =  self.pool.get('event.event').browse(cr, uid, event_id)
573         
574         if data_event.product_id:
575             if not partner_invoice_id:
576                 unit_price=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id]
577                 return {'value': {'unit_price': unit_price, 'event_product': data_event.product_id.name}}
578             data_partner = self.pool.get('res.partner').browse(cr, uid, partner_invoice_id)
579             context.update({'partner_id': data_partner})
580             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]
581             return {'value': {'unit_price': unit_price, 'event_product': data_event.product_id.name}}
582         
583         return {'value': {'unit_price': False, 'event_product': False}}
584
585     def onchange_partner_id(self, cr, uid, ids, part, event_id, email=False):
586         
587         data={}
588         data['badge_partner'] = data['contact_id'] = data['partner_invoice_id'] = data['email_from'] = data['badge_title'] = data['badge_name'] = False
589         if not part:
590             return {'value': data}
591         data['partner_invoice_id']=part
592         # this calls onchange_partner_invoice_id
593         d = self.onchange_partner_invoice_id(cr, uid, ids, event_id, part)
594         # this updates the dictionary
595         data.update(d['value'])
596         addr = self.pool.get('res.partner').address_get(cr, uid, [part])
597         if addr:
598             if addr.has_key('default'):
599                 job_ids = self.pool.get('res.partner.job').search(cr, uid, [('address_id', '=', addr['default'])])
600                 if job_ids:
601                     data['contact_id'] = self.pool.get('res.partner.job').browse(cr, uid, job_ids[0]).contact_id.id
602                     d = self.onchange_contact_id(cr, uid, ids, data['contact_id'], part)
603                     data.update(d['value'])
604         partner_data = self.pool.get('res.partner').browse(cr, uid, part)
605         data['badge_partner'] = partner_data.name
606         return {'value': data}
607
608     def onchange_partner_invoice_id(self, cr, uid, ids, event_id, partner_invoice_id):
609         
610         data={}
611         context={}
612         data['unit_price']=False
613         if not event_id:
614             return {'value': data}
615         data_event =  self.pool.get('event.event').browse(cr, uid, event_id)
616
617         if data_event.product_id:
618             if not partner_invoice_id:
619                 data['unit_price']=self.pool.get('product.product').price_get(cr, uid, [data_event.product_id.id], context=context)[data_event.product_id.id]
620                 return {'value': data}
621             data_partner = self.pool.get('res.partner').browse(cr, uid, partner_invoice_id)
622             context.update({'partner_id': data_partner})
623             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]
624             return {'value': data}
625         return {'value': data}
626
627 event_registration()
628
629
630 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
631