[MERGE] merged with main addons branch
[odoo/odoo.git] / addons / event / event.py
index f3402b0..a54c3cd 100644 (file)
 #
 ##############################################################################
 
+import time
+
 from crm import crm
 from osv import fields, osv
 from tools.translate import _
-import netsvc
-import pooler
 import time
 import tools
 import decimal_precision as dp
 
+
 class event_type(osv.osv):
     """ Event Type """
     _name = 'event.type'
@@ -37,7 +38,7 @@ class event_type(osv.osv):
     }
 event_type()
 
-class event_event(osv.osv):
+class event_event(crm.crm_case, osv.osv):
     """Event"""
     _name = 'event.event'
     _description = __doc__
@@ -55,6 +56,7 @@ class event_event(osv.osv):
             'registration_ids': False,
         })
         return super(event_event, self).copy(cr, uid, id, default=default, context=context)
+
     def onchange_product(self, cr, uid, ids, product_id):
         """This function returns value of  product's unit price based on product id.
         @param self: The object pointer
@@ -100,6 +102,9 @@ class event_event(osv.osv):
         @param context: A standard dictionary for contextual values
         @return: True
         """
+        if not context:
+            context = {}
+        res = False
         if type(ids) in (int, long,):
             ids = [ids]
         data_pool = self.pool.get('ir.model.data')
@@ -107,7 +112,7 @@ class event_event(osv.osv):
         for event in self.browse(cr, uid, ids, context=context):
             total_confirmed = event.register_current
             if total_confirmed >= event.register_min or event.register_max == 0:
-                self.do_confirm(cr, uid, [event.id], context=context)
+                res = self.do_confirm(cr, uid, [event.id], context=context)
             else:
                 unconfirmed_ids.append(event.id)
         if unconfirmed_ids:
@@ -127,7 +132,7 @@ class event_event(osv.osv):
                 'context': context,
                 'nodestroy': True
             }
-        return True
+        return res
 
 
     def _get_register(self, cr, uid, ids, fields, args, context=None):
@@ -153,11 +158,14 @@ class event_event(osv.osv):
                         ('event_id', '=', event.id),
                        ('state', 'in', state)])
 
+            number = 0.0
+            if reg_ids:
+                cr.execute('select sum(nb_register) from event_registration where id IN %s', (tuple(reg_ids),))
+                number = cr.fetchone()
             if 'register_current' in fields:
-                res[event.id]['register_current'] = len(reg_ids)
+                res[event.id]['register_current'] = number and number[0]
             if 'register_prospect' in fields:
-                res[event.id]['register_prospect'] = len(reg_ids)
-
+                res[event.id]['register_prospect'] = number and number[0]
         return res
 
     def write(self, cr, uid, ids, vals, context=None):
@@ -192,12 +200,12 @@ class event_event(osv.osv):
         return res
 
     _columns = {
-        'name': fields.char('Name', size=64, required=True, translate=True, readonly=False, states={'done': [('readonly', True)]}),
+        'name': fields.char('Summary', size=64, required=True, translate=True, readonly=False, states={'done': [('readonly', True)]}),
         'user_id': fields.many2one('res.users', 'Responsible User', readonly=False, states={'done': [('readonly', True)]}),
         'parent_id': fields.many2one('event.event', 'Parent Event', readonly=False, states={'done': [('readonly', True)]}),
         'section_id': fields.many2one('crm.case.section', 'Sale Team', readonly=False, states={'done': [('readonly', True)]}),
         'child_ids': fields.one2many('event.event', 'parent_id', 'Child Events', readonly=False, states={'done': [('readonly', True)]}),
-        'reply_to': fields.char('Reply-To', size=64, readonly=False, states={'done': [('readonly', True)]}, help="The email address put in the 'Reply-To' of all emails sent by Open ERP"),
+        'reply_to': fields.char('Reply-To', size=64, readonly=False, states={'done': [('readonly', True)]}, help="The email address put in the 'Reply-To' of all emails sent by OpenERP"),
         'type': fields.many2one('event.type', 'Type', help="Type of Event like Seminar, Exhibition, Conference, Training.", readonly=False, states={'done': [('readonly', True)]}),
         'register_max': fields.integer('Maximum Registrations', help="Provide Maximun Number of Registrations", readonly=True, states={'draft': [('readonly', False)]}),
         'register_min': fields.integer('Minimum Registrations', help="Providee Minimum Number of Registrations", readonly=True, states={'draft': [('readonly', False)]}),
@@ -219,11 +227,11 @@ class event_event(osv.osv):
         'mail_auto_confirm': fields.boolean('Mail Auto Confirm', readonly=False, states={'done': [('readonly', True)]}, help='Check this box if you want ot use the automatic confirmation emailing or the reminder'),
         'mail_registr': fields.text('Registration Email', readonly=False, states={'done': [('readonly', True)]}, help='This email will be sent when someone subscribes to the event.'),
         'mail_confirm': fields.text('Confirmation Email', readonly=False, states={'done': [('readonly', True)]}, 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."),
-        'product_id': fields.many2one('product.product', 'Product', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Product which is provided cost of event. Invoice of event will be created with this Product."),
+        'product_id': fields.many2one('product.product', 'Product', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="The invoices of this event registration will be created with this Product. Thus it allows you to set the default label and the accounting info you want by default on these invoices."),
         'note': fields.text('Notes', help="Description or Summary of Event", readonly=False, states={'done': [('readonly', True)]}),
         'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', readonly=True, states={'draft': [('readonly', False)]}, help="Pricelist version for current event."),
-        'unit_price': fields.related('product_id', 'list_price', type='float', string='Registration Cost', readonly=True, states={'draft':[('readonly',False)]}),
-        'main_speaker_id': fields.many2one('res.partner','Main Speaker', readonly=False, states={'done': [('readonly', True)]}),
+        'unit_price': fields.related('product_id', 'list_price', type='float', string='Registration Cost', readonly=True, states={'draft':[('readonly',False)]}, help="This will be the default price used as registration cost when invoicing this event. Note that you can specify for each registration a specific amount if you want to", digits_compute=dp.get_precision('Sale Price')),
+        'main_speaker_id': fields.many2one('res.partner','Main Speaker', readonly=False, states={'done': [('readonly', True)]}, help="Speaker who are giving speech on event."),
         'speaker_ids':fields.many2many('res.partner', 'event_speaker_rel', 'speaker_id', 'partner_id', 'Other Speakers', readonly=False, states={'done': [('readonly', True)]}),
         'address_id': fields.many2one('res.partner.address','Location Address', readonly=False, states={'done': [('readonly', True)]}),
         'speaker_confirmed': fields.boolean('Speaker Confirmed', readonly=False, states={'done': [('readonly', True)]}),
@@ -231,7 +239,7 @@ class event_event(osv.osv):
                     type='many2one', relation='res.country', string='Country', readonly=False, states={'done': [('readonly', True)]}),
         'language': fields.char('Language',size=64, readonly=False, states={'done': [('readonly', True)]}),
         'note': fields.text('Description', readonly=False, states={'done': [('readonly', True)]}),
-        'company_id': fields.many2one('res.company', 'Company', required=True, change_default=True, readonly=False, states={'done': [('readonly', True)]}),
+        'company_id': fields.many2one('res.company', 'Company', required=False, change_default=True, readonly=False, states={'done': [('readonly', True)]}),
 
     }
 
@@ -239,6 +247,7 @@ class event_event(osv.osv):
         'state': 'draft',
         'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'event.event', context=c),
         'user_id': lambda obj, cr, uid, context: uid,
+        'section_id': crm.crm_case._get_section,
     }
 
     def _check_recursion(self, cr, uid, ids):
@@ -282,7 +291,7 @@ class event_registration(osv.osv):
     """Event Registration"""
     _name= 'event.registration'
     _description = __doc__
-    _inherit = 'crm.meeting'
+    _inherit = 'mailgate.thread'
 
     def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
         cur_obj = self.pool.get('res.currency')
@@ -297,13 +306,14 @@ class event_registration(osv.osv):
 
     _columns = {
         'name': fields.char('Summary', size=124,  readonly=True, states={'draft': [('readonly', False)]}),
-        'email_cc': fields.text('CC', size=252 , readonly=False, states={'done': [('readonly', True)]}, help="These people will receive a copy of the future communication between partner and users by email"),
+        'email_cc': fields.text('CC', size=252 , readonly=False, states={'done': [('readonly', True)]}, help="These email addresses will be added to the CC field of all inbound and outbound emails for this record before being sent. Separate multiple email addresses with a comma"),
         'nb_register': fields.integer('Quantity', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Number of Registrations or Tickets"),
-        'event_id': fields.many2one('event.event', 'Event Related', required=True, readonly=True, states={'draft': [('readonly', False)]}),
+        'event_id': fields.many2one('event.event', 'Event', required=True, readonly=True, states={'draft': [('readonly', False)]}),
+        'partner_id': fields.many2one('res.partner', 'Partner', states={'done': [('readonly', True)]}),
         "partner_invoice_id": fields.many2one('res.partner', 'Partner Invoiced', readonly=True, states={'draft': [('readonly', False)]}),
         "contact_id": fields.many2one('res.partner.contact', 'Partner Contact', readonly=False, states={'done': [('readonly', True)]}), #TODO: filter only the contacts that have a function into the selected partner_id
-        "unit_price": fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Event Price'), readonly=True, states={'draft': [('readonly', False)]}),
-        'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal', digits_compute= dp.get_precision('Event Price')),
+        "unit_price": fields.float('Unit Price', required=True, digits_compute=dp.get_precision('Sale Price'), readonly=True, states={'draft': [('readonly', False)]}),
+        'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal', digits_compute=dp.get_precision('Sale Price')),
         "badge_ids": fields.one2many('event.registration.badge', 'registration_id', 'Badges', readonly=False, states={'done': [('readonly', True)]}),
         "event_product": fields.char("Invoice Name", size=128, readonly=True, states={'draft': [('readonly', False)]}),
         "tobe_invoiced": fields.boolean("To be Invoiced", readonly=True, states={'draft': [('readonly', False)]}),
@@ -311,15 +321,30 @@ class event_registration(osv.osv):
         'date_closed': fields.datetime('Closed', readonly=True),
         'ref': fields.reference('Reference', selection=crm._links_get, size=128),
         'ref2': fields.reference('Reference 2', selection=crm._links_get, size=128),
-        'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('history', '=', True),('model','=',_name)]),
+        'email_from': fields.char('Email', size=128, states={'done': [('readonly', True)]}, help="These people will receive email."),
+        'create_date': fields.datetime('Creation Date' , readonly=True),
+        'write_date': fields.datetime('Write Date' , readonly=True),
+        'description': fields.text('Description', states={'done': [('readonly', True)]}),
+        'message_ids': fields.one2many('mailgate.message', 'res_id', 'Messages', domain=[('model','=',_name)]),
         'log_ids': fields.one2many('mailgate.message', 'res_id', 'Logs', domain=[('history', '=', False),('model','=',_name)]),
-        'section_id': fields.related('event_id', 'section_id', type='many2one', relation='crm.case.section', string='Sale Team', store=True, readonly=True, states={'draft':[('readonly',False)]}),
+        'date_deadline': fields.related('event_id','date_end', type='datetime', string="End Date", readonly=True),
+        'date': fields.related('event_id', 'date_begin', type='datetime', string="Start Date", readonly=True),
+        'user_id': fields.many2one('res.users', 'Responsible', states={'done': [('readonly', True)]}),
+        'active': fields.boolean('Active'),
+        'section_id': fields.related('event_id', 'section_id', type='many2one', relation='crm.case.section', string='Sale Team', store=True, readonly=True),
         'company_id': fields.related('event_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True, states={'draft':[('readonly',False)]}),
+        'state': fields.selection([('open', 'Confirmed'),
+                                    ('draft', 'Unconfirmed'),
+                                    ('cancel', 'Cancelled'),
+                                    ('done', 'Done')], 'State', \
+                                    size=16, readonly=True)
     }
     _defaults = {
         'nb_register': 1,
         'tobe_invoiced':  True,
-        'date': time.strftime('%Y-%m-%d %H:%M:%S')
+        'state': 'draft',
+        'active': True,
+        'user_id': lambda self, cr, uid, ctx: uid,
     }
 
     def _make_invoice(self, cr, uid, reg, lines, context=None):
@@ -334,11 +359,8 @@ class event_registration(osv.osv):
 
         val_invoice = inv_pool.onchange_partner_id(cr, uid, [], 'out_invoice', reg.partner_invoice_id.id, False, False)
         val_invoice['value'].update({'partner_id': reg.partner_invoice_id.id})
-        partner_address_id = val_invoice['value']['address_invoice_id']
-
-        value = inv_lines_pool.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)
 
-        l = inv_lines_pool.read(cr, uid, lines)
+        inv_lines_pool.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)
 
         val_invoice['value'].update({
                 'origin': reg.event_product,
@@ -349,7 +371,7 @@ class event_registration(osv.osv):
             })
         inv_id = inv_pool.create(cr, uid, val_invoice['value'])
         inv_pool.button_compute(cr, uid, [inv_id])
-        self._history(cr, uid, [reg], _('Invoiced'))
+        self.history(cr, uid, [reg], _('Invoiced'))
         return inv_id
 
     def action_invoice_create(self, cr, uid, ids, grouped=False, date_inv = False, context=None):
@@ -418,7 +440,7 @@ class event_registration(osv.osv):
         """
         res = self.write(cr, uid, ids, {'state': 'open'}, context=context)
         self.mail_user(cr, uid, ids)
-        self._history(cr, uid, ids, _('Open'))
+        self.history(cr, uid, ids, _('Open'))
         return res
 
     def do_close(self, cr, uid, ids, context=None):
@@ -432,7 +454,7 @@ class event_registration(osv.osv):
         if invoice_id:
             values['invoice_id'] = invoice_id
         res = self.write(cr, uid, ids, values)
-        self._history(cr, uid, ids, msg)
+        self.history(cr, uid, ids, msg)
         return res
 
     def check_confirm(self, cr, uid, ids, context=None):
@@ -441,6 +463,8 @@ class event_registration(osv.osv):
         @param context: A standard dictionary for contextual values
         @return: True
         """
+        if not context:
+            context = {}
         data_pool = self.pool.get('ir.model.data')
         unconfirmed_ids = []
         for registration in self.browse(cr, uid, ids, context=context):
@@ -503,32 +527,10 @@ class event_registration(osv.osv):
         """This Function Cancel Event Registration.
         """
         registrations = self.browse(cr, uid, ids)
-        self._history(cr, uid, registrations, _('Cancel'))
+        self.history(cr, uid, registrations, _('Cancel'))
         self.write(cr, uid, ids, {'state': 'cancel'})
         return True
 
-    def create(self, cr, uid, values, context=None):
-        """ Overrides orm create method.
-        """
-        event_obj = self.pool.get('event.event')
-        event = event_obj.browse(cr, uid, values['event_id'], context=context)
-        values['date_deadline']= event.date_begin
-        values['description']= event.mail_confirm
-        res = super(event_registration, self).create(cr, uid, values, context=context)
-        registrations = self.browse(cr, uid, [res], context=context)
-        self._history(cr, uid, registrations, _('Created'))
-        return res
-
-    def write(self, cr, uid, ids, values, context=None):
-        """ Overrides orm write method.
-        """
-        event_obj = self.pool.get('event.event')
-        if 'event_id' in values:
-            event = event_obj.browse(cr, uid, values['event_id'], context=context)
-            values['date_deadline']= event.date_begin
-            values['description']= event.mail_confirm
-        return super(event_registration, self).write(cr, uid, ids, values, context=context)
-
     def mail_user(self, cr, uid, ids, confirm=False, context=None):
         """
         Send email to user
@@ -544,7 +546,7 @@ class event_registration(osv.osv):
                 email_to = regestration.email_from
             if regestration.email_cc:
                 email_cc += [regestration.email_cc]
-            if not (email_to and email_cc):
+            if not (email_to or email_cc):
                 continue
             subject = ""
             body = ""
@@ -591,11 +593,9 @@ class event_registration(osv.osv):
         data ={}
         if not contact:
             return data
-        contact_obj = self.pool.get('res.partner.contact')
         addr_obj = self.pool.get('res.partner.address')
         job_obj = self.pool.get('res.partner.job')
 
-        contact_id = contact_obj.browse(cr, uid, contact)
         if partner:
             partner_addresses = addr_obj.search(cr, uid, [('partner_id', '=', partner)])
             job_ids = job_obj.search(cr, uid, [('contact_id', '=', contact), ('address_id', 'in', partner_addresses)])
@@ -621,7 +621,10 @@ class event_registration(osv.osv):
         res_obj = self.pool.get('res.partner')
 
         data_event =  event_obj.browse(cr, uid, event_id)
-        res = {'value': {'unit_price': False, 'event_product': False, 'user_id': False}}
+        res = {'value': {'unit_price': False, 'event_product': False, 'user_id': False,
+                        'date': data_event.date_begin, 'date_deadline': data_event.date_end, 'description': data_event.note, 'name': data_event.name,
+                        'section_id': data_event.section_id and data_event.section_id.id or False,
+                        }}
         if data_event.user_id.id:
             res['value'].update({'user_id':data_event.user_id.id})
         if data_event.product_id:
@@ -630,6 +633,8 @@ class event_registration(osv.osv):
                 partner = res_obj.browse(cr, uid, partner_invoice_id, context=context)
                 pricelist_id = pricelist_id or partner.property_product_pricelist.id
             unit_price = prod_obj._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': pricelist_id})[data_event.product_id.id]
+            if not unit_price:
+                unit_price = data_event.unit_price
             res['value'].update({'unit_price': unit_price, 'event_product': data_event.product_id.name})
         return res
 
@@ -662,7 +667,6 @@ class event_registration(osv.osv):
                     data['contact_id'] = job_obj.browse(cr, uid, job_ids[0]).contact_id.id
                     d = self.onchange_contact_id(cr, uid, ids, data['contact_id'], part)
                     data.update(d['value'])
-        partner_data = res_obj.browse(cr, uid, part)
         return {'value': data}
 
     def onchange_partner_invoice_id(self, cr, uid, ids, event_id, partner_invoice_id):
@@ -690,7 +694,10 @@ class event_registration(osv.osv):
             if partner_invoice_id:
                 partner = res_obj.browse(cr, uid, partner_invoice_id, context=context)
                 pricelist_id = pricelist_id or partner.property_product_pricelist.id
-            data['unit_price'] = prod_obj._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': pricelist_id})[data_event.product_id.id]
+            unit_price = prod_obj._product_price(cr, uid, [data_event.product_id.id], False, False, {'pricelist': pricelist_id})[data_event.product_id.id]
+            if not unit_price:
+                unit_price = data_event.unit_price
+            data['unit_price'] = unit_price
         return {'value': data}
 
 event_registration()
@@ -707,4 +714,3 @@ class event_registration_badge(osv.osv):
 event_registration_badge()
 
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-