import datetime from django.core.management.base import BaseCommand from ...models import Appointment, Location, AppointmentType, AppointmentTypeLink def get_easter_monday(easter_sunday): return next_weekday(easter_sunday, 0) def get_ascension_day(easter_sunday): return easter_sunday + datetime.timedelta(days=39) class Command(BaseCommand): help = 'import holidays for the specified years' def add_arguments(self, parser): parser.add_argument('year', nargs='+', type=int) def handle(self, *args, **options): for location in Location.objects.exclude(name="Flying Team").all(): for year in options['year']: self.stdout.write("importing holidays for year {} and location {}".format(year, location)) # new years day self.create_holiday(year, 1, 1, "New Years Day", location) # easter monday easter_sunday = get_easter_sunday_date(year) easter_monday = get_easter_monday(easter_sunday) self.create_holiday(year, easter_monday.month, easter_monday.day, "Easter Monday", location) # ascension day ascension_day = get_ascension_day(easter_sunday) self.create_holiday(year, ascension_day.month, ascension_day.day, "Ascension Day", location) # pentecost monday pentecost_day = get_pentecost_day(easter_sunday) self.create_holiday(year, pentecost_day.month, pentecost_day.day, "Pentecost Monday", location) # labour day self.create_holiday(year, 5, 1, "Labour Day", location) # national day self.create_holiday(year, 6, 23, "National Day", location) # assumption day self.create_holiday(year, 8, 15, "Assumption Day", location) # all saints day self.create_holiday(year, 11, 1, "All Saints Day", location) # christmas self.create_holiday(year, 12, 25, "Christmas Day", location) self.create_holiday(year, 12, 26, "St Stephens Day", location) def create_holiday(self, year, month, day, comment, location): # check if already exists: count = Appointment.objects.filter(datetime_when__year=year, datetime_when__month=month, datetime_when__day=day, location=location, comment=comment).count() if count != 0: self.stdout.write( 'an holiday with the same description already exists for the same day: {}'.format(comment)) return holiday = Appointment() holiday.datetime_when = datetime.datetime(year=year, month=month, day=day, hour=9) holiday.location = location holiday.length = 60 * 8 holiday.comment = comment holiday.visit_id = None holiday.save() appointment_type_other, _ = AppointmentType.objects.get_or_create(code='OTHER', defaults={'default_duration': 60}) link = AppointmentTypeLink(appointment=holiday, appointment_type=appointment_type_other) link.save() def get_easter_sunday_date(year): # source: http://www.officeholidays.com/religious/christian/easter_monday.php c = year // 100 n = year - 19 * (year // 19) k = (c - 17) // 25 i = c - c // 4 - (c - k) // 3 + 19 * n + 15 i = i - 30 * (i // 30) i = i - (i // 28) * (1 - (i // 28) * (29 // (i + 1)) * ((21 - n) // 11)) j = year + year // 4 + i + 2 - c + c // 4 j = j - 7 * (j // 7) l = i - j month = 3 + (l + 40) // 44 day = l + 28 - 31 * (month // 4) return datetime.datetime(year=year, month=month, day=day) def get_pentecost_day(easter_sunday): return easter_sunday + datetime.timedelta(days=50) def next_weekday(day_datetime, week_day): days_ahead = week_day - day_datetime.weekday() if days_ahead <= 0: days_ahead += 7 return day_datetime + datetime.timedelta(days_ahead)