"""
Map
The entry point is club_menu() which loads the page menu.html
Menu.html uses HTMX to load the tab pages e.g. tab_dashboard_htmx()
"""
import datetime
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.utils import timezone
from accounts.models import UserAdditionalInfo
from accounts.views.core import (
get_user_or_unregistered_user_from_system_number,
)
from club_sessions.models import Session
from events.models import Congress, CongressMaster
from organisations.decorators import check_club_menu_access
from organisations.forms import ResultsEmailMessageForm
from organisations.models import (
Organisation,
OrgEmailTemplate,
ClubLog,
)
from organisations.views.admin import (
rbac_get_basic_and_advanced,
)
from organisations.views.club_menu_tabs.access import access_basic, access_advanced
from organisations.views.club_menu_tabs.utils import (
_menu_rbac_has_access,
_user_is_uber_admin,
get_members_balance,
)
from organisations.club_admin_core import (
get_member_count,
)
from payments.models import UserPendingPayment
from payments.views.core import org_balance
from rbac.core import (
rbac_user_has_role,
)
from rbac.models import RBACUserGroup, RBACGroupRole
from rbac.views import rbac_forbidden
from results.models import ResultsFile
from utils.utils import cobalt_paginator
@check_club_menu_access()
def tab_access_htmx(request, club):
"""build the access tab in club menu"""
# Access tab - we have basic or advanced which are very different so use two functions for this
rbac_basic, rbac_advanced = rbac_get_basic_and_advanced(club)
if rbac_basic:
return access_basic(request, club)
elif rbac_advanced:
return access_advanced(request, club)
else:
return HttpResponse(
"<h3>This club has not been set up normally. Unable to manage access through the Club Menu.</h3>"
)
@check_club_menu_access()
def tab_dashboard_htmx(request, club):
"""build the dashboard tab in club menu"""
# Get members active now
member_count = get_member_count(club)
# Gets members active 28 days ago
past = timezone.now() - datetime.timedelta(days=28)
member_count_before = get_member_count(club, past)
diff = member_count - member_count_before
diff_28_days = "No change" if diff == 0 else f"{diff:+,}"
congress_count = Congress.objects.filter(congress_master__org=club).count()
staff_count = (
RBACUserGroup.objects.filter(group__rbacgrouprole__model_id=club.id)
.filter(group__name_qualifier=club.rbac_name_qualifier)
.values_list("member")
.distinct()
.count()
)
# Get any outstanding set up required
has_templates = OrgEmailTemplate.objects.all().exists()
public_profile_edited = ClubLog.objects.filter(
action="Updated public profile", organisation=club
).exists()
has_members = member_count > 0
warnings = (
not has_templates
or not club.bank_bsb
or not club.bank_account
or not public_profile_edited
or not has_members
)
# See if this has just been set up
try:
is_initial = ClubLog.objects.latest("pk").action == "Initial defaults set up"
except ClubLog.DoesNotExist:
is_initial = False
return render(
request,
"organisations/club_menu/dashboard/dashboard_htmx.html",
{
"club": club,
"member_count": member_count,
"congress_count": congress_count,
"staff_count": staff_count,
"diff_28_days": diff_28_days,
"has_templates": has_templates,
"public_profile_edited": public_profile_edited,
"has_members": has_members,
"is_initial": is_initial,
"warnings": warnings,
},
)
@check_club_menu_access()
def tab_congress_htmx(request, club):
"""build the congress tab in club menu"""
congress_masters = CongressMaster.objects.filter(org=club)
for congress_master in congress_masters:
congress_master.has_congresses = bool(
Congress.objects.filter(congress_master=congress_master).exists()
)
# Show button for draft congresses if there are any
show_draft = (
Congress.objects.filter(congress_master__org=club)
.filter(status="Draft")
.exists()
)
return render(
request,
"organisations/club_menu/congress/congress_htmx.html",
{"club": club, "congress_masters": congress_masters, "show_draft": show_draft},
)
@check_club_menu_access()
def tab_sessions_htmx(request, club, message=""):
"""build the sessions tab in club menu"""
sessions = (
Session.objects.filter(session_type__organisation=club)
.order_by("-session_date", "-pk")
.select_related("session_type")
)
things = cobalt_paginator(request, sessions)
hx_post = reverse("organisations:club_menu_tab_sessions_htmx")
hx_vars = f"club_id:{club.id}"
return render(
request,
"organisations/club_menu/sessions/sessions_htmx.html",
{
"club": club,
"things": things,
"hx_post": hx_post,
"hx_vars": hx_vars,
"message": message,
},
)
[docs]
@login_required()
def tab_finance_statement(request, club_id):
"""Entry point for the new club finance statement, for COB-766"""
return club_menu(request, club_id, show_tab="finance")
[docs]
@login_required()
def tab_comms_edit_batch_ep(request, club_id, batch_id_id):
"""Entry point for editing an email batch under the comms tab
Used when wanting to navigate from outside the club menu to the comms tab
and editing a specific inflight batch"""
return club_menu(
request, club_id, show_tab="comms", click_id=f"id_{batch_id_id}_edit_button"
)
[docs]
@login_required()
def tab_entry_point(request, club_id, tab_name):
"""Entry point for showing a specified tab"""
return club_menu(request, club_id, show_tab=tab_name)
@check_club_menu_access()
def tab_finance_htmx(request, club, message=""):
"""build the finance tab in club menu"""
# Get balance and transactions
balance = org_balance(club)
# Get member balances
members_balance = get_members_balance(club)
# Get any outstanding debts
user_pending_payments = UserPendingPayment.objects.filter(organisation=club)
# augment data
for user_pending_payment in user_pending_payments:
user_pending_payment.player = get_user_or_unregistered_user_from_system_number(
user_pending_payment.system_number
)
user_pending_payment.hx_delete = reverse(
"organisations:club_menu_tab_finance_cancel_user_pending_debt_htmx"
)
user_pending_payment.hx_vars = (
f"club_id:{club.id}, user_pending_payment_id:{user_pending_payment.id}"
)
return render(
request,
"organisations/club_menu/finance/finance_htmx.html",
{
"club": club,
"balance": balance,
"members_balance": members_balance,
"user_pending_payments": user_pending_payments,
"message": message,
},
)
@check_club_menu_access()
def tab_forums_htmx(request, club):
"""build the forums tab in club menu"""
return render(
request, "organisations/club_menu/forums/forums_htmx.html", {"club": club}
)
@check_club_menu_access()
def tab_results_htmx(request, club, message=None):
"""build the results tab in club menu"""
recent_results = ResultsFile.objects.filter(organisation=club).order_by(
"-event_date"
)
things = cobalt_paginator(request, recent_results)
hx_post = reverse("organisations:club_menu_tab_results_htmx")
hx_vars = f"club_id:{club.id}"
hx_delete = reverse("organisations:club_menu_tab_results_delete_results_file_htmx")
for thing in things:
thing.hx_vars = f"club_id:{club.id},results_file_id:{thing.id}"
# Get results email form
results_email_message_form = ResultsEmailMessageForm(instance=club)
# See if a template exists for results
results_template_exists = OrgEmailTemplate.objects.filter(
organisation=club, template_name="Results"
).exists()
return render(
request,
"organisations/club_menu/results/results_htmx.html",
{
"club": club,
"things": things,
"hx_post": hx_post,
"hx_delete": hx_delete,
"hx_vars": hx_vars,
"message": message,
"results_email_message_form": results_email_message_form,
"results_template_exists": results_template_exists,
},
)