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

+146
View File
@@ -0,0 +1,146 @@
from typing import TYPE_CHECKING
from django.db import models
from django.utils.translation import gettext_lazy as _
from rules.contrib.models import RulesModel
from outbo.apps.activity_log.enums import MessageType
from outbo.apps.activity_log.models import ProjectLogItem
from outbo.apps.core.models import TimestampableDeletableMixin, SoftDeletableManager
from outbo.apps.products.models import Product
from outbo.apps.projects import rules
from outbo.apps.projects.fields import SlugField
from outbo.apps.projects.models import ProjectNumber
if TYPE_CHECKING:
from outbo.apps.authentication.models import User
class ProjectManager(SoftDeletableManager):
def create(self, **kwargs):
products_amount = kwargs.pop("products_amount", None)
project: "Project" = super().create(**kwargs)
if products_amount is not None:
project.add_products(products_amount=products_amount)
project.save()
return project
class Project(TimestampableDeletableMixin, RulesModel):
objects = ProjectManager()
all_objects = ProjectManager(alive_only=False)
class Meta:
rules_permissions = {
"view": rules.can_read_project,
"add": rules.can_create_project,
"change": rules.can_update_project,
"delete": rules.can_delete_project,
}
ordering = ["-updated_at__date", "slug"]
def slugify(self):
brand_prefix = self.category.name[:2].upper()
category_prefix = self.brand.name[:2].upper()
number = ProjectNumber.objects.get_next_number(
prefix=f"{brand_prefix}{category_prefix}"
)
week_year = self.promo_date.strftime("%U%y")
return f"#{brand_prefix}{category_prefix}{number}-{week_year}"
slug = SlugField(
verbose_name=_("project identifier"), max_length=15, slugify=slugify
)
name = models.CharField(
verbose_name=_("name"), max_length=254, blank=False, null=False
)
description = models.TextField(
verbose_name=_("description"), blank=False, null=False
)
category = models.ForeignKey(
verbose_name=_("category"),
to="organizations.Category",
on_delete=models.CASCADE,
null=False,
)
brand = models.ForeignKey(
verbose_name=_("brand"),
to="organizations.Brand",
on_delete=models.CASCADE,
null=False,
)
printing_files_date = models.DateField(
verbose_name=_("printing files delivery date"), null=False
)
promo_date = models.DateField(verbose_name=_("promo date"), null=False)
# internal fields
published = models.BooleanField(
verbose_name=_("published"), blank=False, null=False, default=False
)
@property
def _max_product_stage_obj(self):
max_product_stage_obj = (
self.products.order_by("-stage__order").first()
)
if not max_product_stage_obj:
return None
return max_product_stage_obj
@property
def max_product_stage(self):
return self._max_product_stage_obj.stage.id
@property
def max_product_stage_description(self):
return self._max_product_stage_obj.stage.description
def __str__(self):
if self.slug:
return f"[{self.slug}] {self.name}"
else:
return self.name
def publishable_for_user(self, *, user: "User"):
if user.is_observer or user.is_trader:
return False
return not self.published and all(
[
product.has_brief_publishable_for_user(user=user)
for product in self.products.all()
]
)
def save(self, *args, **kwargs):
products_amount = kwargs.pop("products_amount", None)
super().save(*args, **kwargs)
if products_amount is not None:
self.add_products(products_amount=products_amount)
def add_products(self, *, products_amount):
[Product.objects.create(project=self) for _ in range(products_amount)]
self.save()
def publish_as_user(self, *, user: "User"):
self.published = True
for product in self.products.all():
product.send_action_emails_for_users_passing_test(
test=lambda u: u in [m.user for m in self.members.all()]
and u.is_agency,
action_url="https://outbo.pl/projects/{id}/products/{pid}",
)
product.publish_brief_as_user(user=user)
product.save()
ProjectLogItem.objects.create(
project=self,
created_by=user,
message="Project published",
message_type=MessageType.SUCCESS,
)
self.save()