def updateMeeting(meetingid,request,clubid):
        ecode = ""
        try:
            curMeeting =  Meeting.objects.get(id__exact=meetingid)
        except:
            ecode = "Meeting is not existing"
            return (0,ecode,False,0) #meeting is not existing
        
        if "version" in request.DATA:
            if curMeeting.version > request.DATA["version"]:
                ecode = "Meeting has been updated, please refresh your meeting first."
                return (0,ecode,True,0) #Version is not the latest one
        else:
            ecode = "Version is required while updating the meeting."
            return (0,ecode,True,0) #meeting Version
            
        try:
            exMeeting = None
            exMeeting =  Meeting.objects.filter(club_id__exact=clubid,meetingno__exact=request.DATA["meetingno"])[0]
            if exMeeting and exMeeting.id != curMeeting.id:
                ecode = "Duplicated as meeting number."
                return (0,ecode,False,0)
        except:
            pass
        
        try:
            exMeeting = None
            starttime = datetime.fromtimestamp(request.DATA["stime"]/1000)
            sts = datetime(starttime.year,starttime.month,starttime.day)
            sTimeticks = int(time.mktime(sts.timetuple())*1000)
            eTimeticks = sTimeticks + 86400000 #24*3600000
            exMeeting = Meeting.objects.filter(club_id__exact=clubid,starttime__gt =sTimeticks,starttime__lt =eTimeticks)[0]
            if exMeeting and exMeeting.id != curMeeting.id:
                ecode = "Duplicated as meeting date."
                return (0,ecode,False,0)
        except:
            pass 
        
        curMeeting.meetingno = request.DATA["meetingno"]
        curMeeting.theme = request.DATA["theme"]
        curMeeting.venue = request.DATA["venue"]
        #meeting time : 3/13/2014 07:44
        curMeeting.starttime = request.DATA["stime"]
        curMeeting.endtime = curMeeting.starttime + 2*3600000
        
        try:
            curMeeting.save()
        except:
            ecode = "Failed to save this meeting."
            return (0,ecode,False,0)
        
        # activity = {"sequence":1,"title":"Title","duration":5,"roles":null};
        CurActivities = []
        CurRoles = []
        CurARs = []
        CurERs = []
        CurEFs = []
        if "activities" in request.DATA and request.DATA["activities"] is not None \
        and len(request.DATA["activities"]) > 0:
            for reqActivity in request.DATA["activities"]:
                act = None
                if "id" in reqActivity and reqActivity["id"] > 0 and reqActivity["id"] < 4000000000:
                    try:
                        act = Activity.objects.get(id=reqActivity["id"])
                    except:
                        pass
                if act is None:
                    try:
                        acts = Activity.objects.filter(meeting=curMeeting,title=reqActivity["title"])
                        if acts and len(acts)> 0:
                            act = acts[0]
                    except:
                        pass
                if act is None:
                    act = Activity()
         
                act.title = reqActivity["title"]
                act.expand = reqActivity["expand"]
                act.name = reqActivity["name"]
                act.duration = reqActivity["duration"]
                act.sequence = reqActivity["sequence"]
                act.meeting = curMeeting
                act.save()
                CurActivities.append(act)
                
                # role= {"sequence":1,"roletype":0,"title":"Title","minduration":1,"maxduration":2};
                if "roles" in reqActivity and reqActivity["roles"] is not None \
                and len(reqActivity["roles"]) > 0:
                    for reqRole in reqActivity["roles"]:
                        mrole = None
                        if "id" in reqRole and reqRole["id"] > 0 and reqRole["id"] < 4000000000: #id>4000000000 is for new object 
                            try:
                                mrole = RoleTaken.objects.get(id=reqRole["id"])
                            except:
                                pass
                        if mrole is None:
                            try:
                                mroles = RoleTaken.objects.filter(meeting=curMeeting,title=reqRole["title"],roletype=reqRole["roletype"])
                                if mroles and len(mroles) > 0:
                                    mrole = mroles[0]
                            except:
                                pass
                        if mrole is None:
                            mrole = RoleTaken()
 
                        if mrole not in CurRoles:
                            mrole.roletype = reqRole["roletype"]
                            if "title" in reqRole and len(reqRole["title"])>1 :
                                mrole.title = reqRole["title"]
                            else:
                                mrole.title = RoleDesc[reqRole["roletype"]]
                            #mrole.comment = ""
                            mrole.ctask = reqRole["ctask"]
                            mrole.ltask = reqRole["ltask"]
                            
                            owner = None
                            if reqRole["userid"] > 0:
                                owner = Person.objects.get(id=reqRole["userid"])
                            mrole.owner = owner
                            
                            if mrole.roletype == 10 or mrole.roletype == 16:
                                if reqRole["toid"] >0 and reqRole["toid"] < 4000000000:
                                    mrole.iefor_id = reqRole["toid"]
                                else: #for the new role, the role to be evaluated maybe not here
                                    pass 
                            
                            mrole.meeting = curMeeting
                            mrole.save()

                            CurRoles.append(mrole)                            
                            
                            if mrole.roletype == 9 or mrole.roletype == 12:
                                if reqRole["id"] > 4000000000:
                                    CurEFs.append({'role':mrole,'fid':reqRole["id"]})
                            elif mrole.roletype == 10 or mrole.roletype == 16:
                                if reqRole["toid"] > 4000000000:
                                    CurERs.append({'role':mrole,'fef':reqRole["toid"]})

                        arr = None
                        if "arid" in reqRole and reqRole["arid"] > 0 and reqRole["arid"]<4000000000:
                            try:
                                arr = ARRelation.objects.get(id=reqRole["arid"])
                            except:
                                pass
                        """
                        if arr is None:
                            try:
                                arrs = ARRelation.objects.filter(activity=act,roletaken=mrole)
                                if arrs and len(arrs):
                                    arr = arrs[0]
                            except:
                                pass
                        """
                        if arr is None:
                            arr = ARRelation()
                        
                        arr.ctitle = reqRole["ctitle"]                                  
                        arr.activity = act
                        arr.roletaken = mrole
                        arr.sequence = reqRole["sequence"]
                        arr.minduration = reqRole["minduration"]
                        arr.maxduration = reqRole["maxduration"]
                        arr.save()
                        CurARs.append(arr)
        
        try:
            ARRelation.objects.filter(Q(activity__meeting__id__exact=curMeeting.id) & ~Q(id__in=MeetingUtil.getIDs(CurARs))).delete()
        except:
            pass
        
        try:
            RoleTaken.objects.filter(Q(meeting__id__exact=curMeeting.id) & ~Q(id__in=MeetingUtil.getIDs(CurRoles))).delete()
        except:
            pass
        
        try:
            Activity.objects.filter(Q(meeting__id__exact=curMeeting.id) & ~Q(id__in=MeetingUtil.getIDs(CurActivities))).delete()
        except:
            pass
        
        try:
            bookers = RoleTaken.objects.filter(meeting__id__exact=curMeeting.id,owner__isnull=False).values("owner").distinct()
            regs = Attendance.objects.filter(meeting__id__exact=curMeeting.id).values("owner").distinct()
            
            tobeRegs = []
            if bookers and len(bookers) > 0:
                tobeRegs = [booker for booker in bookers if booker not in regs]
            
            for reg in tobeRegs:
                attendance = None
                try:
                    attendance = Attendance.objects.get(meeting_id__exact=curMeeting.id,owner_id__exact=reg["owner"])
                    attendance.av = True
                    attendance.save()
                except:
                    attendance = Attendance()
                    attendance.meeting = curMeeting
                    attendance.owner_id = reg["owner"]
                    attendance.av=True
                    attendance.save()
        except:
            pass
        
        for cer in CurERs:
            for cef in CurEFs:
                if cer['fef'] == cef['fid']:
                    cer['role'].iefor = cef['role']
                    try:
                        cer['role'].save()
                        break
                    except:
                        pass
        
        ecode = "Meeting {} is updated successfully!".format(curMeeting.meetingno)              
        return (curMeeting.pk,ecode,False,curMeeting.version)
    def createNormalMeeting(request,clubid):
        try:
            exCount = 0
            exCount =  Meeting.objects.filter(meetingno__exact=request.DATA["meetingno"],club_id__exact=clubid).count()
            if exCount > 0:
                return (0,"Meeting is duplicated with meeting number!")
        except:
            pass
        
        try:
            exCount = 0            
            starttime = datetime.fromtimestamp(request.DATA["starttime"]/1000)
            sts = datetime(starttime.year,starttime.month,starttime.day)
            sTimeticks = int(time.mktime(sts.timetuple())*1000)
            eTimeticks = sTimeticks + 86400000 #24*3600000
            exCount = Meeting.objects.filter(starttime__gt =sTimeticks,starttime__lt =eTimeticks,club_id__exact=clubid).count()
            if exCount > 0:
                return (0,"Meeting is duplicated with meeting time!")
        except:
            pass
        
        #this user is on some term which is not finished
        try:
            term = Term.objects.filter(club_id__exact = clubid,finished__exact=False).order_by('startdate')[0]
        except:
            return (0,"Meeting is invalid as no related term is existed!")

        meeting = Meeting()
        meeting.meetingno = request.DATA["meetingno"]
        meeting.theme = request.DATA["theme"]
        meeting.venue = request.DATA["venue"]
        #meeting time : 3/13/2014 07:44
        meeting.starttime = request.DATA["starttime"]
        meeting.endtime = meeting.starttime + 2*3600000
        meeting.status = MeetingStatus.CREATED
        meeting.term = term
        meeting.club = term.club
        
        try:
            meeting.save()
        except:
            return (0,"Meeting is invalid as internal error!")
        
        # activity = {"sequence":1,"title":"Title","duration":5,"roles":null};
        CurRoles = []
        EFRoles = {RoleEnum.Speaker:[],RoleEnum.IE:[],RoleEnum.TTM:[],RoleEnum.TTE:[]}
        if "activities" in request.DATA and request.DATA["activities"] is not None \
        and len(request.DATA["activities"]) > 0:
            for reqActivity in request.DATA["activities"]:
                act = Activity()
                act.title = reqActivity["title"]
                act.expand = reqActivity["expand"]
                act.name = reqActivity["name"]
                act.duration = reqActivity["duration"]
                act.sequence = reqActivity["sequence"]
                act.meeting = meeting
                act.save()
                
                # role= {"sequence":1,"roletype":0,"title":"Title","minduration":1,"maxduration":2};
                if "roles" in reqActivity and reqActivity["roles"] is not None \
                and len(reqActivity["roles"]) > 0:
                    actduration = 0
                    for reqRole in reqActivity["roles"]:
                        mrole = None
                        for irole in CurRoles:
                            if irole.roletype == reqRole["roletype"] and irole.title == reqRole["title"]:
                                mrole = irole
                                break
                        if mrole is None:
                            mrole = RoleTaken()
                            mrole.roletype = reqRole["roletype"]
                            if reqRole["title"] and len(reqRole["title"])>1 :
                                mrole.title = reqRole["title"]
                            else:
                                mrole.title = RoleDesc[reqRole["roletype"]] 
                            if (mrole.roletype == RoleEnum.Speaker or mrole.roletype == RoleEnum.TTM \
                            or mrole.roletype == RoleEnum.Workshop) and (not ":" in mrole.title):
                                mrole.title = mrole.title + ":"
                            mrole.comment = ""
                            mrole.ctask = ""
                            mrole.ltask = ""
                            mrole.owner = None
                            mrole.iefor = None
                            mrole.meeting = meeting
                            mrole.save()
                            CurRoles.append(mrole)
                            
                        arr = ARRelation()
                        arr.ctitle = reqRole["ctitle"]
                        arr.activity = act
                        arr.roletaken = mrole                                            
                        arr.sequence = reqRole["sequence"]                            
                        arr.minduration = reqRole["minduration"]
                        arr.maxduration = reqRole["maxduration"]
                        arr.save()
                        
                        if mrole.roletype == RoleEnum.Speaker or mrole.roletype == RoleEnum.IE \
                        or mrole.roletype == RoleEnum.TTM or mrole.roletype == RoleEnum.TTE:
                            newef = True
                            for efrole in EFRoles[mrole.roletype]:
                                if efrole['role'].id == mrole.id:
                                    newef = False
                                    break
                            if newef:
                                EFRoles[mrole.roletype].append({'role':mrole,'iefor':reqRole["iefor"]})                        
                        
                        actduration = actduration + arr.maxduration
                
                    act.duration = actduration
                    #act.duration = 0
                    act.save()
                    
        for erole in EFRoles[RoleEnum.IE]:
            for efrole in EFRoles[RoleEnum.Speaker]:
                if len(erole['iefor'])>0 and erole['iefor'] == efrole['role'].title:
                    erole['role'].iefor_id = efrole['role'].id
                    erole['role'].title = erole['role'].title.split(":")[0]+":for " + efrole['role'].title.split(":")[0]
                    erole['role'].save()
                    break
        
        for erole in EFRoles[RoleEnum.TTE]:
            for efrole in EFRoles[RoleEnum.TTM]:
                if len(erole['iefor'])>0 and erole['iefor'] == efrole['role'].title:
                    erole['role'].iefor_id = efrole['role'].id
                    erole['role'].title = erole['role'].title.split(":")[0]+":for " + efrole['role'].title.split(":")[0]
                    erole['role'].save()
                    break
                    
        return (meeting.pk,"Meeting {} is created successfully!".format(meeting.meetingno))