membershipworks: Convert EventMeetingTime to subclass of Reservation
This commit is contained in:
parent
35c063c44e
commit
e4280361d1
@ -103,11 +103,12 @@ class TransactionAdmin(BaseMembershipWorksAdmin):
|
|||||||
|
|
||||||
class EventMeetingTimeInline(admin.TabularInline):
|
class EventMeetingTimeInline(admin.TabularInline):
|
||||||
model = EventMeetingTime
|
model = EventMeetingTime
|
||||||
|
fields = ["start", "end", "duration", "resources"]
|
||||||
|
readonly_fields = ["duration"]
|
||||||
|
autocomplete_fields = ["resources"]
|
||||||
extra = 0
|
extra = 0
|
||||||
min_num = 1
|
min_num = 1
|
||||||
|
|
||||||
readonly_fields = ["duration"]
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(EventInstructor)
|
@admin.register(EventInstructor)
|
||||||
class EventInstructorAdmin(admin.ModelAdmin):
|
class EventInstructorAdmin(admin.ModelAdmin):
|
||||||
|
@ -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",
|
||||||
|
),
|
||||||
|
]
|
@ -30,6 +30,8 @@ import nh3
|
|||||||
from django_db_views.db_view import DBView
|
from django_db_views.db_view import DBView
|
||||||
from django_stubs_ext import WithAnnotations
|
from django_stubs_ext import WithAnnotations
|
||||||
|
|
||||||
|
from reservations.models import Reservation
|
||||||
|
|
||||||
|
|
||||||
class BaseModel(models.Model):
|
class BaseModel(models.Model):
|
||||||
_api_names_override: dict[str, str] = {}
|
_api_names_override: dict[str, str] = {}
|
||||||
@ -619,29 +621,27 @@ else:
|
|||||||
EventExtAnnotatedWithFinancials = WithAnnotations[EventExt]
|
EventExtAnnotatedWithFinancials = WithAnnotations[EventExt]
|
||||||
|
|
||||||
|
|
||||||
class EventMeetingTime(models.Model):
|
class EventMeetingTime(Reservation):
|
||||||
event = models.ForeignKey(
|
event = models.ForeignKey(
|
||||||
EventExt, on_delete=models.CASCADE, related_name="meeting_times"
|
EventExt, on_delete=models.CASCADE, related_name="meeting_times"
|
||||||
)
|
)
|
||||||
start = models.DateTimeField()
|
|
||||||
end = models.DateTimeField()
|
|
||||||
|
|
||||||
duration = models.GeneratedField(
|
# TODO: should probably do some validation in python to enforce
|
||||||
expression=F("end") - F("start"),
|
# - uniqueness and non-overlapping (per event)
|
||||||
output_field=models.DurationField(),
|
# - min/max start/end time == event start end
|
||||||
db_persist=False,
|
|
||||||
|
def make_google_calendar_event(self):
|
||||||
|
status = (
|
||||||
|
"confirmed"
|
||||||
|
if self.event.cap > 0 and self.event.calendar != Event.EventCalendar.HIDDEN
|
||||||
|
else "cancelled"
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
return super().make_google_calendar_event() | {
|
||||||
constraints = [
|
# TODO: add event description and links
|
||||||
models.UniqueConstraint(
|
"summary": self.event.unescaped_title,
|
||||||
fields=["event", "start", "end"], name="unique_event_start_end"
|
"status": status,
|
||||||
),
|
}
|
||||||
models.CheckConstraint(check=Q(end__gt=F("start")), name="end_after_start"),
|
|
||||||
]
|
|
||||||
|
|
||||||
def __str__(self) -> str:
|
|
||||||
return f"{self.start} - {self.end}"
|
|
||||||
|
|
||||||
|
|
||||||
class EventInvoice(models.Model):
|
class EventInvoice(models.Model):
|
||||||
|
Loading…
Reference in New Issue
Block a user