sync calendar on item creation

This commit is contained in:
Ruidy 2024-08-16 19:58:49 +02:00
parent 6a15d1b32a
commit 3983de237f
No known key found for this signature in database
GPG key ID: E00F51288CB857CC
5 changed files with 86 additions and 42 deletions

View file

@ -1,6 +1,9 @@
package config
import "os"
type Host struct {
Items map[string]HostItem
Name string
Address string
City string
@ -10,13 +13,18 @@ type Host struct {
InvoicePrefix string
PaymentMethods []string
Platforms []string
Items []HostItem
CustomerSeed int
}
type HostItem struct {
Name string
CalendarId string
// Price is the daily price in EUR
Price float64
// If true, the item will be added to the calendar
MustSyncCalendar bool
HasEndDate bool
// If true, a tax item will be added to the invoice
Taxable bool // TODO: create taxes auto if taxable item
}
func NewHost() *Host {
@ -29,31 +37,34 @@ func NewHost() *Host {
Email: "location.villafleurie@gmail.com",
CustomerSeed: 239,
InvoicePrefix: "VFNI",
PaymentMethods: []string{"Card", "Cash", "Cheque", "Transfer"},
Platforms: []string{"Booking", "AirBnb", "TripAdvisor", "Other"},
Items: []HostItem{
{
Name: "T2",
Price: 59.0,
PaymentMethods: []string{"Card", "Cash", "Cheque", "Transfer"}, // TODO: add to DB
Platforms: []string{"Booking", "AirBnb", "TripAdvisor", "Other"}, // TODO: add to DB
Items: map[string]HostItem{ // TODO: move to DB
"T2": {
Price: 59.0,
CalendarId: os.Getenv("CALENDAR_ID_T2"),
MustSyncCalendar: true,
HasEndDate: true,
Taxable: true,
},
{
Name: "T3",
Price: 80.0,
"T3": {
Price: 80.0,
CalendarId: os.Getenv("CALENDAR_ID_T3"),
MustSyncCalendar: true,
HasEndDate: true,
Taxable: true,
},
{
Name: "Airport",
"Airport": {
Price: 25.0,
},
{
Name: "Port",
"Port": {
Price: 20.0,
},
{
Name: "Transport",
"Transport": {
Price: 20.0,
},
{
Name: "Taxes",
"Taxes": { // TODO: remove after auto creation enabled
Price: 1.5,
},
},

View file

@ -37,7 +37,7 @@ func (bs Service) All() []*Line {
return bookings
}
func (bs Service) Create(From time.Time, To time.Time, Name string, PhoneNumber string, Email string, Platform string,
func (bs Service) Create(From time.Time, To time.Time, Name, PhoneNumber, Email, Platform string,
CustomerNumber int, PlatformFees float64, externalId *string,
) *Booking {
b := &Booking{

View file

@ -52,14 +52,21 @@ func NewService(ctx context.Context, credJson string, opts ...Option) (*Service,
return &Service{Service: srv}, nil
}
func (s *Service) Create(from, to time.Time) (*calendar.Event, error) {
l := s.CalendarList.List()
r, e := l.Do()
log.Println(e)
for _, c := range r.Items {
log.Printf("%+v: %s", c.Summary, c.Id)
}
return nil, nil
func (s *Service) Create(calendarId, name, description string, from, to time.Time) error {
ne, err := s.Events.Insert(calendarId, &calendar.Event{
Description: name,
End: &calendar.EventDateTime{
Date: to.Format(time.DateOnly),
},
Start: &calendar.EventDateTime{
Date: from.Format(time.DateOnly),
},
Summary: description,
}).Do()
log.Println(err)
log.Printf("%+v: %s", ne.Summary, ne.Id)
return err
}
func (s *Service) List(from, to time.Time) (*calendar.Events, error) { return nil, nil }

View file

@ -2,6 +2,7 @@ package server
import (
"context"
"errors"
"fmt"
"io"
"net/http"
@ -16,6 +17,7 @@ import (
"github.com/rjNemo/rentease/config"
"github.com/rjNemo/rentease/constant"
"github.com/rjNemo/rentease/internal/booking"
"github.com/rjNemo/rentease/internal/calendar"
"github.com/rjNemo/rentease/internal/view"
myTime "github.com/rjNemo/rentease/pkg/time"
)
@ -77,7 +79,6 @@ func handleBookingCreate(bs *booking.Service) echo.HandlerFunc {
nb.ExternalId = nil
}
b := bs.Create(nb.From, nb.To, nb.Name, nb.PhoneNumber, nb.Email, nb.Platform, nb.CustomerNumber, nb.PlatformFees, nb.ExternalId)
// sync the calendar
return c.Redirect(http.StatusSeeOther, fmt.Sprintf("%s/%d", constant.RouteBooking, b.Id))
}
}
@ -212,7 +213,14 @@ func handleLineItemForm(bs *booking.Service) echo.HandlerFunc {
}
}
func handleCreateItem(bs *booking.Service) echo.HandlerFunc {
func handleCreateItem(bs *booking.Service, cs *calendar.Service, hc *config.Host) echo.HandlerFunc {
type NewItem struct {
Item string `form:"item"`
PaymentMethod string `form:"method"`
Quantity int `form:"quantity"`
Price float64 `form:"price"`
}
return func(c echo.Context) error {
bookingIdStr := c.Param("id")
bid, err := strconv.Atoi(bookingIdStr)
@ -220,18 +228,31 @@ func handleCreateItem(bs *booking.Service) echo.HandlerFunc {
return err
}
type NewItem struct {
Item string `form:"item"`
PaymentMethod string `form:"method"`
Quantity int `form:"quantity"`
Price float64 `form:"price"`
}
b := bs.One(bid)
ni := new(NewItem)
if err := c.Bind(ni); err != nil {
log.Warn(err)
return err
}
i := bs.CreateItem(bid, ni.Item, ni.Quantity, ni.Price, ni.PaymentMethod)
itm, ok := hc.Items[ni.Item]
if !ok {
return errors.New(fmt.Sprintf("invalid item name %q", ni.Item))
}
i := bs.CreateItem(b.Id, ni.Item, ni.Quantity, ni.Price, ni.PaymentMethod)
if err = cs.Create(
itm.CalendarId,
b.Name,
fmt.Sprintf("Reservation: %s\n %d voyageur(s)\n", b.Name, b.CustomerNumber),
b.From, b.To,
); err != nil {
log.Printf("could not create event %w", err)
captureError(c, err)
}
return renderTempl(c, http.StatusCreated, view.LineItem(&view.ItemViewModel{
Id: strconv.Itoa(i.Id),
Item: i.Item,

View file

@ -80,11 +80,8 @@ func NewRouter(fs embed.FS, debug bool, secret string, origins []string) *echo.E
e.HideBanner = !debug
e.Debug = debug
e.HTTPErrorHandler = func(err error, c echo.Context) {
if hub := sentryecho.GetHubFromContext(c); hub != nil {
hub.WithScope(func(s *sentry.Scope) {
hub.CaptureMessage(err.Error())
})
}
captureError(c, err)
code := http.StatusInternalServerError
var he *echo.HTTPError
if errors.As(err, &he) {
@ -111,3 +108,11 @@ func NewRouter(fs embed.FS, debug bool, secret string, origins []string) *echo.E
return e
}
func captureError(c echo.Context, err error) {
if hub := sentryecho.GetHubFromContext(c); hub != nil {
hub.WithScope(func(s *sentry.Scope) {
hub.CaptureMessage(err.Error())
})
}
}