mirror of
https://github.com/ae-utbm/sith.git
synced 2024-11-18 12:13:24 +00:00
enhance admin pages
This commit is contained in:
parent
26c94c9ec6
commit
ceb2888f82
@ -21,11 +21,24 @@
|
|||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
from ajax_select import make_ajax_form
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from club.models import Club, Membership
|
from club.models import Club, Membership
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Club)
|
@admin.register(Club)
|
||||||
admin.site.register(Membership)
|
class ClubAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("name", "unix_name", "parent", "is_active")
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Membership)
|
||||||
|
class MembershipAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("user", "club", "role", "start_date", "end_date")
|
||||||
|
search_fields = (
|
||||||
|
"user__username",
|
||||||
|
"user__first_name",
|
||||||
|
"user__last_name",
|
||||||
|
"club__name",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(Membership, {"user": "users"})
|
||||||
|
26
com/admin.py
26
com/admin.py
@ -21,23 +21,37 @@
|
|||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
from ajax_select import make_ajax_form
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from haystack.admin import SearchModelAdmin
|
from haystack.admin import SearchModelAdmin
|
||||||
|
|
||||||
from com.models import *
|
from com.models import *
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(News)
|
||||||
class NewsAdmin(SearchModelAdmin):
|
class NewsAdmin(SearchModelAdmin):
|
||||||
search_fields = ["title", "summary", "content"]
|
list_display = ("title", "type", "club", "author")
|
||||||
|
search_fields = ("title", "summary", "content")
|
||||||
|
form = make_ajax_form(
|
||||||
|
News,
|
||||||
|
{
|
||||||
|
"author": "users",
|
||||||
|
"moderator": "users",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Poster)
|
||||||
|
class PosterAdmin(SearchModelAdmin):
|
||||||
|
list_display = ("name", "club", "date_begin", "date_end", "moderator")
|
||||||
|
form = make_ajax_form(Poster, {"moderator": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Weekmail)
|
||||||
class WeekmailAdmin(SearchModelAdmin):
|
class WeekmailAdmin(SearchModelAdmin):
|
||||||
search_fields = ["title"]
|
list_display = ("title", "sent")
|
||||||
|
search_fields = ("title",)
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Sith)
|
admin.site.register(Sith)
|
||||||
admin.site.register(News, NewsAdmin)
|
|
||||||
admin.site.register(Weekmail, WeekmailAdmin)
|
|
||||||
admin.site.register(Screen)
|
admin.site.register(Screen)
|
||||||
admin.site.register(Poster)
|
|
||||||
|
@ -24,17 +24,19 @@
|
|||||||
|
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from ajax_select import make_ajax_form
|
from ajax_select import make_ajax_form
|
||||||
from core.models import User, Page, RealGroup, SithFile
|
from core.models import User, Page, RealGroup, MetaGroup, SithFile
|
||||||
from django.contrib.auth.models import Group as AuthGroup
|
from django.contrib.auth.models import Group as AuthGroup
|
||||||
from haystack.admin import SearchModelAdmin
|
from haystack.admin import SearchModelAdmin
|
||||||
|
|
||||||
|
|
||||||
admin.site.unregister(AuthGroup)
|
admin.site.unregister(AuthGroup)
|
||||||
|
admin.site.register(MetaGroup)
|
||||||
admin.site.register(RealGroup)
|
admin.site.register(RealGroup)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(User)
|
||||||
class UserAdmin(SearchModelAdmin):
|
class UserAdmin(SearchModelAdmin):
|
||||||
list_display = ["first_name", "last_name", "username", "email", "nick_name"]
|
list_display = ("first_name", "last_name", "username", "email", "nick_name")
|
||||||
form = make_ajax_form(
|
form = make_ajax_form(
|
||||||
User,
|
User,
|
||||||
{
|
{
|
||||||
@ -48,11 +50,9 @@ class UserAdmin(SearchModelAdmin):
|
|||||||
search_fields = ["first_name", "last_name", "username"]
|
search_fields = ["first_name", "last_name", "username"]
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(User, UserAdmin)
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(Page)
|
@admin.register(Page)
|
||||||
class PageAdmin(admin.ModelAdmin):
|
class PageAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("name", "_full_name", "owner_group")
|
||||||
form = make_ajax_form(
|
form = make_ajax_form(
|
||||||
Page,
|
Page,
|
||||||
{
|
{
|
||||||
@ -66,4 +66,12 @@ class PageAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
@admin.register(SithFile)
|
@admin.register(SithFile)
|
||||||
class SithFileAdmin(admin.ModelAdmin):
|
class SithFileAdmin(admin.ModelAdmin):
|
||||||
form = make_ajax_form(SithFile, {"parent": "files"}) # ManyToManyField
|
list_display = ("name", "owner", "size", "date", "is_in_sas")
|
||||||
|
form = make_ajax_form(
|
||||||
|
SithFile,
|
||||||
|
{
|
||||||
|
"parent": "files",
|
||||||
|
"owner": "users",
|
||||||
|
"moderator": "users",
|
||||||
|
},
|
||||||
|
) # ManyToManyField
|
||||||
|
@ -28,8 +28,9 @@ from ajax_select import register, LookupChannel
|
|||||||
from core.views.site import search_user
|
from core.views.site import search_user
|
||||||
from core.models import User, Group, SithFile
|
from core.models import User, Group, SithFile
|
||||||
from club.models import Club
|
from club.models import Club
|
||||||
from counter.models import Product, Counter
|
from counter.models import Product, Counter, Customer
|
||||||
from accounting.models import ClubAccount, Company
|
from accounting.models import ClubAccount, Company
|
||||||
|
from eboutic.models import BasketItem
|
||||||
|
|
||||||
|
|
||||||
def check_token(request):
|
def check_token(request):
|
||||||
@ -60,6 +61,21 @@ class UsersLookup(RightManagedLookupChannel):
|
|||||||
return item.get_display_name()
|
return item.get_display_name()
|
||||||
|
|
||||||
|
|
||||||
|
@register("customers")
|
||||||
|
class CustomerLookup(RightManagedLookupChannel):
|
||||||
|
model = Customer
|
||||||
|
|
||||||
|
def get_query(self, q, request):
|
||||||
|
users = search_user(q)
|
||||||
|
return [user.customer for user in users]
|
||||||
|
|
||||||
|
def format_match(self, obj):
|
||||||
|
return obj.user.get_mini_item()
|
||||||
|
|
||||||
|
def format_item_display(self, obj):
|
||||||
|
return f"{obj.user.get_display_name()} ({obj.account_id})"
|
||||||
|
|
||||||
|
|
||||||
@register("groups")
|
@register("groups")
|
||||||
class GroupsLookup(RightManagedLookupChannel):
|
class GroupsLookup(RightManagedLookupChannel):
|
||||||
model = Group
|
model = Group
|
||||||
|
115
counter/admin.py
115
counter/admin.py
@ -21,19 +21,36 @@
|
|||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
from ajax_select import make_ajax_form
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from haystack.admin import SearchModelAdmin
|
from haystack.admin import SearchModelAdmin
|
||||||
|
|
||||||
from counter.models import *
|
from counter.models import *
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Product)
|
||||||
class ProductAdmin(SearchModelAdmin):
|
class ProductAdmin(SearchModelAdmin):
|
||||||
search_fields = ["name", "code"]
|
list_display = (
|
||||||
|
"name",
|
||||||
|
"code",
|
||||||
|
"product_type",
|
||||||
|
"selling_price",
|
||||||
|
"profit",
|
||||||
|
"archived",
|
||||||
|
)
|
||||||
|
search_fields = ("name", "code")
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Customer)
|
||||||
class CustomerAdmin(SearchModelAdmin):
|
class CustomerAdmin(SearchModelAdmin):
|
||||||
search_fields = ["account_id"]
|
list_display = ("user", "account_id", "amount")
|
||||||
|
search_fields = (
|
||||||
|
"account_id",
|
||||||
|
"user__username",
|
||||||
|
"user__first_name",
|
||||||
|
"user__last_name",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(Customer, {"user": "users"})
|
||||||
|
|
||||||
|
|
||||||
@admin.register(BillingInfo)
|
@admin.register(BillingInfo)
|
||||||
@ -41,12 +58,86 @@ class BillingInfoAdmin(admin.ModelAdmin):
|
|||||||
list_display = ("first_name", "last_name", "address_1", "city", "country")
|
list_display = ("first_name", "last_name", "address_1", "city", "country")
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(Customer, CustomerAdmin)
|
@admin.register(Counter)
|
||||||
admin.site.register(Product, ProductAdmin)
|
class CounterAdmin(admin.ModelAdmin):
|
||||||
admin.site.register(ProductType)
|
list_display = ("name", "club", "type")
|
||||||
admin.site.register(Counter)
|
form = make_ajax_form(
|
||||||
admin.site.register(Refilling)
|
Counter,
|
||||||
admin.site.register(Selling)
|
{
|
||||||
admin.site.register(Permanency)
|
"products": "products",
|
||||||
admin.site.register(CashRegisterSummary)
|
"sellers": "users",
|
||||||
admin.site.register(Eticket)
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Refilling)
|
||||||
|
class RefillingAdmin(SearchModelAdmin):
|
||||||
|
list_display = ("customer", "amount", "counter", "payment_method", "date")
|
||||||
|
search_fields = (
|
||||||
|
"customer__user__username",
|
||||||
|
"customer__user__first_name",
|
||||||
|
"customer__user__last_name",
|
||||||
|
"customer__account_id",
|
||||||
|
"counter__name",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(
|
||||||
|
Refilling,
|
||||||
|
{
|
||||||
|
"customer": "customers",
|
||||||
|
"operator": "users",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Selling)
|
||||||
|
class SellingAdmin(SearchModelAdmin):
|
||||||
|
list_display = ("customer", "label", "unit_price", "quantity", "counter", "date")
|
||||||
|
search_fields = (
|
||||||
|
"customer__user__username",
|
||||||
|
"customer__user__first_name",
|
||||||
|
"customer__user__last_name",
|
||||||
|
"customer__account_id",
|
||||||
|
"counter__name",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(
|
||||||
|
Selling,
|
||||||
|
{
|
||||||
|
"customer": "customers",
|
||||||
|
"seller": "users",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Permanency)
|
||||||
|
class PermanencyAdmin(SearchModelAdmin):
|
||||||
|
list_display = ("user", "counter", "start", "duration")
|
||||||
|
search_fields = (
|
||||||
|
"user__username",
|
||||||
|
"user__first_name",
|
||||||
|
"user__last_name",
|
||||||
|
"counter__name",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(Permanency, {"user": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(ProductType)
|
||||||
|
class ProductTypeAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("name", "priority")
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(CashRegisterSummary)
|
||||||
|
class CashRegisterSummaryAdmin(SearchModelAdmin):
|
||||||
|
list_display = ("user", "counter", "date")
|
||||||
|
search_fields = (
|
||||||
|
"user__username",
|
||||||
|
"user__first_name",
|
||||||
|
"user__last_name",
|
||||||
|
"counter__name",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(CashRegisterSummary, {"user": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Eticket)
|
||||||
|
class EticketAdmin(SearchModelAdmin):
|
||||||
|
list_display = ("product", "event_date", "event_title")
|
||||||
|
search_fields = ("product__name", "event_title")
|
||||||
|
@ -305,6 +305,10 @@ class Product(models.Model):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@property
|
||||||
|
def profit(self):
|
||||||
|
return self.selling_price - self.purchase_price
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "%s (%s)" % (self.name, self.code)
|
return "%s (%s)" % (self.name, self.code)
|
||||||
|
|
||||||
@ -762,6 +766,12 @@ class Permanency(models.Model):
|
|||||||
self.end.strftime("%Y-%m-%d %H:%M:%S") if self.end else "",
|
self.end.strftime("%Y-%m-%d %H:%M:%S") if self.end else "",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def duration(self):
|
||||||
|
if self.end is None:
|
||||||
|
return self.activity - self.start
|
||||||
|
return self.end - self.start
|
||||||
|
|
||||||
|
|
||||||
class CashRegisterSummary(models.Model):
|
class CashRegisterSummary(models.Model):
|
||||||
user = models.ForeignKey(
|
user = models.ForeignKey(
|
||||||
|
@ -21,11 +21,32 @@
|
|||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
from ajax_select import make_ajax_form
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from eboutic.models import *
|
from eboutic.models import *
|
||||||
|
|
||||||
admin.site.register(Basket)
|
|
||||||
admin.site.register(Invoice)
|
@admin.register(Basket)
|
||||||
admin.site.register(BasketItem)
|
class BasketAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("user", "date", "get_total")
|
||||||
|
form = make_ajax_form(Basket, {"user": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(BasketItem)
|
||||||
|
class BasketItemAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("basket", "product_name", "product_unit_price", "quantity")
|
||||||
|
search_fields = ("product_name",)
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Invoice)
|
||||||
|
class InvoiceAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("user", "date", "validated")
|
||||||
|
search_fields = ("user__username", "user__first_name", "user__last_name")
|
||||||
|
form = make_ajax_form(Invoice, {"user": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(InvoiceItem)
|
||||||
|
class InvoiceItemAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("invoice", "product_name", "product_unit_price", "quantity")
|
||||||
|
search_fields = ("product_name",)
|
||||||
|
@ -1,3 +1,37 @@
|
|||||||
|
from ajax_select import make_ajax_form
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
# Register your models here.
|
from election.models import Election, Role, ElectionList, Candidature
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Election)
|
||||||
|
class ElectionAdmin(admin.ModelAdmin):
|
||||||
|
list_display = (
|
||||||
|
"title",
|
||||||
|
"is_candidature_active",
|
||||||
|
"is_vote_active",
|
||||||
|
"is_vote_finished",
|
||||||
|
"archived",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(Election, {"voters": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Role)
|
||||||
|
class RoleAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("election", "title", "max_choice")
|
||||||
|
search_fields = ("election__title", "title")
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(ElectionList)
|
||||||
|
class ElectionListAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("election", "title")
|
||||||
|
search_fields = ("election__title", "title")
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Candidature)
|
||||||
|
class CandidatureAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("user", "role", "election_list")
|
||||||
|
form = make_ajax_form(Candidature, {"user": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
# Votes must stay fully anonymous, so no ModelAdmin for Vote model
|
||||||
|
@ -21,13 +21,29 @@
|
|||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
from ajax_select import make_ajax_form
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from launderette.models import *
|
from launderette.models import *
|
||||||
|
|
||||||
# Register your models here.
|
|
||||||
admin.site.register(Launderette)
|
@admin.register(Launderette)
|
||||||
admin.site.register(Machine)
|
class LaunderetteAdmin(admin.ModelAdmin):
|
||||||
admin.site.register(Token)
|
list_display = ("name", "counter")
|
||||||
admin.site.register(Slot)
|
|
||||||
|
|
||||||
|
@admin.register(Machine)
|
||||||
|
class MachineAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("name", "launderette", "type", "is_working")
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Token)
|
||||||
|
class TokenAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("name", "launderette", "type", "user")
|
||||||
|
form = make_ajax_form(Token, {"user": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(Slot)
|
||||||
|
class SlotAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("machine", "user", "start_date")
|
||||||
|
form = make_ajax_form(Slot, {"user": "users"})
|
||||||
|
@ -21,7 +21,39 @@
|
|||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
from ajax_select import make_ajax_form
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from haystack.admin import SearchModelAdmin
|
||||||
|
|
||||||
# Register your models here.
|
from pedagogy.models import UV, UVComment, UVCommentReport
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(UV)
|
||||||
|
class UVAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("code", "title", "credit_type", "credits", "department")
|
||||||
|
search_fields = ("code", "title", "department")
|
||||||
|
form = make_ajax_form(UV, {"author": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(UVComment)
|
||||||
|
class UVCommentAdmin(admin.ModelAdmin):
|
||||||
|
list_display = ("author", "uv", "grade_global", "publish_date")
|
||||||
|
search_fields = (
|
||||||
|
"author__username",
|
||||||
|
"author__first_name",
|
||||||
|
"author__last_name",
|
||||||
|
"uv__code",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(UVComment, {"author": "users"})
|
||||||
|
|
||||||
|
|
||||||
|
@admin.register(UVCommentReport)
|
||||||
|
class UVCommentReportAdmin(SearchModelAdmin):
|
||||||
|
list_display = ("reporter", "uv")
|
||||||
|
search_fields = (
|
||||||
|
"reporter__username",
|
||||||
|
"reporter__first_name",
|
||||||
|
"reporter__last_name",
|
||||||
|
"comment__uv__code",
|
||||||
|
)
|
||||||
|
form = make_ajax_form(UVCommentReport, {"reporter": "users"})
|
||||||
|
@ -325,6 +325,10 @@ class UVCommentReport(models.Model):
|
|||||||
)
|
)
|
||||||
reason = models.TextField(_("reason"))
|
reason = models.TextField(_("reason"))
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def uv(self):
|
||||||
|
return self.comment.uv
|
||||||
|
|
||||||
def is_owned_by(self, user):
|
def is_owned_by(self, user):
|
||||||
"""
|
"""
|
||||||
Can be created by a pedagogy admin, a superuser or a subscriber
|
Can be created by a pedagogy admin, a superuser or a subscriber
|
||||||
|
@ -21,20 +21,25 @@
|
|||||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
from ajax_select import make_ajax_form
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from subscription.models import Subscription
|
from subscription.models import Subscription
|
||||||
from haystack.admin import SearchModelAdmin
|
|
||||||
|
|
||||||
|
|
||||||
class SubscriptionAdmin(SearchModelAdmin):
|
@admin.register(Subscription)
|
||||||
search_fields = [
|
class SubscriptionAdmin(admin.ModelAdmin):
|
||||||
|
list_display = (
|
||||||
|
"member",
|
||||||
|
"subscription_type",
|
||||||
|
"subscription_start",
|
||||||
|
"subscription_end",
|
||||||
|
"location",
|
||||||
|
)
|
||||||
|
search_fields = (
|
||||||
"member__username",
|
"member__username",
|
||||||
"subscription_start",
|
"subscription_start",
|
||||||
"subscription_end",
|
"subscription_end",
|
||||||
"subscription_type",
|
"subscription_type",
|
||||||
]
|
)
|
||||||
|
form = make_ajax_form(Subscription, {"member": "users"})
|
||||||
|
|
||||||
admin.site.register(Subscription, SubscriptionAdmin)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user