// Package cms provides functions to read hotel records from the CMS and retrieve their reservation system configuration. package cms import ( "bytes" "encoding/json" "errors" "fmt" "io" "net/http" "strings" "time" "gitea.futuresens.co.uk/futuresens/cmstypes" ) // ReadHotel gets the hotel record from CMS and returns its reservation system // configuration if the record has been updated since the last read. func ReadHotel(hotelCode, CMSBaseURL string) (cmstypes.ReservationSystemRec, error) { var reservationSystem cmstypes.ReservationSystemRec if hotelCode == "" { return reservationSystem, errors.New("hotel code is empty") } if CMSBaseURL == "" { return reservationSystem, errors.New("CMS base URL is empty") } var request cmstypes.RequestRec request.Auth.ID = hotelCode request.Auth.APIKey = cmstypes.APIKey request.Auth.Hotel = hotelCode request.Data = hotelCode requestData, err := json.Marshal(request) if err != nil { return reservationSystem, fmt.Errorf( "marshal CMS hotel request: %w", err, ) } requestURL := CMSBaseURL + cmstypes.APIHotelDetails req, err := http.NewRequest(http.MethodPost, requestURL, bytes.NewReader(requestData)) if err != nil { return reservationSystem, fmt.Errorf( "create CMS hotel request: %w", err, ) } req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "application/json") client := &http.Client{ Timeout: 15 * time.Second, } resp, err := client.Do(req) if err != nil { return reservationSystem, fmt.Errorf( "perform CMS hotel request: %w", err, ) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return reservationSystem, fmt.Errorf( "read CMS hotel response: %w", err, ) } if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices { return reservationSystem, fmt.Errorf( "CMS hotel request returned HTTP %s: %s", resp.Status, string(body), ) } var hotelResponse cmstypes.HotelResponseRec if err := json.Unmarshal(body, &hotelResponse); err != nil { return reservationSystem, fmt.Errorf( "unmarshal CMS hotel response: %w", err, ) } if hotelResponse.Status.Code != cmstypes.StatusSuccessCode { return reservationSystem, fmt.Errorf( "CMS hotel request failed: %s", hotelResponse.Status.Message, ) } if hotelResponse.TheHotel.Updated <= -1 { return reservationSystem, errors.New( "hotel record not updated since last read", ) } return hotelResponse.TheHotel.ReservationSystem, nil } func PaymentSystemIndex(name string) int { for i, paySystemName := range cmstypes.PaySystemNames { if strings.EqualFold(paySystemName, name) { return i } } return -1 }