@@ -66,26 +66,113 @@ public IActionResult GetAll([FromQuery]ScanFilters filters)
66
66
return Ok ( ScanRepository . GetAll ( filters ) ) ;
67
67
}
68
68
69
+ /// <summary>
70
+ /// Deletes a Check-In Scan.
71
+ /// </summary>
72
+ /// <param name="eventId">The Id of the Event.</param>
73
+ /// <param name="id">Either the Veteran Id or Card Number of the Veteran.</param>
74
+ /// <returns>See attributes.</returns>
75
+ /// <response code="204">The Scan was deleted successfully.</response>
76
+ /// <response code="400">The Veteran Id or Card Number is invalid.</response>
77
+ /// <response code="401">Unauthorized.</response>
78
+ /// <response code="404">The specified Card Number or Veteran Id doesn't match an enrolled Veteran.</response>
79
+ /// <response code="500">The server encountered an error while processing the request.</response>
80
+ [ HttpDelete ( "{eventId}/{id}" ) ]
81
+ [ Authorize ]
82
+ [ ProducesResponseType ( 400 ) ]
83
+ [ ProducesResponseType ( 401 ) ]
84
+ [ ProducesResponseType ( 404 ) ]
85
+ [ ProducesResponseType ( typeof ( Exception ) , 500 ) ]
86
+ public IActionResult Delete ( Guid eventId , string id )
87
+ {
88
+ return Delete ( eventId , id , null ) ;
89
+ }
90
+
91
+ /// <summary>
92
+ /// Deletes a Service Scan.
93
+ /// </summary>
94
+ /// <param name="eventId">The Id of the Event.</param>
95
+ /// <param name="id">Either the Veteran Id or Card Number of the Veteran.</param>
96
+ /// <param name="serviceId">The optional Service Id.</param>
97
+ /// <returns>See attributes.</returns>
98
+ /// <response code="204">The Scan was deleted successfully.</response>
99
+ /// <response code="400">The Veteran Id or Card Number is invalid.</response>
100
+ /// <response code="401">Unauthorized.</response>
101
+ /// <response code="404">The specified Card Number or Veteran Id doesn't match an enrolled Veteran.</response>
102
+ /// <response code="500">The server encountered an error while processing the request.</response>
103
+ [ HttpDelete ( "{eventId}/{id}/{serviceId}" ) ]
104
+ [ Authorize ]
105
+ [ ProducesResponseType ( 400 ) ]
106
+ [ ProducesResponseType ( 401 ) ]
107
+ [ ProducesResponseType ( 404 ) ]
108
+ [ ProducesResponseType ( typeof ( Exception ) , 500 ) ]
109
+ public IActionResult Delete ( Guid eventId , string id , Guid ? serviceId = null )
110
+ {
111
+ if ( string . IsNullOrEmpty ( id ) )
112
+ {
113
+ return BadRequest ( $ "The card or veteran ID is null or empty.") ;
114
+ }
115
+
116
+ var veteran = default ( Veteran ) ;
117
+
118
+ if ( int . TryParse ( id , out var cardNumber ) )
119
+ {
120
+ veteran = VeteranRepository
121
+ . GetAll ( new VeteranFilters ( ) { CardNumber = cardNumber } )
122
+ . SingleOrDefault ( ) ;
123
+ }
124
+ else if ( Guid . TryParse ( id , out var veteranId ) )
125
+ {
126
+ veteran = VeteranRepository . Get ( veteranId ) ;
127
+ }
128
+ else
129
+ {
130
+ return BadRequest ( $ "The provided ID is neither a Card Number nor Veteran ID.") ;
131
+ }
132
+
133
+ if ( veteran == default ( Veteran ) )
134
+ {
135
+ return StatusCode ( 404 , $ "The specified Card Number or Veteran Id doesn't match an enrolled Veteran.") ;
136
+ }
137
+
138
+ var scan = ScanRepository . Get ( eventId , veteran . Id , serviceId ) ;
139
+
140
+ if ( scan == default ( Scan ) )
141
+ {
142
+ return StatusCode ( 404 , $ "A Scan matching the specified information could not be found.") ;
143
+ }
144
+
145
+ try
146
+ {
147
+ ScanRepository . Delete ( eventId , veteran . Id , serviceId ) ;
148
+ return NoContent ( ) ;
149
+ }
150
+ catch ( Exception ex )
151
+ {
152
+ throw new Exception ( $ "Error deleting the Scan matching the specified information: { ex . Message } . See inner Exception for details.", ex ) ;
153
+ }
154
+ }
155
+
69
156
/// <summary>
70
157
/// Performs an Event Scan.
71
158
/// </summary>
72
159
/// <param name="scan">The scan context.</param>
73
160
/// <returns>See attributes.</returns>
74
- /// <response code="200">The Scan has already been recorded.</response>
75
161
/// <response code="201">The Scan was recorded or updated.</response>
76
162
/// <response code="400">The specified Scan was invalid.</response>
77
163
/// <response code="401">Unauthorized.</response>
78
164
/// <response code="403">The Veteran has not checked in for the Event.</response>
79
165
/// <response code="404">The specified Veteran, Event or Service was invalid.</response>
166
+ /// <response code="409">The Scan has already been recorded.</response>
80
167
/// <response code="500">The server encountered an error while processing the request.</response>
81
168
[ HttpPut ( "" ) ]
82
169
[ Authorize ]
83
- [ ProducesResponseType ( typeof ( Scan ) , 200 ) ]
84
170
[ ProducesResponseType ( typeof ( Scan ) , 201 ) ]
85
171
[ ProducesResponseType ( typeof ( string ) , 400 ) ]
86
172
[ ProducesResponseType ( 401 ) ]
87
173
[ ProducesResponseType ( 403 ) ]
88
174
[ ProducesResponseType ( 404 ) ]
175
+ [ ProducesResponseType ( typeof ( ScanError ) , 409 ) ]
89
176
[ ProducesResponseType ( typeof ( Exception ) , 500 ) ]
90
177
public IActionResult Scan ( [ FromBody ] ScanRequest scan )
91
178
{
@@ -94,37 +181,50 @@ public IActionResult Scan([FromBody]ScanRequest scan)
94
181
return BadRequest ( ModelState . GetReadableString ( ) ) ;
95
182
}
96
183
184
+ if ( ! int . TryParse ( scan . CardNumber , out var cardNumber ) )
185
+ {
186
+ return BadRequest ( $ "Card Number { scan . CardNumber } is not a valid integer.") ;
187
+ }
188
+
97
189
var @event = EventRepository . Get ( ( Guid ) scan . EventId ) ;
98
190
99
191
if ( @event == default ( Event ) )
100
192
{
101
193
StatusCode ( 404 , "The specified Event could not be found." ) ;
102
194
}
103
195
196
+ var service = ServiceRepository . Get ( scan . ServiceId ) ;
197
+
198
+ if ( service == default ( Service ) )
199
+ {
200
+ return StatusCode ( 404 , "The specified Service could not be found." ) ;
201
+ }
202
+
104
203
var veteran = VeteranRepository
105
- . GetAll ( new VeteranFilters ( ) { CardNumber = scan . CardNumber , IncludePhotoBase64 = true } )
204
+ . GetAll ( new VeteranFilters ( ) { CardNumber = cardNumber , IncludePhotoBase64 = true } )
106
205
. SingleOrDefault ( ) ;
107
206
108
207
if ( veteran == default ( Veteran ) )
109
208
{
110
209
return StatusCode ( 404 , $ "Card Number { scan . CardNumber } doesn't match an enrolled Veteran.") ;
111
210
}
112
211
212
+ var previousScans = ScanRepository . GetAll ( new ScanFilters ( ) { EventId = scan . EventId , VeteranId = veteran . Id } ) ;
213
+ var existingCheckIn = previousScans . Where ( s => s . ServiceId == Guid . Empty ) . SingleOrDefault ( ) ;
214
+
113
215
var scanRecord = new Scan ( )
114
216
{
115
217
EventId = ( Guid ) scan . EventId ,
116
218
VeteranId = veteran . Id ,
117
219
ServiceId = scan . ServiceId ,
118
- PlusOne = scan . PlusOne ,
119
220
ScanById = User . GetId ( ) ,
120
221
ScanDate = DateTime . UtcNow ,
121
222
} ;
122
223
123
- var previousScans = ScanRepository . GetAll ( new ScanFilters ( ) { EventId = scan . EventId , VeteranId = veteran . Id } ) ;
124
-
224
+ // check in scan
125
225
if ( scan . ServiceId == Guid . Empty )
126
226
{
127
- var existingCheckIn = previousScans . Where ( s => s . ServiceId == Guid . Empty ) . SingleOrDefault ( ) ;
227
+ scanRecord . PlusOne = scan . PlusOne ;
128
228
129
229
if ( existingCheckIn == default ( Scan ) )
130
230
{
@@ -136,27 +236,24 @@ public IActionResult Scan([FromBody]ScanRequest scan)
136
236
}
137
237
else
138
238
{
139
- return StatusCode ( 200 , new ScanResponse ( existingCheckIn , veteran ) ) ;
239
+ return Conflict ( new ScanError ( existingCheckIn , veteran , "Duplicate Scan" ) ) ;
140
240
}
141
241
}
142
242
143
- var service = ServiceRepository . Get ( scan . ServiceId ) ;
144
-
145
- if ( service == default ( Service ) )
243
+ // service scan
244
+ if ( existingCheckIn == default ( Scan ) )
146
245
{
147
- return StatusCode ( 404 , "The specified Service could not be found." ) ;
246
+ return StatusCode ( 403 , new ScanError ( scanRecord , veteran , "The Veteran has not checked in for this Event." ) ) ;
148
247
}
149
248
150
- if ( ! previousScans . Where ( s => s . ServiceId == Guid . Empty ) . Any ( ) )
151
- {
152
- return StatusCode ( 403 , "The Veteran has not checked in for this Event." ) ;
153
- }
249
+ var previousServiceScan = previousScans . Where ( s => s . ServiceId == scan . ServiceId ) . SingleOrDefault ( ) ;
154
250
155
- if ( previousScans . Where ( s => s . ServiceId == scan . ServiceId ) . Any ( ) )
251
+ if ( previousServiceScan != default ( Scan ) )
156
252
{
157
- return StatusCode ( 200 , previousScans . Where ( s => s . ServiceId == scan . ServiceId ) . SingleOrDefault ( ) ) ;
253
+ return Conflict ( new ScanError ( previousServiceScan , veteran , "Duplicate Scan" ) ) ;
158
254
}
159
255
256
+ scanRecord . PlusOne = existingCheckIn . PlusOne ;
160
257
return CreateScan ( scanRecord , veteran ) ;
161
258
}
162
259
0 commit comments