def set_next_relative_date(start_date, day_of_week, week_of_month, separation_count): arg = MO(1) if day_of_week == 1: arg = MO(week_of_month) if day_of_week == 2: arg = TU(week_of_month) if day_of_week == 3: arg = WE(week_of_month) if day_of_week == 4: arg = TH(week_of_month) if day_of_week == 5: arg = FR(week_of_month) if day_of_week == 6: arg = SA(week_of_month) if day_of_week == 7: arg = SU(week_of_month) if week_of_month == -1: return start_date + relativedelta( day=31, months=+separation_count, weekday=arg) return start_date + relativedelta( day=1, months=+separation_count, weekday=arg)
def _get_date_range(self, date_range): """Returns a start and end date for a given period. These dates are used to in a query to pick rows on or after the start date but before the end date. """ today = self._get_today() if date_range == "today": start_date = today end_date = start_date + relativedelta(days=1) elif date_range == "yesterday": start_date = today + relativedelta(days=-1) end_date = today elif date_range == "thisweek": start_date = today + relativedelta(weekday=MO(-1)) end_date = today + relativedelta(days=1) elif date_range == "lastweek": start_date = today + relativedelta(weekday=MO(-2)) end_date = start_date + relativedelta(weeks=1) elif date_range == "thismonth": start_date = today + relativedelta(day=1) end_date = today + relativedelta(months=1, day=1) elif date_range == "lastmonth": start_date = today + relativedelta(months=-1, day=1) end_date = start_date + relativedelta(months=1, day=1) else: raise Exception(f"invalid value '{date_range}' for date_range parameter.") return start_date, end_date
def _generate_period(self): """ Generate tuple reprenseting grid column period with start datetime and end datetime. We use `rrule` as this lib takes DST (Daylight Saving Time) into account. We select the period the user wants in its timezone (the `read_group` groups by datetime in current user TZ). Then, convert it into UTC to be sent and use by the sytem. """ start = self._start.replace(tzinfo=None) stop = self._end.replace(tzinfo=None) + STEP_BY[ self. step] # add a step as the given stop limit is not included in column domain if self.step == 'day': r = rrule.rrule(rrule.DAILY, dtstart=start, until=stop) if self.step == 'week': # Seems that PostgresSQL consider Monday as first week day (The ISO-8601 week starts on # Monday). See https://www.postgresql.org/docs/9.1/functions-datetime.html start = start + relativedelta(weekday=MO(-1)) stop = stop + relativedelta(weekday=MO(-1)) r = rrule.rrule(rrule.WEEKLY, dtstart=start, until=stop, wkst=MO) if self.step == 'month': r = rrule.rrule(rrule.MONTHLY, dtstart=start, until=stop) date_range = [] previous_dt = None for dt in r: current_dt = self._user_tz.localize(dt) if previous_dt: date_range.append((previous_dt.astimezone(pytz.utc), current_dt.astimezone(pytz.utc))) previous_dt = current_dt return date_range
class US(Market): tz = timezone("America/New_York") # http://www.nasdaq.com/about/trading-schedule.aspx #trading_hour = TradeHour(TradeTime(9, 30), TradeTime(16, 0)) # force to retrieve today's price trading_hour = TradeHour(TradeTime(9, 30), TradeTime(21, 0)) # http://en.wikipedia.org/wiki/Public_holidays_in_the_United_States holidays = [] for year in range(2005, 2025): holidays.extend([ # TODO: if holiday falls in weekend then ... date(year, 1, 1), # New Year's Day (datetime(year, 1, 1) + relativedelta(weekday=MO(3))).date(), # Martin Luther King, Jr. (datetime(year, 2, 1) + relativedelta(weekday=MO(3))).date(), # Presidents' Day (datetime(year, 6, 1) + relativedelta(weekday=MO(-1))).date(), # Memorial Day date(year, 7, 4), # Independence Day (datetime(year, 9, 1) + relativedelta(weekday=MO(1))).date(), # Labor Day (datetime(year, 10, 1) + relativedelta(weekday=MO(2))).date(), # Columbus Day date(year, 11, 11), # Veterans Day (datetime(year, 11, 1) + relativedelta(weekday=TH(4))).date(), # Thanksgiving Day date(year, 12, 25), # Christmas ]) def __init__(self, name="US"): super().__init__() self.name = name self.datasources = { "yahoo" : Yahoo(), "google": Google(), } self.datasource = self.datasources["yahoo"]
class MontrealHolidayCalendar(AbstractHolidayCalendar): rules = [ Holiday("New Year's Day", month=1, day=1, observance=next_monday), GoodFriday, EasterMonday, Holiday("Jour des Patriotes", month=5, day=24, offset=pd.DateOffset(weekday=MO(-1))), Holiday("St. Jean Baptiste", month=6, day=24, observance=nearest_workday), Holiday("Canada Day", month=7, day=1, observance=nearest_workday), Holiday("Labor Day", month=9, day=1, offset=pd.DateOffset(weekday=MO(1))), Holiday("Thanksgiving", month=10, day=1, offset=pd.DateOffset(weekday=MO(2))), Holiday("Christmas Day", month=12, day=25, observance=sunday_to_monday), ]
def long_term(partner, date): """ Takes a time series dataframe, converts dates to a series of numbers, uses it as x and the cumulative 1-year TEU of the partner's shipping history as y for a level 2 polynomial regression. We derive this polynome a the required date to find the slope of that function in order to classify the risk of that partner to churn. :param partner: pd.DataFrame :param date: Requested date as a string :return: lt_slope the slope of the derivative to polynomial regression, a float """ lt_risk = False # mdate = parser.parse(str(date)).toordinal() mdate = partner[partner.etd_wkdat == date].index[0] # x = [x.toordinal() for x in partner.etd_wkdat] x = partner.index y = partner.rolling_year_teu.tolist() p2 = np.poly1d(np.polyfit(x, y, 2)) print(p2) lt_slope = p2.deriv()[1] * np.float64(mdate) + p2.deriv()[0] print(lt_slope) lt_slope = float("{0:.2f}".format(lt_slope)) # dd = mdates.num2date(x) # _ = plt.plot(dd, y, '-', dd, p2(x), '--') # plt.ylabel('TEU') # plt.xlabel(partner.dcd_fullname.unique()[0]) # plt.show() # lt_evolution: average rolling_year_teu over last 6 weeks compared to the same 6 weeks the previous year current_period = partner[partner.etd_wkdat.isin([ pd.to_datetime(str(w).split('/')[0]).date() for w in pd.period_range(date - datetime.timedelta(weeks=51) + relativedelta(weekday=MO(-1)), date + relativedelta(weekday=MO(-1)), freq='W-SUN') ])].rolling_year_teu last_year = partner[partner.etd_wkdat.isin([ pd.to_datetime(str(w).split('/')[0]).date() for w in pd.period_range(date - datetime.timedelta(days=365.25) - datetime.timedelta(weeks=51) + relativedelta(weekday=MO(-1)), date - datetime.timedelta(days=365.25) + relativedelta(weekday=MO(-1)), freq='W-SUN') ])].rolling_year_teu lt_evolution = float("{0:.2f}".format( (current_period.mean() - last_year.mean()) / last_year.mean())) # Handle non-numerical results (replace them with 100% increase because they represent a division by zero # for the case of past = some number present = zero) lt_evolution = 1.0 if np.isinf(lt_evolution) or np.isnan( lt_evolution) else lt_evolution if lt_slope < -1.0 or lt_evolution < -0.3: lt_risk = True return lt_slope, lt_evolution, lt_risk
def __change_day_by_law(holiday, latest_days=(3, 4)): # Law No. 139-97 - Holidays Dominican Republic - Jun 27, 1997 if holiday >= date(1997, 6, 27): if holiday.weekday() in [1, 2]: holiday -= rd(weekday=MO(-1)) elif holiday.weekday() in latest_days: holiday += rd(weekday=MO(1)) return holiday
def short_term(partner, date): """ Looks at a period of 12 weeks does a linear regression of the cumulative 1-year TEU. If the slope is negative and inferior to the slope of the linear regression over the same period of the previous year, the partner is classified at risk. :param partner: pd.DataFrame :param date: Requested date as a string :return: st_slope, a float """ st_risk = False # Current period: 12 previous and current weeks current_period = partner[partner.etd_wkdat.isin([ pd.to_datetime(str(w).split('/')[0]).date() for w in pd.period_range(date - datetime.timedelta(weeks=11) + relativedelta(weekday=MO(-1)), date + relativedelta(weekday=MO(-1)), freq='W-SUN') ])] # x_curr = [x.toordinal() for x in current_period.etd_wkdat] x_curr = current_period.index y_curr = current_period.rolling_year_teu.tolist() p_curr = np.poly1d(np.polyfit(x_curr, y_curr, 1)) print(p_curr) st_slope = float("{0:.2f}".format(p_curr.deriv()[0])) # Last year period: same 12 weeks, one year prior last_year = partner[partner.etd_wkdat.isin([ pd.to_datetime(str(w).split('/')[0]).date() for w in pd.period_range(date - datetime.timedelta(days=365.25) - datetime.timedelta(weeks=11) + relativedelta(weekday=MO(-1)), date - datetime.timedelta(days=365.25) + relativedelta(weekday=MO(-1)), freq='W-SUN') ])] # x_past = [x.toordinal() for x in last_year.etd_wkdat] x_past = last_year.index y_past = last_year.weekly_teu.tolist() p_past = np.poly1d(np.polyfit(x_past, y_past, 1)) st_evolution = float("{0:.2f}".format( (current_period.weekly_teu.mean() - last_year.weekly_teu.mean()) / last_year.weekly_teu.mean())) # Handle non-numerical results (replace them with 100% increase because they represent a division by zero # for the case of past = some number present = zero) st_evolution = 1.0 if np.isinf(st_evolution) or np.isnan( st_evolution) else st_evolution if st_slope < p_past.deriv()[0] or st_evolution < -0.3: st_risk = True return st_slope, st_evolution, st_risk
class USTradingCalendar(AbstractHolidayCalendar): rules = [ Holiday("new_years_day", month=1, day=1), Holiday("mlk_day", month=1, day=1, offset=pd.DateOffset(weekday=MO(3))), Holiday("super_bowl", month=2, day=1, offset=pd.DateOffset(weekday=SU(1))), Holiday("valentines_day", month=2, day=14), Holiday("presidents_day", month=2, day=1, offset=pd.DateOffset(weekday=MO(3))), Holiday("easter", month=1, day=1, offset=[Easter()]), Holiday("mothers_day", month=5, day=1, offset=pd.DateOffset(weekday=SU(2))), Holiday("memorial_day", month=5, day=31, offset=pd.DateOffset(weekday=MO(-1))), Holiday("july_4th", month=7, day=4), Holiday("labor_day", month=9, day=1, offset=pd.DateOffset(weekday=MO(1))), Holiday("columbus_day", month=10, day=1, offset=pd.DateOffset(weekday=MO(2))), Holiday("halloween", month=10, day=31), Holiday("veterans_day", month=11, day=11), Holiday("thanksgiving", month=11, day=1, offset=pd.DateOffset(weekday=TH(4))), Holiday("black_friday", month=11, day=1, offset=[pd.DateOffset(weekday=TH(4)), Day(1)]), Holiday("cyber_monday", month=11, day=1, offset=[pd.DateOffset(weekday=TH(4)), Day(4)]), Holiday("christmas", month=12, day=25), ]
def _populate(self, year): holidays.UnitedStates._populate(self, year) # Remove Martin Luther King Day self.pop(date(year, 1, 1) + relativedelta(weekday=MO(+3)), None) # Remove Columbus Day self.pop(date(year, 10, 1) + relativedelta(weekday=MO(+2)), None) # Remove Veterans Day self.pop(date(year, 11, 11), None) # Add good friday self[holidays.easter(year) + relativedelta(days=-2)] = 'Good Friday'
def generate_grid(start_dt, end_dt): grid = [] dt_cursor = start_dt + relativedelta(weekday=MO(-1)) while dt_cursor < end_dt: days_b = (start_dt - dt_cursor).days days_a = (end_dt - dt_cursor).days + 1 grid.append( list( zip([':minus:'] * days_b + [':white_circle:'] * (min(5, days_a) - max(days_b, 0)) + [':black_circle:'] * min(2, days_a - 5, max(0, 7 - days_b)) + [':minus:'] * (7 - days_a), [dt_cursor + relativedelta(days=i) for i in range(7)]))) dt_cursor += relativedelta(weeks=1, weekday=MO(-1)) return grid
def start_of_bucket(current_date): new_date = current_date + relativedelta(weekday=MO(-1)) return app.timezone.localize( datetime(year=new_date.year, month=new_date.month, day=new_date.day))
def _send_report_by_email(userprofile, project): user = userprofile.user context_for_email = {} current_date = date.today() previuos_date = current_date - relativedelta(weeks=+1) from_date = previuos_date - relativedelta(weekday=MO(-1)) to_date = previuos_date - relativedelta(weekday=6) context_for_email['user'] = user context_for_email['from_date'] = from_date context_for_email['to_date'] = to_date context_for_email['report'] = userprofile.report(from_date, to_date, project) # detailed total of hours between [from_date, to_date] total_hrs = 0 for r in context_for_email['report']: total_hrs += r[3] context_for_email['total_hrs_detailed'] = total_hrs context_for_email['num_loggable_hours'] = userprofile.num_loggable_hours( from_date, to_date) subject = render_to_string('previous_week_report_subject.txt', context_for_email) # Email subject *must not* contain newlines subject = ''.join(subject.splitlines()) message = render_to_string('previous_week_report_message.txt', context_for_email) user.email_user(subject, message)
def gen_memorial_day(self): # Memorial Day if self.populating_year > 1970: self[date(self.populating_year, 5, 31) + rd(weekday=MO(-1))] = "Memorial Day" elif self.populating_year >= 1888: self[date(populating_year, 5, 30)] = "Memorial Day"
def get_bounds(dt, interval): ''' Returns interval bounds the datetime is in. ''' day = _to_datetime(_remove_time(dt)) dt = _to_datetime(dt) if interval == 'minute': begin = datetime.datetime(dt.year, dt.month, dt.day, dt.hour, dt.minute, tzinfo=dt.tzinfo) end = begin + relativedelta(minutes=1) elif interval == 'hour': begin = datetime.datetime(dt.year, dt.month, dt.day, dt.hour, tzinfo=dt.tzinfo) end = begin + relativedelta(hours=1) elif interval == 'day': begin = day end = day + relativedelta(days=1) elif interval == 'week': begin = day - relativedelta(weekday=MO(-1)) end = begin + datetime.timedelta(days=7) elif interval == 'month': begin = datetime.datetime(dt.year, dt.month, 1, tzinfo=dt.tzinfo) end = begin + relativedelta(months=1) elif interval == 'year': begin = datetime.datetime(dt.year, 1, 1, tzinfo=dt.tzinfo) end = datetime.datetime(dt.year+1, 1, 1, tzinfo=dt.tzinfo) else: raise InvalidInterval('Inverval not supported.') end = end - relativedelta(microseconds=1) return begin, end
def get_period_date_ranges(self): '''Funcion encargada de obtener el rango entre periodos''' from dateutil.relativedelta import relativedelta, MO from_date, to_date = getdate(self.filters.from_date), getdate(self.filters.to_date) increment = { "Monthly": 1, "Quarterly": 3, "Half-Yearly": 6, "Yearly": 12 }.get(self.filters.range, 1) if self.filters.range in ['Monthly', 'Quarterly']: from_date = from_date.replace(day = 1) elif self.filters.range == "Yearly": from_date = get_fiscal_year(from_date)[1] else: from_date = from_date + relativedelta(from_date, weekday=MO(-1)) self.periodic_daterange = [] for dummy in range(1, 53): if self.filters.range == "Weekly": period_end_date = add_days(from_date, 6) else: period_end_date = add_to_date(from_date, months=increment, days=-1) if period_end_date > to_date: period_end_date = to_date self.periodic_daterange.append(period_end_date) from_date = add_days(period_end_date, 1) if period_end_date == to_date: break
def missing_dates(partner, min_date, date): first_week = partner.etd_week.min() full_dates = [str(p).split('/')[0] for p in pd.period_range(datetime.datetime.strptime(min_date, '%Y-%m-%d'), max(date + relativedelta(weekday=MO(-1)), partner.etd_wkdat.max()), freq='W-SUN')] full_weeks = [datetime.datetime.strptime(d, '%Y-%m-%d').strftime("%Y-%W") for d in full_dates] for idx, week in enumerate(full_weeks): if not partner.etd_week.isin([week]).any(): if week < first_week: rolling_year_teu = 0 else: try: rolling_year_teu = partner[partner.etd_week == full_weeks[idx-1]].rolling_year_teu.values[0] - \ partner[partner.etd_wkdat == (datetime.datetime.strptime(str(int(week.split('-')[0]) - 1) + '-' + week.split('-')[1] + '-1', '%Y-%W-%w') - datetime.timedelta(days=7))].weekly_teu.values[0] except: rolling_year_teu = partner[partner.etd_week == full_weeks[idx - 1]].rolling_year_teu.values[0] partner = partner.append({'dcd_partner_code': partner.dcd_partner_code.unique()[0], 'dcd_fullname': partner.dcd_fullname.unique()[0], 'etd_week': str(week), 'etd_wkdat': datetime.datetime.strptime(full_dates[idx], '%Y-%m-%d'), #'extract_date': partner.extract_date.unique()[0], 'weekly_teu': 0, 'rolling_year_teu': rolling_year_teu}, ignore_index=True) partner = partner.sort_values('etd_week') return partner
def get_user_stats(): # make a dict of dicts with the following shape for each user # total not implemented - will need to add an all-time count for when we enter a new year stats = {} for user in User.objects.all(): stats[user.username] = { 'hide_from_stats': user.hide_from_stats, 'total_week': 0, 'total_month': 0, 'total_year': 0, 'wins_week': 0, 'wins_month': 0, 'wins_year': 0, 'losses_week': 0, 'losses_month': 0, 'losses_year': 0, 'ratio_week': 0, 'ratio_month': 0, 'ratio_year': 0, 'elo': 1200, } now = timezone.datetime.now() start_of_week = now.replace(hour=0, minute=0, second=0) + relativedelta(weekday=MO(-1)) start_of_month = now.replace(day=1, hour=0, minute=0, second=0) start_of_year = now.replace(month=1, day=1, hour=0, minute=0, second=0) # for the last week, month, and year, sum the wins and losses for each user for result in PoolResult.objects.filter( created_on__gte=start_of_week).select_related('winner', 'loser'): stats[result.winner.username]['total_week'] += 1 stats[result.winner.username]['wins_week'] += 1 stats[result.loser.username]['total_week'] += 1 stats[result.loser.username]['losses_week'] += 1 for result in PoolResult.objects.filter( created_on__gte=start_of_month).select_related('winner', 'loser'): stats[result.winner.username]['total_month'] += 1 stats[result.winner.username]['wins_month'] += 1 stats[result.loser.username]['total_month'] += 1 stats[result.loser.username]['losses_month'] += 1 for result in PoolResult.objects.filter( created_on__gte=start_of_year).select_related('winner', 'loser'): stats[result.winner.username]['total_year'] += 1 stats[result.winner.username]['wins_year'] += 1 stats[result.loser.username]['total_year'] += 1 stats[result.loser.username]['losses_year'] += 1 # then get the weekly, monthly, and yearly win percentage for user in stats: stats[user]['ratio_week'] = percent(float(stats[user]['wins_week']), float(stats[user]['total_week'])) stats[user]['ratio_month'] = percent(float(stats[user]['wins_month']), float(stats[user]['total_month'])) stats[user]['ratio_year'] = percent(float(stats[user]['wins_year']), float(stats[user]['total_year'])) return stats
def test_get_week_coursework(self): today = timezone.now().date() monday = today + relativedelta(weekday=MO(-1)) sunday = today + relativedelta(weekday=SU(+1)) week = (monday, sunday) enrollment = EnrollmentFactory( grade_level__school_year__start_date=today - datetime.timedelta(days=30)) student = enrollment.student school_year = enrollment.grade_level.school_year GradeLevelFactory(school_year=school_year) course = CourseFactory(grade_level=enrollment.grade_level) coursework_1 = CourseworkFactory(student=student, course_task__course=course, completed_date=monday) coursework_2 = CourseworkFactory(student=student, course_task__course=course, completed_date=monday) week_coursework = student.get_week_coursework(week) self.assertEqual(week_coursework, {course.id: { monday: [coursework_1, coursework_2] }})
def _populate(self, year): # Populate the holiday list with the default US holidays holidays.UnitedStates._populate(self, year) # Remove Columbus Day self.pop(date(year, 10, 1) + relativedelta(weekday=MO(+2)), None) # Remove Veterans Day self.pop(date(year, 11, 11), None)
def next_bucket(current_date): new_date = current_date + relativedelta(days=+1, weekday=MO(+1)) return app.timezone.localize( datetime(year=new_date.year, month=new_date.month, day=new_date.day))
def R7_parser(self): self.START_DATE = self.gdate if "MONTHS" in self.kwargs: self.START_DATE = delta(self.START_DATE, months=self.kwargs["MONTHS"]) if "DAYINDEX" in self.kwargs and "DAYNAME" in self.kwargs: if self.kwargs["DAYINDEX"] - 2 == 0: self.START_DATE = self.START_DATE + relativedelta( day=1, weekday=MO(self.kwargs["DAYNAME"])) if self.kwargs["DAYINDEX"] - 2 == 1: self.START_DATE = self.START_DATE + relativedelta( day=1, weekday=TU(self.kwargs["DAYNAME"])) if self.kwargs["DAYINDEX"] - 2 == 2: self.START_DATE = self.START_DATE + relativedelta( day=1, weekday=WE(self.kwargs["DAYNAME"])) if self.kwargs["DAYINDEX"] - 2 == 3: self.START_DATE = self.START_DATE + relativedelta( day=1, weekday=TH(self.kwargs["DAYNAME"])) if self.kwargs["DAYINDEX"] - 2 == 4: self.START_DATE = self.START_DATE + relativedelta( day=1, weekday=FR(self.kwargs["DAYNAME"])) if self.kwargs["DAYINDEX"] - 2 == 5: self.START_DATE = self.START_DATE + relativedelta( day=1, weekday=SA(self.kwargs["DAYNAME"])) if self.kwargs["DAYINDEX"] - 2 == 6: self.START_DATE = self.START_DATE + relativedelta( day=1, weekday=SU(self.kwargs["DAYNAME"]))
def generate_timelog_data(): users = User.objects.all() projects = Project.objects.all() dumps = Dump.objects.all() current_date = date.today() previuos_date = current_date - relativedelta(weeks=+1) date_timelog = previuos_date - relativedelta(weekday=MO(-1)) # Genera registros de Lunes a Viernes for day in range(0, 5): # Genera registros para 5 usuarios aleatorios for u in range(1, 6): user = random.choice(users) project = random.choice(projects) dump = random.choice(dumps) task_name = 'task %s' % day hours = round(random.random() * 10, 3) description = 'description %s do %s' % (user.username, task_name) timelog = TimeLog(date=date_timelog, project=project, task_name=task_name, user=user, hours_booked=hours, description=description, dump=dump) timelog.save() date_timelog = date_timelog + relativedelta(days=1)
def start_end_date_for_period(period, default_start_date=False, default_end_date=False): """Return the start and end date for a goal period based on today :param str default_start_date: string date in DEFAULT_SERVER_DATE_FORMAT format :param str default_end_date: string date in DEFAULT_SERVER_DATE_FORMAT format :return: (start_date, end_date), dates in string format, False if the period is not defined or unknown""" today = date.today() if period == 'daily': start_date = today end_date = start_date elif period == 'weekly': start_date = today + relativedelta(weekday=MO(-1)) end_date = start_date + timedelta(days=7) elif period == 'monthly': start_date = today.replace(day=1) end_date = today + relativedelta(months=1, day=1, days=-1) elif period == 'yearly': start_date = today.replace(month=1, day=1) end_date = today.replace(month=12, day=31) else: # period == 'once': start_date = default_start_date # for manual goal, start each time end_date = default_end_date return (start_date, end_date) return fields.Datetime.to_string(start_date), fields.Datetime.to_string( end_date)
def _get_start_of_week(self, span): user_lang = self.env['res.lang'].search([('code', '=', self.env.user.lang)]) week_start_map = {'1': MO(-1), '2': TU(-1), '3': WE(-1), '4': TH(-1), '5': FR(-1), '6': SA(-1), '7': SU(-1)} week_start_delta = relativedelta(weekday=week_start_map.get(user_lang.week_start, MO(-1))) if span == 'week': return week_start_delta return START_OF[span] + week_start_delta
def generate_weekly_report(): today = localdate(now()) last_week_sun = today + relativedelta(weekday=SU(-1)) last_week_mon = last_week_sun + relativedelta(weekday=MO(-1)) for user in User.objects.filter(pushover_user_key__isnull=False, pushover_api_token__isnull=False): totals = (ReportEntry.objects.filter( station__owner=user, created__gte=last_week_mon, created__lte=last_week_sun).values("phone_number").annotate( total_refund=Sum("station__refund_value"))) message = "\n".join([ f"{total.get('phone_number', 'anonymous')}: ${total.get('total_refund')}" for total in totals ]) if message: Client( user_key=user.pushover_user_key, api_token=user.pushover_api_token ).send_message( message, title= f"Todovoodoo: Weekly Refund Report ({last_week_mon.isoformat()} -- {last_week_sun.isoformat()})", priority=1, )
def get_period_date_ranges(self): from dateutil.relativedelta import MO, relativedelta from_date, to_date = getdate(self.filters.from_date), getdate(self.filters.to_date) increment = { 'Monthly': 1, 'Quarterly': 3, 'Half-Yearly': 6, 'Yearly': 12 }.get(self.filters.range, 1) if self.filters.range in ['Monthly', 'Quarterly']: from_date = from_date.replace(day=1) elif self.filters.range == 'Yearly': from_date = get_fiscal_year(from_date)[1] else: from_date = from_date + relativedelta(from_date, weekday=MO(-1)) self.periodic_daterange = [] for dummy in range(1, 53): if self.filters.range == 'Weekly': period_end_date = add_days(from_date, 6) else: period_end_date = add_to_date(from_date, months=increment, days=-1) if period_end_date > to_date: period_end_date = to_date self.periodic_daterange.append(period_end_date) from_date = add_days(period_end_date, 1) if period_end_date == to_date: break
def update_type(self, mf_type, mf_anchor=0): mf_type = MF_RNG(mf_type) if type(mf_type) == int else mf_type if mf_type == MF_RNG.DAY: # from 00:00 to 24:00 tmp = datetime(self.end.year, self.end.month, self.end.day) self.end = tmp + relativedelta(days=mf_anchor) self.start = self.end + relativedelta(days=1) self.hint = self.end.strftime('%Y-%m-%d (%a)') elif mf_type == MF_RNG.WEEK: # from MON to SUN tmp = datetime(self.end.year, self.end.month, self.end.day) mf_anchor = -1 if mf_anchor == 0 else mf_anchor #FIXME: get last Monday when anchor==0 self.end = tmp + relativedelta(weekday=MO(mf_anchor)) self.start = self.end + relativedelta(days=7) self.hint = self.end.strftime('Week %U (%b), %Y') elif mf_type == MF_RNG.MONTH: # from 1st to end-th tmp = datetime(self.end.year, self.end.month, 1) self.end = tmp + relativedelta(months=mf_anchor) self.start = self.end + relativedelta(months=1) self.hint = self.end.strftime('%b, %Y') elif mf_type == MF_RNG.YEAR: # from Jan to Dec self.end = datetime(self.end.year, 1, 1) + relativedelta(years=mf_anchor) self.start = self.end + relativedelta(years=1) self.hint = self.end.strftime('Year %Y') else: return self.mf_type = mf_type pass
def testInequalityWeekdays(self): # Different weekdays no_wday = relativedelta(year=1997, month=4) wday_mo_1 = relativedelta(year=1997, month=4, weekday=MO(+1)) wday_mo_2 = relativedelta(year=1997, month=4, weekday=MO(+2)) wday_tu = relativedelta(year=1997, month=4, weekday=TU) self.assertTrue(wday_mo_1 == wday_mo_1) self.assertFalse(no_wday == wday_mo_1) self.assertFalse(wday_mo_1 == no_wday) self.assertFalse(wday_mo_1 == wday_mo_2) self.assertFalse(wday_mo_2 == wday_mo_1) self.assertFalse(wday_mo_1 == wday_tu) self.assertFalse(wday_tu == wday_mo_1)
def week_from_date(day): if isinstance(day, six.string_types): day = datetime.datetime.strptime(day, '%Y-%m-%d').date() from dateutil.relativedelta import relativedelta, MO, SU weekbegin = day + relativedelta(weekday=MO(-1)) weekend = day + relativedelta(weekday=SU(1)) week_code = '%d_%d' % (day.isocalendar()[0], day.isocalendar()[1]) return week_code, weekbegin, weekend