update report template (#43)

This commit is contained in:
Ruidy 2025-02-22 12:28:56 +01:00 committed by GitHub
parent b0198f7f9a
commit 44cf04bac7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 210 additions and 92 deletions

View file

@ -1,68 +1,118 @@
<!DOCTYPE html>
<html lang="en">
<html lang="fr">
<head>
<link rel="stylesheet" href="main.css">
<style>
body {
font-family: Arial, sans-serif;
background-color: #f9f9f9;
color: #333;
margin: 0;
padding: 20px;
}
.header {
background-color: #007b8f;
color: white;
padding: 20px;
text-align: center;
font-size: 24px;
font-weight: bold;
}
.report-summary {
display: flex;
justify-content: space-between;
margin-top: 20px;
padding: 15px;
background-color: #eef7f9;
border-radius: 5px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.summary-item {
font-size: 18px;
font-weight: bold;
}
.bookings-table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
background-color: white;
}
.bookings-table th, .bookings-table td {
border: 1px solid #ddd;
padding: 10px;
text-align: left;
}
.bookings-table th {
background-color: #007b8f;
color: white;
}
.total-row {
font-weight: bold;
background-color: #eef7f9;
}
</style>
</head>
<body>
<h1>Bilan réservations</h1>
<h2>{{month}} {{ year }}</h2>
<div class="overflow-auto">
<table class="items-table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Nom</th>
<th scope="col">Du</th>
<th scope="col">Au</th>
<th scope="col">Revenue (€)</th>
<th scope="col">Platforme</th>
<th scope="col">Commission (€)</th>
<th scope="col">NemoImmo (€)</th>
<th scope="col">Profit (€)</th>
</tr>
</thead>
<tbody>
{% for row in lines %}
<tr>
<th scope="row"> {{ row.Id }} </th>
<td>{{ row.CustomerName }}</td>
<td>{{ row.From }}</td>
<td>{{ row.To }}</td>
<td>{{ row.Total }}</td>
<td>{{ row.Platform }}</td>
<td>{{ row.PlatformFees }}</td>
<td>{{ row.Fee }}</td>
<td>{{ row.Profit }}</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td scope="row">Totaux</td>
<td></td>
<td></td>
<td></td>
<td>{{ total }}</td>
<td></td>
<td>{{ platformFees }}</td>
<td>{{ fee }}</td>
<td>{{ profit }}</td>
</tr>
<tr>
<td scope="row"></td>
<td></td>
<td></td>
<td>dont CB :</td>
<td>{{ cardTotal }}</td>
<td>Frais Booking :</td>
<td>{{ bookingFees }}</td>
<td></td>
<td></td>
</tr>
</tfoot>
</table>
</div>
<div class="header">
Rapport Mensuel - {{ .Month }} {{ .Year }}
</div>
<div class="report-summary">
<div class="summary-item">Revenu total : {{ .Total }} €</div>
<div class="summary-item">dont paiements par Carte Bancaire : {{ .CardTotal }} €</div>
<div class="summary-item">Frais Booking.com : {{ .BookingFees }} €</div>
<div class="summary-item">Frais NemoImmo : {{ .Fee }} €</div>
<div class="summary-item">Bénéfice : {{ .Profit }} €</div>
</div>
<table class="bookings-table">
<thead>
<tr>
<th>N° Facture</th>
<th>Nom Client</th>
<th>Du</th>
<th>Au</th>
<th>Revenu (€)</th>
<th>Plateforme</th>
<th>Frais Plateforme (€)</th>
<th>Frais NemoImmo (€)</th>
<th>Bénéfice (€)</th>
</tr>
</thead>
<tbody>
{{ range .Lines }}
<tr>
<td>{{ .InvoiceNumber }}</td>
<td>{{ .CustomerName }}</td>
<td>{{ .From }}</td>
<td>{{ .To }}</td>
<td>{{ .Total }}</td>
<td>{{ .Platform }}</td>
<td>{{ .PlatformFees }}</td>
<td>{{ .Fee }}</td>
<td>{{ .Profit }}</td>
</tr>
{{ end }}
</tbody>
<tfoot>
<tr class="total-row">
<td colspan="4">Totaux</td>
<td>{{ .Total }}</td>
<td></td>
<td>{{ .PlatformFees }}</td>
<td>{{ .Fee }}</td>
<td>{{ .Profit }}</td>
</tr>
</tfoot>
</table>
</body>
</html>

View file

@ -1,6 +1,8 @@
package constant
var Months = []string{
type Month string
var Months = []Month{
"January",
"February",
"March",
@ -14,3 +16,20 @@ var Months = []string{
"November",
"December",
}
func (m Month) ToFrench() string {
return map[Month]string{
"January": "Janvier",
"February": "Février",
"March": "Mars",
"April": "Avril",
"May": "Mai",
"June": "Juin",
"July": "Juillet",
"August": "Août",
"September": "Septembre",
"October": "Octobre",
"November": "Novembre",
"December": "Décembre",
}[m]
}

View file

@ -3,6 +3,7 @@ package pdf
import (
"bytes"
"fmt"
"log"
"os"
"text/template"
@ -36,6 +37,23 @@ func (pc *HtmlPdfClient) BuildInvoice(data booking.Invoice) (string, error) {
return outputPath, nil
}
func (pc *HtmlPdfClient) BuildReport(context map[string]any, period string, month int, year int) error {
panic("unimplemented")
func (pc *HtmlPdfClient) BuildReport(report booking.ReportData, period string, month int, year int) (string, error) {
tmpl, err := template.ParseFS(assets.Static, "assets/html/report.html")
if err != nil {
return "", fmt.Errorf("error parsing template: %v", err)
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, report); err != nil {
log.Printf("err: %+v\n", err)
return "", fmt.Errorf("error executing template: %v", err)
}
outputPath := fmt.Sprintf("report-%s-%d-%d.html", period, month, year)
if err := os.WriteFile(outputPath, buf.Bytes(), 0644); err != nil {
log.Printf("err: %+v\n", err)
return "", fmt.Errorf("error writing HTML file: %v", err)
}
return outputPath, nil
}

View file

@ -62,11 +62,11 @@ func handlePdfCreateReport(bs *booking.Service) echo.HandlerFunc {
}
report := bs.Report(period, month, year)
err = bs.BuildReport(report, period, month, year)
filePath,err := bs.BuildReport(report, period, month, year)
if err != nil {
return err
}
return c.Attachment("tmp.pdf", fmt.Sprintf("VF-%02d-report.pdf", month))
return c.File(filePath)
}
}

View file

@ -29,7 +29,9 @@ func handleReportsPage() echo.HandlerFunc {
if err != nil {
yearStr = time.Now().Format("2006")
}
return renderTempl(c, http.StatusOK, view.Reports(constant.Months, month, yearStr))
return renderTempl(c, http.StatusOK, view.Reports(u.Map(constant.Months, func(m constant.Month) string {
return string(m)
}), month, yearStr))
}
}

View file

@ -6,8 +6,13 @@ import (
"time"
u "github.com/rjNemo/underscore"
"github.com/rjNemo/rentease/internal/config"
"github.com/rjNemo/rentease/internal/constant"
)
var hc = config.NewHost()
type Report struct {
Lines []*Line
Total float64
@ -18,27 +23,51 @@ type Report struct {
BookingFees float64
}
func (r Report) Serialize(month, year int) map[string]any {
return map[string]any{
"month": month,
"year": year,
"total": strconv.FormatFloat(r.Total, 'f', 2, 64),
"platform_fees": strconv.FormatFloat(r.PlatformFees, 'f', 2, 64),
"fee": strconv.FormatFloat(r.Fee, 'f', 2, 64),
"profit": strconv.FormatFloat(r.Profit, 'f', 2, 64),
"card_total": strconv.FormatFloat(r.CardTotal, 'f', 2, 64),
"booking_fees": strconv.FormatFloat(r.BookingFees, 'f', 2, 64),
"lines": u.Map(r.Lines, func(l *Line) map[string]any {
return map[string]any{
"id": l.Id,
"name": l.CustomerName,
"from": l.From.Format("02/01/2006"),
"to": l.To.Format("02/01/2006"),
"total": strconv.FormatFloat(l.Total, 'f', 2, 64),
"platform": l.Platform,
"platform_fees": strconv.FormatFloat(l.PlatformFees, 'f', 2, 64),
"fee": strconv.FormatFloat(l.Fee(), 'f', 2, 64),
"profit": strconv.FormatFloat(l.Profit(), 'f', 2, 64),
type ReportData struct {
Month string
Year int
Total string
PlatformFees string
Fee string
Profit string
CardTotal string
BookingFees string
Lines []ReportLine
}
type ReportLine struct {
InvoiceNumber string
CustomerName string
From string
To string
Total string
Platform string
PlatformFees string
Fee string
Profit string
}
func (r Report) Data(month, year int) ReportData {
return ReportData{
Month: constant.Months[month-1].ToFrench(),
Year: year,
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),
CardTotal: strconv.FormatFloat(r.CardTotal, 'f', 2, 64),
BookingFees: strconv.FormatFloat(r.BookingFees, 'f', 2, 64),
Lines: u.Map(r.Lines, func(l *Line) ReportLine {
return ReportLine{
InvoiceNumber: l.InvoiceNumber(hc),
CustomerName: l.CustomerName,
From: l.From.Format("02/01/2006"),
To: l.To.Format("02/01/2006"),
Total: strconv.FormatFloat(l.Total, 'f', 2, 64),
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),
}
}),
}
@ -82,6 +111,6 @@ func (bs Service) Report(period string, month, year int) *Report {
}
}
func (bs Service) BuildReport(report *Report, period string, month, year int) error {
return bs.pdf.BuildReport(report.Serialize(month, year), period, month, year)
func (bs Service) BuildReport(report *Report, period string, month, year int) (string, error) {
return bs.pdf.BuildReport(report.Data(month, year), period, month, year)
}

View file

@ -31,7 +31,7 @@ type Store interface {
type PdfClient interface {
BuildInvoice(invoice Invoice) (string, error)
BuildReport(context map[string]any, period string, month, year int) error
BuildReport(report ReportData, period string, month, year int) (string, error)
}
type CalendarClient interface {