package server import ( "fmt" "net/http" "strconv" "time" "github.com/a-h/templ" u "github.com/rjNemo/underscore" "github.com/rjNemo/rentease/internal/config" "github.com/rjNemo/rentease/internal/constant" "github.com/rjNemo/rentease/internal/service/booking" "github.com/rjNemo/rentease/internal/view" ) func handleReportsPage() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { monthStr := r.URL.Query().Get("month") month, err := strconv.Atoi(monthStr) if err != nil || month < 1 || month > 12 { month = int(time.Now().Month()) } yearStr := r.URL.Query().Get("year") if _, err = strconv.Atoi(yearStr); err != nil { yearStr = time.Now().Format("2006") } component := view.Reports(u.Map(constant.Months, func(m constant.Month) string { return string(m) }), month, yearStr) if err := renderTempl(w, http.StatusOK, component); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } } func handleReportCompute(bs *booking.Service, hc *config.Host) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if err := r.ParseForm(); err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } period := r.FormValue("period") if !u.Contains([]string{"month", "year"}, period) { http.Error(w, fmt.Sprintf("%q is not a valid period", period), http.StatusBadRequest) return } monthStr := r.FormValue("month") month, err := strconv.Atoi(monthStr) if err != nil || month < 1 || month > 12 { http.Error(w, fmt.Sprintf("%q is not a valid month", monthStr), http.StatusBadRequest) return } yearStr := r.FormValue("year") year, err := strconv.Atoi(yearStr) if err != nil { http.Error(w, fmt.Sprintf("%q is not a valid year", yearStr), http.StatusBadRequest) return } report := bs.Report(period, month, year) reportVm := &view.ReportViewModel{ Total: strconv.FormatFloat(report.Total, 'f', 2, 64), PlatformFees: strconv.FormatFloat(report.PlatformFees, 'f', 2, 64), Fee: strconv.FormatFloat(report.Fee, 'f', 2, 64), Profit: strconv.FormatFloat(report.Profit, 'f', 2, 64), CardTotal: strconv.FormatFloat(report.CardTotal, 'f', 2, 64), BookingFees: strconv.FormatFloat(report.BookingFees, 'f', 2, 64), PdfUrl: templ.URL(fmt.Sprintf("%s/pdf?period=%s&month=%d&year=%d", constant.RouteReports, period, month, year)), Lines: u.Map(report.Lines, func(l *booking.Line) *view.ReportLine { return &view.ReportLine{ Id: l.InvoiceNumber(hc), Url: templ.SafeURL(fmt.Sprintf("%s/%d", constant.RouteBooking, l.ID)), Total: strconv.FormatFloat(l.Total, 'f', 2, 64), CustomerName: l.CustomerName, From: l.From.Format(time.DateOnly), To: l.To.Format(time.DateOnly), Platform: l.Platform, PlatformFees: strconv.FormatFloat(l.PlatformFees, 'f', 2, 64), Fee: strconv.FormatFloat(l.Fee(), 'f', 2, 64), Profit: strconv.FormatFloat(l.Profit(), 'f', 2, 64), } }), } if err := renderTempl(w, http.StatusOK, view.ReportSection(reportVm)); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } }