mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-06 02:36:49 +00:00
feat: get and update payment line
This commit is contained in:
parent
e5ad26c8e3
commit
68c6f27763
11 changed files with 292 additions and 11 deletions
|
|
@ -143,3 +143,22 @@ func (ps *PgStore) CreatePayment(p *booking.Payment) (*booking.Payment, error) {
|
|||
}
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (ps *PgStore) GetPayment(id int) (*booking.Payment, error) {
|
||||
p := &booking.Payment{}
|
||||
err := ps.db.First(p, id).Error
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (ps *PgStore) UpdatePayment(id int, amount float64, paymentMethod string) (*booking.Payment, error) {
|
||||
p := new(booking.Payment)
|
||||
err := ps.db.Model(p).
|
||||
Clauses(clause.Returning{}).
|
||||
Where("id = ?", id).
|
||||
Updates(map[string]any{
|
||||
"amount": amount,
|
||||
"payment_method": paymentMethod,
|
||||
}).
|
||||
Error
|
||||
return p, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,8 +150,8 @@ func handleBookingPage(bs *booking.Service, hc *config.Host) echo.HandlerFunc {
|
|||
ItemUrl: fmt.Sprintf("%s/%d", constant.RouteItem, i.Id),
|
||||
}
|
||||
}),
|
||||
Payments: u.Map(b.Payments, func(p booking.Payment) view.Payment {
|
||||
return view.Payment{
|
||||
Payments: u.Map(b.Payments, func(p booking.Payment) view.PaymentViewModel {
|
||||
return view.PaymentViewModel{
|
||||
Amount: strconv.FormatFloat(p.Amount, 'f', 2, 64),
|
||||
PaymentMethod: p.PaymentMethod,
|
||||
PaymentUrl: fmt.Sprintf("%s/%d", constant.RoutePayment, p.ID),
|
||||
|
|
@ -360,6 +360,29 @@ func handleItemUpdate(bs *booking.Service) echo.HandlerFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func handlePaymentUpdate(bs *booking.Service) echo.HandlerFunc {
|
||||
type updatePayment struct {
|
||||
Id int `param:"id"`
|
||||
Amount float64 `form:"amount"`
|
||||
PaymentMethod string `form:"paymentMethod"`
|
||||
}
|
||||
return func(c echo.Context) error {
|
||||
up := new(updatePayment)
|
||||
|
||||
if err := c.Bind(up); err != nil {
|
||||
return fmt.Errorf("could not parse update payment request body: %w", err)
|
||||
}
|
||||
|
||||
p := bs.UpdatePayment(up.Id, up.Amount, up.PaymentMethod)
|
||||
|
||||
return renderTempl(c, http.StatusOK, view.PaymentLine(&view.PaymentViewModel{
|
||||
Amount: strconv.FormatFloat(p.Amount, 'f', 2, 64),
|
||||
PaymentMethod: p.PaymentMethod,
|
||||
PaymentUrl: fmt.Sprintf("%s/%d", constant.RoutePayment, p.ID),
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
func handleBookingCancel(bs *booking.Service) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@ func handleCreatePayment(bs *booking.Service) echo.HandlerFunc {
|
|||
ItemUrl: fmt.Sprintf("%s/%d", constant.RouteItem, i.Id),
|
||||
}
|
||||
}),
|
||||
Payments: u.Map(nb.Payments, func(p booking.Payment) view.Payment {
|
||||
return view.Payment{
|
||||
Payments: u.Map(nb.Payments, func(p booking.Payment) view.PaymentViewModel {
|
||||
return view.PaymentViewModel{
|
||||
Amount: strconv.FormatFloat(p.Amount, 'f', 2, 64),
|
||||
PaymentMethod: p.PaymentMethod,
|
||||
PaymentUrl: fmt.Sprintf("%s/%d", constant.RoutePayment, p.ID),
|
||||
|
|
@ -61,8 +61,20 @@ func handleCreatePayment(bs *booking.Service) echo.HandlerFunc {
|
|||
}
|
||||
}
|
||||
|
||||
type Payment struct {
|
||||
BookingID int
|
||||
Amount float64
|
||||
PaymentMethod string
|
||||
func handlePaymentForm(bs *booking.Service) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
idStr := c.Param("id")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p := bs.OnePayment(id)
|
||||
form := view.PaymentForm(&view.PaymentViewModel{
|
||||
Amount: strconv.FormatFloat(p.Amount, 'f', 2, 64),
|
||||
PaymentMethod: p.PaymentMethod,
|
||||
PaymentUrl: fmt.Sprintf("%s/%d", constant.RoutePayment, p.ID),
|
||||
})
|
||||
return renderTempl(c, http.StatusOK, form)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,4 +41,6 @@ func (s Server) MountHandlers() {
|
|||
private.GET("/reports/pdf", handlePdfCreateReport(s.bs))
|
||||
|
||||
private.POST("/payments/:id", handleCreatePayment(s.bs))
|
||||
private.PUT("/payments/:id", handlePaymentUpdate(s.bs))
|
||||
private.GET("/payments/:id", handlePaymentForm(s.bs))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,6 +76,16 @@ func (m *MockStore) CreatePayment(p *Payment) (*Payment, error) {
|
|||
return args.Get(0).(*Payment), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockStore) GetPayment(id int) (*Payment, error) {
|
||||
args := m.Called(id)
|
||||
return args.Get(0).(*Payment), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *MockStore) UpdatePayment(id int, amount float64, paymentMethod string) (*Payment, error) {
|
||||
args := m.Called(id, amount, paymentMethod)
|
||||
return args.Get(0).(*Payment), args.Error(1)
|
||||
}
|
||||
|
||||
// MockParserClient is a mock implementation of the parser.Client interface
|
||||
type MockParserClient struct {
|
||||
mock.Mock
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
package booking
|
||||
|
||||
import "gorm.io/gorm"
|
||||
import (
|
||||
"log"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type Payment struct {
|
||||
gorm.Model
|
||||
|
|
@ -9,3 +13,11 @@ type Payment struct {
|
|||
Amount float64
|
||||
PaymentMethod string
|
||||
}
|
||||
|
||||
func (bs Service) OnePayment(id int) *Payment {
|
||||
p, err := bs.store.GetPayment(id)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ type Store interface {
|
|||
|
||||
// Payment methods
|
||||
CreatePayment(p *Payment) (*Payment, error)
|
||||
GetPayment(id int) (*Payment, error)
|
||||
UpdatePayment(id int, amount float64, paymentMethod string) (*Payment, error)
|
||||
}
|
||||
|
||||
type PdfClient interface {
|
||||
|
|
@ -114,3 +116,11 @@ func (bs Service) CreatePayment(bid int, amount float64, paymentMethod string) (
|
|||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func (bs Service) UpdatePayment(id int, amount float64, paymentMethod string) *Payment {
|
||||
p, err := bs.store.UpdatePayment(id, amount, paymentMethod)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ type BookingViewModel struct {
|
|||
Total string
|
||||
}
|
||||
|
||||
type Payment struct {
|
||||
type PaymentViewModel struct {
|
||||
Amount string
|
||||
PaymentMethod string
|
||||
PaymentUrl string
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@ package view
|
|||
|
||||
type ItemListViewModel struct {
|
||||
Items []ItemViewModel
|
||||
Payments []Payment
|
||||
Payments []PaymentViewModel
|
||||
}
|
||||
|
|
|
|||
46
internal/view/payment.templ
Normal file
46
internal/view/payment.templ
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
package view
|
||||
|
||||
templ PaymentLine(payment *PaymentViewModel) {
|
||||
<tr class="hover">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>- { payment.Amount }</td>
|
||||
<td>{ payment.PaymentMethod }</td>
|
||||
<td></td>
|
||||
<td class="flex gap-2">
|
||||
<button class="btn btn-sm btn-outline" hx-get={ payment.PaymentUrl } hx-target="closest tr" hx-swap="outerHTML">Edit</button>
|
||||
</td>
|
||||
</tr>
|
||||
}
|
||||
|
||||
templ PaymentForm(payment *PaymentViewModel) {
|
||||
<tr class="hover">
|
||||
<form hx-put={ payment.PaymentUrl } id="edit-payment" hx-target="closest tr" hx-swap="outerHTML">
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td>
|
||||
<input
|
||||
class="input input-bordered input-sm w-full"
|
||||
type="number"
|
||||
inputmode="decimal"
|
||||
step="0.01"
|
||||
value={ payment.Amount }
|
||||
name="amount"
|
||||
form="edit-payment"
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
class="input input-bordered input-sm w-full"
|
||||
value={ payment.PaymentMethod }
|
||||
name="paymentMethod"
|
||||
form="edit-payment"
|
||||
/>
|
||||
</td>
|
||||
<td></td>
|
||||
<td>
|
||||
<button class="btn btn-sm btn-primary" type="submit" form="edit-payment">Save</button>
|
||||
</td>
|
||||
</form>
|
||||
</tr>
|
||||
}
|
||||
147
internal/view/payment_templ.go
Normal file
147
internal/view/payment_templ.go
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.819
|
||||
package view
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
func PaymentLine(payment *PaymentViewModel) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<tr class=\"hover\"><td></td><td></td><td>- ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 string
|
||||
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(payment.Amount)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 7, Col: 24}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "</td><td>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(payment.PaymentMethod)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 8, Col: 29}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</td><td></td><td class=\"flex gap-2\"><button class=\"btn btn-sm btn-outline\" hx-get=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(payment.PaymentUrl)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 11, Col: 69}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\" hx-target=\"closest tr\" hx-swap=\"outerHTML\">Edit</button></td></tr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func PaymentForm(payment *PaymentViewModel) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var5 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var5 == nil {
|
||||
templ_7745c5c3_Var5 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<tr class=\"hover\"><form hx-put=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(payment.PaymentUrl)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 18, Col: 35}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" id=\"edit-payment\" hx-target=\"closest tr\" hx-swap=\"outerHTML\"><td></td><td></td><td><input class=\"input input-bordered input-sm w-full\" type=\"number\" inputmode=\"decimal\" step=\"0.01\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(payment.Amount)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 27, Col: 27}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\" name=\"amount\" form=\"edit-payment\"></td><td><input class=\"input input-bordered input-sm w-full\" value=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(payment.PaymentMethod)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/view/payment.templ`, Line: 35, Col: 34}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\" name=\"paymentMethod\" form=\"edit-payment\"></td><td></td><td><button class=\"btn btn-sm btn-primary\" type=\"submit\" form=\"edit-payment\">Save</button></td></form></tr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
||||
Loading…
Reference in a new issue