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

+11
View File
@@ -0,0 +1,11 @@
from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _
class OrganizationsAppConfig(AppConfig):
name = "outbo.apps.organizations"
label = "organizations"
verbose_name = _("Organizations")
default_app_config = "outbo.apps.organizations.OrganizationsAppConfig"
+57
View File
@@ -0,0 +1,57 @@
from django.contrib import admin
from polymorphic.admin import (
PolymorphicChildModelAdmin,
PolymorphicChildModelFilter,
)
from outbo.apps.core.admin import PolymorphicParentModelAdmin
from outbo.apps.organizations.models import (
Organization,
AgencyOrganization,
ClientOrganization,
SupplierOrganization,
Brand,
Category,
)
class _OrganizationChildAdmin(PolymorphicChildModelAdmin):
base_model = Organization
@admin.register(AgencyOrganization)
class AgencyOrganizationAdmin(_OrganizationChildAdmin):
base_model = AgencyOrganization
@admin.register(ClientOrganization)
class ClientOrganizationAdmin(_OrganizationChildAdmin):
base_model = ClientOrganization
search_fields = ["name"]
@admin.register(SupplierOrganization)
class SupplierOrganizationAdmin(_OrganizationChildAdmin):
base_model = SupplierOrganization
search_fields = ["name"]
@admin.register(Organization)
class OrganizationAdmin(PolymorphicParentModelAdmin):
base_model = Organization
child_models = (AgencyOrganization, ClientOrganization, SupplierOrganization)
list_filter = (PolymorphicChildModelFilter,)
search_fields = ["name"]
@admin.register(Brand)
class BrandAdmin(admin.ModelAdmin):
autocomplete_fields = ["client", "suppliers", "categories"]
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
search_fields = ["name"]
# NOTE: https://stackoverflow.com/questions/9879687/adding-a-manytomanywidget-to-the-reverse-of-a-manytomanyfield-in-the-django-admi/13189954
@@ -0,0 +1,220 @@
# Generated by Django 2.2.7 on 2019-11-29 08:57
from django.db import migrations, models
import django.db.models.deletion
import outbo.apps.core.fields
import rules.contrib.models
class Migration(migrations.Migration):
initial = True
dependencies = [
("contenttypes", "0002_remove_content_type_name"),
]
operations = [
migrations.CreateModel(
name="Category",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"created_at",
outbo.apps.core.fields.CreationDateTimeField(
auto_now_add=True, verbose_name="Created at"
),
),
(
"updated_at",
outbo.apps.core.fields.ModificationDateTimeField(
auto_now=True, verbose_name="Updated at"
),
),
(
"deleted_at",
outbo.apps.core.fields.RemovalDateTimeField(
blank=True, editable=False, null=True, verbose_name="Deleted at"
),
),
("name", models.CharField(max_length=254, verbose_name="name")),
],
options={
"verbose_name": "category",
"verbose_name_plural": "categories",
"ordering": ["name"],
},
bases=(rules.contrib.models.RulesModelMixin, models.Model),
),
migrations.CreateModel(
name="Organization",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"created_at",
outbo.apps.core.fields.CreationDateTimeField(
auto_now_add=True, verbose_name="Created at"
),
),
(
"updated_at",
outbo.apps.core.fields.ModificationDateTimeField(
auto_now=True, verbose_name="Updated at"
),
),
(
"deleted_at",
outbo.apps.core.fields.RemovalDateTimeField(
blank=True, editable=False, null=True, verbose_name="Deleted at"
),
),
("name", models.CharField(max_length=100)),
(
"polymorphic_ctype",
models.ForeignKey(
editable=False,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="polymorphic_organizations.organization_set+",
to="contenttypes.ContentType",
),
),
],
options={"abstract": False,},
bases=(rules.contrib.models.RulesModelMixin, models.Model),
),
migrations.CreateModel(
name="AgencyOrganization",
fields=[
(
"organization_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="organizations.Organization",
),
),
],
options={"verbose_name": "agency", "verbose_name_plural": "agencies",},
bases=("organizations.organization",),
),
migrations.CreateModel(
name="ClientOrganization",
fields=[
(
"organization_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="organizations.Organization",
),
),
("uses_simple_project_flow", models.BooleanField(default=False)),
],
options={"verbose_name": "client", "verbose_name_plural": "clients",},
bases=("organizations.organization",),
),
migrations.CreateModel(
name="SupplierOrganization",
fields=[
(
"organization_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="organizations.Organization",
),
),
],
options={"verbose_name": "supplier", "verbose_name_plural": "suppliers",},
bases=("organizations.organization",),
),
migrations.CreateModel(
name="Brand",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"created_at",
outbo.apps.core.fields.CreationDateTimeField(
auto_now_add=True, verbose_name="Created at"
),
),
(
"updated_at",
outbo.apps.core.fields.ModificationDateTimeField(
auto_now=True, verbose_name="Updated at"
),
),
(
"deleted_at",
outbo.apps.core.fields.RemovalDateTimeField(
blank=True, editable=False, null=True, verbose_name="Deleted at"
),
),
("name", models.CharField(max_length=50, verbose_name="name")),
(
"categories",
models.ManyToManyField(
related_name="brands",
related_query_name="brand",
to="organizations.Category",
verbose_name="categories",
),
),
(
"client",
models.ForeignKey(
on_delete=django.db.models.deletion.PROTECT,
related_name="brands",
related_query_name="brand",
to="organizations.ClientOrganization",
verbose_name="client",
),
),
(
"suppliers",
models.ManyToManyField(
related_name="brands",
related_query_name="brand",
to="organizations.SupplierOrganization",
verbose_name="suppliers",
),
),
],
options={"verbose_name": "brand", "verbose_name_plural": "brands",},
bases=(rules.contrib.models.RulesModelMixin, models.Model),
),
]
@@ -0,0 +1,25 @@
# Generated by Django 2.2.10 on 2020-05-25 08:25
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("organizations", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name="brand",
name="client",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="brands",
related_query_name="brand",
to="organizations.ClientOrganization",
verbose_name="client",
),
),
]
Whitespace-only changes.
@@ -0,0 +1,8 @@
from .organization import (
Organization,
AgencyOrganization,
ClientOrganization,
SupplierOrganization,
)
from .brand import Brand
from .category import Category
+38
View File
@@ -0,0 +1,38 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
from rules.contrib.models import RulesModel
from outbo.apps.core.models import TimestampableDeletableMixin
from outbo.apps.organizations import rules
class Brand(TimestampableDeletableMixin, RulesModel):
class Meta:
verbose_name = _("brand")
verbose_name_plural = _("brands")
rules_permissions = {"read": rules.can_read_brand}
name = models.CharField(verbose_name=_("name"), max_length=50)
client = models.ForeignKey(
verbose_name=_("client"),
to="ClientOrganization",
on_delete=models.CASCADE,
related_name="brands",
related_query_name="brand",
null=False,
)
suppliers = models.ManyToManyField(
verbose_name=_("suppliers"),
to="SupplierOrganization",
related_name="brands",
related_query_name="brand",
)
categories = models.ManyToManyField(
verbose_name=_("categories"),
to="Category",
related_name="brands",
related_query_name="brand",
)
def __str__(self):
return self.name
+17
View File
@@ -0,0 +1,17 @@
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
class Category(TimestampableDeletableMixin, RulesModel):
class Meta:
verbose_name = _("category")
verbose_name_plural = _("categories")
ordering = ["name"]
name = models.CharField(verbose_name=_("name"), max_length=254)
def __str__(self):
return self.name
@@ -0,0 +1,50 @@
from django.utils.translation import gettext_lazy as _
from django.db import models
from outbo.apps.core.models import (
RulesPolymorphicModel,
TimestampableDeletableMixin,
SoftDeletablePolymorphicManager,
)
class Organization(TimestampableDeletableMixin, RulesPolymorphicModel):
objects = SoftDeletablePolymorphicManager()
all_objects = SoftDeletablePolymorphicManager(alive_only=False)
name = models.CharField(max_length=100)
def __str__(self):
return f"[{str(self.polymorphic_ctype).title()}] {self.name}"
@property
def type(self):
return self.polymorphic_ctype
@type.setter
def type(self, value):
self.polymorphic_ctype = value
@type.deleter
def type(self):
del self.polymorphic_ctype
class AgencyOrganization(Organization):
class Meta:
verbose_name = _("agency")
verbose_name_plural = _("agencies")
class ClientOrganization(Organization):
class Meta:
verbose_name = _("client")
verbose_name_plural = _("clients")
uses_simple_project_flow = models.BooleanField(null=False, default=False)
class SupplierOrganization(Organization):
class Meta:
verbose_name = _("supplier")
verbose_name_plural = _("suppliers")
+11
View File
@@ -0,0 +1,11 @@
from rules import always_deny, predicate
@predicate
def can_read_brand(user, brand):
return always_deny
@predicate
def can_read_category(user, category):
return always_deny
+94
View File
@@ -0,0 +1,94 @@
from rest_framework import serializers
from outbo.apps.core.serializers import PolymorphicSerializer
from outbo.apps.organizations.models import (
AgencyOrganization,
ClientOrganization,
SupplierOrganization,
Brand,
Category,
Organization,
)
# Organizations
class _BaseOrganizationSerializer(serializers.ModelSerializer):
class Meta:
fields = (
"id",
"name",
)
class _OrganizationSerializer:
class List(_BaseOrganizationSerializer):
class Meta(_BaseOrganizationSerializer.Meta):
model = Organization
class _AgencyOrganizationSerializer:
class List(_BaseOrganizationSerializer):
class Meta(_BaseOrganizationSerializer.Meta):
model = AgencyOrganization
class _ClientOrganizationSerializer:
class List(_BaseOrganizationSerializer):
class Meta(_BaseOrganizationSerializer.Meta):
model = ClientOrganization
class _SupplierOrganizationSerializer:
class List(_BaseOrganizationSerializer):
class Meta(_BaseOrganizationSerializer.Meta):
model = SupplierOrganization
class _BaseOrganizationPolymorphicSerializer(PolymorphicSerializer):
model_serializer_mapping = {
AgencyOrganization: _AgencyOrganizationSerializer.List,
ClientOrganization: _ClientOrganizationSerializer.List,
SupplierOrganization: _SupplierOrganizationSerializer.List,
Organization: _OrganizationSerializer.List,
}
class OrganizationSerializer:
class Retrieve(_BaseOrganizationPolymorphicSerializer):
pass
class List(_BaseOrganizationPolymorphicSerializer):
pass
# Brands
class _BaseBrandSerializer(serializers.ModelSerializer):
class Meta:
model = Brand
fields = ["name"]
class BrandSerializer(serializers.ModelSerializer):
# Create & Update not needed
class Retrieve(_BaseBrandSerializer):
pass
class List(_BaseBrandSerializer):
class Meta(_BaseBrandSerializer.Meta):
fields = ["id"] + _BaseBrandSerializer.Meta.fields
# Categories
class _BaseCategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ["name"]
class CategorySerializer:
class Retrieve(_BaseCategorySerializer):
pass
class List(_BaseCategorySerializer):
class Meta(_BaseCategorySerializer.Meta):
fields = ["id"] + _BaseCategorySerializer.Meta.fields
+10
View File
@@ -0,0 +1,10 @@
from rest_framework import routers
from outbo.apps.organizations.viewsets import BrandViewSet, CategoryViewSet
app_name = "organizations"
router = routers.SimpleRouter()
router.register(prefix="brands", viewset=BrandViewSet)
router.register(prefix="categories", viewset=CategoryViewSet)
urlpatterns = router.urls
+29
View File
@@ -0,0 +1,29 @@
from outbo.apps.core.viewsets import (
MultipleSerializerViewSet,
AutoPermissionViewSetMixin,
ListModelMixin,
RetrieveModelMixin,
)
from outbo.apps.organizations.models import Brand, Category
from outbo.apps.organizations.serializers import BrandSerializer, CategorySerializer
class BrandViewSet(
RetrieveModelMixin,
ListModelMixin,
AutoPermissionViewSetMixin,
MultipleSerializerViewSet,
):
queryset = Brand.objects.all()
serializer_class_set = BrandSerializer
class CategoryViewSet(
RetrieveModelMixin,
ListModelMixin,
AutoPermissionViewSetMixin,
MultipleSerializerViewSet,
):
queryset = Category.objects.all()
serializer_class_set = CategorySerializer