Files

167 lines
4.0 KiB
Python

from decimal import Decimal, InvalidOperation
from django.template.loader import render_to_string
from liveview import liveview_handler, send
from app.yearly.models import PlannedExpense
MONTH_LABELS = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
]
def _render_planned_tables(year, editing_id=None):
months_data = []
for m in range(1, 13):
items = PlannedExpense.objects.filter(year=year, month=m)
total = sum(i.amount for i in items)
months_data.append(
{
"month": m,
"label": MONTH_LABELS[m - 1],
"items": items,
"total": total,
}
)
grand_total = sum(md["total"] for md in months_data)
# Clone years
available_years = (
PlannedExpense.objects.exclude(year=year)
.values_list("year", flat=True)
.distinct()
.order_by("-year")
)
return render_to_string(
"pages/yearly/partials/planned_tables.html",
{
"months_data": months_data,
"year": year,
"grand_total": grand_total,
"editing_id": editing_id,
"clone_years": list(available_years),
},
)
@liveview_handler("add_planned_expense")
def add_planned_expense(consumer, content):
form = content.get("form", {})
year = int(form.get("year", 0))
month = int(form.get("pe_month", 0))
concept = form.get("pe_concept", "").strip()
amount_raw = form.get("pe_amount", "").replace(",", ".")
if not concept or not amount_raw or not year or not month:
return
try:
amount = Decimal(amount_raw)
except (InvalidOperation, ValueError):
return
PlannedExpense.objects.create(
year=year, month=month, concept=concept, amount=amount
)
html = _render_planned_tables(year)
send(consumer, {"target": "#planned-expenses", "html": html})
@liveview_handler("edit_planned_expense")
def edit_planned_expense(consumer, content):
data = content.get("data", {})
pe_id = data.get("data_id", "")
year = int(data.get("data_year", 0))
if not pe_id or not year:
return
html = _render_planned_tables(year, editing_id=int(pe_id))
send(consumer, {"target": "#planned-expenses", "html": html})
@liveview_handler("save_planned_expense")
def save_planned_expense(consumer, content):
form = content.get("form", {})
pe_id = form.get("pe_id", "")
year = int(form.get("year", 0))
month = int(form.get("pe_month", 0))
concept = form.get("pe_concept", "").strip()
amount_raw = form.get("pe_amount", "").replace(",", ".")
if not pe_id or not concept or not amount_raw or not year or not month:
return
try:
amount = Decimal(amount_raw)
pe = PlannedExpense.objects.get(id=pe_id)
pe.month = month
pe.concept = concept
pe.amount = amount
pe.save()
except (InvalidOperation, ValueError, PlannedExpense.DoesNotExist):
return
html = _render_planned_tables(year)
send(consumer, {"target": "#planned-expenses", "html": html})
@liveview_handler("cancel_edit_planned_expense")
def cancel_edit_planned_expense(consumer, content):
data = content.get("data", {})
year = int(data.get("data_year", 0))
if not year:
return
html = _render_planned_tables(year)
send(consumer, {"target": "#planned-expenses", "html": html})
@liveview_handler("delete_planned_expense")
def delete_planned_expense(consumer, content):
data = content.get("data", {})
pe_id = data.get("data_id", "")
year = int(data.get("data_year", 0))
if not pe_id or not year:
return
PlannedExpense.objects.filter(id=pe_id).delete()
html = _render_planned_tables(year)
send(consumer, {"target": "#planned-expenses", "html": html})
@liveview_handler("clone_planned_expenses")
def clone_planned_expenses(consumer, content):
form = content.get("form", {})
source_year = int(form.get("clone_pe_source", 0))
year = int(form.get("year", 0))
if not source_year or not year:
return
source_items = PlannedExpense.objects.filter(year=source_year)
for item in source_items:
PlannedExpense.objects.create(
year=year, month=item.month, concept=item.concept, amount=item.amount
)
html = _render_planned_tables(year)
send(consumer, {"target": "#planned-expenses", "html": html})