@@ -2,15 +2,18 @@ package hu.kirdev.schpincer.web
2
2
3
3
import hu.kirdev.schpincer.dto.ItemEntityDto
4
4
import hu.kirdev.schpincer.dto.ManualUserDetails
5
+ import hu.kirdev.schpincer.model.ItemCategory
5
6
import hu.kirdev.schpincer.model.ItemEntity
6
7
import hu.kirdev.schpincer.model.OpeningEntity
8
+ import hu.kirdev.schpincer.model.OrderStatus
7
9
import hu.kirdev.schpincer.service.*
8
10
import io.swagger.annotations.ApiOperation
9
11
import org.slf4j.LoggerFactory
10
12
import org.springframework.beans.factory.annotation.Value
11
13
import org.springframework.http.HttpStatus
12
14
import org.springframework.http.ResponseEntity
13
15
import org.springframework.web.bind.annotation.*
16
+ import java.lang.Integer.min
14
17
import java.text.SimpleDateFormat
15
18
import java.util.concurrent.ConcurrentHashMap
16
19
import java.util.stream.Collectors
@@ -143,19 +146,19 @@ open class ApiController(
143
146
if (requestBody.id < 0 || requestBody.time < 0 || requestBody.detailsJson == " {}" )
144
147
return ResponseEntity (RESPONSE_INTERNAL_ERROR , HttpStatus .OK )
145
148
val user = request.getUserIfPresent() ? : return responseOf(" Error 403" , HttpStatus .FORBIDDEN )
146
- try {
149
+ return try {
147
150
if (requestBody.manualOrderDetails != null ) {
148
151
log.info(" {}:{} is making a manual order with details: {}, for {}" ,
149
- user.name, user.uid, requestBody.detailsJson, requestBody.manualOrderDetails?.toString() ? : " null" )
150
- return orders.makeManualOrder(user, requestBody.id, requestBody.count, requestBody.time.toLong(),
151
- requestBody.comment, requestBody.detailsJson, requestBody.manualOrderDetails!! )
152
+ user.name, user.uid, requestBody.detailsJson, requestBody.manualOrderDetails?.toString() ? : " null" )
153
+ orders.makeManualOrder(user, requestBody.id, requestBody.count, requestBody.time.toLong(),
154
+ requestBody.comment, requestBody.detailsJson, requestBody.manualOrderDetails!! )
152
155
} else {
153
- return orders.makeOrder(user, requestBody.id, requestBody.count, requestBody.time.toLong(),
154
- requestBody.comment, requestBody.detailsJson)
156
+ orders.makeOrder(user, requestBody.id, requestBody.count, requestBody.time.toLong(),
157
+ requestBody.comment, requestBody.detailsJson)
155
158
}
156
159
} catch (e: FailedOrderException ) {
157
160
log.warn(" Failed to make new order by '${request.getUserIfPresent()?.uid ? : " n/a" } ' reason: ${e.response} " )
158
- return responseOf(e.response)
161
+ responseOf(e.response)
159
162
}
160
163
}
161
164
@@ -242,22 +245,44 @@ open class ApiController(
242
245
return openings.findNextWeek()
243
246
.filter { it.circle != null }
244
247
.filter { it.orderStart <= System .currentTimeMillis() }
245
- .map { OpeningDetail (
246
- name = it.circle?.displayName ? : " n/a" ,
247
- icon = it.circle?.logoUrl?.let { url -> baseUrl + url },
248
- feeling = it.feeling ? : " " ,
249
- available = Math .max(0 , Math .min(
250
- it.timeWindows.sumOf { tw -> tw.normalItemCount },
251
- it.maxOrder - it.timeWindows.sumOf { tw -> it.maxOrderPerInterval - tw.normalItemCount
252
- })),
253
- outOf = it.maxOrder,
254
- banner = it.prUrl.let { url -> baseUrl + url },
255
- day = timeService.format(it.dateStart, " u" )?.toInt().let { daysOfTheWeek[it ? : 0 ] },
256
- comment = " ${timeService.format(it.orderEnd, " u" )?.toInt().let { daysOfTheWeek[it ? : 0 ] }} " +
257
- " ${timeService.format(it.orderEnd, " HH:mm" )} -ig rendelhető" ,
258
- circleUrl = it.circle?.alias?.let { alias -> baseUrl + " p/" + alias } ? : baseUrl + " p/" + (it.circle?.id ? : 0 ),
259
- circleColor = it.circle?.cssClassName ? : " none"
260
- ) }
248
+ .map { openingEntity ->
249
+ OpeningDetail (
250
+ name = openingEntity.circle?.displayName ? : " n/a" ,
251
+ icon = openingEntity.circle?.logoUrl?.let { url -> baseUrl + url },
252
+ feeling = openingEntity.feeling ? : " " ,
253
+ available = calculateAvailable(openingEntity),
254
+ outOf = openingEntity.maxOrder,
255
+ banner = openingEntity.prUrl.let { url -> baseUrl + url },
256
+ day = timeService.format(openingEntity.dateStart, " u" )?.toInt().let { daysOfTheWeek[it ? : 0 ] },
257
+ comment = " ${
258
+ timeService.format(openingEntity.orderEnd, " u" )?.toInt().let { daysOfTheWeek[it ? : 0 ] }
259
+ } " +
260
+ " ${timeService.format(openingEntity.orderEnd, " HH:mm" )} -ig rendelhető" ,
261
+ circleUrl = openingEntity.circle?.alias?.let { alias -> baseUrl + " p/" + alias }
262
+ ? : (baseUrl + " p/" + (openingEntity.circle?.id ? : 0 )),
263
+ circleColor = openingEntity.circle?.cssClassName ? : " none"
264
+ ) }
265
+ }
266
+
267
+ private fun calculateAvailable (openingEntity : OpeningEntity ): Int {
268
+ val orders = orders.findAllByOpening(openingEntity.id)
269
+ .filter { it.status == OrderStatus .ACCEPTED }
270
+
271
+ val maxOverall = openingEntity.maxOrder - orders.sumOf { it.count }
272
+ val available = min(maxOverall, orders.groupBy { it.orderedItem?.category ? : 0 }
273
+ .map { pair -> pair.key to pair.value.sumOf { it.count } }
274
+ .map { pair ->
275
+ when (ItemCategory .of(pair.first)) {
276
+ ItemCategory .DEFAULT -> maxOverall
277
+ ItemCategory .ALPHA -> openingEntity.maxAlpha - pair.second
278
+ ItemCategory .BETA -> openingEntity.maxBeta - pair.second
279
+ ItemCategory .GAMMA -> openingEntity.maxGamma - pair.second
280
+ ItemCategory .DELTA -> openingEntity.maxDelta - pair.second
281
+ ItemCategory .LAMBDA -> openingEntity.maxLambda - pair.second
282
+ }
283
+ }
284
+ .maxOrNull() ? : 0 )
285
+ return available
261
286
}
262
287
263
288
data class UpcomingOpeningDetail (
@@ -286,23 +311,21 @@ open class ApiController(
286
311
287
312
return openings.findNextWeek()
288
313
.filter { it.circle != null }
289
- .map { UpcomingOpeningDetail (
290
- name = it.circle?.displayName ? : " n/a" ,
291
- orderStart = it.orderStart,
292
- openingStart = it.dateStart,
293
- icon = it.circle?.logoUrl?.let { url -> baseUrl + url },
294
- feeling = it.feeling ? : " " ,
295
- available = Math .max(0 , Math .min(
296
- it.timeWindows.sumOf { tw -> tw.normalItemCount },
297
- it.maxOrder - it.timeWindows.sumOf { tw -> it.maxOrderPerInterval - tw.normalItemCount
298
- })),
299
- outOf = it.maxOrder,
300
- banner = it.prUrl.let { url -> baseUrl + url },
301
- day = timeService.format(it.dateStart, " u" )?.toInt().let { daysOfTheWeek[it ? : 0 ] },
302
- comment = " ${timeService.format(it.orderEnd, " u" )?.toInt().let { daysOfTheWeek[it ? : 0 ] }} " +
303
- " ${timeService.format(it.orderEnd, " HH:mm" )} -ig rendelhető" ,
304
- circleUrl = it.circle?.alias?.let { alias -> baseUrl + " p/" + alias } ? : baseUrl + " p/" + (it.circle?.id ? : 0 ),
305
- circleColor = it.circle?.cssClassName ? : " none"
314
+ .map { openingEntity ->
315
+ UpcomingOpeningDetail (
316
+ name = openingEntity.circle?.displayName ? : " n/a" ,
317
+ orderStart = openingEntity.orderStart,
318
+ openingStart = openingEntity.dateStart,
319
+ icon = openingEntity.circle?.logoUrl?.let { url -> baseUrl + url },
320
+ feeling = openingEntity.feeling ? : " " ,
321
+ available = calculateAvailable(openingEntity),
322
+ outOf = openingEntity.maxOrder,
323
+ banner = openingEntity.prUrl.let { url -> baseUrl + url },
324
+ day = timeService.format(openingEntity.dateStart, " u" )?.toInt().let { daysOfTheWeek[it ? : 0 ] },
325
+ comment = " ${timeService.format(openingEntity.orderEnd, " u" )?.toInt().let { daysOfTheWeek[it ? : 0 ] }} " +
326
+ " ${timeService.format(openingEntity.orderEnd, " HH:mm" )} -ig rendelhető" ,
327
+ circleUrl = openingEntity.circle?.alias?.let { alias -> baseUrl + " p/" + alias } ? : (baseUrl + " p/" + (openingEntity.circle?.id ? : 0 )),
328
+ circleColor = openingEntity.circle?.cssClassName ? : " none"
306
329
) }
307
330
}
308
331
0 commit comments