membershipworks: Convert EventMeetingTime to subclass of Reservation

This commit is contained in:
Adam Goldsmith 2024-08-05 22:48:36 -04:00
parent 35c063c44e
commit e4280361d1
3 changed files with 102 additions and 19 deletions

View File

@ -103,11 +103,12 @@ class TransactionAdmin(BaseMembershipWorksAdmin):
class EventMeetingTimeInline(admin.TabularInline):
model = EventMeetingTime
fields = ["start", "end", "duration", "resources"]
readonly_fields = ["duration"]
autocomplete_fields = ["resources"]
extra = 0
min_num = 1
readonly_fields = ["duration"]
@admin.register(EventInstructor)
class EventInstructorAdmin(admin.ModelAdmin):

View File

@ -0,0 +1,82 @@
# Generated by Django 5.0.7 on 2024-07-30 23:10
import django.db.models.deletion
from django.db import migrations, models
def convert_meetingtimes_to_reservations(apps, schema_editor):
Reservation = apps.get_model("reservations", "Reservation")
EventMeetingTime = apps.get_model("membershipworks", "EventMeetingTime")
for meeting_time in EventMeetingTime.objects.all():
reservation = Reservation.objects.create(
id=meeting_time.id,
start=meeting_time.start,
end=meeting_time.end,
)
meeting_time.reservation_ptr = reservation
meeting_time.save()
class Migration(migrations.Migration):
dependencies = [
("membershipworks", "0019_eventext_should_survey_eventext_survey_email_sent"),
("reservations", "0001_initial"),
]
operations = [
# add reservation field
migrations.AddField(
model_name="eventmeetingtime",
name="reservation_ptr",
field=models.OneToOneField(
auto_created=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
serialize=False,
to="reservations.reservation",
),
preserve_default=False,
),
migrations.RunPython(convert_meetingtimes_to_reservations, atomic=True),
# remove primary key
migrations.RemoveField(
model_name="eventmeetingtime",
name="id",
),
# make reservation non-nullable
migrations.AlterField(
model_name="eventmeetingtime",
name="reservation_ptr",
field=models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="reservations.reservation",
),
preserve_default=False,
),
# delete old columns
migrations.RemoveConstraint(
model_name="eventmeetingtime",
name="unique_event_start_end",
),
migrations.RemoveConstraint(
model_name="eventmeetingtime",
name="end_after_start",
),
migrations.RemoveField(
model_name="eventmeetingtime",
name="duration",
),
migrations.RemoveField(
model_name="eventmeetingtime",
name="end",
),
migrations.RemoveField(
model_name="eventmeetingtime",
name="start",
),
]

View File

@ -30,6 +30,8 @@ import nh3
from django_db_views.db_view import DBView
from django_stubs_ext import WithAnnotations
from reservations.models import Reservation
class BaseModel(models.Model):
_api_names_override: dict[str, str] = {}
@ -619,29 +621,27 @@ else:
EventExtAnnotatedWithFinancials = WithAnnotations[EventExt]
class EventMeetingTime(models.Model):
class EventMeetingTime(Reservation):
event = models.ForeignKey(
EventExt, on_delete=models.CASCADE, related_name="meeting_times"
)
start = models.DateTimeField()
end = models.DateTimeField()
duration = models.GeneratedField(
expression=F("end") - F("start"),
output_field=models.DurationField(),
db_persist=False,
# TODO: should probably do some validation in python to enforce
# - uniqueness and non-overlapping (per event)
# - min/max start/end time == event start end
def make_google_calendar_event(self):
status = (
"confirmed"
if self.event.cap > 0 and self.event.calendar != Event.EventCalendar.HIDDEN
else "cancelled"
)
class Meta:
constraints = [
models.UniqueConstraint(
fields=["event", "start", "end"], name="unique_event_start_end"
),
models.CheckConstraint(check=Q(end__gt=F("start")), name="end_after_start"),
]
def __str__(self) -> str:
return f"{self.start} - {self.end}"
return super().make_google_calendar_event() | {
# TODO: add event description and links
"summary": self.event.unescaped_title,
"status": status,
}
class EventInvoice(models.Model):