mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-11 21:26:50 +00:00
Some checks are pending
CI / checks (push) Waiting to run
Introduce backend and frontend support for generating Stripe payment links for outstanding booking balances. Adds a new POST endpoint to create payment links, updates booking view to include a Stripe button, and integrates error handling and feedback for payment link creation. Refactors view models and templates to support the new feature.
122 lines
3.4 KiB
Go
122 lines
3.4 KiB
Go
package booking
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"github.com/rjNemo/rentease/internal/config"
|
|
stripeclient "github.com/rjNemo/rentease/internal/driver/stripe"
|
|
)
|
|
|
|
type Store interface {
|
|
All() []*Line
|
|
Search(value string) []*Line
|
|
List(from, to time.Time) ([]*Line, error)
|
|
CardTotal(from, to time.Time) (float64, error)
|
|
Get(id int) *Booking
|
|
Create(b *Booking) error
|
|
Update(b *Booking) error
|
|
Cancel(id int) error
|
|
|
|
// Item methods
|
|
CreateItem(i *Item) error
|
|
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)
|
|
GetPayment(id int) (*Payment, error)
|
|
UpdatePayment(id int, amount float64, paymentMethod string) (*Payment, error)
|
|
UpsertStripePayment(p *Payment) (*Payment, error)
|
|
FindStripePayment(stripePaymentID string) (*Payment, error)
|
|
}
|
|
|
|
type StripeClient interface {
|
|
ListPayments(ctx context.Context, params stripeclient.ListPaymentsParams) ([]stripeclient.Payment, error)
|
|
CreatePaymentLink(ctx context.Context, params stripeclient.CreatePaymentLinkParams) (string, error)
|
|
}
|
|
|
|
type PdfClient interface {
|
|
BuildInvoice(invoice Invoice) (string, error)
|
|
BuildReport(report ReportData, period string, month, year int) (string, error)
|
|
}
|
|
|
|
type CalendarClient interface {
|
|
Create(calendarID, name, description string, from, to time.Time) error
|
|
}
|
|
|
|
type parserClient interface {
|
|
Parse(rawContent string) (*Booking, error)
|
|
}
|
|
|
|
type Service struct {
|
|
store Store
|
|
parser parserClient
|
|
pdf PdfClient
|
|
logger *slog.Logger
|
|
stripe StripeClient
|
|
}
|
|
|
|
func NewService(logger *slog.Logger, store Store, parser parserClient, pdf PdfClient, stripe StripeClient) (*Service, error) {
|
|
svcLogger := logger
|
|
if svcLogger == nil {
|
|
svcLogger = slog.Default()
|
|
}
|
|
|
|
return &Service{
|
|
logger: svcLogger.With(slog.String("component", "booking_service")),
|
|
store: store,
|
|
parser: parser,
|
|
pdf: pdf,
|
|
stripe: stripe,
|
|
}, nil
|
|
}
|
|
|
|
func (bs Service) All() []*Line {
|
|
bs.logger.Info("fetching all bookings")
|
|
return bs.store.All()
|
|
}
|
|
|
|
func (bs Service) Search(value string) []*Line {
|
|
return bs.store.Search(value)
|
|
}
|
|
|
|
func (bs Service) Create(From time.Time, To time.Time, Name, PhoneNumber, Email, Platform string,
|
|
CustomerNumber int, PlatformFees float64, externalID *string,
|
|
) *Booking {
|
|
// TODO: return the error
|
|
b := NewBooking(From, To, Name, PhoneNumber, Email, Platform, CustomerNumber, PlatformFees, externalID)
|
|
err := bs.store.Create(b)
|
|
if err != nil {
|
|
bs.logger.Info("failed to create booking", slog.Any("err", err))
|
|
}
|
|
return b
|
|
}
|
|
|
|
func (bs Service) One(id int) *Booking {
|
|
return bs.store.Get(id)
|
|
}
|
|
|
|
// Update updates an existing booking with new data
|
|
func (bs Service) Update(id int, From time.Time, To time.Time, Name string, PhoneNumber string, Email string, Platform string,
|
|
CustomerNumber int, PlatformFees float64, externalID *string,
|
|
) *Booking {
|
|
b := NewBooking(From, To, Name, PhoneNumber, Email, Platform, CustomerNumber, PlatformFees, externalID).WithID(id)
|
|
if err := bs.store.Update(b); err != nil {
|
|
bs.logger.Info("failed to create booking", slog.Any("err", err))
|
|
}
|
|
return b
|
|
}
|
|
|
|
func (bs Service) Cancel(id int) {
|
|
err := bs.store.Cancel(id)
|
|
if err != nil {
|
|
bs.logger.Info("failed to create booking", slog.Any("err", err))
|
|
}
|
|
}
|
|
|
|
func (bs Service) BuildInvoice(b *Booking, hc *config.Host) (string, error) {
|
|
return bs.pdf.BuildInvoice(b.ToInvoice(hc))
|
|
}
|