mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-06 02:36:49 +00:00
send data to render pdf
This commit is contained in:
parent
b42fe35831
commit
ec853f6b66
14 changed files with 62 additions and 27 deletions
|
|
@ -10,6 +10,7 @@ Manage your holiday rental
|
|||
- [x] Build the pdf invoice
|
||||
- [ ] Refactor the env variable calls to a Config struct with proper defaults
|
||||
- [x] Refactor handlers to call their dependencies instead of taking them from the Server struct
|
||||
- [ ] Embed mandatory assets, css in the executable
|
||||
|
||||
## Built With
|
||||
|
||||
|
|
|
|||
7
config/host.go
Normal file
7
config/host.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package config
|
||||
|
||||
type Host struct{}
|
||||
|
||||
func NewHost() *Host {
|
||||
return &Host{}
|
||||
}
|
||||
|
|
@ -7,26 +7,26 @@ import (
|
|||
)
|
||||
|
||||
type Booking struct {
|
||||
From time.Time
|
||||
To time.Time
|
||||
gorm.Model
|
||||
Id int
|
||||
Name string `gorm:"column:customer_name"`
|
||||
PhoneNumber string
|
||||
CustomerNumber int `gorm:"column:customers"`
|
||||
Email string
|
||||
From time.Time
|
||||
To time.Time
|
||||
Platform string
|
||||
PlatformFees float64 `gorm:"type:decimal(10,2)"`
|
||||
Items []Item
|
||||
Id int
|
||||
CustomerNumber int `gorm:"column:customers"`
|
||||
PlatformFees float64 `gorm:"type:decimal(10,2)"`
|
||||
}
|
||||
|
||||
type Item struct {
|
||||
gorm.Model
|
||||
Id int
|
||||
BookingId int
|
||||
Item string
|
||||
Quantity int
|
||||
Price float64 `gorm:"type:decimal(10,2)"`
|
||||
PaymentMethod string
|
||||
PaymentStatus string `gorm:"default:Pending"`
|
||||
Id int
|
||||
BookingId int
|
||||
Quantity int
|
||||
Price float64 `gorm:"type:decimal(10,2)"`
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,16 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/labstack/gommon/log"
|
||||
|
||||
"github.com/rjNemo/rentease/internal/booking"
|
||||
u "github.com/rjNemo/underscore"
|
||||
)
|
||||
|
||||
type PdfService struct {
|
||||
|
|
@ -27,13 +32,25 @@ func NewPdfService() *PdfService {
|
|||
}
|
||||
}
|
||||
|
||||
func (ps PdfService) BuildInvoice() error {
|
||||
func (ps PdfService) BuildInvoice(b *booking.Booking) error {
|
||||
data := struct {
|
||||
Context map[string]any `json:"context"`
|
||||
Path string `json:"path"`
|
||||
ProjectId string `json:"projectId"`
|
||||
}{
|
||||
Context: map[string]any{},
|
||||
Context: map[string]any{
|
||||
"id": fmt.Sprintf("VFNI%04s", strconv.Itoa(b.Id)),
|
||||
"name": b.Name,
|
||||
"phone_number": b.PhoneNumber,
|
||||
"custumers_number": b.CustomerNumber,
|
||||
"platform": b.Platform,
|
||||
"from": b.From.Format("Monday 02 January 2006"),
|
||||
"to": b.To.Format("Monday 02 January 2006"),
|
||||
"lines": b.Items,
|
||||
"total": strconv.FormatFloat(u.Reduce(b.Items, func(i booking.Item, sum float64) float64 {
|
||||
return sum + i.Price*float64(i.Quantity)
|
||||
}, 0.0), 'f', 2, 64),
|
||||
},
|
||||
Path: ps.invoicePath,
|
||||
ProjectId: ps.projectId,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,25 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/rjNemo/rentease/internal/booking"
|
||||
"github.com/rjNemo/rentease/internal/pdf"
|
||||
)
|
||||
|
||||
func handleCreateInvoicePdf(ps *pdf.PdfService) echo.HandlerFunc {
|
||||
func handleCreateInvoicePdf(bs *booking.Service, ps *pdf.PdfService) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
err := ps.BuildInvoice()
|
||||
idStr := c.Param("id")
|
||||
c.Logger().Info(idStr)
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := bs.One(id)
|
||||
|
||||
err = ps.BuildInvoice(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
package server
|
||||
|
||||
func (s Server) MountHandlers() {
|
||||
// landing page
|
||||
s.Router.GET("/", handleHomePage())
|
||||
s.Router.GET("/bookings", handleListBookingPage(s.bs))
|
||||
s.Router.GET("/bookings/new", handleNewBookingPage())
|
||||
s.Router.POST("/bookings/new", handleCreateBooking(s.bs))
|
||||
s.Router.GET("/bookings/:id", handleBookingPage(s.bs))
|
||||
s.Router.POST("bookings/:id/items", handleCreateItem(s.bs))
|
||||
s.Router.POST("/bookings/:id/items", handleCreateItem(s.bs))
|
||||
s.Router.GET("/bookings/pdf/:id", handleCreateInvoicePdf(s.bs, s.ps))
|
||||
s.Router.GET("/reports", handleReportsPage())
|
||||
s.Router.GET("/reports/do", handleComputeReport(s.bs))
|
||||
s.Router.GET("/pdf/:id", handleCreateInvoicePdf(s.bs, s.ps))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,21 +13,20 @@ import (
|
|||
"github.com/a-h/templ"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/rjNemo/rentease/config"
|
||||
"github.com/rjNemo/rentease/internal/booking"
|
||||
"github.com/rjNemo/rentease/internal/pdf"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Router *echo.Echo
|
||||
db *gorm.DB
|
||||
bs *booking.Service
|
||||
ps *pdf.PdfService
|
||||
addr string
|
||||
}
|
||||
|
||||
func New(bs *booking.Service, ps *pdf.PdfService) *Server {
|
||||
func New(bs *booking.Service, ps *pdf.PdfService, hc *config.Host) *Server {
|
||||
s := &Server{
|
||||
Router: NewRouter(),
|
||||
bs: bs,
|
||||
|
|
@ -91,7 +90,6 @@ func customHTTPErrorHandler(e *echo.Echo) echo.HTTPErrorHandler {
|
|||
if errors.As(err, &he) {
|
||||
code = he.Code
|
||||
}
|
||||
e.Logger.Error(err)
|
||||
|
||||
errorPage := fmt.Sprintf("assets/html/HTTP%d.html", code)
|
||||
if err := c.File(errorPage); err != nil {
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ templ BookingById(booking *BookingViewModel) {
|
|||
<section>
|
||||
<h3>Line Items </h3>
|
||||
<div class="overflow-auto">
|
||||
<table role="grid">
|
||||
<table class="striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">Item</th>
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ func BookingById(booking *BookingViewModel) templ.Component {
|
|||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></label></div></fieldset><button type=\"submit\">Update</button></form></section><section><h3>Line Items </h3><div class=\"overflow-auto\"><table role=\"grid\"><thead><tr><th scope=\"col\">Item</th><th scope=\"col\">Quantity</th><th scope=\"col\">Price (€)</th><th scope=\"col\">Payment Method</th><th scope=\"col\">Payment Status</th><th scope=\"col\">Sub-total (€)</th></tr></thead> <tbody id=\"line-items\">")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("\"></label></div></fieldset><button type=\"submit\">Update</button></form></section><section><h3>Line Items </h3><div class=\"overflow-auto\"><table class=\"striped\"><thead><tr><th scope=\"col\">Item</th><th scope=\"col\">Quantity</th><th scope=\"col\">Price (€)</th><th scope=\"col\">Payment Method</th><th scope=\"col\">Payment Status</th><th scope=\"col\">Sub-total (€)</th></tr></thead> <tbody id=\"line-items\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ templ ListBookings(bookings []*ListBookingsViewModel) {
|
|||
<h2>Overview of the activity</h2>
|
||||
</hgroup>
|
||||
<div class="overflow-auto">
|
||||
<table role="grid">
|
||||
<table class="striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ func ListBookings(bookings []*ListBookingsViewModel) templ.Component {
|
|||
templ_7745c5c3_Buffer = templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<hgroup><h1>Bookings </h1><h2>Overview of the activity</h2></hgroup><div class=\"overflow-auto\"><table role=\"grid\"><thead><tr><th scope=\"col\">ID</th><th scope=\"col\">Name</th><th scope=\"col\">Total (€)</th><th scope=\"col\">From</th><th scope=\"col\">To</th><th scope=\"col\">Platform</th></tr></thead> <tbody>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<hgroup><h1>Bookings </h1><h2>Overview of the activity</h2></hgroup><div class=\"overflow-auto\"><table class=\"striped\"><thead><tr><th scope=\"col\">ID</th><th scope=\"col\">Name</th><th scope=\"col\">Total (€)</th><th scope=\"col\">From</th><th scope=\"col\">To</th><th scope=\"col\">Platform</th></tr></thead> <tbody>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ templ ReportSection(report []*ReportViewModel) {
|
|||
</div>
|
||||
</div>
|
||||
<div class="overflow-auto">
|
||||
<table role="grid">
|
||||
<table class="striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">ID</th>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func ReportSection(report []*ReportViewModel) templ.Component {
|
|||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"grid\"><h2>Your report </h2><div><button class=\"outline\">Create PDF</button></div></div><div class=\"overflow-auto\"><table role=\"grid\"><thead><tr><th scope=\"col\">ID</th><th scope=\"col\">Name</th><th scope=\"col\">From</th><th scope=\"col\">To</th><th scope=\"col\">Total (€)</th><th scope=\"col\">Platform</th><th scope=\"col\">Platform Fees</th></tr></thead> <tbody>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<div class=\"grid\"><h2>Your report </h2><div><button class=\"outline\">Create PDF</button></div></div><div class=\"overflow-auto\"><table class=\"striped\"><thead><tr><th scope=\"col\">ID</th><th scope=\"col\">Name</th><th scope=\"col\">From</th><th scope=\"col\">To</th><th scope=\"col\">Total (€)</th><th scope=\"col\">Platform</th><th scope=\"col\">Platform Fees</th></tr></thead> <tbody>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
|
|
|||
3
main.go
3
main.go
|
|
@ -8,6 +8,7 @@ import (
|
|||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
|
||||
"github.com/rjNemo/rentease/config"
|
||||
"github.com/rjNemo/rentease/internal/booking"
|
||||
"github.com/rjNemo/rentease/internal/pdf"
|
||||
"github.com/rjNemo/rentease/internal/server"
|
||||
|
|
@ -33,5 +34,5 @@ func main() {
|
|||
log.Fatalf("error migrating the database %s\n", err)
|
||||
}
|
||||
|
||||
server.New(booking.NewService(db), pdf.NewPdfService()).Start()
|
||||
server.New(booking.NewService(db), pdf.NewPdfService(), config.NewHost()).Start()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue