mirror of
https://github.com/rjNemo/rentease.git
synced 2026-06-12 05:36:49 +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.
75 lines
1.8 KiB
Go
75 lines
1.8 KiB
Go
package booking
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"strings"
|
|
|
|
stripeclient "github.com/rjNemo/rentease/internal/driver/stripe"
|
|
)
|
|
|
|
// ErrBookingNotFound indicates that a booking could not be retrieved from the datastore.
|
|
var ErrBookingNotFound = errors.New("booking not found")
|
|
|
|
// ErrNoOutstandingBalance indicates that the booking has already been fully paid.
|
|
var ErrNoOutstandingBalance = errors.New("booking has no outstanding balance")
|
|
|
|
// CreateStripePaymentLink generates a Stripe payment link for the outstanding balance of a booking.
|
|
func (bs Service) CreateStripePaymentLink(ctx context.Context, bookingID int) (string, error) {
|
|
if bs.stripe == nil {
|
|
return "", ErrStripeClientNotConfigured
|
|
}
|
|
|
|
b := bs.store.Get(bookingID)
|
|
if b == nil || b.ID == 0 {
|
|
return "", ErrBookingNotFound
|
|
}
|
|
|
|
outstanding := calculateOutstandingBalance(b)
|
|
if outstanding <= 0 {
|
|
return "", ErrNoOutstandingBalance
|
|
}
|
|
|
|
description := fmt.Sprintf("Payment for booking %d", b.ID)
|
|
if name := strings.TrimSpace(b.Name); name != "" {
|
|
description = fmt.Sprintf("Payment for %s", name)
|
|
}
|
|
|
|
url, err := bs.stripe.CreatePaymentLink(ctx, stripeclient.CreatePaymentLinkParams{
|
|
Amount: outstanding,
|
|
Currency: "eur",
|
|
BookingID: uint(b.ID),
|
|
Description: description,
|
|
PaymentMethodTypes: []string{"card", "sepa_debit"},
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return url, nil
|
|
}
|
|
|
|
func calculateOutstandingBalance(b *Booking) float64 {
|
|
if b == nil {
|
|
return 0
|
|
}
|
|
|
|
var total float64
|
|
for _, item := range b.Items {
|
|
total += item.Price * float64(item.Quantity)
|
|
}
|
|
|
|
var paid float64
|
|
for _, payment := range b.Payments {
|
|
paid += payment.Amount
|
|
}
|
|
|
|
outstanding := total - paid
|
|
outstanding = math.Round(outstanding*100) / 100
|
|
if outstanding < 0 {
|
|
return 0
|
|
}
|
|
return outstanding
|
|
}
|