-
Notifications
You must be signed in to change notification settings - Fork 0
/
addcinemaseat.go
189 lines (154 loc) · 5.86 KB
/
addcinemaseat.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
package services
import (
"errors"
"fmt"
"net/http"
"reflect"
"github.com/Wolechacho/ticketmaster-backend/database/entities"
sequentialguid "github.com/Wolechacho/ticketmaster-backend/helpers"
"github.com/Wolechacho/ticketmaster-backend/helpers/utilities"
"github.com/samber/lo"
"gorm.io/gorm"
)
type CreateCinemaSeatRequest struct {
Id string `param:"Id"`
CinemaHallId string `param:"cinemaHallId"`
Seats []CinemaSeatModel `json:"cinemaSeats"`
}
type CreateCinemaSeatResponse struct {
StatusCode int
}
type CinemaHallDTO struct {
CinemaId string
CinemaHallId string
TotalSeat int
}
type CinemaSeatDTO struct {
CinemaHallId string
SeatNumber int
}
func (cinemaService CinemaService) AddCinemaSeat(request CreateCinemaSeatRequest) (CreateCinemaSeatResponse, []error) {
validationErrors := validateCinemSeatRequiredFields(request)
if len(validationErrors) > 0 {
return CreateCinemaSeatResponse{StatusCode: http.StatusBadRequest}, validationErrors
}
seatNumbers := []int{}
if len(request.Seats) > 1 {
for _, seat := range request.Seats {
seatNumbers = append(seatNumbers, seat.SeatNumber)
}
duplicateSeatNumbers := lo.FindDuplicates(seatNumbers)
if len(duplicateSeatNumbers) > 0 {
return CreateCinemaSeatResponse{StatusCode: http.StatusBadRequest}, []error{errors.New("seat number in the request contains duplicates")}
}
}
var err error
cinemaQuery, err := cinemaService.DB.Table("cinemas").
Where("cinemas.Id = ?", request.Id).
Where("cinemas.IsDeprecated = ?", false).
Joins("join cinemaHalls on cinemas.Id = cinemaHalls.CinemaId").
Where("cinemaHalls.Id = ?", request.CinemaHallId).
Where("cinemaHalls.IsDeprecated = ?", false).
Select("cinemas.Id AS CinemaId, cinemaHalls.Id AS CinemaHallId, cinemaHalls.TotalSeat AS TotalSeat").
Rows()
if err != nil {
return CreateCinemaSeatResponse{StatusCode: http.StatusInternalServerError}, []error{err}
}
defer cinemaQuery.Close()
var existingHalls CinemaHallDTO
i := 0
for cinemaQuery.Next() {
if i > 1 {
break
}
err = cinemaQuery.Scan(&existingHalls.CinemaId, &existingHalls.CinemaHallId, &existingHalls.TotalSeat)
if err != nil {
return CreateCinemaSeatResponse{StatusCode: http.StatusInternalServerError}, []error{err}
}
i++
}
if reflect.ValueOf(existingHalls).IsZero() {
return CreateCinemaSeatResponse{StatusCode: http.StatusBadRequest}, []error{errors.New("cinema info not found")}
}
if existingHalls.TotalSeat < len(request.Seats) {
return CreateCinemaSeatResponse{StatusCode: http.StatusBadRequest}, []error{fmt.Errorf(("total number of cinema seats in the system is less that the new seats to add"))}
}
cinemaHallQuery, err := cinemaService.DB.Table("cinemaHalls").
Where("cinemaHalls.Id = ?", existingHalls.CinemaHallId).
Where("cinemaHalls.IsDeprecated = ?", false).
Joins("join cinemaSeats on cinemaHalls.Id = cinemaSeats.CinemaHallId").
Where("cinemaSeats.IsDeprecated = ?", false).
Select("cinemaHalls.Id AS CinemaHallId, cinemaSeats.SeatNumber AS SeatNumber").
Rows()
if err != nil {
return CreateCinemaSeatResponse{StatusCode: http.StatusInternalServerError}, []error{err}
}
defer cinemaHallQuery.Close()
var existingSeats []CinemaSeatDTO
for cinemaHallQuery.Next() {
var cinemaSeatDTO CinemaSeatDTO
err = cinemaHallQuery.Scan(&cinemaSeatDTO.CinemaHallId, &cinemaSeatDTO.SeatNumber)
if err != nil {
return CreateCinemaSeatResponse{StatusCode: http.StatusInternalServerError}, []error{err}
}
existingSeats = append(existingSeats, cinemaSeatDTO)
}
if len(existingSeats)+len(request.Seats) > existingHalls.TotalSeat {
return CreateCinemaSeatResponse{StatusCode: http.StatusBadRequest}, []error{fmt.Errorf(("total number of cinema seats in the system is less that the new seats to add"))}
}
//check for duplicates
for _, exSeat := range existingSeats {
for _, seat := range request.Seats {
if exSeat.SeatNumber == seat.SeatNumber {
return CreateCinemaSeatResponse{StatusCode: http.StatusBadRequest}, []error{errors.New("seat number already exist in the system")}
}
}
}
//add new seats
err = cinemaService.DB.Transaction(func(tx *gorm.DB) error {
if len(request.Seats) > 0 {
for _, seat := range request.Seats {
cinemaSeat := entities.CinemaSeat{
Id: sequentialguid.New().String(),
SeatNumber: seat.SeatNumber,
Type: int(seat.Type),
IsDeprecated: false,
CinemaHallId: request.CinemaHallId,
}
if err = tx.Create(&cinemaSeat).Error; err != nil {
// return any error will rollback
return err
}
}
}
return nil
})
if err != nil {
return CreateCinemaSeatResponse{StatusCode: http.StatusInternalServerError}, []error{err}
}
return CreateCinemaSeatResponse{StatusCode: http.StatusOK}, nil
}
func validateCinemSeatRequiredFields(request CreateCinemaSeatRequest) []error {
validationErrors := []error{}
if len(request.Id) == 0 || len(request.Id) < 36 {
validationErrors = append(validationErrors, errors.New("cinemaId is a required field with 36 characters"))
}
if request.Id == utilities.DEFAULT_UUID {
validationErrors = append(validationErrors, errors.New("cinemaId should have a valid UUID"))
}
if len(request.CinemaHallId) == 0 || len(request.CinemaHallId) < 36 {
validationErrors = append(validationErrors, errors.New("cinemahallId is a required field with 36 characters"))
}
if request.CinemaHallId == utilities.DEFAULT_UUID {
validationErrors = append(validationErrors, errors.New("cinemahallId should have a valid UUID"))
}
for i, seat := range request.Seats {
if seat.SeatNumber <= 0 {
validationErrors = append(validationErrors, fmt.Errorf("CinemaSeat[%d].SeatNumber should not have be zero or negative number", i))
}
if seat.Type <= 0 {
validationErrors = append(validationErrors, fmt.Errorf("CinemaSeat[%d].Type should not have be zero or negative number", i))
}
}
return validationErrors
}