示例#1
0
    def changeSchedule(self, start, duration, sesshun, reason, desc):
        """
        Change the schedule, and take care of all the time accounting.
        This is meant for use in such cases as examplified in Memo 11.2.
        Right now, this only handles substituting one session for one
        or more sessions, where the time taken is accounted to one of these
        Reasons:
            time to other session due to weather
            time to other session due to rfi
            time to other session due to other reason
        and the time given to the new session is marked as short notice.
        Note that the times are not *assigned*, but instead times and descs.
        are incremented, so as not to overwrite previous changes.
        """

        # get rid of this once develompent has stablized.
        debug = False

        if debug:
            print "changeSchedule: "
            print start, duration, sesshun

        # tag the description
        nowStr = datetime.now().strftime("%Y-%m-%d %H:%M")    
        descHead = " [Insert Period (%s) " % nowStr 
        # dictionary of who gave and who got, where:
        # descDct[gave/got] = [(desc. of original period, time, period id)]
        descDct = dict(gave_time = [], got_time = [])

        # what periods are we affecting?
        duration_mins = duration * 60.0
        ps = Period.get_periods(start, duration_mins)
        if debug:
            print "len(ps): ", len(ps)
            for p in ps:
                print p 

        scheduledPeriods = [p for p in ps if p.state.abbreviation == 'S']
        if len(scheduledPeriods) != len(ps):
            msg = "All affected Periods must be in the Scheduled State"
            return (False, msg)

        # first, adjust each of the affected periods - including time accnting
        end = start + timedelta(hours = duration)
        for p in ps:
            need_scoring = False
            if debug:
                print "changing period: ", p
                print "comparing period: ", p.start, p.end()
                print "w/:               ", start, end 
            if p.start >= start and p.end() <= end:
                if debug:
                    print "delete period!"
                # this entire period is being replaced
                descDct["gave_time"].append((p.__str__(), p.duration, p.id))
                other_sess_time = p.duration
                p.delete() # the Deleted State!
            elif p.start >= start and p.end() > end:
                if debug:
                    print "start period later"
                # we're chopping off the beginning of this period
                new_duration = TimeAgent.timedelta2frachours(p.end() - end)
                other_sess_time = p.duration - new_duration
                descDct["gave_time"].append((p.__str__(),other_sess_time, p.id))
                p.duration = new_duration
                p.start = end
                need_scoring = True
            elif p.start < start and p.end() > end:
                if debug:
                    print "bi-secting period"
                # we're chopping out the middle of a period: we fix this
                # by adjusting the period, then creating a new one
                descDct["gave_time"].append((p.__str__(), duration, p.id))
                original_duration = p.duration
                original_end      = p.end()
                p.duration = TimeAgent.timedelta2frachours(start - p.start)
                # the new one
                new_dur = TimeAgent.timedelta2frachours(original_end - end)
                accounting = Period_Accounting(scheduled = new_dur
                                             , short_notice = new_dur
                                             , description = "" #description
                                               )
                accounting.save()                             
                pending = Period_State.objects.get(abbreviation = 'P')
                period_2cd_half = Period.create(session  = p.session
                                       , start    = end
                                       , duration = new_dur
                                       , state    = pending
                                       , score    = 0.0
                                       , forecast = end
                                       , accounting = accounting 
                                         )
                init_rcvrs_from_session(period_2cd_half.session, period_2cd_half)
                self.reinitScore(period_2cd_half)
                period_2cd_half.save()                         
                # the original period is really giving up time to the 
                # bi-secting new period, and the new second half!
                other_sess_time = duration + new_dur
                need_scoring = True
            elif p.start < start and p.end() > start:
                if debug:
                    print "shorten period"
                # we're chopping off the end of this period
                new_duration = TimeAgent.timedelta2frachours(start - p.start)
                other_sess_time = p.duration - new_duration
                descDct["gave_time"].append((p.__str__(),other_sess_time, p.id))
                p.duration = new_duration
                need_scoring = True
                         
            else:
                raise "not covered"
            # now change this periods time accounting
            if p is not None:
                if debug:
                    print "changes: ", p
                # increment values: don't overwrite them!
                value = p.accounting.get_time(reason)
                p.accounting.set_changed_time(reason, value + other_sess_time)
                p.accounting.save()
                if need_scoring:
                    self.reinitScore(p)
                p.save()

        # finally, anything to replace it with?
        if sesshun is not None:
            # create a period for this
            pa = Period_Accounting(scheduled    = duration
                                 , short_notice = duration
                                 , description  = "") #description)
            pa.save()   
            scheduled = Period_State.objects.get(abbreviation = 'S')
            p = Period.create(session    = sesshun
                            , start      = start
                            , duration   = duration
                            , score      = 0.0
                            , state      = scheduled
                            , forecast   = start
                            , accounting = pa)
            init_rcvrs_from_session(p.session, p)
            self.reinitScore(p)
            p.save()    
            descDct["got_time"].append((p.__str__(),p.duration, p.id))

        # in all cases, give the description of entire event:
        self.assignDescriptions(descDct, descHead, desc)

        return (True, None)