mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-06 02:36:49 +00:00
Moves all payment-related logic (manual payments, Stripe sync, webhook handling) from the booking service into a dedicated payment service (`internal/service/payment`). Updates server, cron, and handler wiring to inject and use the new payment service. Adjusts tests, routes, and documentation to reflect the new separation of concerns. This improves cohesion, clarifies responsibilities, and prepares for future payment features. No database schema changes are introduced.
116 lines
2.9 KiB
Go
116 lines
2.9 KiB
Go
package booking
|
|
|
|
import (
|
|
"errors"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"github.com/rjNemo/rentease/internal/config"
|
|
)
|
|
|
|
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, error)
|
|
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)
|
|
}
|
|
|
|
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
|
|
}
|
|
|
|
func NewService(logger *slog.Logger, store Store, parser parserClient, pdf PdfClient) (*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,
|
|
}, 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, error) {
|
|
b, err := bs.store.Get(id)
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, ErrBookingNotFound
|
|
}
|
|
return nil, err
|
|
}
|
|
return b, nil
|
|
}
|
|
|
|
// 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))
|
|
}
|