Migrates lookups

* products
* files
* Groups
* Clubs
* Accounting
This commit is contained in:
Antoine Bartuccio 2024-10-20 00:18:53 +02:00
parent ce4f57bd8f
commit e3dcad62cc
10 changed files with 192 additions and 20 deletions

23
accounting/api.py Normal file
View File

@ -0,0 +1,23 @@
from typing import Annotated
from annotated_types import MinLen
from ninja_extra import ControllerBase, api_controller, paginate, route
from ninja_extra.pagination import PageNumberPaginationExtra
from ninja_extra.schemas import PaginatedResponseSchema
from accounting.models import ClubAccount, Company
from accounting.schemas import ClubAccountSchema, CompanySchema
from core.api_permissions import CanAccessLookup
@api_controller("/lookup", permissions=[CanAccessLookup])
class AccountingController(ControllerBase):
@route.get("/club-account", response=PaginatedResponseSchema[ClubAccountSchema])
@paginate(PageNumberPaginationExtra, page_size=50)
def search_club_account(self, search: Annotated[str, MinLen(1)]):
return ClubAccount.objects.filter(name__icontains=search).values()
@route.get("/company", response=PaginatedResponseSchema[CompanySchema])
@paginate(PageNumberPaginationExtra, page_size=50)
def search_company(self, search: Annotated[str, MinLen(1)]):
return Company.objects.filter(name__icontains=search).values()

15
accounting/schemas.py Normal file
View File

@ -0,0 +1,15 @@
from ninja import ModelSchema
from accounting.models import ClubAccount, Company
class ClubAccountSchema(ModelSchema):
class Meta:
model = ClubAccount
fields = ["id", "name"]
class CompanySchema(ModelSchema):
class Meta:
model = Company
fields = ["id", "name"]

22
club/api.py Normal file
View File

@ -0,0 +1,22 @@
from typing import Annotated
from annotated_types import MinLen
from ninja_extra import ControllerBase, api_controller, paginate, route
from ninja_extra.pagination import PageNumberPaginationExtra
from ninja_extra.schemas import PaginatedResponseSchema
from club.models import Club
from club.schemas import ClubSchema
from core.api_permissions import CanAccessLookup
@api_controller("/club")
class ClubController(ControllerBase):
@route.get(
"/search",
response=PaginatedResponseSchema[ClubSchema],
permissions=[CanAccessLookup],
)
@paginate(PageNumberPaginationExtra, page_size=50)
def search_club(self, search: Annotated[str, MinLen(1)]):
return Club.objects.filter(name__icontains=search).values()

9
club/schemas.py Normal file
View File

@ -0,0 +1,9 @@
from ninja import ModelSchema
from club.models import Club
class ClubSchema(ModelSchema):
class Meta:
model = Club
fields = ["id", "name"]

View File

@ -11,11 +11,15 @@ from ninja_extra.pagination import PageNumberPaginationExtra
from ninja_extra.schemas import PaginatedResponseSchema from ninja_extra.schemas import PaginatedResponseSchema
from club.models import Mailing from club.models import Mailing
from core.api_permissions import CanView, IsLoggedInCounter, IsOldSubscriber, IsRoot from core.api_permissions import (
from core.models import User CanAccessLookup,
CanView,
)
from core.models import SithFile, User
from core.schemas import ( from core.schemas import (
FamilyGodfatherSchema, FamilyGodfatherSchema,
MarkdownSchema, MarkdownSchema,
SithFileSchema,
UserFamilySchema, UserFamilySchema,
UserFilterSchema, UserFilterSchema,
UserProfileSchema, UserProfileSchema,
@ -44,7 +48,7 @@ class MailingListController(ControllerBase):
return data return data
@api_controller("/user", permissions=[IsOldSubscriber | IsRoot | IsLoggedInCounter]) @api_controller("/user", permissions=[CanAccessLookup])
class UserController(ControllerBase): class UserController(ControllerBase):
@route.get("", response=list[UserProfileSchema]) @route.get("", response=list[UserProfileSchema])
def fetch_profiles(self, pks: Query[set[int]]): def fetch_profiles(self, pks: Query[set[int]]):
@ -62,6 +66,18 @@ class UserController(ControllerBase):
) )
@api_controller("/file")
class SithFileController(ControllerBase):
@route.get(
"/search",
response=PaginatedResponseSchema[SithFileSchema],
permissions=[CanAccessLookup],
)
@paginate(PageNumberPaginationExtra, page_size=50)
def search_files(self, query: Annotated[str, annotated_types.MinLen(1)]):
return SithFile.objects.filter(is_in_sas=False).filter(name__icontains=query)
DepthValue = Annotated[int, annotated_types.Ge(0), annotated_types.Le(10)] DepthValue = Annotated[int, annotated_types.Ge(0), annotated_types.Le(10)]
DEFAULT_DEPTH = 4 DEFAULT_DEPTH = 4

View File

@ -127,9 +127,12 @@ class IsLoggedInCounter(BasePermission):
"""Check that a user is logged in a counter.""" """Check that a user is logged in a counter."""
def has_permission(self, request: HttpRequest, controller: ControllerBase) -> bool: def has_permission(self, request: HttpRequest, controller: ControllerBase) -> bool:
if "/counter/" not in request.META["HTTP_REFERER"]: if "/counter/" not in request.META.get("HTTP_REFERER", ""):
return False return False
token = request.session.get("counter_token") token = request.session.get("counter_token")
if not token: if not token:
return False return False
return Counter.objects.filter(token=token).exists() return Counter.objects.filter(token=token).exists()
CanAccessLookup = IsOldSubscriber | IsRoot | IsLoggedInCounter

View File

@ -30,7 +30,7 @@ class RightManagedLookupChannel(LookupChannel):
raise PermissionDenied raise PermissionDenied
@register("users") @register("users") # Migrated
class UsersLookup(RightManagedLookupChannel): class UsersLookup(RightManagedLookupChannel):
model = User model = User
@ -44,7 +44,7 @@ class UsersLookup(RightManagedLookupChannel):
return item.get_display_name() return item.get_display_name()
@register("customers") @register("customers") # Never used
class CustomerLookup(RightManagedLookupChannel): class CustomerLookup(RightManagedLookupChannel):
model = Customer model = Customer
@ -58,7 +58,7 @@ class CustomerLookup(RightManagedLookupChannel):
return f"{obj.user.get_display_name()} ({obj.account_id})" return f"{obj.user.get_display_name()} ({obj.account_id})"
@register("groups") @register("groups") # Migrated
class GroupsLookup(RightManagedLookupChannel): class GroupsLookup(RightManagedLookupChannel):
model = Group model = Group
@ -72,7 +72,7 @@ class GroupsLookup(RightManagedLookupChannel):
return item.name return item.name
@register("clubs") @register("clubs") # Migrated
class ClubLookup(RightManagedLookupChannel): class ClubLookup(RightManagedLookupChannel):
model = Club model = Club
@ -86,7 +86,7 @@ class ClubLookup(RightManagedLookupChannel):
return item.name return item.name
@register("counters") @register("counters") # Migrated
class CountersLookup(RightManagedLookupChannel): class CountersLookup(RightManagedLookupChannel):
model = Counter model = Counter
@ -97,7 +97,7 @@ class CountersLookup(RightManagedLookupChannel):
return item.name return item.name
@register("products") @register("products") # Migrated
class ProductsLookup(RightManagedLookupChannel): class ProductsLookup(RightManagedLookupChannel):
model = Product model = Product
@ -111,7 +111,7 @@ class ProductsLookup(RightManagedLookupChannel):
return "%s (%s)" % (item.name, item.code) return "%s (%s)" % (item.name, item.code)
@register("files") @register("files") # Migrated
class SithFileLookup(RightManagedLookupChannel): class SithFileLookup(RightManagedLookupChannel):
model = SithFile model = SithFile
@ -119,7 +119,7 @@ class SithFileLookup(RightManagedLookupChannel):
return self.model.objects.filter(name__icontains=q)[:50] return self.model.objects.filter(name__icontains=q)[:50]
@register("club_accounts") @register("club_accounts") # Migrated
class ClubAccountLookup(RightManagedLookupChannel): class ClubAccountLookup(RightManagedLookupChannel):
model = ClubAccount model = ClubAccount
@ -130,7 +130,7 @@ class ClubAccountLookup(RightManagedLookupChannel):
return item.name return item.name
@register("companies") @register("companies") # Migrated
class CompaniesLookup(RightManagedLookupChannel): class CompaniesLookup(RightManagedLookupChannel):
model = Company model = Company

View File

@ -8,7 +8,7 @@ from haystack.query import SearchQuerySet
from ninja import FilterSchema, ModelSchema, Schema from ninja import FilterSchema, ModelSchema, Schema
from pydantic import AliasChoices, Field from pydantic import AliasChoices, Field
from core.models import User from core.models import Group, SithFile, User
class SimpleUserSchema(ModelSchema): class SimpleUserSchema(ModelSchema):
@ -45,6 +45,18 @@ class UserProfileSchema(ModelSchema):
return obj.profile_pict.get_download_url() return obj.profile_pict.get_download_url()
class SithFileSchema(ModelSchema):
class Meta:
model = SithFile
fields = ["id", "name"]
class GroupSchema(ModelSchema):
class Meta:
model = Group
fields = ["id", "name"]
class UserFilterSchema(FilterSchema): class UserFilterSchema(FilterSchema):
search: Annotated[str, MinLen(1)] search: Annotated[str, MinLen(1)]
exclude: list[int] | None = Field( exclude: list[int] | None = Field(

View File

@ -12,11 +12,25 @@
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# #
from ninja_extra import ControllerBase, api_controller, route from typing import Annotated
from core.api_permissions import CanView, IsRoot from annotated_types import MinLen
from counter.models import Counter from django.db.models import Q
from counter.schemas import CounterSchema from ninja import Query
from ninja_extra import ControllerBase, api_controller, paginate, route
from ninja_extra.pagination import PageNumberPaginationExtra
from ninja_extra.schemas import PaginatedResponseSchema
from core.api_permissions import CanAccessLookup, CanView, IsRoot
from core.models import Group
from core.schemas import GroupSchema
from counter.models import Counter, Product
from counter.schemas import (
CounterFilterSchema,
CounterSchema,
ProductSchema,
SimplifiedCounterSchema,
)
@api_controller("/counter") @api_controller("/counter")
@ -37,3 +51,42 @@ class CounterController(ControllerBase):
for c in counters: for c in counters:
self.check_object_permissions(c) self.check_object_permissions(c)
return counters return counters
@route.get(
"/search",
response=PaginatedResponseSchema[SimplifiedCounterSchema],
permissions=[CanAccessLookup],
)
@paginate(PageNumberPaginationExtra, page_size=50)
def search_counter(self, filters: Query[CounterFilterSchema]):
return filters.filter(Counter.objects.all())
@api_controller("/product")
class ProductController(ControllerBase):
@route.get(
"/search",
response=PaginatedResponseSchema[ProductSchema],
permissions=[CanAccessLookup],
)
@paginate(PageNumberPaginationExtra, page_size=50)
def search_products(self, search: Annotated[str, MinLen(1)]):
return (
Product.objects.filter(
Q(name__icontains=search) | Q(code__icontains=search)
)
.filter(archived=False)
.values()
)
@api_controller("/group")
class GroupController(ControllerBase):
@route.get(
"/search",
response=PaginatedResponseSchema[GroupSchema],
permissions=[CanAccessLookup],
)
@paginate(PageNumberPaginationExtra, page_size=50)
def search_group(self, search: Annotated[str, MinLen(1)]):
return Group.objects.filter(name__icontains=search).values()

View File

@ -1,7 +1,10 @@
from ninja import ModelSchema from typing import Annotated
from annotated_types import MinLen
from ninja import Field, FilterSchema, ModelSchema
from core.schemas import SimpleUserSchema from core.schemas import SimpleUserSchema
from counter.models import Counter from counter.models import Counter, Product
class CounterSchema(ModelSchema): class CounterSchema(ModelSchema):
@ -11,3 +14,19 @@ class CounterSchema(ModelSchema):
class Meta: class Meta:
model = Counter model = Counter
fields = ["id", "name", "type", "club", "products"] fields = ["id", "name", "type", "club", "products"]
class CounterFilterSchema(FilterSchema):
search: Annotated[str, MinLen(1)] = Field(None, q="name__icontains")
class SimplifiedCounterSchema(ModelSchema):
class Meta:
model = Counter
fields = ["id", "name"]
class ProductSchema(ModelSchema):
class Meta:
model = Product
fields = ["id", "name", "code"]