From 79873249d6b1fd58acfbddd546a1efd71218f30b Mon Sep 17 00:00:00 2001 From: Ruidy Date: Sun, 8 Sep 2024 22:51:50 +0200 Subject: [PATCH] introduce booking store --- internal/booking/service.go | 135 ++++++++++++++-------------------- internal/booking/store.go | 143 ++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+), 81 deletions(-) create mode 100644 internal/booking/store.go diff --git a/internal/booking/service.go b/internal/booking/service.go index f4835e9..174ef29 100644 --- a/internal/booking/service.go +++ b/internal/booking/service.go @@ -11,46 +11,27 @@ import ( u "github.com/rjNemo/underscore" "gorm.io/gorm" - "gorm.io/gorm/clause" "github.com/rjNemo/rentease/internal/config" ) type Service struct { - db *gorm.DB + store *PgStore } func NewService(db *gorm.DB) (*Service, error) { - return &Service{db: db}, nil + return &Service{store: NewPgStore(db)}, nil } func (bs Service) All() []*Line { - bookings := make([]*Line, 0) - 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 + return bs.store.All() } func (bs Service) Search(value string) []*Line { - bookings := make([]*Line, 0) - 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 + return bs.store.Search(value) } +// TODO: return the error func (bs Service) Create(From time.Time, To time.Time, Name, PhoneNumber, Email, Platform string, CustomerNumber int, PlatformFees float64, externalId *string, ) *Booking { @@ -65,7 +46,7 @@ func (bs Service) Create(From time.Time, To time.Time, Name, PhoneNumber, Email, PlatformFees: PlatformFees, ExternalId: externalId, } - err := bs.db.Create(b) + err := bs.store.Create(b) if err != nil { 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 { - b := &Booking{Id: id} - bs.db.Preload("Items").First(b) - return b + return bs.store.Get(id) } +// TODO: return the error 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 { @@ -93,7 +73,9 @@ func (bs Service) Update(id int, From time.Time, To time.Time, Name string, Phon PlatformFees: PlatformFees, ExternalId: externalId, } - bs.db.Save(b) + if err := bs.store.Update(b); err != nil { + log.Println(err) + } return b } @@ -105,7 +87,9 @@ func (bs Service) CreateItem(bookingId int, item config.HostItem, quantity int, Price: price, PaymentMethod: paymentMethod, } - _ = bs.db.Create(i) + if err := bs.store.CreateItem(i); err != nil { + log.Println(err) + } items = append(items, i) if item.Taxes != 0.0 { @@ -116,7 +100,9 @@ func (bs Service) CreateItem(bookingId int, item config.HostItem, quantity int, Price: item.Taxes, PaymentMethod: "Cash", } - _ = bs.db.Create(ti) + if err := bs.store.CreateItem(ti); err != nil { + log.Println(err) + } 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 { - i := new(Item) - bs.db.Model(i).Clauses(clause.Returning{}).Where("id = ?", id).Update("payment_status", "Completed") + i, err := bs.store.PayItem(id) + if err != nil { + log.Println(err) + } return i } func (bs Service) OneItem(id int) *Item { - i := &Item{Id: id} - bs.db.First(i) + i, err := bs.store.GetItem(id) + if err != nil { + log.Println(err) + } return i } func (bs Service) UpdateItem(id int, item string, qty int, price float64, paymentMethod, paymentStatus string) *Item { - i := new(Item) - bs.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, - }) + i, err := bs.store.UpdateItem(id, item, paymentMethod, paymentStatus, qty, price) + if err != nil { + log.Println(err) + } return i } @@ -184,7 +170,6 @@ func (l Line) Profit() float64 { } func (bs Service) BuildReport(period string, month, year int) *Report { - lines := make([]*Line, 0) var startDate 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) } - bs.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; - `, - startDate.Format(time.DateOnly), endDate.Format(time.DateOnly)). - Scan(&lines) + lines, err := bs.store.List(startDate, endDate) + if err != nil { + log.Println(err) + } - cardTotal := 0.0 - bs.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; - `, - startDate.Format("2006-01-02"), endDate.Format("2006-01-02")). - Scan(&cardTotal) + cardTotal, err := bs.store.CardTotal(startDate, endDate) + if err != nil { + log.Println(err) + } return &Report{ 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 { - b := &BookingRequest{ - CustomerName: Name, - PhoneNumber: &PhoneNumber, - CustomerNumber: CustomerNumber, - Email: &Email, - From: From, - To: To, - ItemType: Item, - } - _ = bs.db.Create(b) - return b -} +// func (bs Service) CreateRequest(From time.Time, To time.Time, Name string, PhoneNumber string, Email string, Item string, CustomerNumber int) *BookingRequest { +// b := &BookingRequest{ +// CustomerName: Name, +// PhoneNumber: &PhoneNumber, +// CustomerNumber: CustomerNumber, +// Email: &Email, +// From: From, +// To: To, +// ItemType: Item, +// } +// _ = bs.db.Create(b) +// return b +// } func (bs Service) Cancel(id int) { - b := &Booking{Id: id} - bs.db.Model(&b).Update("canceled", true) + err := bs.store.Cancel(id) + if err != nil { + log.Println(err) + } } func (bs Service) ParseFromApi(rawContent string) (*Booking, error) { diff --git a/internal/booking/store.go b/internal/booking/store.go new file mode 100644 index 0000000..b2e0d1c --- /dev/null +++ b/internal/booking/store.go @@ -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 +}