Skip to content

Commit

Permalink
Budget summary per committee and budget line (#206)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr-salto authored Nov 7, 2024
1 parent 23399b5 commit e1883ba
Show file tree
Hide file tree
Showing 4 changed files with 378 additions and 170 deletions.
4 changes: 3 additions & 1 deletion compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ services:
- 8000:8000
volumes:
- ./media:/app/media
- ./templates:/app/templates
develop:
watch:
- path: .
Expand All @@ -39,6 +40,8 @@ services:
interval: 2s
timeout: 2s
retries: 3
ports:
- 5432:5432
login:
image: ghcr.io/datasektionen/nyckeln-under-dorrmattan
ports:
Expand All @@ -47,4 +50,3 @@ services:
# Since we're using the real pls, it's nice to use some user with a lot of privileges. Putting
# Melvin here since he's treasurer at the time of writing.
KTH_ID: melvinj

3 changes: 3 additions & 0 deletions stats/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
url(r'^$', views.index, name='stats-index'),
url(r'^summary/$', views.summary, name='stats-summary'),
url(r'^monthly/(?P<year>\d+)/$', views.monthly, name='stats-breakdown'),
url(r'^cost_centres/$', views.cost_centres, name='stats-committees'),
url(r'^sec_cost_centres/$', views.sec_cost_centres, name='stats-sec_cost_centre'),
url(r'^budget_lines/$', views.budget_lines, name='stats-budget_lines'),
]
162 changes: 128 additions & 34 deletions stats/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,42 +42,136 @@ def index(request):
'budget_url': settings.BUDGET_URL,
})

@csrf_exempt
@require_GET
def summary(request):
if request.method == "POST":
body_data = json.loads(request.body)
# we tried getting it to work with ids, but it didn't,
# so we're using names for now

expense_parts = None

if "year" in body_data:
expense_parts = models.ExpensePart.objects.filter(
budget_line=body_data['budget_line'],
cost_centre=body_data['cost_centre'],
secondary_cost_centre=body_data['cost_centre'],
expense__expense_date__year=body_data['year'],
).all()
else:
expense_parts = models.ExpensePart.objects.filter(
budget_line=body_data['budget_line'],
cost_centre=body_data['cost_centre'],
secondary_cost_centre=body_data['cost_centre'],
).all()

sum_amount = 0

for expense_part in expense_parts:
sum_amount += expense_part.amount

return JsonResponse({
'name': body_data['cost_centre'],
'costCentre': body_data['cost_centre'],
'budgetLine': body_data['budget_line'],
'year': body_data.get("year"),
'amount': sum_amount,
expense_parts = None

cost_centre = request.GET.get('cost_centre')
year = request.GET.get('year')
secondary_cost_centre = request.GET.get('secondary_cost_centre')
budget_line = request.GET.get('budget_line')

if not cost_centre or not year:
return JsonResponse({'error': 'cost_centre and year are required'}, status=400)
if secondary_cost_centre == '':
# Filter ExpensePart by cost_centre and year
expense_parts = models.ExpensePart.objects.filter(
cost_centre=cost_centre,
expense__expense_date__year=year
).all()
elif budget_line == '':
# Filter ExpensePart by cost_centre and year
expense_parts = models.ExpensePart.objects.filter(
cost_centre=cost_centre,
expense__expense_date__year=year,
secondary_cost_centre=secondary_cost_centre
).all()
else:
# Filter ExpensePart by cost_centre and year
expense_parts = models.ExpensePart.objects.filter(
cost_centre=cost_centre,
expense__expense_date__year=year,
secondary_cost_centre=secondary_cost_centre,
budget_line = budget_line
).all()

sum_amount = 0
expense_parts_list = [] # To store each expense part for debugging or detailed view

for expense_part in expense_parts:
sum_amount += expense_part.amount
# Optionally add the expense part details to the response
expense_parts_list.append({
'expense': str(expense_part.expense), # String representation of the expense
'amount': float(expense_part.amount), # Convert to float for JSON compatibility
'budget_line': expense_part.budget_line
})
return Response(status=status.HTTP_404_NOT_FOUND)

return JsonResponse({
'amount': sum_amount,
})


@require_GET
def sec_cost_centres(request):
expense_parts = None

cost_centre = request.GET.get('cost_centre')
year = request.GET.get('year')
if not cost_centre or not year:
return JsonResponse({'error': 'cost_centre and year are required'}, status=400)

# Filter ExpensePart by cost_centre and year
expense_parts = models.ExpensePart.objects.filter(
cost_centre=cost_centre,
expense__expense_date__year=year
).all()

sec_cost_centres = set()

for expense_part in expense_parts:
sec_cost_centres.add(expense_part.secondary_cost_centre)
# Optionally add the expense part details to the response

sec_cost_centres_list = list(sec_cost_centres)

return JsonResponse({
'sec_cost_centres': sec_cost_centres_list
})

@require_GET
def budget_lines(request):
expense_parts = None

cost_centre = request.GET.get('cost_centre')
year = request.GET.get('year')
secondary_cost_centre = request.GET.get('secondary_cost_centre')
if not cost_centre or not year or not secondary_cost_centre:
return JsonResponse({'error': 'cost_centre and year are required'}, status=400)

# Filter ExpensePart by cost_centre and year
expense_parts = models.ExpensePart.objects.filter(
cost_centre=cost_centre,
expense__expense_date__year=year,
secondary_cost_centre = secondary_cost_centre
).all()

budget_lines = set()

for expense_part in expense_parts:
budget_lines.add(expense_part.budget_line)

budget_lines_list = list(budget_lines)

return JsonResponse({
'budget_lines': budget_lines_list
})



@require_GET
def cost_centres(request):
"""
Returns the distinct cost centres (committees) from all expenses.
"""
expense_queryset = models.Expense.objects.all()
# expense_queryset is a list of expenses


# Collecting cost centres from each expense
cost_centres = set() # Use a set to avoid duplicates

for expense in expense_queryset:
for cost_centre in expense.cost_centres():
cost_centres.add(cost_centre['cost_centre'])

# Convert the set back to a list
cost_centres_list = list(cost_centres)

return JsonResponse({
'cost_centres': cost_centres_list
})



@require_GET
Expand Down
Loading

0 comments on commit e1883ba

Please sign in to comment.