hardlink/cms/cms.go

121 lines
2.7 KiB
Go

// 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
}