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 '∞'})"