[MERGE]: Merged lp:~openerp-dev/openobject-addons/trunk-event_improvements-atp-event_...
[odoo/odoo.git] / addons / event / event.py
index a69e17a..5b14f25 100644 (file)
@@ -102,6 +102,23 @@ class event_event(osv.osv):
             total_confirmed = self.event.register_current
             if total_confirmed < self.event.register_min or total_confirmed > self.event.register_max and self.event.register_max!=0:
                 raise osv.except_osv(_('Error!'),_("The total of confirmed registration for the event '%s' does not meet the expected minimum/maximum. You should maybe reconsider those limits before going further") % (self.event.name))
+            
+    def check_available_seats(self, cr, uid, ids, context=None):
+        if isinstance(ids, list):
+            ids = ids[0]
+        else:
+            ids = ids 
+        total_confirmed = self.browse(cr, uid, ids, context=context).register_current
+        register_max = self.browse(cr, uid, ids, context=context).register_max
+        available_seats = register_max - total_confirmed
+        return available_seats
+            
+    def check_registration_limits_before(self, cr, uid, ids, no_of_registration, context=None):
+        available_seats = self.check_available_seats(cr, uid, ids, context=context)
+        if available_seats and no_of_registration > available_seats:
+             raise osv.except_osv(_('Warning!'),_("Only %d Seats are Available!") % (available_seats))
+        elif available_seats == 0:
+            raise osv.except_osv(_('Warning!'),_("No Tickets Available!"))
 
     def confirm_event(self, cr, uid, ids, context=None):
         register_pool = self.pool.get('event.registration')
@@ -149,26 +166,25 @@ class event_event(osv.osv):
                 elif field == 'register_prospect':
                     number = reg_draft
                 elif field == 'register_avail':
-                    number = event.register_max-reg_open
+                    #the number of ticket is unlimited if the event.register_max field is not set. 
+                    #In that cas we arbitrary set it to 9999, it is used in the kanban view to special case the display of the 'subscribe' button
+                    number = event.register_max - reg_open if event.register_max != 0 else 9999
                 res[event.id][field] = number
         return res
-    
+
     def _subscribe_fnc(self, cr, uid, ids, fields, args, context=None):
-        """Get Subscribe or Unsubscribe registration value.
-        @param ids: List of Event registration type's id
-        @param fields: List of function fields(subscribe).
-        @param context: A standard dictionary for contextual values
-        @return: Dictionary of function fields value.
+        """This functional fields compute if the current user (uid) is already subscribed or not to the event passed in parameter (ids)
         """
         register_pool = self.pool.get('event.registration')
         res = {}
         for event in self.browse(cr, uid, ids, context=context):
-            curr_reg_id = register_pool.search(cr,uid,[('user_id','=',uid),('event_id','=',event.id)])
-            if not curr_reg_id:res[event.id] = False
+            res[event.id] = False
+            curr_reg_id = register_pool.search(cr, uid, [('user_id', '=', uid), ('event_id', '=' ,event.id)])
             if curr_reg_id:
-                for reg in register_pool.browse(cr,uid,curr_reg_id,context=context):
-                    res[event.id] = False
-                    if reg.subscribe:res[event.id]= True
+                for reg in register_pool.browse(cr, uid, curr_reg_id, context=context):
+                    if reg.state in ('open','done'):
+                        res[event.id]= True
+                        continue
         return res 
 
     _columns = {
@@ -185,7 +201,7 @@ class event_event(osv.osv):
         'date_begin': fields.datetime('Start Date', required=True, readonly=True, states={'draft': [('readonly', False)]}),
         'date_end': fields.datetime('End Date', required=True, readonly=True, states={'draft': [('readonly', False)]}),
         'state': fields.selection([
-            ('draft', 'Draft'),
+            ('draft', 'Unconfirmed'),
             ('confirm', 'Confirmed'),
             ('done', 'Done'),
             ('cancel', 'Cancelled')],
@@ -197,13 +213,15 @@ class event_event(osv.osv):
         'reply_to': fields.char('Reply-To Email', size=64, readonly=False, states={'done': [('readonly', True)]}, help="The email address of the organizer is likely to be put here, with the effect to be in the 'Reply-To' of the mails sent automatically at event or registrations confirmation. You can also put the email address of your mail gateway if you use one."),
         'main_speaker_id': fields.many2one('res.partner','Main Speaker', readonly=False, states={'done': [('readonly', True)]}, help="Speaker who will be giving speech at the 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)]}),
+        'address_id': fields.many2one('res.partner','Location Address', readonly=False, states={'done': [('readonly', True)]}),
         'speaker_confirmed': fields.boolean('Speaker Confirmed', readonly=False, states={'done': [('readonly', True)]}),
         'country_id': fields.related('address_id', 'country_id',
                     type='many2one', relation='res.country', string='Country', readonly=False, states={'done': [('readonly', True)]}),
         'note': fields.text('Description', readonly=False, states={'done': [('readonly', True)]}),
         'company_id': fields.many2one('res.company', 'Company', required=False, change_default=True, readonly=False, states={'done': [('readonly', True)]}),
-        'subscribe' : fields.function(_subscribe_fnc, type="boolean", string='Subscribe'),
+        'is_subscribed' : fields.function(_subscribe_fnc, type="boolean", string='Subscribed'),
+        'location_id': fields.many2one('res.partner','Organization Address', readonly=False, states={'done': [('readonly', True)]}),
+        
     }
 
     _defaults = {
@@ -211,25 +229,26 @@ class event_event(osv.osv):
         '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,
     }
-    
-    def subscribe_to_event(self,cr,uid,ids,context=None):
+
+    def subscribe_to_event(self, cr, uid, ids, context=None):
         register_pool = self.pool.get('event.registration')
         user_pool = self.pool.get('res.users')
-        user = user_pool.browse(cr,uid,uid,context)
-        curr_reg_id = register_pool.search(cr,uid,[('user_id','=',user.id),('event_id','=',ids[0])])
-        if not curr_reg_id:
-            curr_reg_id = register_pool.create(cr, uid, {'event_id':ids[0],'email':user.user_email,
-                                                         'name':user.name,'user_id':user.id,
-                                                         'subscribe':True
-                                                         })
-        if isinstance(curr_reg_id, (int, long)):curr_reg_id = [curr_reg_id]
-        return register_pool.confirm_registration(cr,uid,curr_reg_id,context)
-    
-    def unsubscribe_to_event(self,cr,uid,ids,context=None):
+        num_of_seats = int(context.get('ticket', 1))
+        self.check_registration_limits_before(cr, uid, ids, num_of_seats, context=context)
+        user = user_pool.browse(cr, uid, uid, context=context)
+        curr_reg_ids = register_pool.search(cr, uid, [('user_id', '=', user.id), ('event_id', '=' , ids[0])])
+        #the subscription is done with UID = 1 because in case we share the kanban view, we want anyone to be able to subscribe
+        if not curr_reg_ids:
+            curr_reg_ids = [register_pool.create(cr, 1, {'event_id': ids[0] ,'email': user.user_email, 'name':user.name, 'user_id': user.id, 'nb_register': num_of_seats})]
+        else:
+            register_pool.write(cr, uid, curr_reg_ids, {'nb_register': num_of_seats}, context=context)
+        return register_pool.confirm_registration(cr, 1, curr_reg_ids, context=context)
+
+    def unsubscribe_to_event(self, cr, uid, ids, context=None):
         register_pool = self.pool.get('event.registration')
-        curr_reg_id = register_pool.search(cr,uid,[('user_id','=',uid),('event_id','=',ids[0])])
-        if isinstance(curr_reg_id, (int, long)):curr_reg_id = [curr_reg_id]
-        return register_pool.button_reg_cancel(cr,uid,curr_reg_id,context)
+        #the unsubscription is done with UID = 1 because in case we share the kanban view, we want anyone to be able to unsubscribe
+        curr_reg_ids = register_pool.search(cr, 1, [('user_id', '=', uid), ('event_id', '=', ids[0])])
+        return register_pool.button_reg_cancel(cr, 1, curr_reg_ids, context=context)
 
     def _check_closing_date(self, cr, uid, ids, context=None):
         for event in self.browse(cr, uid, ids, context=context):
@@ -258,15 +277,13 @@ class event_registration(osv.osv):
     """Event Registration"""
     _name= 'event.registration'
     _description = __doc__
-    _inherit = ['mail.thread','res.partner.address']
+    _inherit = ['mail.thread','res.partner']
     _columns = {
         'id': fields.integer('ID'),
         'origin': fields.char('Origin', size=124,readonly=True,help="Name of the sale order which create the registration"),
         'nb_register': fields.integer('Number of Participants', 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_address_id': fields.many2one('res.partner.address', 'Partner', states={'done': [('readonly', True)]}),
-        "contact_id": fields.many2one('res.partner.address', 'Partner Contact', readonly=False, states={'done': [('readonly', True)]}),
         'create_date': fields.datetime('Creation Date' , readonly=True),
         'date_closed': fields.datetime('Attended Date', readonly=True),
         'date_open': fields.datetime('Registration Date', readonly=True),
@@ -281,13 +298,11 @@ class event_registration(osv.osv):
                                     ('cancel', 'Cancelled'),
                                     ('done', 'Attended')], 'State',
                                     size=16, readonly=True),
-        'subscribe': fields.boolean('Subscribe'),
     }
 
     _defaults = {
         'nb_register': 1,
         'state': 'draft',
-        #'user_id': lambda self, cr, uid, ctx: uid,
     }
     _order = 'name, create_date desc'
 
@@ -297,12 +312,16 @@ class event_registration(osv.osv):
 
     def confirm_registration(self, cr, uid, ids, context=None):
         self.message_append(cr, uid, ids,_('State set to open'),body_text= _('Open'))
-        return self.write(cr, uid, ids, {'state': 'open','subscribe':True}, context=context)
+        return self.write(cr, uid, ids, {'state': 'open'}, context=context)
 
 
     def registration_open(self, cr, uid, ids, context=None):
         """ Open Registration
         """
+        event_obj = self.pool.get('event.event')
+        event_id = self.browse(cr, uid, ids, context=context)[0].event_id.id
+        no_of_registration = self.browse(cr, uid, ids, context=context)[0].nb_register
+        event_obj.check_registration_limits_before(cr, uid, event_id, no_of_registration, context=context)
         res = self.confirm_registration(cr, uid, ids, context=context)
         self.mail_user(cr, uid, ids, context=context)
         return res
@@ -324,7 +343,7 @@ class event_registration(osv.osv):
 
     def button_reg_cancel(self, cr, uid, ids, context=None, *args):
         self.message_append(cr, uid, ids,_('State set to Cancel'),body_text= _('Cancel'))
-        return self.write(cr, uid, ids, {'state': 'cancel','subscribe':False})
+        return self.write(cr, uid, ids, {'state': 'cancel'})
 
     def mail_user(self, cr, uid, ids, context=None):
         """
@@ -353,7 +372,7 @@ class event_registration(osv.osv):
         data ={}
         if not contact:
             return data
-        addr_obj = self.pool.get('res.partner.address')
+        addr_obj = self.pool.get('res.partner')
         contact_id =  addr_obj.browse(cr, uid, contact, context=context)
         data = {
             'email':contact_id.email,
@@ -391,5 +410,5 @@ class event_registration(osv.osv):
         return {'value': data}
 
 event_registration()
-
+    
 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: