diff --git a/internal/repository/booking/pg_store.go b/internal/repository/booking/pg_store.go index bec8417..5977d9e 100644 --- a/internal/repository/booking/pg_store.go +++ b/internal/repository/booking/pg_store.go @@ -136,3 +136,10 @@ func (ps *PgStore) UpdateItem(id int, item string, paymentMethod string, payment Error return i, err } + +func (ps *PgStore) CreatePayment(p *booking.Payment) (*booking.Payment, error) { + if err := ps.db.Create(p).Error; err != nil { + return nil, fmt.Errorf("failed to create payment: %w", err) + } + return p, nil +} diff --git a/internal/server/handle_payments.go b/internal/server/handle_payments.go index 0d6e0ca..31559d2 100644 --- a/internal/server/handle_payments.go +++ b/internal/server/handle_payments.go @@ -1,15 +1,24 @@ package server import ( - "log" + "fmt" + "net/http" "strconv" "github.com/labstack/echo/v4" + u "github.com/rjNemo/underscore" + "github.com/rjNemo/rentease/internal/constant" "github.com/rjNemo/rentease/internal/service/booking" + "github.com/rjNemo/rentease/internal/view" ) func handleCreatePayment(bs *booking.Service) echo.HandlerFunc { + type CreatePaymentInput struct { + Amount float64 `form:"amount"` + PaymentMethod string `form:"paymentMethod"` + } + return func(c echo.Context) error { idStr := c.Param("id") id, err := strconv.Atoi(idStr) @@ -17,9 +26,42 @@ func handleCreatePayment(bs *booking.Service) echo.HandlerFunc { return err } - b := bs.One(id) - log.Println(b) + np := new(CreatePaymentInput) + c.Bind(np) - return nil + b := bs.One(id) + + _, err = bs.CreatePayment(b.Id, np.Amount, np.PaymentMethod) + if err != nil { + return err + } + + nb := bs.One(id) + return renderTempl(c, http.StatusOK, view.ItemList(view.ItemListViewModel{ + Items: u.Map(nb.Items, func(i booking.Item) view.ItemViewModel { + return view.ItemViewModel{ + Id: strconv.Itoa(i.Id), + Item: i.Item, + Quantity: strconv.Itoa(i.Quantity), + Price: strconv.FormatFloat(i.Price, 'f', 2, 64), + SubTotal: strconv.FormatFloat(i.Price*float64(i.Quantity), 'f', 2, 64), + PaymentStatus: i.PaymentStatus, + ItemUrl: fmt.Sprintf("%s/%d", constant.RouteItem, i.Id), + Payments: u.Map(b.Payments, func(p booking.Payment) view.Payment { + return view.Payment{ + Amount: strconv.FormatFloat(p.Amount, 'f', 2, 64), + PaymentMethod: p.PaymentMethod, + PaymentUrl: fmt.Sprintf("%s/%d", constant.RoutePayment, p.ID), + } + }), + } + }), + })) } } + +type Payment struct { + BookingID int + Amount float64 + PaymentMethod string +} diff --git a/internal/service/booking/models.go b/internal/service/booking/models.go index 77743ca..88a68c4 100644 --- a/internal/service/booking/models.go +++ b/internal/service/booking/models.go @@ -21,6 +21,7 @@ type Booking struct { Platform string ExternalId *string `gorm:"uniqueIndex:booking_external_id"` Items []Item + Payments []Payment `gorm:"foreignKey:BookingID"` Id int CustomerNumber int `gorm:"column:customers"` PlatformFees float64 `gorm:"type:decimal(10,2)"` @@ -29,7 +30,8 @@ type Booking struct { // NewBooking creates a new booking with the given parameters func NewBooking(from, to time.Time, name, phoneNumber, email, platform string, - customerNumber int, platformFees float64, externalId *string) *Booking { + customerNumber int, platformFees float64, externalId *string, +) *Booking { return &Booking{ From: from, To: to, diff --git a/internal/service/booking/payment.go b/internal/service/booking/payment.go index 876c221..73d7728 100644 --- a/internal/service/booking/payment.go +++ b/internal/service/booking/payment.go @@ -4,7 +4,8 @@ import "gorm.io/gorm" type Payment struct { gorm.Model - BookingID int + BookingID uint `gorm:"not null;index"` + Booking Booking `gorm:"foreignKey:BookingID;constraint:OnDelete:CASCADE"` Amount float64 PaymentMethod string } diff --git a/internal/service/booking/service.go b/internal/service/booking/service.go index 3fafdc2..cb3194e 100644 --- a/internal/service/booking/service.go +++ b/internal/service/booking/service.go @@ -22,6 +22,9 @@ type Store interface { PayItem(id int) (*Item, error) GetItem(id int) (*Item, error) UpdateItem(id int, item string, paymentMethod string, paymentStatus string, qty int, price float64) (*Item, error) + + // Payment methods + CreatePayment(p *Payment) (*Payment, error) } type PdfClient interface { @@ -98,3 +101,16 @@ func (bs Service) Cancel(id int) { func (bs Service) BuildInvoice(b *Booking, hc *config.Host) error { return bs.pdf.BuildInvoice(b.Serialize(hc)) } + +func (bs Service) CreatePayment(bid int, amount float64, paymentMethod string) (*Payment, error) { + p, err := bs.store.CreatePayment(&Payment{ + BookingID: uint(bid), + Amount: amount, + PaymentMethod: paymentMethod, + }) + if err != nil { + return nil, err + } + + return p, nil +} diff --git a/main.go b/main.go index 3a0b655..dd8a59d 100644 --- a/main.go +++ b/main.go @@ -53,7 +53,7 @@ func run(c context.Context, getEnv func(string) string) error { return fmt.Errorf("error connecting to the database %w", err) } - if err = database.Migrate(db, &booking.Booking{}, &booking.BookingRequest{}, &booking.Item{}); err != nil { + if err = database.Migrate(db, &booking.Booking{}, &booking.BookingRequest{}, &booking.Item{}, &booking.Payment{}); err != nil { return fmt.Errorf("error migrating the database %w", err) }