feat(time-blocks): Add seed_holidays management command

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
poduck
2025-12-04 17:21:02 -05:00
parent 8d0cc1e90a
commit 2d7c1dcd27

View File

@@ -0,0 +1,201 @@
"""Management command to seed US holidays."""
from django.core.management.base import BaseCommand
from schedule.models import Holiday
US_HOLIDAYS = [
# Fixed date holidays
{
"code": "new_years_day",
"name": "New Year's Day",
"country": "US",
"holiday_type": Holiday.Type.FIXED,
"month": 1,
"day": 1,
},
{
"code": "independence_day",
"name": "Independence Day",
"country": "US",
"holiday_type": Holiday.Type.FIXED,
"month": 7,
"day": 4,
},
{
"code": "veterans_day",
"name": "Veterans Day",
"country": "US",
"holiday_type": Holiday.Type.FIXED,
"month": 11,
"day": 11,
},
{
"code": "christmas_eve",
"name": "Christmas Eve",
"country": "US",
"holiday_type": Holiday.Type.FIXED,
"month": 12,
"day": 24,
},
{
"code": "christmas_day",
"name": "Christmas Day",
"country": "US",
"holiday_type": Holiday.Type.FIXED,
"month": 12,
"day": 25,
},
{
"code": "new_years_eve",
"name": "New Year's Eve",
"country": "US",
"holiday_type": Holiday.Type.FIXED,
"month": 12,
"day": 31,
},
# Floating holidays (Nth weekday of month)
{
"code": "mlk_day",
"name": "Martin Luther King Jr. Day",
"country": "US",
"holiday_type": Holiday.Type.FLOATING,
"month": 1,
"week_of_month": 3, # 3rd Monday of January
"day_of_week": 0, # Monday
},
{
"code": "presidents_day",
"name": "Presidents Day",
"country": "US",
"holiday_type": Holiday.Type.FLOATING,
"month": 2,
"week_of_month": 3, # 3rd Monday of February
"day_of_week": 0, # Monday
},
{
"code": "memorial_day",
"name": "Memorial Day",
"country": "US",
"holiday_type": Holiday.Type.FLOATING,
"month": 5,
"week_of_month": 5, # Last Monday of May (5 = last)
"day_of_week": 0, # Monday
},
{
"code": "juneteenth",
"name": "Juneteenth",
"country": "US",
"holiday_type": Holiday.Type.FIXED,
"month": 6,
"day": 19,
},
{
"code": "labor_day",
"name": "Labor Day",
"country": "US",
"holiday_type": Holiday.Type.FLOATING,
"month": 9,
"week_of_month": 1, # 1st Monday of September
"day_of_week": 0, # Monday
},
{
"code": "columbus_day",
"name": "Columbus Day",
"country": "US",
"holiday_type": Holiday.Type.FLOATING,
"month": 10,
"week_of_month": 2, # 2nd Monday of October
"day_of_week": 0, # Monday
},
{
"code": "thanksgiving",
"name": "Thanksgiving Day",
"country": "US",
"holiday_type": Holiday.Type.FLOATING,
"month": 11,
"week_of_month": 4, # 4th Thursday of November
"day_of_week": 3, # Thursday
},
{
"code": "thanksgiving_friday",
"name": "Day After Thanksgiving",
"country": "US",
"holiday_type": Holiday.Type.FLOATING,
"month": 11,
"week_of_month": 4, # 4th Friday of November (day after Thanksgiving)
"day_of_week": 4, # Friday
},
# Calculated holidays (Easter-based)
{
"code": "easter",
"name": "Easter Sunday",
"country": "US",
"holiday_type": Holiday.Type.CALCULATED,
"calculation_rule": "easter",
},
{
"code": "good_friday",
"name": "Good Friday",
"country": "US",
"holiday_type": Holiday.Type.CALCULATED,
"calculation_rule": "easter-2", # 2 days before Easter
},
]
class Command(BaseCommand):
"""Seed US holidays into the database."""
help = "Seed US holidays for the time blocking system"
def add_arguments(self, parser):
parser.add_argument(
"--clear",
action="store_true",
help="Clear existing holidays before seeding",
)
def handle(self, *args, **options):
"""Create or update holiday records."""
if options["clear"]:
deleted_count, _ = Holiday.objects.filter(country="US").delete()
self.stdout.write(
self.style.WARNING(f"Deleted {deleted_count} existing US holidays")
)
created_count = 0
updated_count = 0
for holiday_data in US_HOLIDAYS:
code = holiday_data["code"]
holiday, created = Holiday.objects.update_or_create(
code=code,
defaults=holiday_data,
)
if created:
created_count += 1
self.stdout.write(f" Created: {holiday.name}")
else:
updated_count += 1
self.stdout.write(f" Updated: {holiday.name}")
self.stdout.write(
self.style.SUCCESS(
f"\nDone! Created {created_count}, updated {updated_count} holidays."
)
)
# Show sample dates for the current year
from datetime import date
current_year = date.today().year
self.stdout.write(f"\nHoliday dates for {current_year}:")
for holiday in Holiday.objects.filter(country="US", is_active=True).order_by("month", "day"):
try:
holiday_date = holiday.get_date_for_year(current_year)
if holiday_date:
self.stdout.write(f" {holiday.name}: {holiday_date.strftime('%B %d, %Y')}")
except Exception as e:
self.stdout.write(
self.style.ERROR(f" {holiday.name}: Error calculating date - {e}")
)