Fix dashboard period ranges and add previous month and quarter options

Oriol told me what he actually wants: a way to see the current month,
quarter, and year for both double-check that the taxes form are filled
in correct and to see whether the business is doing well.  This is
specially important for the quarter period, as he has to fill taxes
each quarter.  Thus, the “last 90 days” thing i did was easier for me,
but completely useless for him.

We also decided to add previous month and previous quarter options
because it would be unfair to expect users check that data exactly the
last day or “lose access” to it.
This commit is contained in:
jordi fita mas 2023-05-19 14:05:57 +02:00
parent 121f03b63c
commit d1b978054b
3 changed files with 89 additions and 52 deletions

View File

@ -1,14 +1,17 @@
package pkg package pkg
import ( import (
"fmt"
"github.com/julienschmidt/httprouter" "github.com/julienschmidt/httprouter"
"net/http" "net/http"
) )
const ( const (
YearPeriod = "year"
QuarterPeriod = "quarter"
MonthPeriod = "month" MonthPeriod = "month"
YestermonthPeriod = "yestermonth"
QuarterPeriod = "quarter"
YesterquarterPeriod = "yesterquarter"
YearPeriod = "year"
YesteryearPeriod = "yesteryear" YesteryearPeriod = "yesteryear"
) )
@ -30,21 +33,27 @@ func ServeDashboard(w http.ResponseWriter, r *http.Request, _ httprouter.Params)
http.Error(w, err.Error(), http.StatusBadRequest) http.Error(w, err.Error(), http.StatusBadRequest)
return return
} }
periodStart := "30 DAYS" periodStart := "date_trunc('month', current_date)::date"
periodEnd := "0 DAYS" periodEnd := "current_date"
switch filters.Period.Selected { switch filters.Period.Selected {
case YearPeriod: case YestermonthPeriod:
periodStart = "1 YEAR" periodStart = "date_trunc('month', current_date - interval '1 month')::date"
periodEnd = "(date_trunc('month', current_date) - interval '1 day')::date"
case QuarterPeriod: case QuarterPeriod:
periodStart = "3 MONTHS" periodStart = "date_trunc('quarter', current_date)::date"
case YesterquarterPeriod:
periodStart = "date_trunc('quarter', current_date - interval '3 months')::date"
periodEnd = "(date_trunc('quarter', current_date) - interval '1 day')::date"
case YearPeriod:
periodStart = "date_trunc('year', current_date)::date"
case YesteryearPeriod: case YesteryearPeriod:
periodStart = "2 YEARS" periodStart = "date_trunc('year', current_date - interval '1 year')::date"
periodEnd = "1 YEAR" periodEnd = "(date_trunc('year', current_date) - interval '1 day')::date"
case "": case "":
filters.Period.Selected = MonthPeriod filters.Period.Selected = MonthPeriod
} }
conn := getConn(r) conn := getConn(r)
rows := conn.MustQuery(r.Context(), ` rows := conn.MustQuery(r.Context(), fmt.Sprintf(`
select to_price(0, decimal_digits) as sales select to_price(0, decimal_digits) as sales
, to_price(coalesce(invoice.total, 0), decimal_digits) as income , to_price(coalesce(invoice.total, 0), decimal_digits) as income
, to_price(coalesce(expense.total, 0), decimal_digits) as expenses , to_price(coalesce(expense.total, 0), decimal_digits) as expenses
@ -56,13 +65,13 @@ func ServeDashboard(w http.ResponseWriter, r *http.Request, _ httprouter.Params)
select company_id, sum(total)::integer as total select company_id, sum(total)::integer as total
from invoice from invoice
join invoice_amount using (invoice_id) join invoice_amount using (invoice_id)
where invoice_date between CURRENT_DATE - $2::interval and CURRENT_DATE - $3::interval where invoice_date between %[1]s and %[2]s
group by company_id group by company_id
) as invoice using (company_id) ) as invoice using (company_id)
left join ( left join (
select company_id, sum(amount)::integer as total select company_id, sum(amount)::integer as total
from expense from expense
where invoice_date between CURRENT_DATE - $2::interval and CURRENT_DATE - $3::interval where invoice_date between %[1]s and %[2]s
group by company_id group by company_id
) as expense using (company_id) ) as expense using (company_id)
left join ( left join (
@ -73,7 +82,7 @@ func ServeDashboard(w http.ResponseWriter, r *http.Request, _ httprouter.Params)
join invoice_tax_amount using (invoice_id) join invoice_tax_amount using (invoice_id)
join tax using (tax_id) join tax using (tax_id)
join tax_class using (tax_class_id) join tax_class using (tax_class_id)
where invoice_date between CURRENT_DATE - $2::interval and CURRENT_DATE - $3::interval where invoice_date between %[1]s and %[2]s
group by invoice.company_id group by invoice.company_id
) as invoice_tax using (company_id) ) as invoice_tax using (company_id)
left join ( left join (
@ -84,12 +93,12 @@ func ServeDashboard(w http.ResponseWriter, r *http.Request, _ httprouter.Params)
join expense_tax_amount using (expense_id) join expense_tax_amount using (expense_id)
join tax using (tax_id) join tax using (tax_id)
join tax_class using (tax_class_id) join tax_class using (tax_class_id)
where invoice_date between CURRENT_DATE - $2::interval and CURRENT_DATE - $3::interval where invoice_date between %[1]s and %[2]s
group by expense.company_id group by expense.company_id
) as expense_tax using (company_id) ) as expense_tax using (company_id)
join currency using (currency_code) join currency using (currency_code)
where company_id = $1 where company_id = $1
`, company.Id, periodStart, periodEnd) `, periodStart, periodEnd), company.Id)
defer rows.Close() defer rows.Close()
dashboard := &DashboardPage{ dashboard := &DashboardPage{
@ -122,19 +131,27 @@ func newDashboardFilterForm(locale *Locale, company *Company) *dashboardFilterFo
Label: pgettext("input", "Period", locale), Label: pgettext("input", "Period", locale),
Options: []*RadioOption{ Options: []*RadioOption{
{ {
Label: pgettext("period option", "Year", locale), Label: pgettext("period option", "Month", locale),
Value: YearPeriod, Value: MonthPeriod,
},
{
Label: pgettext("period option", "Previous month", locale),
Value: YestermonthPeriod,
}, },
{ {
Label: pgettext("period option", "Quarter", locale), Label: pgettext("period option", "Quarter", locale),
Value: QuarterPeriod, Value: QuarterPeriod,
}, },
{ {
Label: pgettext("period option", "Month", locale), Label: pgettext("period option", "Previous quarter", locale),
Value: MonthPeriod, Value: YesterquarterPeriod,
}, },
{ {
Label: pgettext("period option", "Previous Year", locale), Label: pgettext("period option", "Year", locale),
Value: YearPeriod,
},
{
Label: pgettext("period option", "Previous year", locale),
Value: YesteryearPeriod, Value: YesteryearPeriod,
}, },
}, },

View File

@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: numerus\n" "Project-Id-Version: numerus\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2023-05-17 11:59+0200\n" "POT-Creation-Date: 2023-05-19 13:55+0200\n"
"PO-Revision-Date: 2023-01-18 17:08+0100\n" "PO-Revision-Date: 2023-01-18 17:08+0100\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n" "Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Catalan <ca@dodds.net>\n" "Language-Team: Catalan <ca@dodds.net>\n"
@ -739,29 +739,39 @@ msgstr "La confirmació no és igual a la contrasenya."
msgid "Selected language is not valid." msgid "Selected language is not valid."
msgstr "Heu seleccionat un idioma que no és vàlid." msgstr "Heu seleccionat un idioma que no és vàlid."
#: pkg/dashboard.go:112 #: pkg/dashboard.go:131
msgctxt "input" msgctxt "input"
msgid "Period" msgid "Period"
msgstr "Període" msgstr "Període"
#: pkg/dashboard.go:115 #: pkg/dashboard.go:134
msgctxt "period option"
msgid "Year"
msgstr "Any"
#: pkg/dashboard.go:119
msgctxt "period option"
msgid "Quarter"
msgstr "Trimestre"
#: pkg/dashboard.go:123
msgctxt "period option" msgctxt "period option"
msgid "Month" msgid "Month"
msgstr "Mes" msgstr "Mes"
#: pkg/dashboard.go:127 #: pkg/dashboard.go:138
msgctxt "period option" msgctxt "period option"
msgid "Previous Year" msgid "Previous month"
msgstr "Mes anterior"
#: pkg/dashboard.go:142
msgctxt "period option"
msgid "Quarter"
msgstr "Trimestre"
#: pkg/dashboard.go:146
msgctxt "period option"
msgid "Previous quarter"
msgstr "Trimestre anterior"
#: pkg/dashboard.go:150
msgctxt "period option"
msgid "Year"
msgstr "Any"
#: pkg/dashboard.go:154
msgctxt "period option"
msgid "Previous year"
msgstr "Any anterior" msgstr "Any anterior"
#: pkg/expenses.go:129 #: pkg/expenses.go:129

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: numerus\n" "Project-Id-Version: numerus\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n" "Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2023-05-17 11:59+0200\n" "POT-Creation-Date: 2023-05-19 13:55+0200\n"
"PO-Revision-Date: 2023-01-18 17:45+0100\n" "PO-Revision-Date: 2023-01-18 17:45+0100\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n" "Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Spanish <es@tp.org.es>\n" "Language-Team: Spanish <es@tp.org.es>\n"
@ -739,29 +739,39 @@ msgstr "La confirmación no corresponde con la contraseña."
msgid "Selected language is not valid." msgid "Selected language is not valid."
msgstr "Habéis escogido un idioma que no es válido." msgstr "Habéis escogido un idioma que no es válido."
#: pkg/dashboard.go:112 #: pkg/dashboard.go:131
msgctxt "input" msgctxt "input"
msgid "Period" msgid "Period"
msgstr "Periodo" msgstr "Periodo"
#: pkg/dashboard.go:115 #: pkg/dashboard.go:134
msgctxt "period option"
msgid "Year"
msgstr "Año"
#: pkg/dashboard.go:119
msgctxt "period option"
msgid "Quarter"
msgstr "Trimestre"
#: pkg/dashboard.go:123
msgctxt "period option" msgctxt "period option"
msgid "Month" msgid "Month"
msgstr "Mes" msgstr "Mes"
#: pkg/dashboard.go:127 #: pkg/dashboard.go:138
msgctxt "period option" msgctxt "period option"
msgid "Previous Year" msgid "Previous month"
msgstr "Mes anterior"
#: pkg/dashboard.go:142
msgctxt "period option"
msgid "Quarter"
msgstr "Trimestre"
#: pkg/dashboard.go:146
msgctxt "period option"
msgid "Previous quarter"
msgstr "Trimestre anterior"
#: pkg/dashboard.go:150
msgctxt "period option"
msgid "Year"
msgstr "Año"
#: pkg/dashboard.go:154
msgctxt "period option"
msgid "Previous year"
msgstr "Año anterior" msgstr "Año anterior"
#: pkg/expenses.go:129 #: pkg/expenses.go:129