from django.db import models
from django.utils.safestring import mark_safe
from grapple.helpers import register_query_field, register_streamfield_block
from grapple.models import GraphQLForeignKey, GraphQLStreamfield, GraphQLString
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
from wagtail import blocks
from wagtail.admin.panels import FieldPanel, InlinePanel, MultiFieldPanel, TitleFieldPanel
from wagtail.models import Orderable, StreamField
from wagtail.snippets.models import register_snippet
@register_streamfield_block
class OpeningHoursRangeBlock(blocks.StructBlock):
# closed = blocks.BooleanBlock(required=False, help_text="Kryss av her om lokalet er stengt.")
# blocks.RegexBlock(regex=r'^\d\d:\d\d$', error_messages={'invalid': 'Må være på formatet HH:MM'}, help_text="Tidspunkt på formatet HH:MM")
time_from = blocks.TimeBlock(required=False, label="Åpner")
time_to = blocks.TimeBlock(required=False, label="Stenger")
custom = blocks.CharBlock(
required=False,
label="Fritekst",
help_text=mark_safe(
"Tekst som vises istedenfor tidspunkter. F.eks. Åpent ved arrangement"
),
)
graphql_fields = [
GraphQLString("time_from", required=False),
GraphQLString("time_to", required=False),
GraphQLString("custom", required=False),
]
@register_streamfield_block
class OpeningHoursWeekBlock(blocks.StructBlock):
monday = OpeningHoursRangeBlock(label="Mandag")
tuesday = OpeningHoursRangeBlock(label="Tirsdag")
wednesday = OpeningHoursRangeBlock(label="Onsdag")
thursday = OpeningHoursRangeBlock(label="Torsdag")
friday = OpeningHoursRangeBlock(label="Fredag")
saturday = OpeningHoursRangeBlock(label="Lørdag")
sunday = OpeningHoursRangeBlock(label="Søndag")
graphql_fields = [
GraphQLStreamfield("monday", required=False, is_list=False),
GraphQLStreamfield("tuesday", required=False, is_list=False),
GraphQLStreamfield("wednesday", required=False, is_list=False),
GraphQLStreamfield("thursday", required=False, is_list=False),
GraphQLStreamfield("friday", required=False, is_list=False),
GraphQLStreamfield("saturday", required=False, is_list=False),
GraphQLStreamfield("sunday", required=False, is_list=False),
]
class OpeningHoursItem(Orderable):
FUNCTION_CHOICES = [
("glassbaren", "Glassbaren"),
("bokcafeen", "Bokcaféen"),
("ekspedisjonen", "Ekspedisjonen"),
]
WEEKDAYS = (
("monday", "Mandag"),
("tuesday", "Tirsdag"),
("wednesday", "Onsdag"),
("thursday", "Torsdag"),
("friday", "Fredag"),
("saturday", "Lørdag"),
("sunday", "Søndag"),
)
opening_hours_set = ParentalKey(
"openinghours.OpeningHoursSet", on_delete=models.CASCADE, related_name="items"
)
function = models.CharField(
max_length=32,
default="",
choices=FUNCTION_CHOICES,
blank=False,
help_text="Hvilket lokale/funksjon?",
)
week = StreamField(
[("week", OpeningHoursWeekBlock())],
min_num=1,
max_num=1,
)
panels = [
FieldPanel("function"),
FieldPanel("week"),
]
graphql_fields = [
GraphQLString("function", required=True),
GraphQLStreamfield("week", required=False),
]
@register_snippet
@register_query_field("openingHoursSet", "openingHoursSets")
class OpeningHoursSet(ClusterableModel):
name = models.CharField(
max_length=256,
null=False,
blank=False,
help_text=mark_safe(
"Enkel beskrivelse av hvilken periode disse åpningstidene dekker, "
"f.eks. Vanlige åpningstider eller Sommer 2032."
),
)
effective_from = models.DateField(null=False, blank=False)
effective_to = models.DateField(null=True, blank=True)
announcement = models.TextField(
blank=True,
help_text=mark_safe(
"En kort notis som vil vises i forbindelse med åpningstidene, "
"f.eks. Huset er stengt i perioden A til B.. Kan være blank."
),
)
panels = [
TitleFieldPanel("name"),
FieldPanel("announcement"),
MultiFieldPanel(
heading="Gyldighet",
children=[
FieldPanel("effective_from", heading="Fra"),
FieldPanel("effective_to", heading="Til"),
],
),
InlinePanel("items", label="Lokaler/funksjoner"),
]
graphql_fields = [
GraphQLString("name", required=True),
GraphQLString("announcement", required=False),
GraphQLString("effective_from", required=True),
GraphQLString("effective_to", required=False),
GraphQLForeignKey("items", "openinghours.OpeningHoursItem", required=False, is_list=True),
]
class Meta:
verbose_name = "Opening hours set"
verbose_name_plural = "Opening hours sets"
ordering = ["effective_from"]
def __str__(self):
return f"{self.name} ({self.effective_from} - {self.effective_to or '∞'})"