Exemple #1
0
def cal_work_experience_days(sender, instance, **kwargs):
    """ calculates the amount of days experience working - roughly"""
    all_months = []
    #Get all politican work experience instances
    for experience in instance.politician.work.all():
        # when saving a new instance it saves the object first to get and idThis makes sure that the code is only
        # done on instances that are fully complete.
        if experience.startdate:
            # check if they are currently getting experience or if they have an end date
            if experience.enddate:
                end = experience.enddate
            else:
                end = date.today()
            #Find out how many months that this period represents
            months = monthdelta.monthmod(experience.startdate, end)
            # add all months in the range to a list
            for month in range(0, (months[0].months + 1)):
                all_months.append(experience.startdate +
                                  relativedelta.relativedelta(months=+month))
    # remove duplicates from list
    num_months = len(list_unique_order_preserving(all_months))
    # calculate roughly how many days this is
    instance.politician.work_experience_days = num_months * (365 / 12)
    # save politician with newly calculated number of days
    instance.politician.save()
Exemple #2
0
def detail(request, user_id, id):
    the_detail = Work.objects.get(id=id)
    the_goals = Goal.objects.filter(work_id=id, is_end=0)
    today = date.today().strftime('%Y/%m/%d')
    dt1 = the_detail.created_at
    dt2 = the_detail.deadline
    # 2つの日付の差を、月単位/年単位で求める -----------
    # (monthdelta(20), datetime.timedelta(days=25)) <-タプル(リストみたいなもん)
    mmod = monthmod(dt1, dt2)

    ## 月数差(余りは切り捨て)
    months = mmod[0].months  # 20

    ## 年数差(余りは切り捨て)月数差を12で割ります。月の日数は色々ですが、年の月数は常に12なのでこれでok
    years = mmod[0].months // 12  # 1
    created_at = the_detail.created_at.strftime('%Y/%m/%d')
    deadline = the_detail.deadline.strftime('%Y/%m/%d')
    data = {
        'user_id': user_id,
        'detail': the_detail,
        'months': range(months),
        'years': years,
        'created_at': created_at,
        'today': today,
        'deadline': deadline,
        'the_goals': the_goals,
    }
    return render(request, 'pages/detail.html', data)
Exemple #3
0
def month_diff(d1, d2):
    """
    return the difference between d1, d2
    """
    # year_diff = d2.year - d1.year
    # month = year_diff * 12 + abs(d1.month - d2.month)
    # month = month if month else 1
    month_diff = monthmod(d1, d2)[0].months
    return month_diff if month_diff else 1
Exemple #4
0
def months_diff(d1, d2, date_format='%Y-%m-%d'):
    """
    days between d1 and d2 both included, so if d1 = d2.
    :param d1: date string
    :param d2: date string
    :param date_format:
    :return: d2 - d1 in months
    """
    date1 = datetime.strptime(d1, date_format)
    date2 = datetime.strptime(d2, date_format)
    return monthdelta.monthmod(date1, date2)[0].months
def date_to_monthnum(date: datetime.date) -> int:
    """Convert a given date object to the number-of-months-since-0-AD.

    Why? Because that's how Heavens Above encodes it.

    Args:
        date: The date to convert.

    Returns:
        The number of months since 0 AD.
    """
    ad1 = datetime.date(1, 1, 1)
    return monthdelta.monthmod(ad1, date)[0].months + 12
Exemple #6
0
def months_diff(d1, d2, date_format=None):
    """
    days between d1 and d2 both included, so if d1 = d2.
    :param d1: date string
    :param d2: date string
    :param date_format:
    :return: d2 - d1 in months
    """
    f1 = get_date_format(d1) if date_format is None else date_format
    f2 = get_date_format(d2) if date_format is None else date_format
    if f1 is None or f2 is None:
        return None
    else:
        date1 = datetime.strptime(d1, f1)
        date2 = datetime.strptime(d2, f2)
        return monthdelta.monthmod(date1, date2)[0].months
Exemple #7
0
 def duration_str(self):
     monthdelta, timedelta = monthmod(self.first_visit(), timezone.now().date())
     months = monthdelta.months
     days = timedelta.days
     years = months/12
     month_remainder = months - (years * 12)
     retval = ""
     if months < 12:
         retval ="%d months" % months
     else:
         if years == 1 :
             retval = "1 year"
         elif years > 1:
             retval = "%d years" % years
         if month_remainder > 1:
             retval += " and %d months" % month_remainder
     return retval
Exemple #8
0
def is_reminder_required(record, months_to_notify):
    """
    Input
      record: A dictionary of key rcid to value of a subset of fields from the redcap db
  
    Output
      boolean: True/False based on satisfying the condition to email 
  """
    try:
        if record['lstremndr_dt'] == datetime.today().date().strftime(
                '%Y/%m/%d'):
            print 'already sent'
            return False, 0
        if record['testing_reminder'] != u'1':
            # if the patient had opted out of reminders Don't bother further condtions
            return False, 0
        elif (record['rapid1'] is u'1'
              and record['rapid2'] is not u'0') or record['dhiv'] is u'P':
            # The above condition is true for positive patients
            # Since positive patients will be going through
            # a different treatment plan, they dont need to
            # be reminded for testing. So return false
            # The values meani, 0-Negative 1-Positive 2-Indeterminate
            return False, 0
        else:
            current_date = datetime.today()
            visit_date = datetime.strptime(record['visit_date'], "%Y-%m-%d")
            year = visit_date.year
            current_year = current_date.year
            limit_year = current_year - 2
            print(limit_year)
            if year < limit_year:
                return False, 0
            month, days = monthmod(visit_date, current_date)
            # Now, if record has a visit date that falls in to you notification slab,
            # Then this email Id should be notified
            if month.months >= months_to_notify:
                if visit_date.month in companion_months(current_date.month):
                    return True, month.months

    except:
        #Ignore if we don't have the user information for the rcid
        log.critical(traceback.format_exc())

    return False, 0
Exemple #9
0
def is_reminder_required_etc(record, months_to_notify):

    try:
        current_date = datetime.today()
        visit_date = datetime.strptime(record['collect_date'], "%Y-%m-%d")

        month, days = monthmod(visit_date, current_date)
        # Now, if record has a visit date that falls in to you notification slab,
        # Then this email Id should be notified
        if month.months >= months_to_notify:
            if visit_date.month in companion_months(current_date.month):
                return True, month.months

    except:
        #Ignore if we don't have the user information for the rcid
        log.critical(traceback.format_exc())

    return False, 0
Exemple #10
0
	def calculateTimeInRank(self,_start_date):
		tir = ''
		totalMonths = None
		try:
			if _start_date:
				then = dateUtils.parseUTCDateOnly(_start_date)
				now = dateUtils.parseUTCDateOnly(dateUtils.formatUTCDateOnly())
				delta = monthdelta.monthmod(then,now)
				months = delta[0].months
				totalMonths = months
				if months > 11:
					months = totalMonths
					years = months/12
					months -= years*12
					tir = '%iy ' % (years)
				tir += '%im' % (months)
		except Exception,e:
			pass
Exemple #11
0
def get_project_month(start_date, end_date, format=None):
    # 2つの日付の差を、月単位/年単位で求める -----------
    mmod = monthmod(start_date, end_date)
    # 月数差(余りは切り捨て)
    month_delta = mmod[0].months + 1
    # print(month_delta)

    project_month_list = []
    if format == 'year_month':
        for i in range(month_delta):
            project_month_list.append((start_date + relativedelta(months=i)).strftime('%Y-%m-%d')[:-3])
    else:
        for i in range(month_delta):
            project_month_list.append((start_date + relativedelta(months=i)).strftime('%Y-%m-%d'))


    # print(project_month_list)
    return project_month_list
Exemple #12
0
def update_month_booking(sender, instance, **kwargs):
    '''
    Обновление данных о месячной загрузке в связанной таблице MonthBooking
    '''
    # disable the handler during fixture loading
    if kwargs['raw']:
        return

    # удаление старых данных
    MonthBooking.objects.filter(booking=instance).delete()

    # округление начального и конечного месяца участия в проекте до 1 числа
    start_month = instance.start_date.replace(day=1)
    end_month = instance.finish_date.replace(day=1)

    # месяцы, в которых нужно отразить нагрузку
    month_generator = (
        start_month + monthdelta(i)
        for i in range(monthmod(start_month, end_month)[0].months + 1))

    for month in month_generator:
        # последнее число месяца
        monthtail = month + monthdelta(1) - timedelta(1)

        start = month if instance.start_date < month else instance.start_date
        finish = monthtail if instance.finish_date > monthtail else instance.finish_date

        days = workdays(start,
                        finish)  # число запланированных рабочих дней в месяце
        vol = volume(days, instance.load)  # трудоемкость работ в месяце
        load = days / workdays(month,
                               monthtail) * instance.load  # нагрузка за месяц

        # заполнение таблицы помесячной загрузки
        month_booking = MonthBooking(booking=instance,
                                     month=month,
                                     days=days,
                                     load=load,
                                     volume=vol)
        month_booking.save()
Exemple #13
0
def cal_political_experience_days(sender, instance, **kwargs):
    all_months = []
    #Get all politican political experience instances
    for experience in instance.politician.political.all():
        # when saving a new instance it saves the object first to get and idThis makes sure that the code is only
        # done on instances that are fully complete.
        if experience.startdate:
            # check if they are currently getting experience or if they have an end date
            if experience.enddate:
                end = experience.enddate
            else:
                end = date.today()
            #Find out how many months that this period represents
            months = monthdelta.monthmod(experience.startdate, end)
            # add all months in the range to a list
            for month in range(0,(months[0].months + 1)):
                all_months.append(experience.startdate + relativedelta.relativedelta(months=+month))
    # remove duplicates from list
    num_months = len(list_unique_order_preserving(all_months))
    # calculate roughly how many days this is
    instance.politician.political_experience_days = num_months * (365 / 12)
    # save politician with newly calculated number of days
    instance.politician.save()
Exemple #14
0
    def _cmpt_mw_rng(self):
        '''Compute moving window range, number of possible windows and
        number of possible maximum steps per window'''

        win_rng = []

        if self._twt == 'month':
            t_idx_0 = self._t_idx[0]

            for date in self._t_idx:
                win_rng.append(monthmod(t_idx_0, date)[0].months)

            self._ws_inc = self._ws

        elif self._twt == 'year':
            t_idx_0 = self._t_idx[0].year

            for date in self._t_idx:
                win_rng.append(date.year - t_idx_0)

            self._ws_inc = self._ws

        elif self._twt == 'range':
            n_wins = int(np.ceil(self._n_data_pts / self._tuss))

            win_rng = np.repeat(np.arange(n_wins),
                                self._tuss)[:self._n_data_pts]

            self._ws_inc = int(self._ws // self._tuss)

        else:
            raise NotImplementedError

        win_rng = np.array(win_rng, dtype=np.int64, order='c')
        win_rng.flags.writeable = False

        max_val = win_rng.max()

        assert np.all(win_rng >= 0), 'win_rng is not ascending!'

        assert max_val > self._ws_inc, (
            'Number of possible windows less than window_size!')

        unq_win_rng_vals = np.unique(win_rng)

        if (self._twt == 'month') or (self._twt == 'year'):

            mwi = unq_win_rng_vals.shape[0] - self._ws

        elif self._twt == 'range':
            mwi = unq_win_rng_vals.shape[0] - self._ws_inc

        self._mwr = win_rng
        self._mwi = mwi + 1

        assert self._mwi > 1, (
            'Number of final windows cannot be less than two!')

        max_steps = 0
        for i in range(self._mwi):
            ris = (self._mwr >= i) & (self._mwr < (i + self._ws_inc))
            max_steps = max(max_steps, ris.sum())

        max_steps = int(max_steps)
        assert max_steps, 'This should not happen!'

        self._mss = max_steps

        if self.verbose:
            print('_mwi:', self._mwi)
            print('_mss:', self._mss)
            print('_mwr:', self._mwr)
            print('unq_win_rng_vals:', unq_win_rng_vals)

        self._mw_rng_cmptd_flag = True
        return
Exemple #15
0
def printGraph():
    """ 履歴をグラフに表示 """

    jdata = jsonUtils.readJsonFile(dataFile)
    if (jdata == {}):
        return 404

    xl = []
    yl = []
    yd = []
    expi = 0
    # 月々のデータを取得
    for row in jdata['log']:
        adj = 0
        if ('adj' in row):
            adj = row['adj']

        when = datetime.datetime.strptime(row['when'], '%Y-%m-%d')
        if (datetime.date(when.year + SHOW_YEARS, when.month, when.day) <
                datetime.date.today()):
            continue

        xl.append(when)
        yl.append(row['bank'] + row['cash'] - row['card'])

        # 定期出費を計上
        dum = 0
        for erow in jdata['exp']:
            ewhen = datetime.datetime.strptime(erow['when'], '%Y-%m-%d')
            ewhen = ewhen.date() - datetime.timedelta(days=ewhen.day - 1)
            ldate = when.date() - datetime.timedelta(days=when.day - 1)

            if ((ldate > ewhen) and
                (ldate <= ewhen + monthdelta.monthdelta(erow['month']))):
                dum += erow['exp'] * (monthdelta.monthmod(
                    ldate, ewhen + monthdelta.monthdelta(
                        erow['month']))[0].months) / erow['month']

        yd.append(row['bank'] + row['cash'] - row['card'] + adj + dum)

    xe = []
    ye = []
    for row in [row for row in jdata['exp'] if row['month'] == 0]:
        when = datetime.datetime.strptime(row['when'], '%Y-%m-%d')
        if (datetime.date(when.year + SHOW_YEARS, when.month, when.day) <
                datetime.date.today()):
            continue
        xe.append(when)
        ye.append(row['exp'])

    plt.switch_backend("agg")
    plt.subplots(figsize=(16, 9))
    plt.plot(xl, yd, label="dummy", linestyle="--")
    plt.plot(xl, yl, label="log")
    plt.scatter(xe, ye, label="expense", color="red")
    plt.xlabel("when")
    plt.ylabel("金額", fontproperties=fp)
    plt.legend()

    plt.savefig("log.png")

    return 0
Exemple #16
0
 def prev_billing_date(self, test_date=None):
     if not test_date:
         test_date = date.today()
     day_difference = monthmod(self.start_date, test_date)[1]
     return test_date - day_difference
Exemple #17
0
	def prev_billing_date(self, test_date=date.today()):
		day_difference = monthmod(self.start_date, test_date)[1]
		return test_date - day_difference
Exemple #18
0
def get_owners_and_dates(asset_ID, request_start, request_end):

    # define the owners_and_dates class that will be populated and returned

    class Owners_And_Dates(object):

        slots = 0

        def __init__(self, asset_id, owner_id, first_name, last_name,
                     start_for_owner, end_for_owner, start_requested,
                     end_requested, days_requested, days_available,
                     days_unavailable, unavailable_date_detail,
                     available_date_detail):
            self.asset_id = asset_id
            self.owner_id = owner_id
            self.start_for_owner = start_for_owner
            self.end_for_owner = end_for_owner
            self.start_requested = start_requested
            self.end_requested = end_requested
            self.first_name = first_name
            self.last_name = last_name
            self.days_requested = days_requested
            self.days_available = days_available
            self.days_unavailable = days_unavailable
            self.slot_id = start_requested.toordinal()
            self.date_span_unavailable_detail = unavailable_date_detail
            self.date_span_available_detail = available_date_detail
            Owners_And_Dates.slots += 1

        def get_date_span_detail(self):

            # if days_available < days_requested, then the user can click to view details
            # this function will get the details (records from BookingDetails table)
            # and store them in an object

            if self.days_available < self.days_requested:

                details = BookingDetail.objects.all().filter(
                    booking_id_id=self.asset_id, )

            return {(1, 2, 3), (2, 3, 4)}

        def owner_display_name(self):
            return "%s %s" % (self.first_name, self.last_name)

        def numberOfSlots(self):
            return Owners_And_Dates.slots

        def __repr__(self):
            return "Owner is: %s | Start Date: %s | End Date: %s" % (
                self.owner_id, self.owner_display_name, self.start_for_owner,
                self.end_for_owner)

        def __str__(self):
            return "Owner is: %s | Start Date: %s | End Date: %s" % (
                self.owner_id, self.start_for_owner, self.end_for_owner)

    # empty object
    owners_and_dates_list = []
    # empty dictionary
    sort_order_of_owners = {}

    # get the asset in question
    the_asset = Asset.objects.get(pk=asset_ID)

    # extract the variables needed for later
    static_start_date = the_asset.sharing_start_date
    slot_duration = the_asset.slot_duration_unit
    num_slots = int(the_asset.number_of_slot_units)

    # don't continue if no slots entered (will get divide by zero error)
    if num_slots == 0:
        return []

    # don't continue if the requested start date is on or before the static start date!
    if request_start <= static_start_date:
        return []

    # populate dictionary of the sort order and owners
    the_asset_mapping = Asset_User_Mapping.objects.all().filter(
        asset_ID=asset_ID, is_owner=True).order_by("position_in_rotation")

    if the_asset_mapping.count() == 0:
        return []

    for mapping in the_asset_mapping:

        sort_order_of_owners[mapping.position_in_rotation] = mapping.user_ID_id

    # ensure the dates are python dates (may not be needed when coming from database)
    dateformat = '%Y-%m-%d'
    start_date = request_start
    end_date = request_end

    # calculate number of days requested (i.e. number of nights)
    requested_num_days = end_date.toordinal() - start_date.toordinal()
    print "%s nights" % requested_num_days

    # check here if there is only one Owner
    if the_asset_mapping.count() == 1:

        # check Booking table to find out the number of days un-available for the range
        date_ranges = check_availability(asset_ID, start_date, end_date)
        unavailable_details = date_ranges['unavailable']
        num_days_available = requested_num_days - len(unavailable_details)
        num_days_unavailable = requested_num_days - num_days_available
        slot_owner_on_requested_start_date = sort_order_of_owners.get(1)
        o = User.objects.get(id=slot_owner_on_requested_start_date)
        available_details = date_ranges['available']
        o_and_d = Owners_And_Dates(
            asset_ID, slot_owner_on_requested_start_date, o.first_name,
            o.last_name, start_date, end_date, start_date, end_date,
            requested_num_days, num_days_available, num_days_unavailable,
            unavailable_details, available_details)
        owners_and_dates_list.append(o_and_d)

        return owners_and_dates_list

    if str(slot_duration) == "Week":
        slot_duration_days = 7
    elif str(slot_duration) == "Month":
        slot_duration_days = 30  # can't use a set number here for months
    else:
        slot_duration = 1

    # calculate number of days in the owner-duration period
    num_days_per_period = slot_duration_days * num_slots
    print "Number of days per Owner: %s" % num_days_per_period
    if str(slot_duration) == "Week":

        # get the number of slots from static start date to requested start date
        # in order to work out the number of slots since static start date
        delta = start_date - static_start_date
        num_duration_periods_from_static_to_start = delta.days / slot_duration_days
        num_slot_periods_in_static_to_start = num_duration_periods_from_static_to_start / num_slots
        print "%s is the number of %s since static start date" % (
            num_duration_periods_from_static_to_start, slot_duration)
        print "%s is number of slots since static start date" % num_slot_periods_in_static_to_start

    elif str(slot_duration) == "Month":

        # get the number of months from static start date to requested start date
        # this will be the number of slots since static start date
        num_months = monthdelta.monthmod(static_start_date, start_date)
        num_duration_periods_from_static_to_start = num_months[0].months
        num_slot_periods_in_static_to_start = int(
            num_duration_periods_from_static_to_start) / num_slots
        print "%s is the number of %s since static start date" % (
            num_duration_periods_from_static_to_start, slot_duration)
        print "%s is number of slots since static start date" % num_slot_periods_in_static_to_start
        print "%s is the days remaining" % num_months[1].days

    # then which slot in the rotation order is being requested
    remainder_of_mod = divmod(num_slot_periods_in_static_to_start,
                              len(sort_order_of_owners))
    slot_order_on_requested_start_date = remainder_of_mod[1] + 1
    slot_owner_on_requested_start_date = sort_order_of_owners.get(
        slot_order_on_requested_start_date)
    print "%s is slot order on the requested start date" % slot_order_on_requested_start_date
    print "%s is the ID of the owner on the requested start date" % slot_owner_on_requested_start_date

    # requested start date is in someone's slot - get the start and end date of that slot
    if str(slot_duration) == "Week":
        slot_start_for_start_date = get_start_slot_date(
            static_start_date, start_date, num_days_per_period, dateformat)
        slot_end_for_start_date = get_end_slot_date(slot_start_for_start_date,
                                                    num_days_per_period)

    elif str(slot_duration) == "Month":
        # start date will simply be day of static start day with month and year of requested start date!
        slot_start_for_start_date = datetime.date(start_date.year,
                                                  start_date.month,
                                                  static_start_date.day)
        # slot end will be the same date plus <num_slots> later
        slot_end_for_start_date = slot_start_for_start_date + monthdelta.monthdelta(
            num_slots)

    print "%s is start of slot with requested start date" % slot_start_for_start_date
    print "%s is end of slot with requested start date" % slot_end_for_start_date

    # now work out if only one owner is affected by the requested date range
    # or more than one owner
    # store Owner ID and slot start and slot end dates in object to return

    # first slot details

    delta = slot_end_for_start_date - start_date
    num_days_slot_1 = delta.days
    print "first slot delta days: %s" % num_days_slot_1

    # depending on whether the last/end requested date falls before or after the slot_end,
    # the 'end_date' variable and days_requested variable for next functions will differ
    if requested_num_days < num_days_slot_1:
        first_slot_end_date = end_date
        days_requested = requested_num_days
    else:
        first_slot_end_date = slot_end_for_start_date
        days_requested = num_days_slot_1

    print "first slot end date: %s" % first_slot_end_date
    print "days requested: %s" % days_requested

    # start date could be the very first day of a slot,
    # if so, move on to the next slot (don't add a record of '0' days)

    # check Booking table to find out the number of days un-available for the range
    date_ranges = check_availability(asset_ID, start_date, first_slot_end_date)
    unavailable_details = date_ranges['unavailable']
    num_days_available = days_requested - len(unavailable_details)
    num_days_unavailable = days_requested - num_days_available
    o = User.objects.get(id=slot_owner_on_requested_start_date)
    available_details = date_ranges['available']
    o_and_d = Owners_And_Dates(
        asset_ID, slot_owner_on_requested_start_date, o.first_name,
        o.last_name, slot_start_for_start_date, slot_end_for_start_date,
        start_date, first_slot_end_date, days_requested, num_days_available,
        num_days_unavailable, unavailable_details, available_details)
    owners_and_dates_list.append(o_and_d)

    # if the number from subtracting requested end date from the slot end date is >=0
    # then there is no need to move into the next slot i.e. only one owner should be returned
    delta = slot_end_for_start_date - end_date
    print "delta: %s" % delta
    if delta.days >= 0:
        print "delta days: %s" % delta.days
        print "Stays in first slot"
        slots_affected = 1

    else:
        print "delta days: %s" % delta.days
        print "Goes to second slot"

        print "%s days required from owner slot 1: " % num_days_slot_1, slot_owner_on_requested_start_date

        days_to_cover = requested_num_days - num_days_slot_1
        print "%s days left to cover" % days_to_cover

        end_of_previous_slot = slot_end_for_start_date

        # use this to check rows/items to return
        slots_affected = 1

        previous_slot_order = slot_order_on_requested_start_date

        while days_to_cover > 0:

            # get date info for next slot
            next_slot_start_date = end_of_previous_slot

            if str(slot_duration) == "Week":
                next_slot_end = get_end_slot_date(next_slot_start_date,
                                                  num_days_per_period)
            elif str(slot_duration) == "Month":
                next_slot_end = next_slot_start_date + monthdelta.monthdelta(
                    num_slots)

            # get sort order of next slot
            if (previous_slot_order + 1) > len(sort_order_of_owners):
                next_slot_order = 1
            else:
                next_slot_order = previous_slot_order + 1

            # get slot owner of next slot
            next_slot_owner = sort_order_of_owners.get(next_slot_order)

            # increment
            slots_affected += 1

            # check if remainder days is more than one duration period
            # works for weeks (always 7 days), but for months, need to calculate the ACTUAL number of days
            # in the next period (this will vary with different length months)

            if str(slot_duration) == "Month":
                num_days_in_next_period = next_slot_end.toordinal(
                ) - next_slot_start_date.toordinal()
                # store in this variable for ease of code
                num_days_per_period = num_days_in_next_period

            if days_to_cover > num_days_per_period:

                # this is not the last time in loop because there are more days to cover
                # reset to remainder for next time in loop
                days_to_cover = days_to_cover - num_days_per_period
                end_of_previous_slot = next_slot_end
                previous_slot_order = next_slot_order

                print "%s is owner ORDER" % next_slot_order
                print "%s days required from next owner with ID: %s" % (
                    num_days_per_period, next_slot_owner)
                print "%s is start of next slot" % next_slot_start_date
                print "%s is end of next slot" % next_slot_end
                print "%s days still to cover" % days_to_cover

                date_ranges = check_availability(asset_ID,
                                                 next_slot_start_date,
                                                 next_slot_end)
                unavailable_details = date_ranges['unavailable']
                num_days_available = num_days_per_period - len(
                    unavailable_details)
                num_days_unavailable = num_days_per_period - num_days_available
                o = User.objects.get(id=next_slot_owner)
                available_details = date_ranges['available']
                o_and_d = Owners_And_Dates(
                    asset_ID, next_slot_owner, o.first_name, o.last_name,
                    next_slot_start_date, next_slot_end, next_slot_start_date,
                    next_slot_end, num_days_per_period, num_days_available,
                    num_days_unavailable, unavailable_details,
                    available_details)

                owners_and_dates_list.append(o_and_d)

            else:

                # finally, we have come to the end because remaining days to cover is less than one duration period
                delta = end_date - next_slot_start_date
                days_of_current_slot = delta.days
                print "%s is owner ORDER" % next_slot_order
                print "%s days required until end of the booking" % days_of_current_slot
                print "%s days required from next (final) owner with ID: %s" % (
                    days_of_current_slot, next_slot_owner)
                print "%s is start of next (final) slot" % next_slot_start_date
                print "%s is end of next (final) slot" % next_slot_end

                date_ranges = check_availability(asset_ID,
                                                 next_slot_start_date,
                                                 end_date)
                unavailable_details = date_ranges['unavailable']
                num_days_available = days_of_current_slot - len(
                    unavailable_details)
                num_days_unavailable = days_of_current_slot - num_days_available
                o = User.objects.get(id=next_slot_owner)
                available_details = date_ranges['available']
                o_and_d = Owners_And_Dates(
                    asset_ID, next_slot_owner, o.first_name, o.last_name,
                    next_slot_start_date, next_slot_end, next_slot_start_date,
                    end_date, days_of_current_slot, num_days_available,
                    num_days_unavailable, unavailable_details,
                    available_details)

                owners_and_dates_list.append(o_and_d)

                # make sure to set to zero to end the loop
                days_to_cover = 0
                print "%s days still to cover" % days_to_cover

    # return "owners and dates: %s | slots affected: %s" % (owners_and_dates_list,slots_affected)
    return owners_and_dates_list
Exemple #19
0
 def prev_billing_date(self, test_date=None):
     if not test_date:
         test_date = date.today()
     day_difference = monthmod(self.start_date, test_date)[1]
     return test_date - day_difference
Exemple #20
0
    def bill(self):
        """
        Issue a bill for a vendor.

        This method is called periodically by an external tool. It let all duties bill up and the
        executes all price modifiers such as discount encounters.

        We have to bill the vendor at the time of call. Only when the billing happened already
        today (or in the future) we will ignore that call.

        :rvalue:`tariff.Bill` the created bill (invoice)
        """
        if self.last_billed >= timezone.now().date():
            return Bill.objects.filter(period_end=timezone.now().date()).get()

        if self.next_billing > timezone.now().date():
            raise ValueError(
                "Can not bill before the end of billing period - close it instead."
            )

        contractor = defaults.vendor()
        bill = Bill.objects.create(
            vendor=self.vendor,
            logo=contractor.logo.path if contractor.logo else None,
            subscriber=self.vendor.address,
            period_start=self.last_billed,
            period_end=self.next_billing,
            contractor=contractor.address,
            contractor_bank=contractor.bank_account)

        months, rest = monthmod(self.last_billed, self.next_billing)
        # tranform date to datetime for billing useng StatisticsManager
        last_billed = datetime(self.last_billed.year, self.last_billed.month,
                               self.last_billed.day)
        # bill by months (because of Discounts and better visibility on the bill)
        for month in range(months.months):
            total = Decimal("0.00")
            for tariff, price in Statistics.objects.bill(
                    self.vendor, last_billed + monthdelta(month),
                    last_billed + monthdelta(month + 1)):
                bill.add_item(tariff, price, settings.TAX)
                total += price

            discount = Discount.objects.cut_the_price(self.vendor, total)
            if discount is not None:
                bill.add_item(*discount)

        # bill the remaining time (if there is some)
        if rest.days > 1:
            total = Decimal("0.00")
            for tariff, price in Statistics.objects.bill(
                    self.vendor, last_billed + months,
                    last_billed + months + rest):
                bill.add_item(tariff, price, settings.TAX)
                total += price

            discount = Discount.objects.cut_the_price(self.vendor, total)
            if discount is not None:
                bill.add_item(*discount)

        if bill.total < 0:
            bill.add_item(_("Rounding price to zero"), -1 * bill.total)

        self.last_billed = self.next_billing

        self.save()  # periods change is taken care of in .save() method
        bill.save()
        bill.send()
        return bill