Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/bornhack/environment_settings.py.dist.dev
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ IRCBOT_CHANNELS = {
IRCBOT_PUBLIC_CHANNEL = "#my-bornhack-channel"
IRCBOT_VOLUNTEER_CHANNEL = "#my-bornhack-channel"

ACCOUNTINGSYSTEM_EMAIL = "accounting_system@example.com"
ECONOMYTEAM_EMAIL = "economy@example.com"
ECONOMYTEAM_NAME = "Economy"

BANKACCOUNT_IBAN = "LOL"
BANKACCOUNT_SWIFTBIC = "lol"
BANKACCOUNT_REG = "lol"
Expand Down
42 changes: 7 additions & 35 deletions src/economy/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.db.models import Prefetch
from django.core.exceptions import ValidationError
from django.db.models import Prefetch
from django.db.models import Q
from django.db.models import Sum
from django.http import HttpResponse
Expand Down Expand Up @@ -415,16 +415,8 @@ class ReimbursementCreateView(CampViewMixin, ExpensePermissionMixin, CreateView)

def dispatch(self, request, *args, **kwargs):
"""Get any approved and un-reimbursed expenses and revenues, or return error."""
self.expenses = request.user.expenses.filter(
reimbursement__isnull=True,
approved=True,
payment_status="PAID_NEEDS_REIMBURSEMENT",
)
self.revenues = request.user.revenues.filter(
reimbursement__isnull=True,
approved=True,
payment_status="PAID_NEEDS_REDISBURSEMENT",
)
self.expenses = request.user.profile.paid_expenses_needs_reimbursement
self.revenues = request.user.profile.paid_revenues_needs_redisbursement
if not self.expenses and not self.revenues:
messages.error(
request,
Expand Down Expand Up @@ -458,28 +450,8 @@ def form_valid(self, form):
reverse("economy:dashboard", kwargs={"camp_slug": self.camp.slug}),
)

# get the expenses for this user
expenses = Expense.objects.filter(
user=self.request.user,
approved=True,
reimbursement__isnull=True,
payment_status="PAID_NEEDS_REIMBURSEMENT",
)
expenses_total = expenses.aggregate(Sum("amount"))["amount__sum"] or 0

# get the revenues for this user
revenues = Revenue.objects.filter(
user=self.request.user,
approved=True,
reimbursement__isnull=True,
payment_status="PAID_NEEDS_REDISBURSEMENT",
)
revenues_total = revenues.aggregate(Sum("amount"))["amount__sum"] or 0
if not expenses and not revenues:
messages.error(self.request, "No approved unhandled expenses or revenues found")
return redirect(
reverse("economy:dashboard", kwargs={"camp_slug": self.camp.slug}),
)
expenses_total = self.expenses.aggregate(Sum("amount"))["amount__sum"] or 0
revenues_total = self.revenues.aggregate(Sum("amount"))["amount__sum"] or 0

# calculate the reimbursement total
reimbursement_total = expenses_total - revenues_total
Expand All @@ -502,12 +474,12 @@ def form_valid(self, form):
reimbursement.save()

# add all expenses to reimbursement
for expense in expenses:
for expense in self.expenses:
expense.reimbursement = reimbursement
expense.save()

# add all revenues to reimbursement
for revenue in revenues:
for revenue in self.revenues:
revenue.reimbursement = reimbursement
revenue.save()

Expand Down
8 changes: 7 additions & 1 deletion src/profiles/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@

from .signal_handlers import create_profile
from .signal_handlers import profile_pre_save
from .signal_handlers import set_session_on_login
from .signal_handlers import redisbursement_msg_on_login
from .signal_handlers import reimbursement_msg_on_login
from .signal_handlers import set_session_on_login

logger = logging.getLogger(f"bornhack.{__name__}")

Expand Down Expand Up @@ -42,3 +43,8 @@ def ready(self) -> None:
sender=User,
dispatch_uid="reimbursement_msg_on_login_signal",
)
user_logged_in.connect(
redisbursement_msg_on_login,
sender=User,
dispatch_uid="redisbursement_msg_on_login_signal",
)
34 changes: 28 additions & 6 deletions src/profiles/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from django.utils.translation import gettext_lazy as _
from django_prometheus.models import ExportModelOperationsMixin

from economy.models import Expense
from economy.models import Revenue
from utils.models import CreatedUpdatedModel
from utils.models import UUIDModel

Expand Down Expand Up @@ -76,31 +78,51 @@ class Meta:
)

@property
def email(self):
def email(self) -> str:
return self.user.email

def __str__(self) -> str:
return self.user.username

def approve_public_credit_name(self) -> None:
"""This method just sets profile.public_credit_name_approved=True and calls save()
It is used in an admin action.
"""This method just sets profile.public_credit_name_approved=True
and calls save(). It is used in an admin action.
"""
self.public_credit_name_approved = True
self.save()

@property
def get_public_credit_name(self):
"""Convenience method to return profile.public_credit_name if it is approved,
def get_public_credit_name(self) -> str:
"""Convenience method to return profile.public_credit_name if approved,
and the string "Unnamed" otherwise.
"""
if self.public_credit_name_approved:
return self.public_credit_name
return "Unnamed"

@property
def get_name(self):
def get_name(self) -> str:
"""Convenience method to return profile.name if set, otherwise username."""
if self.name:
return self.name
return self.user.username

@property
def paid_expenses_needs_reimbursement(self) -> models.QuerySet:
"""The paid_expense_needs_reimbursement property."""
return Expense.objects.filter(
user=self.user,
approved=True,
reimbursement__isnull=True,
payment_status="PAID_NEEDS_REIMBURSEMENT",
)

@property
def paid_revenues_needs_redisbursement(self) -> models.QuerySet:
"""The paid_revenues_needs_redisbursement property."""
return Revenue.objects.filter(
user=self.user,
approved=True,
reimbursement__isnull=True,
payment_status="PAID_NEEDS_REDISBURSEMENT",
)
29 changes: 20 additions & 9 deletions src/profiles/signal_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,26 @@ def set_session_on_login(sender, request, user, **kwargs) -> None:
"""Signal handler called on_login to set session["theme"] from the user profile."""
request.session["theme"] = request.user.profile.theme

def reimbursement_msg_on_login(sender, request, user, **kwargs) -> None:
"""
Add message when user has approved expenses without matching reimbursement.
"""
approved_expenses = user.expenses.all().filter(approved=True, reimbursement=None)

if approved_expenses.exists():
messages.info(
request,
f"NOTE: You have {approved_expenses.count()} expenses with a missing reimbursement. Please create a reimbursement once all your expenses have been approved."
def reimbursement_msg_on_login(sender, request, user, **kwargs) -> None:
"""Add message for reminding user about missing reimbursement."""
expenses = user.profile.paid_expenses_needs_reimbursement
if expenses.exists():
msg = (
f"NOTE: You have {expenses.count()} expense(s) with missing "
"reimbursement. Please create a reimbursement once all your "
"expenses have been approved."
)
messages.info(request, msg)


def redisbursement_msg_on_login(sender, request, user, **kwargs) -> None:
"""Add message for reminding user about missing redisbursement."""
revenues = user.profile.paid_revenues_needs_redisbursement
if revenues.exists():
msg = (
f"NOTE: You have {revenues.count()} revenue(s) with missing "
"redisbursement. Please create a redisbursement once all your "
"revenue(s) have been approved."
)
messages.info(request, msg)
14 changes: 2 additions & 12 deletions src/utils/bootstrap/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2037,18 +2037,8 @@ def create_camp_reimbursements(self, camp: Camp) -> None:
.distinct(),
)
for user in users:
expenses = Expense.objects.filter(
user=user,
approved=True,
reimbursement__isnull=True,
payment_status="PAID_NEEDS_REIMBURSEMENT",
)
revenues = Revenue.objects.filter(
user=user,
approved=True,
reimbursement__isnull=True,
payment_status="PAID_NEEDS_REDISBURSEMENT",
)
expenses = user.profile.paid_expenses_needs_reimbursement
revenues = user.profile.paid_revenues_needs_redisbursement
if not expenses and not revenues:
continue
reimbursement = Reimbursement.objects.create(
Expand Down
Loading