from itertools import product from django.db import models from django.utils.translation import gettext_lazy as _ from django_fsm import FSMField, transition from rules.contrib.models import RulesModel from outbo.apps.activity_log.enums import MessageType from outbo.apps.activity_log.models import ProductLogItem from outbo.apps.core.models import TimestampableDeletableMixin from outbo.apps.core.utils import get_current_date, is_empty_set from outbo.apps.final_photobriefing.models import FinalBrief from outbo.apps.photobriefing import rules from outbo.apps.photobriefing.enums import ChoiceRole class Brief(TimestampableDeletableMixin, RulesModel): class Meta: rules_permissions = { "add": rules.can_create_brief, "view": rules.can_read_brief, "change": rules.can_update_brief, "delete": rules.can_delete_brief, } product = models.OneToOneField( verbose_name=_("product"), to="products.Product", on_delete=models.CASCADE, primary_key=True, editable=False, related_name="photo_brief", related_query_name="photo_brief", ) session_date = models.DateField( verbose_name=_("photo session date"), blank=False, null=False, default=get_current_date, ) concept_description = models.TextField(blank=True, null=False) stage = FSMField(default="created", protected=True) def save(self, *args, **kwargs): result = super().save(*args, **kwargs) if self.product: self.product.save() return result def acceptable_for_user(self, *, user): if user.is_observer or user.is_trader: return False return not user.is_agency and self.stage == "published" def publishable_for_user(self, *, user): if user.is_observer or user.is_trader: return False all_categories = set(self.items.values_list("category", flat=True)) if self.editable_for_user(user=user) and not is_empty_set(all_categories): return True return False def completable_for_user(self, *, user): if user.is_observer or user.is_trader: return False if not user.is_agency or self.stage != "published": return False roles = [ChoiceRole.SUPPLIER, ChoiceRole.CLIENT] all_categories = set(self.items.values_list("category", flat=True)) if is_empty_set(all_categories): return False for category, role in product(all_categories, roles): if not self.choices.filter(category_id=category, role=role).exists(): return False return True def editable_for_user(self, *, user): if user.is_observer or user.is_trader: return False if not user.is_agency or not self.stage == "created": return False return self.product.stage.group in [2, 3] @transition(field="stage", source="created", target="published") def publish_as_user(self, *, user): ProductLogItem.objects.create( product=self.product, created_by=user, message="Photobriefing published", message_type=MessageType.SUCCESS, ) @transition(field="stage", source="published", target="completed") def complete_as_user(self, *, user): FinalBrief.objects.create(brief=self) ProductLogItem.objects.create( product=self.product, created_by=user, message="Photobriefing completed", message_type=MessageType.SUCCESS, )