Initial commit from ZIP

This commit is contained in:
kusz committed 2024-11-27 13:18:16 +01:00
commit 378d4692a9
454 files changed
+40367

No files matched your search

@@ -0,0 +1,5 @@
from .brief import Brief
from .brief_item import BriefItem
from .brief_item_photo import BriefItemPhoto
from .brief_item_choice import BriefItemChoice
from .category import Category
+107
View File
@@ -0,0 +1,107 @@
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,
)
@@ -0,0 +1,32 @@
from django.db import models
from rules.contrib.models import RulesModel
from outbo.apps.core.models import TimestampableDeletableMixin
from django.utils.translation import gettext_lazy as _
from outbo.apps.photobriefing import rules
class BriefItem(TimestampableDeletableMixin, RulesModel):
class Meta:
rules_permissions = {
"add": rules.can_create_brief_item,
"view": rules.can_read_brief_item,
"change": rules.can_update_brief_item,
"delete": rules.can_delete_brief_item,
}
ordering = ["id"]
brief = models.ForeignKey(
verbose_name=_("brief"),
to="Brief",
on_delete=models.CASCADE,
related_name="items",
related_query_name="item",
)
category = models.ForeignKey(
verbose_name=_("category"), to="Category", on_delete=models.CASCADE
)
title = models.CharField(max_length=100, blank=False, null=False)
description = models.TextField(blank=False, null=False)
@@ -0,0 +1,39 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from rules.contrib.models import RulesModel
from outbo.apps.core.models import TimestampableDeletableMixin
from outbo.apps.photobriefing.enums import ChoiceRole
class BriefItemChoice(TimestampableDeletableMixin, RulesModel):
class Meta:
unique_together = (("brief", "category", "role"),)
brief = models.ForeignKey(
verbose_name=_("brief"),
to="Brief",
on_delete=models.CASCADE,
related_name="choices",
related_query_name="choice",
)
category = models.ForeignKey(
verbose_name=_("category"),
to="Category",
on_delete=models.CASCADE,
related_name="choices+",
related_query_name="choice",
)
role = models.CharField(
max_length=30,
choices=[(role, role.value) for role in ChoiceRole],
default=ChoiceRole.INVALID,
editable=False,
)
item = models.ForeignKey(
verbose_name=_("item"),
to="BriefItem",
on_delete=models.CASCADE,
related_name="choices",
related_query_name="choice",
)
@@ -0,0 +1,40 @@
import os
from django.db import models
from django.utils.translation import gettext_lazy as _
from rules import always_allow
from rules.contrib.models import RulesModel
from outbo.apps.core.models import TimestampableDeletableMixin
def filename(self, filename):
return "/".join(
(
"projects",
self.item.brief.product.project.slug[1:],
"photobriefing",
filename,
)
)
class BriefItemPhoto(TimestampableDeletableMixin, RulesModel):
class Meta:
rules_permissions = {
"view": always_allow,
}
item = models.ForeignKey(
verbose_name=_("brief item"),
to="BriefItem",
on_delete=models.CASCADE,
related_name="photos",
related_query_name="photo",
)
file = models.ImageField(verbose_name=_("file"), upload_to=filename)
@property
def filename(self):
return os.path.basename(self.file.name)
+17
View File
@@ -0,0 +1,17 @@
from django.db import models
from rules.contrib.models import RulesModel
from outbo.apps.core.models import TimestampableDeletableMixin
from django.utils.translation import gettext_lazy as _, pgettext
class Category(TimestampableDeletableMixin, RulesModel):
class Meta:
verbose_name = _("category")
verbose_name_plural = _("categories")
label = models.CharField(verbose_name=_("label"), max_length=30, primary_key=True)
description = models.CharField(verbose_name=_("description"), max_length=30)
def __str__(self):
return pgettext("photo_brief_categories", self.description)
+27
View File
@@ -0,0 +1,27 @@
from django.db import models
from django.utils.translation import gettext_lazy as _
from rules.contrib.models import RulesModel
from outbo.apps.core.models import TimestampableDeletableMixin
from outbo.apps.final_photobriefing.enums import PhotoType
class Photo(TimestampableDeletableMixin, RulesModel):
brief = models.ForeignKey(
verbose_name=_("photo brief"),
to="Brief",
on_delete=models.CASCADE,
related_name="photos",
related_query_name="photo",
)
type = models.CharField(
max_length=50,
choices=((type, type.value) for type in PhotoType),
default=PhotoType.INVALID,
)
def filename(self, filename):
return f"projects/{self.brief.product.project.slug[1:]}/photos/{filename}"
file = models.ImageField(verbose_name=_("file"), upload_to=filename)