/samples/booking/app/models/booking.go

http://github.com/robfig/revel · Go · 114 lines · 90 code · 18 blank · 6 comment · 10 complexity · 2ceb39d3ddc4d4787163e8e7dcc4338f MD5 · raw file

  1. package models
  2. import (
  3. "fmt"
  4. "github.com/coopernurse/gorp"
  5. "github.com/robfig/revel"
  6. "regexp"
  7. "time"
  8. )
  9. type Booking struct {
  10. BookingId int
  11. UserId int
  12. HotelId int
  13. CheckInStr string
  14. CheckOutStr string
  15. CardNumber string
  16. NameOnCard string
  17. CardExpMonth int
  18. CardExpYear int
  19. Smoking bool
  20. Beds int
  21. // Transient
  22. CheckInDate time.Time
  23. CheckOutDate time.Time
  24. User *User
  25. Hotel *Hotel
  26. }
  27. // TODO: Make an interface for Validate() and then validation can pass in the
  28. // key prefix ("booking.")
  29. func (booking Booking) Validate(v *revel.Validation) {
  30. v.Required(booking.User)
  31. v.Required(booking.Hotel)
  32. v.Required(booking.CheckInDate)
  33. v.Required(booking.CheckOutDate)
  34. v.Match(booking.CardNumber, regexp.MustCompile(`\d{16}`)).
  35. Message("Credit card number must be numeric and 16 digits")
  36. v.Check(booking.NameOnCard,
  37. revel.Required{},
  38. revel.MinSize{3},
  39. revel.MaxSize{70},
  40. )
  41. }
  42. func (b Booking) Total() int {
  43. return b.Hotel.Price * b.Nights()
  44. }
  45. func (b Booking) Nights() int {
  46. return int((b.CheckOutDate.Unix() - b.CheckInDate.Unix()) / 60 / 60 / 24)
  47. }
  48. const (
  49. DATE_FORMAT = "Jan _2, 2006"
  50. SQL_DATE_FORMAT = "2006-01-02"
  51. )
  52. func (b Booking) Description() string {
  53. if b.Hotel == nil {
  54. return ""
  55. }
  56. return fmt.Sprintf("%s, %s to %s",
  57. b.Hotel.Name,
  58. b.CheckInDate.Format(DATE_FORMAT),
  59. b.CheckOutDate.Format(DATE_FORMAT))
  60. }
  61. func (b Booking) String() string {
  62. return fmt.Sprintf("Booking(%s,%s)", b.User, b.Hotel)
  63. }
  64. // These hooks work around two things:
  65. // - Gorp's lack of support for loading relations automatically.
  66. // - Sqlite's lack of support for datetimes.
  67. func (b *Booking) PreInsert(_ gorp.SqlExecutor) error {
  68. b.UserId = b.User.UserId
  69. b.HotelId = b.Hotel.HotelId
  70. b.CheckInStr = b.CheckInDate.Format(SQL_DATE_FORMAT)
  71. b.CheckOutStr = b.CheckOutDate.Format(SQL_DATE_FORMAT)
  72. return nil
  73. }
  74. func (b *Booking) PostGet(exe gorp.SqlExecutor) error {
  75. var (
  76. obj interface{}
  77. err error
  78. )
  79. obj, err = exe.Get(User{}, b.UserId)
  80. if err != nil {
  81. return fmt.Errorf("Error loading a booking's user (%d): %s", b.UserId, err)
  82. }
  83. b.User = obj.(*User)
  84. obj, err = exe.Get(Hotel{}, b.HotelId)
  85. if err != nil {
  86. return fmt.Errorf("Error loading a booking's hotel (%d): %s", b.HotelId, err)
  87. }
  88. b.Hotel = obj.(*Hotel)
  89. if b.CheckInDate, err = time.Parse(SQL_DATE_FORMAT, b.CheckInStr); err != nil {
  90. return fmt.Errorf("Error parsing check in date '%s':", b.CheckInStr, err)
  91. }
  92. if b.CheckOutDate, err = time.Parse(SQL_DATE_FORMAT, b.CheckOutStr); err != nil {
  93. return fmt.Errorf("Error parsing check out date '%s':", b.CheckOutStr, err)
  94. }
  95. return nil
  96. }