refactor: move month_year_picker to common and make it more generic

This commit is contained in:
Herculino Trotta
2024-10-29 13:41:04 -03:00
parent 6dc02210af
commit fda823ccd5
7 changed files with 91 additions and 16 deletions

View File

@@ -8,4 +8,9 @@ urlpatterns = [
views.toasts,
name="toasts",
),
path(
"ui/month-year-picker/",
views.month_year_picker,
name="month_year_picker",
),
]

View File

@@ -1,5 +1,86 @@
from dateutil.relativedelta import relativedelta
from django.db.models import Count
from django.db.models.functions import ExtractYear, ExtractMonth
from django.shortcuts import render
from django.urls import reverse
from django.utils import timezone
from apps.transactions.models import Transaction
def toasts(request):
return render(request, "common/toasts.html")
return render(request, "common/fragments/toasts.html")
def month_year_picker(request):
field = request.GET.get("field", "reference_date")
for_ = request.GET.get("for", None)
url = None
if for_ == "calendar":
url = "calendar"
elif for_ == "monthly_overview":
url = "monthly_overview"
# Get current month and year from request or use current date
current_date = timezone.localdate(timezone.now())
current_month = int(request.GET.get("month", current_date.month))
current_year = int(request.GET.get("year", current_date.year))
# Set start and end dates
start_date = timezone.datetime(current_year - 1, 1, 1).date()
end_date = timezone.datetime(current_year + 1, 12, 31).date()
# Get years from transactions
transaction_years = Transaction.objects.dates(field, "year", order="ASC")
# Extend start_date and end_date if necessary
if transaction_years:
start_date = min(start_date, transaction_years.first().replace(month=1, day=1))
end_date = max(end_date, transaction_years.last().replace(month=12, day=31))
# Generate all months between start_date and end_date
all_months = []
current_month_date = start_date
while current_month_date <= end_date:
all_months.append(current_month_date)
current_month_date += relativedelta(months=1)
# Get transaction counts for each month
transaction_counts = (
Transaction.objects.annotate(year=ExtractYear(field), month=ExtractMonth(field))
.values("year", "month")
.annotate(transaction_count=Count("id"))
.order_by("year", "month")
)
# Create a dictionary for quick lookup
count_dict = {
(item["year"], item["month"]): item["transaction_count"]
for item in transaction_counts
}
# Create the final result
result = [
{
"year": date.year,
"month": date.month,
"transaction_count": count_dict.get((date.year, date.month), 0),
"url": (
reverse(url, kwargs={"month": date.month, "year": date.year})
if url
else ""
),
}
for date in all_months
]
return render(
request,
"common/fragments/month_year_picker.html",
{
"month_year_data": result,
"current_month": current_month,
"current_year": current_year,
},
)

View File

@@ -19,9 +19,4 @@ urlpatterns = [
views.monthly_summary,
name="monthly_summary",
),
path(
"available_dates/",
views.month_year_picker,
name="available_dates",
),
]

View File

@@ -2,10 +2,6 @@ from decimal import Decimal
from django.contrib.auth.decorators import login_required
from django.db.models import (
Case,
When,
Value,
IntegerField,
Sum,
Q,
)

View File

@@ -1,2 +0,0 @@
from .ui import *
from .main import *

View File

@@ -37,7 +37,7 @@
{% if month_data.month == current_month and month_data.year == current_year %}aria-disabled="true"{% endif %}>
<div class="d-flex justify-content-between">
<a class="text-decoration-none stretched-link {% if month_data.month == current_month and month_data.year == current_year %} text-black{% endif %}"
href="{% url "monthly_overview" month=month_data.month year=month_data.year %}">
href={{ month_data.url }}>
{{ month_data.month|month_name }}</a>
<span class="badge text-bg-secondary">{{ month_data.transaction_count }}</span>
</div>

View File

@@ -26,10 +26,10 @@
class="fa-solid fa-chevron-left"></i></a>
</div>
<div class="tw-text-3xl fw-bold font-monospace tw-w-full text-center"
hx-get="{% url 'available_dates' %}"
hx-get="{% url 'month_year_picker' %}"
hx-target="#generic-offcanvas-left"
hx-trigger="click, date_picker from:window"
hx-vals='{"month": {{ month }}, "year": {{ year }}}' role="button">
hx-vals='{"month": {{ month }}, "year": {{ year }}, "for": "monthly_overview", "field": "reference_date"}' role="button">
{{ month|month_name }} {{ year }}
</div>
<div class="tw-text-base mx-2 h-100 align-items-center d-flex">
@@ -97,7 +97,7 @@
<div class="row gx-xl-4 gy-3">
<div class="col-12 col-xl-4 order-0 order-xl-2">
<div id="summary" hx-get="{% url 'monthly_summary' month=month year=year %}" class="show-loading"
hx-trigger="load, updated from:window, monthly_summary_update from:window">
hx-trigger="load, updated from:window, selective_update from:window">
</div>
</div>
<div class="col-12 col-xl-8 order-2 order-xl-1">