Advertisement
shakasu

Untitled

Feb 14th, 2025 (edited)
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 3.73 KB | None | 0 0
  1. // Ниже реализован сервис бронирования номеров в отеле. В предметной области
  2. // выделены два понятия: Order — заказ, который включает в себя даты бронирования
  3. // и контакты пользователя, и RoomAvailability — количество свободных номеров на
  4. // конкретный день.
  5. //
  6. // Задание:
  7. // - провести рефакторинг кода с выделением слоев и абстракций
  8. // - применить best-practices там где это имеет смысл
  9. // - исправить имеющиеся в реализации логические и технические ошибки и неточности
  10. package main
  11.  
  12. import (
  13.     "encoding/json"
  14.     "errors"
  15.     "fmt"
  16.     "log"
  17.     "net/http"
  18.     "os"
  19.     "time"
  20. )
  21.  
  22. type Order struct {
  23.     HotelID   string    `json:"hotel_id"`
  24.     RoomID    string    `json:"room_id"`
  25.     UserEmail string    `json:"email"`
  26.     From      time.Time `json:"from"`
  27.     To        time.Time `json:"to"`
  28. }
  29.  
  30. var Orders = []Order{}
  31.  
  32. type RoomAvailability struct {
  33.     HotelID string    `json:"hotel_id"`
  34.     RoomID  string    `json:"room_id"`
  35.     Date    time.Time `json:"date"`
  36.     Quota   int       `json:"quota"`
  37. }
  38.  
  39. var Availability = []RoomAvailability{
  40.     {"reddison", "lux", date(2024, 1, 1), 1},
  41.     {"reddison", "lux", date(2024, 1, 2), 1},
  42.     {"reddison", "lux", date(2024, 1, 3), 1},
  43.     {"reddison", "lux", date(2024, 1, 4), 1},
  44.     {"reddison", "lux", date(2024, 1, 5), 0},
  45. }
  46.  
  47. func main() {
  48.     mux := http.NewServeMux()
  49.     mux.HandleFunc("/orders", createOrder)
  50.  
  51.     LogInfo("Server listening on localhost:8080")
  52.     err := http.ListenAndServe(":8080", mux)
  53.     if errors.Is(err, http.ErrServerClosed) {
  54.         LogInfo("Server closed")
  55.     } else if err != nil {
  56.         LogErrorf("Server failed: %s", err)
  57.         os.Exit(1)
  58.     }
  59. }
  60.  
  61. func createOrder(w http.ResponseWriter, r *http.Request) {
  62.     var newOrder Order
  63.     json.NewDecoder(r.Body).Decode(&newOrder)
  64.  
  65.     daysToBook := daysBetween(newOrder.From, newOrder.To)
  66.  
  67.     unavailableDays := make(map[time.Time]struct{})
  68.     for _, day := range daysToBook {
  69.         unavailableDays[day] = struct{}{}
  70.     }
  71.  
  72.     for _, dayToBook := range daysToBook {
  73.         for i, availability := range Availability {
  74.             if !availability.Date.Equal(dayToBook) || availability.Quota < 1 {
  75.                 continue
  76.             }
  77.             availability.Quota -= 1
  78.             Availability[i] = availability
  79.             delete(unavailableDays, dayToBook)
  80.         }
  81.     }
  82.  
  83.     if len(unavailableDays) != 0 {
  84.         http.Error(w, "Hotel room is not available for selected dates", http.StatusInternalServerError)
  85.         LogErrorf("Hotel room is not available for selected dates:\n%v\n%v", newOrder, unavailableDays)
  86.         return
  87.     }
  88.  
  89.     Orders = append(Orders, newOrder)
  90.  
  91.     w.Header().Set("Content-Type", "application/json")
  92.     w.WriteHeader(http.StatusCreated)
  93.     json.NewEncoder(w).Encode(newOrder)
  94.  
  95.     LogInfo("Order successfully created: %v", newOrder)
  96. }
  97.  
  98. func daysBetween(from time.Time, to time.Time) []time.Time {
  99.     if from.After(to) {
  100.         return nil
  101.     }
  102.  
  103.     days := make([]time.Time, 0)
  104.     for d := toDay(from); !d.After(toDay(to)); d = d.AddDate(0, 0, 1) {
  105.         days = append(days, d)
  106.     }
  107.  
  108.     return days
  109. }
  110.  
  111. func toDay(timestamp time.Time) time.Time {
  112.     return time.Date(timestamp.Year(), timestamp.Month(), timestamp.Day(), 0, 0, 0, 0, time.UTC)
  113. }
  114.  
  115. func date(year, month, day int) time.Time {
  116.     return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
  117. }
  118.  
  119. var logger = log.Default()
  120.  
  121. func LogErrorf(format string, v ...any) {
  122.     msg := fmt.Sprintf(format, v...)
  123.     logger.Printf("[Error]: %s\n", msg)
  124. }
  125.  
  126. func LogInfo(format string, v ...any) {
  127.     msg := fmt.Sprintf(format, v...)
  128.     logger.Printf("[Info]: %s\n", msg)
  129. }
  130.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement