From 584c30bdd4276fd7cc7ca37523b0d5dba444dfa0 Mon Sep 17 00:00:00 2001 From: Ruidy Date: Mon, 26 Feb 2024 18:36:30 +0100 Subject: [PATCH] add totals to the report --- internal/booking/service.go | 41 +++++++++++-- internal/server/handle_reports.go | 47 +++++++-------- internal/views/report_section.templ | 25 +++++++- internal/views/report_section_templ.go | 82 ++++++++++++++++++++++---- 4 files changed, 151 insertions(+), 44 deletions(-) diff --git a/internal/booking/service.go b/internal/booking/service.go index 7cb0bd0..01774f6 100644 --- a/internal/booking/service.go +++ b/internal/booking/service.go @@ -5,8 +5,11 @@ import ( "strconv" "time" - "github.com/rjNemo/rentease/config" + u "github.com/rjNemo/underscore" + "gorm.io/gorm" + + "github.com/rjNemo/rentease/config" ) type Service struct { @@ -58,6 +61,14 @@ func (bs Service) CreateItem(bid int, item string, qty int, price float64, metho return i } +type Report struct { + Total float64 + PlatformFees float64 + Fee float64 + Profit float64 + Lines []*Line +} + type Line struct { From time.Time To time.Time @@ -72,8 +83,21 @@ func (l Line) InvoiceNumber(hc *config.Host) string { return fmt.Sprintf("%s%04s", hc.InvoicePrefix, strconv.Itoa(l.Id+hc.CustomerSeed)) } -func (bs Service) BuildReport(period string, month, year int) []*Line { - res := make([]*Line, 0) +func (l Line) Fee() (f float64) { + if l.Platform == "Other" { + f = l.Total * 5 / 100 + } else { + f = l.Total * 10 / 100 + } + return f +} + +func (l Line) Profit() float64 { + return l.Total - l.PlatformFees - l.Fee() +} + +func (bs Service) BuildReport(period string, month, year int) *Report { + lines := make([]*Line, 0) var startDate time.Time var endDate time.Time @@ -97,6 +121,13 @@ func (bs Service) BuildReport(period string, month, year int) []*Line { where sbi.booking_id = b.id; `, startDate.Format("2006-01-02"), endDate.Format("2006-01-02")). - Scan(&res) - return res + Scan(&lines) + + return &Report{ + Total: u.Reduce(lines, func(l *Line, sum float64) float64 { return sum + l.Total }, 0.0), + PlatformFees: u.Reduce(lines, func(l *Line, sum float64) float64 { return sum + l.PlatformFees }, 0.0), + Fee: u.Reduce(lines, func(l *Line, sum float64) float64 { return sum + l.Fee() }, 0.0), + Profit: u.Reduce(lines, func(l *Line, sum float64) float64 { return sum + l.Profit() }, 0.0), + Lines: lines, + } } diff --git a/internal/server/handle_reports.go b/internal/server/handle_reports.go index e52cceb..26128f8 100644 --- a/internal/server/handle_reports.go +++ b/internal/server/handle_reports.go @@ -65,34 +65,29 @@ func handleComputeReport(bs *booking.Service, hc *config.Host) echo.HandlerFunc } } - res := bs.BuildReport(period, month, year) + r := bs.BuildReport(period, month, year) - reportVm := u.Map(res, func(r *booking.Line) *views.ReportViewModel { - fee := computeFee(r) - return &views.ReportViewModel{ - Id: r.InvoiceNumber(hc), - Url: templ.SafeURL(fmt.Sprintf("%s/%d", constants.RouteBooking, r.Id)), - Total: strconv.FormatFloat(r.Total, 'f', 2, 64), - CustomerName: r.CustomerName, - From: r.From.Format("2006-01-02"), - To: r.To.Format("2006-01-02"), - Platform: r.Platform, - PlatformFees: strconv.FormatFloat(r.PlatformFees, 'f', 2, 64), - Fee: strconv.FormatFloat(fee, 'f', 2, 64), - Profit: strconv.FormatFloat(r.Total-r.PlatformFees-fee, 'f', 2, 64), - // TODO: add NemoImmo part and compute the profit - } - }) + reportVm := &views.ReportViewModel{ + Total: strconv.FormatFloat(r.Total, 'f', 2, 64), + PlatformFees: strconv.FormatFloat(r.PlatformFees, 'f', 2, 64), + Fee: strconv.FormatFloat(r.Fee, 'f', 2, 64), + Profit: strconv.FormatFloat(r.Profit, 'f', 2, 64), + Lines: u.Map(r.Lines, func(l *booking.Line) *views.ReportLine { + return &views.ReportLine{ + Id: l.InvoiceNumber(hc), + Url: templ.SafeURL(fmt.Sprintf("%s/%d", constants.RouteBooking, l.Id)), + Total: strconv.FormatFloat(l.Total, 'f', 2, 64), + CustomerName: l.CustomerName, + From: l.From.Format("2006-01-02"), + To: l.To.Format("2006-01-02"), + 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), + } + }), + } return renderTempl(c, http.StatusOK, views.ReportSection(reportVm)) } } - -func computeFee(r *booking.Line) (f float64) { - if r.Platform == "Other" { - f = r.Total * 5 / 100 - } else { - f = r.Total * 10 / 100 - } - return f -} diff --git a/internal/views/report_section.templ b/internal/views/report_section.templ index bdf2cc9..c1546db 100644 --- a/internal/views/report_section.templ +++ b/internal/views/report_section.templ @@ -1,6 +1,14 @@ package views type ReportViewModel struct { + Total string + PlatformFees string + Fee string + Profit string + Lines []*ReportLine +} + +type ReportLine struct { Id string Url templ.SafeURL Total string @@ -13,7 +21,7 @@ type ReportViewModel struct { Profit string } -templ ReportSection(report []*ReportViewModel) { +templ ReportSection(report *ReportViewModel) {

Your report

@@ -36,7 +44,7 @@ templ ReportSection(report []*ReportViewModel) { - for _, row := range report { + for _, row := range report.Lines { @@ -54,6 +62,19 @@ templ ReportSection(report []*ReportViewModel) { } + + + + + + + { report.Total } + + { report.PlatformFees } + { report.Fee } + { report.Profit } + +
} diff --git a/internal/views/report_section_templ.go b/internal/views/report_section_templ.go index 22241aa..0766f98 100644 --- a/internal/views/report_section_templ.go +++ b/internal/views/report_section_templ.go @@ -11,6 +11,14 @@ import "io" import "bytes" type ReportViewModel struct { + Total string + PlatformFees string + Fee string + Profit string + Lines []*ReportLine +} + +type ReportLine struct { Id string Url templ.SafeURL Total string @@ -23,7 +31,7 @@ type ReportViewModel struct { Profit string } -func ReportSection(report []*ReportViewModel) templ.Component { +func ReportSection(report *ReportViewModel) templ.Component { return templ.ComponentFunc(func(ctx context.Context, templ_7745c5c3_W io.Writer) (templ_7745c5c3_Err error) { templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templ_7745c5c3_W.(*bytes.Buffer) if !templ_7745c5c3_IsBuffer { @@ -40,7 +48,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - for _, row := range report { + for _, row := range report.Lines { templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 2) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err @@ -57,7 +65,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { var templ_7745c5c3_Var3 string templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(row.Id) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 42, Col: 16} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 50, Col: 16} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) if templ_7745c5c3_Err != nil { @@ -70,7 +78,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { var templ_7745c5c3_Var4 string templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(row.CustomerName) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 45, Col: 28} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 53, Col: 28} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) if templ_7745c5c3_Err != nil { @@ -83,7 +91,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { var templ_7745c5c3_Var5 string templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(row.From) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 46, Col: 20} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 54, Col: 20} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) if templ_7745c5c3_Err != nil { @@ -96,7 +104,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { var templ_7745c5c3_Var6 string templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(row.To) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 47, Col: 18} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 55, Col: 18} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) if templ_7745c5c3_Err != nil { @@ -109,7 +117,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { var templ_7745c5c3_Var7 string templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(row.Total) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 48, Col: 21} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 56, Col: 21} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) if templ_7745c5c3_Err != nil { @@ -122,7 +130,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { var templ_7745c5c3_Var8 string templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(row.Platform) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 49, Col: 24} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 57, Col: 24} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) if templ_7745c5c3_Err != nil { @@ -135,7 +143,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { var templ_7745c5c3_Var9 string templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(row.PlatformFees) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 50, Col: 28} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 58, Col: 28} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) if templ_7745c5c3_Err != nil { @@ -148,7 +156,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { var templ_7745c5c3_Var10 string templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(row.Fee) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 51, Col: 19} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 59, Col: 19} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) if templ_7745c5c3_Err != nil { @@ -161,7 +169,7 @@ func ReportSection(report []*ReportViewModel) templ.Component { var templ_7745c5c3_Var11 string templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(row.Profit) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 52, Col: 22} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 60, Col: 22} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) if templ_7745c5c3_Err != nil { @@ -176,6 +184,58 @@ func ReportSection(report []*ReportViewModel) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(report.Total) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 70, Col: 23} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 14) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(report.PlatformFees) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 72, Col: 30} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 15) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var14 string + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(report.Fee) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 73, Col: 21} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 16) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var15 string + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(report.Profit) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/views/report_section.templ`, Line: 74, Col: 24} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.WriteWatchModeString(templ_7745c5c3_Buffer, 17) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } if !templ_7745c5c3_IsBuffer { _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteTo(templ_7745c5c3_W) }