introduce booking store

This commit is contained in:
Ruidy 2024-09-08 22:51:50 +02:00
parent aa5dd17d07
commit 79873249d6
No known key found for this signature in database
GPG key ID: E00F51288CB857CC
2 changed files with 197 additions and 81 deletions

View file

@ -11,46 +11,27 @@ import (
u "github.com/rjNemo/underscore" u "github.com/rjNemo/underscore"
"gorm.io/gorm" "gorm.io/gorm"
"gorm.io/gorm/clause"
"github.com/rjNemo/rentease/internal/config" "github.com/rjNemo/rentease/internal/config"
) )
type Service struct { type Service struct {
db *gorm.DB store *PgStore
} }
func NewService(db *gorm.DB) (*Service, error) { func NewService(db *gorm.DB) (*Service, error) {
return &Service{db: db}, nil return &Service{store: NewPgStore(db)}, nil
} }
func (bs Service) All() []*Line { func (bs Service) All() []*Line {
bookings := make([]*Line, 0) return bs.store.All()
bs.db.Raw(`
select bookings.id, customer_name, "from", "to", platform, sum(price * quantity) as total, canceled
from bookings
left join items on bookings.id = items.booking_id
group by bookings.id
order by id desc;
`).
Scan(&bookings)
return bookings
} }
func (bs Service) Search(value string) []*Line { func (bs Service) Search(value string) []*Line {
bookings := make([]*Line, 0) return bs.store.Search(value)
bs.db.Raw(`
select bookings.id, customer_name, "from", "to", platform, sum(price * quantity) as total, canceled
from bookings
left join items on bookings.id = items.booking_id
where customer_name ilike ?
group by bookings.id
order by id desc;
`, fmt.Sprintf("%%%s%%", value)).
Scan(&bookings)
return bookings
} }
// TODO: return the error
func (bs Service) Create(From time.Time, To time.Time, Name, PhoneNumber, Email, Platform string, func (bs Service) Create(From time.Time, To time.Time, Name, PhoneNumber, Email, Platform string,
CustomerNumber int, PlatformFees float64, externalId *string, CustomerNumber int, PlatformFees float64, externalId *string,
) *Booking { ) *Booking {
@ -65,7 +46,7 @@ func (bs Service) Create(From time.Time, To time.Time, Name, PhoneNumber, Email,
PlatformFees: PlatformFees, PlatformFees: PlatformFees,
ExternalId: externalId, ExternalId: externalId,
} }
err := bs.db.Create(b) err := bs.store.Create(b)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
} }
@ -73,11 +54,10 @@ func (bs Service) Create(From time.Time, To time.Time, Name, PhoneNumber, Email,
} }
func (bs Service) One(id int) *Booking { func (bs Service) One(id int) *Booking {
b := &Booking{Id: id} return bs.store.Get(id)
bs.db.Preload("Items").First(b)
return b
} }
// TODO: return the error
func (bs Service) Update(id int, From time.Time, To time.Time, Name string, PhoneNumber string, Email string, Platform string, 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, CustomerNumber int, PlatformFees float64, externalId *string,
) *Booking { ) *Booking {
@ -93,7 +73,9 @@ func (bs Service) Update(id int, From time.Time, To time.Time, Name string, Phon
PlatformFees: PlatformFees, PlatformFees: PlatformFees,
ExternalId: externalId, ExternalId: externalId,
} }
bs.db.Save(b) if err := bs.store.Update(b); err != nil {
log.Println(err)
}
return b return b
} }
@ -105,7 +87,9 @@ func (bs Service) CreateItem(bookingId int, item config.HostItem, quantity int,
Price: price, Price: price,
PaymentMethod: paymentMethod, PaymentMethod: paymentMethod,
} }
_ = bs.db.Create(i) if err := bs.store.CreateItem(i); err != nil {
log.Println(err)
}
items = append(items, i) items = append(items, i)
if item.Taxes != 0.0 { if item.Taxes != 0.0 {
@ -116,7 +100,9 @@ func (bs Service) CreateItem(bookingId int, item config.HostItem, quantity int,
Price: item.Taxes, Price: item.Taxes,
PaymentMethod: "Cash", PaymentMethod: "Cash",
} }
_ = bs.db.Create(ti) if err := bs.store.CreateItem(ti); err != nil {
log.Println(err)
}
items = append(items, ti) items = append(items, ti)
} }
@ -124,26 +110,26 @@ func (bs Service) CreateItem(bookingId int, item config.HostItem, quantity int,
} }
func (bs Service) PayItem(id int) *Item { func (bs Service) PayItem(id int) *Item {
i := new(Item) i, err := bs.store.PayItem(id)
bs.db.Model(i).Clauses(clause.Returning{}).Where("id = ?", id).Update("payment_status", "Completed") if err != nil {
log.Println(err)
}
return i return i
} }
func (bs Service) OneItem(id int) *Item { func (bs Service) OneItem(id int) *Item {
i := &Item{Id: id} i, err := bs.store.GetItem(id)
bs.db.First(i) if err != nil {
log.Println(err)
}
return i return i
} }
func (bs Service) UpdateItem(id int, item string, qty int, price float64, paymentMethod, paymentStatus string) *Item { func (bs Service) UpdateItem(id int, item string, qty int, price float64, paymentMethod, paymentStatus string) *Item {
i := new(Item) i, err := bs.store.UpdateItem(id, item, paymentMethod, paymentStatus, qty, price)
bs.db.Model(i).Clauses(clause.Returning{}).Where("id = ?", id).Updates(map[string]any{ if err != nil {
"item": item, log.Println(err)
"payment_method": paymentMethod, }
"payment_status": paymentStatus,
"quantity": qty,
"price": price,
})
return i return i
} }
@ -184,7 +170,6 @@ func (l Line) Profit() float64 {
} }
func (bs Service) BuildReport(period string, month, year int) *Report { func (bs Service) BuildReport(period string, month, year int) *Report {
lines := make([]*Line, 0)
var startDate time.Time var startDate time.Time
var endDate time.Time var endDate time.Time
@ -196,29 +181,15 @@ func (bs Service) BuildReport(period string, month, year int) *Report {
endDate = time.Date(year, time.December, 31, 0, 0, 0, 0, time.UTC) endDate = time.Date(year, time.December, 31, 0, 0, 0, 0, time.UTC)
} }
bs.db.Raw(` lines, err := bs.store.List(startDate, endDate)
select bookings.id, customer_name, "from", "to", platform, sum(price * quantity) as total, platform_fees if err != nil {
from bookings log.Println(err)
join items on bookings.id = items.booking_id }
where "to" between ? and ?
group by bookings.id
order by bookings.id;
`,
startDate.Format(time.DateOnly), endDate.Format(time.DateOnly)).
Scan(&lines)
cardTotal := 0.0 cardTotal, err := bs.store.CardTotal(startDate, endDate)
bs.db.Raw(` if err != nil {
select sum(total) log.Println(err)
from (select sum(price * quantity) as total }
from bookings
join items on bookings.id = items.booking_id
where "to" between ? and ?
and payment_method = 'Card'
group by booking_id) as t;
`,
startDate.Format("2006-01-02"), endDate.Format("2006-01-02")).
Scan(&cardTotal)
return &Report{ return &Report{
Total: u.Reduce(lines, func(l *Line, sum float64) float64 { return sum + l.Total }, 0.0), Total: u.Reduce(lines, func(l *Line, sum float64) float64 { return sum + l.Total }, 0.0),
@ -236,23 +207,25 @@ func (bs Service) BuildReport(period string, month, year int) *Report {
} }
} }
func (bs Service) CreateRequest(From time.Time, To time.Time, Name string, PhoneNumber string, Email string, Item string, CustomerNumber int) *BookingRequest { // func (bs Service) CreateRequest(From time.Time, To time.Time, Name string, PhoneNumber string, Email string, Item string, CustomerNumber int) *BookingRequest {
b := &BookingRequest{ // b := &BookingRequest{
CustomerName: Name, // CustomerName: Name,
PhoneNumber: &PhoneNumber, // PhoneNumber: &PhoneNumber,
CustomerNumber: CustomerNumber, // CustomerNumber: CustomerNumber,
Email: &Email, // Email: &Email,
From: From, // From: From,
To: To, // To: To,
ItemType: Item, // ItemType: Item,
} // }
_ = bs.db.Create(b) // _ = bs.db.Create(b)
return b // return b
} // }
func (bs Service) Cancel(id int) { func (bs Service) Cancel(id int) {
b := &Booking{Id: id} err := bs.store.Cancel(id)
bs.db.Model(&b).Update("canceled", true) if err != nil {
log.Println(err)
}
} }
func (bs Service) ParseFromApi(rawContent string) (*Booking, error) { func (bs Service) ParseFromApi(rawContent string) (*Booking, error) {

143
internal/booking/store.go Normal file
View file

@ -0,0 +1,143 @@
package booking
import (
"fmt"
"time"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
type PgStore struct {
db *gorm.DB
}
func NewPgStore(db *gorm.DB) *PgStore {
return &PgStore{db}
}
func (ps *PgStore) All() []*Line {
bookings := make([]*Line, 0)
ps.db.Raw(`
select bookings.id, customer_name, "from", "to", platform, sum(price * quantity) as total, canceled
from bookings
left join items on bookings.id = items.booking_id
group by bookings.id
order by id desc;
`).
Scan(&bookings)
return bookings
}
func (ps *PgStore) Search(value string) []*Line {
bookings := make([]*Line, 0)
ps.db.Raw(`
select bookings.id, customer_name, "from", "to", platform, sum(price * quantity) as total, canceled
from bookings
left join items on bookings.id = items.booking_id
where customer_name ilike ?
group by bookings.id
order by id desc;
`, fmt.Sprintf("%%%s%%", value)).
Scan(&bookings)
return bookings
}
func (ps *PgStore) List(from, to time.Time) ([]*Line, error) {
bookings := make([]*Line, 0)
if err := ps.db.Raw(`
select bookings.id, customer_name, "from", "to", platform, sum(price * quantity) as total, platform_fees
from bookings
join items on bookings.id = items.booking_id
where "to" between ? and ?
group by bookings.id
order by bookings.id;
`,
from.Format(time.DateOnly), to.Format(time.DateOnly)).
Scan(&bookings).
Error; err != nil {
return nil, err
}
return bookings, nil
}
func (ps *PgStore) CardTotal(from, to time.Time) (float64, error) {
cardTotal := 0.0
if err := ps.db.Raw(`
select sum(total)
from (select sum(price * quantity) as total
from bookings
join items on bookings.id = items.booking_id
where "to" between ? and ?
and payment_method = 'Card'
group by booking_id) as t;
`,
from.Format(time.DateOnly), to.Format(time.DateOnly)).
Scan(&cardTotal).
Error; err != nil {
return 0.0, err
}
return cardTotal, nil
}
func (ps *PgStore) Get(id int) *Booking {
b := &Booking{Id: id}
ps.db.Preload("Items").First(b)
return b
}
func (ps *PgStore) Create(b *Booking) error {
return ps.db.Create(b).Error
}
func (ps *PgStore) Update(b *Booking) error {
return ps.db.Save(b).Error
}
func (ps *PgStore) Cancel(id int) error {
b := &Booking{Id: id}
return ps.db.Model(&b).
Update("canceled", true).
Error
}
// items
func (ps *PgStore) CreateItem(i *Item) error {
return ps.db.Create(i).Error
}
func (ps *PgStore) PayItem(id int) (*Item, error) {
i := new(Item)
if err := ps.db.Model(i).
Clauses(clause.Returning{}).
Where("id = ?", id).
Update("payment_status", "Completed").
Error; err != nil {
return nil, err
}
return i, nil
}
func (ps *PgStore) GetItem(id int) (*Item, error) {
i := &Item{Id: id}
err := ps.db.First(i).Error
return i, err
}
func (ps *PgStore) UpdateItem(id int, item string, paymentMethod string, paymentStatus string, qty int, price float64) (*Item, error) {
i := new(Item)
err := ps.db.Model(i).
Clauses(clause.Returning{}).
Where("id = ?", id).
Updates(map[string]any{
"item": item,
"payment_method": paymentMethod,
"payment_status": paymentStatus,
"quantity": qty,
"price": price,
}).
Error
return i, err
}