123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // package order -- сущность заказа бронирвоания
- package order
- import (
- "encoding/json"
- "fmt"
- "strings"
- "time"
- "adt/pkg/alias"
- )
- // Order -- сущность заказа бронирования
- type Order struct {
- Id_ alias.OrderId `json:"id"` // Номер заказа
- HotelId_ alias.HotelId `json:"hotel_id"` // ID отеля
- RoomID_ alias.RoomId `json:"room_id"` // ID номера в указанном отеле
- UserEmail_ alias.Email `json:"email"` // Email пользователя
- From_ time.Time `json:"from"` // Дата заезда
- To_ time.Time `json:"to"` // Дата выезда включительно
- LstDay_ []alias.Date `json:"lst_day"` // Список дней бронирования
- }
- // Unmarshall -- десерилаизует структуру Order из json
- func Unmarshall(binData []byte) (*Order, error) {
- sf := &Order{}
- err := json.Unmarshal(binData, sf)
- if err != nil {
- return nil, fmt.Errorf("order.Unmarshall(): in json.Unmarshal, err=\n\t%w", err)
- }
- if sf.HotelId_ == "" {
- return nil, fmt.Errorf("order.Unmarshall(): hotel_id is empty")
- }
- if sf.RoomID_ == "" {
- return nil, fmt.Errorf("order.Unmarshall(): room_id is empty")
- }
- if sf.UserEmail_ == "" {
- return nil, fmt.Errorf("order.Unmarshall(): email is empty")
- }
- if sf.From_ == (time.Time{}) {
- return nil, fmt.Errorf("order.Unmarshall(): from is empty")
- }
- { // Проверка email
- if !strings.Contains(string(sf.UserEmail_), "@") {
- return nil, fmt.Errorf("order.Unmarshall(): email(%q) not have @", sf.UserEmail_)
- }
- if !strings.Contains(string(sf.UserEmail_), ".") {
- return nil, fmt.Errorf("order.Unmarshall(): email(%q) not have .", sf.UserEmail_)
- }
- }
- if sf.To_ == (time.Time{}) {
- return nil, fmt.Errorf("order.Unmarshall(): to is empty")
- }
- if err := sf.daysBetween(); err != nil {
- return nil, fmt.Errorf("order.Unmarshall(): in calc daysBetween, err=\n\t%w", err)
- }
- sf.Id_ = alias.OrderId(fmt.Sprintf("%v.%v.%v.%v", sf.HotelId_, sf.RoomID_, sf.From(), sf.To()))
- return sf, nil
- }
- // Marshall -- сериализует структуру Order
- func (sf *Order) Marshall() []byte {
- binData, _ := json.Marshal(sf)
- return binData
- }
- // Room -- возвращает ID номера в отеле
- func (sf *Order) Room() alias.RoomId {
- return sf.RoomID_
- }
- // Hotel -- возвращает ID отеля
- func (sf *Order) Hotel() alias.HotelId {
- return sf.HotelId_
- }
- // Id -- возвращает номер заказа
- func (sf *Order) Id() alias.OrderId {
- return sf.Id_
- }
- func (sf *Order) daysBetween() error {
- if sf.From_.After(sf.To_) {
- return fmt.Errorf("Order.daysBetween(): from > to")
- }
- sf.LstDay_ = make([]alias.Date, 0)
- cleanTo := cleanDay(sf.To_)
- cleanNext := cleanDay(sf.From_)
- for { // Перебор дней на добавление
- cleanFrom := cleanDay(cleanNext)
- if cleanFrom.After(cleanTo) {
- break
- }
- dateOrder := alias.Date(cleanNext.UTC().Format("2006-01-02"))
- sf.LstDay_ = append(sf.LstDay_, dateOrder)
- if len(sf.LstDay_) > 60 {
- return fmt.Errorf("Order.daysBetween(): lst_day > 60")
- }
- cleanNext = cleanNext.AddDate(0, 0, 1)
- }
- if len(sf.LstDay_) == 0 {
- return fmt.Errorf("Order.daysBetween(): lst_day is empty")
- }
- return nil
- }
- // Округялет дату до дня, FIXME: дата заезда и выезда в 12:00
- func cleanDay(timestamp time.Time) time.Time {
- return time.Date(timestamp.Year(),
- timestamp.Month(),
- timestamp.Day(),
- 0, 0, 0, 0,
- time.UTC)
- }
- // listDay -- возвращает список дней бронирования
- func (sf *Order) ListDay() []alias.Date {
- return sf.LstDay_
- }
- // To -- возвращает дату окончания бронирования (включительно)
- func (sf *Order) To() alias.Date {
- return alias.Date(sf.To_.UTC().Format("2006-01-02"))
- }
- // From -- возвращает дату начала бронирования
- func (sf *Order) From() alias.Date {
- return alias.Date(sf.From_.UTC().Format("2006-01-02"))
- }
|