rentease/internal/service/booking/models.go

133 lines
3.5 KiB
Go

package booking
import (
"fmt"
"strconv"
"time"
u "github.com/rjNemo/underscore"
"gorm.io/gorm"
"github.com/rjNemo/rentease/internal/config"
)
type Booking struct {
From time.Time
To time.Time
gorm.Model
Name string `gorm:"column:customer_name"`
PhoneNumber string
Email string
Platform config.Platform
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)"`
Canceled bool `gorm:"default:false"`
}
// 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 {
return &Booking{
From: from,
To: to,
Name: name,
PhoneNumber: phoneNumber,
CustomerNumber: customerNumber,
Email: email,
Platform: config.Platform(platform),
PlatformFees: platformFees,
ExternalId: externalId,
}
}
func (b Booking) InvoiceNumber(hc *config.Host) string {
return fmt.Sprintf("%s%04s", hc.InvoicePrefix, strconv.Itoa(b.Id+hc.CustomerSeed))
}
func (b Booking) ToInvoice(hc *config.Host) Invoice {
total := u.Reduce(b.Items, func(i Item, sum float64) float64 {
return sum + i.Price*float64(i.Quantity)
}, 0.0)
amountPaid := u.Reduce(b.Payments, func(i Payment, sum float64) float64 {
return sum + i.Amount
}, 0.0)
return Invoice{
Host: *hc,
Name: b.Name,
PhoneNumber: b.PhoneNumber,
CustomersNumber: b.CustomerNumber,
Platform: b.Platform.ToFrench(),
ID: b.InvoiceNumber(hc),
From: b.From.Format("02/01/2006"),
To: b.To.Format("02/01/2006"),
Total: strconv.FormatFloat(total, 'f', 2, 64),
AmountPaid: strconv.FormatFloat(amountPaid, 'f', 2, 64),
BalanceDue: strconv.FormatFloat(total-amountPaid, 'f', 2, 64),
Lines: u.Map(b.Items, func(i Item) InvoiceLine {
return InvoiceLine{
Name: i.ToFrench(),
Quantity: i.Quantity,
Price: strconv.FormatFloat(i.Price, 'f', 2, 64),
Total: strconv.FormatFloat(i.Price*float64(i.Quantity), 'f', 2, 64),
}
}),
Payments: u.Map(b.Payments, func(p Payment) PaymentLine {
return PaymentLine{
Date: p.CreatedAt.Format("02/01/2006"),
Method: p.PaymentMethod.ToFrench(),
Amount: strconv.FormatFloat(p.Amount, 'f', 2, 64),
}
}),
}
}
// WithId returns a copy of the booking with the given ID
func (b *Booking) WithId(id int) *Booking {
b.Id = id
return b
}
type Item struct {
gorm.Model
Item string
PaymentMethod string
PaymentStatus string `gorm:"default:Pending"`
Id int
BookingId int
Quantity int
Price float64 `gorm:"type:decimal(10,2)"`
}
// ToFrench translates the item name to french
func (i Item) ToFrench() string {
switch i.Item {
case "T2":
return "T2"
case "T3":
return "T3"
case "Airport":
return "Transport Aéroport"
case "Port":
return "Transport Gare Maritime"
case "Transport":
return "Transport"
case "Taxes":
return "Taxes de sejour"
default:
return i.Item
}
}
type Payment struct {
gorm.Model
BookingID uint `gorm:"not null;index"`
Booking Booking `gorm:"foreignKey:BookingID;constraint:OnDelete:CASCADE"`
Amount float64
PaymentMethod config.PaymentMethod
}