1
1
package org .folio .orders .utils ;
2
2
3
- import static io .vertx .core .Future .succeededFuture ;
4
- import static java .util .stream .Collectors .toList ;
5
- import static org .apache .commons .lang3 .ObjectUtils .defaultIfNull ;
6
- import static org .apache .commons .lang3 .StringUtils .EMPTY ;
7
- import static org .apache .commons .lang3 .StringUtils .isEmpty ;
8
- import static org .folio .orders .utils .ResourcePathResolver .ALERTS ;
9
- import static org .folio .orders .utils .ResourcePathResolver .REPORTING_CODES ;
10
- import static org .folio .rest .RestConstants .EN ;
11
- import static org .folio .rest .core .exceptions .ErrorCodes .MULTIPLE_NONPACKAGE_TITLES ;
12
- import static org .folio .rest .core .exceptions .ErrorCodes .TITLE_NOT_FOUND ;
13
- import static org .folio .rest .jaxrs .model .PoLine .PaymentStatus .FULLY_PAID ;
14
- import static org .folio .rest .jaxrs .model .PoLine .PaymentStatus .PAYMENT_NOT_REQUIRED ;
15
- import static org .folio .rest .jaxrs .model .PoLine .ReceiptStatus .FULLY_RECEIVED ;
16
- import static org .folio .rest .jaxrs .model .PoLine .ReceiptStatus .RECEIPT_NOT_REQUIRED ;
17
- import static org .folio .service .exchange .ExchangeRateProviderResolver .RATE_KEY ;
18
-
19
- import java .net .URLEncoder ;
20
- import java .nio .charset .StandardCharsets ;
21
- import java .util .ArrayList ;
22
- import java .util .Collection ;
23
- import java .util .Collections ;
24
- import java .util .EnumMap ;
25
- import java .util .List ;
26
- import java .util .Map ;
27
- import java .util .Objects ;
28
- import java .util .Optional ;
29
- import java .util .concurrent .CompletionException ;
30
- import java .util .regex .Matcher ;
31
- import java .util .regex .Pattern ;
32
-
33
- import javax .money .CurrencyUnit ;
34
- import javax .money .Monetary ;
35
- import javax .money .MonetaryAmount ;
36
- import javax .money .convert .ConversionQuery ;
37
- import javax .money .convert .ConversionQueryBuilder ;
38
-
3
+ import io .vertx .core .AsyncResult ;
4
+ import io .vertx .core .CompositeFuture ;
5
+ import io .vertx .core .Future ;
6
+ import io .vertx .core .Handler ;
7
+ import io .vertx .core .eventbus .DeliveryOptions ;
8
+ import io .vertx .core .eventbus .Message ;
9
+ import io .vertx .core .json .JsonObject ;
10
+ import one .util .streamex .IntStreamEx ;
11
+ import one .util .streamex .StreamEx ;
39
12
import org .apache .commons .collections4 .CollectionUtils ;
40
13
import org .apache .commons .collections4 .map .CaseInsensitiveMap ;
41
14
import org .apache .commons .lang3 .ArrayUtils ;
65
38
import org .javamoney .moneta .function .MonetaryFunctions ;
66
39
import org .javamoney .moneta .function .MonetaryOperators ;
67
40
68
- import io .vertx .core .AsyncResult ;
69
- import io .vertx .core .CompositeFuture ;
70
- import io .vertx .core .Future ;
71
- import io .vertx .core .Handler ;
72
- import io .vertx .core .eventbus .DeliveryOptions ;
73
- import io .vertx .core .eventbus .Message ;
74
- import io .vertx .core .json .JsonObject ;
75
- import one .util .streamex .IntStreamEx ;
76
- import one .util .streamex .StreamEx ;
41
+ import javax .money .CurrencyUnit ;
42
+ import javax .money .Monetary ;
43
+ import javax .money .MonetaryAmount ;
44
+ import javax .money .convert .ConversionQuery ;
45
+ import javax .money .convert .ConversionQueryBuilder ;
46
+ import java .net .URLEncoder ;
47
+ import java .nio .charset .StandardCharsets ;
48
+ import java .util .ArrayList ;
49
+ import java .util .Collection ;
50
+ import java .util .Collections ;
51
+ import java .util .EnumMap ;
52
+ import java .util .List ;
53
+ import java .util .Map ;
54
+ import java .util .Objects ;
55
+ import java .util .Optional ;
56
+ import java .util .concurrent .CompletionException ;
57
+ import java .util .regex .Matcher ;
58
+ import java .util .regex .Pattern ;
59
+
60
+ import static io .vertx .core .Future .succeededFuture ;
61
+ import static java .util .stream .Collectors .toList ;
62
+ import static org .apache .commons .lang3 .ObjectUtils .defaultIfNull ;
63
+ import static org .apache .commons .lang3 .StringUtils .EMPTY ;
64
+ import static org .apache .commons .lang3 .StringUtils .isEmpty ;
65
+ import static org .folio .orders .utils .ResourcePathResolver .ALERTS ;
66
+ import static org .folio .orders .utils .ResourcePathResolver .REPORTING_CODES ;
67
+ import static org .folio .rest .RestConstants .EN ;
68
+ import static org .folio .rest .core .exceptions .ErrorCodes .MULTIPLE_NONPACKAGE_TITLES ;
69
+ import static org .folio .rest .core .exceptions .ErrorCodes .TITLE_NOT_FOUND ;
70
+ import static org .folio .rest .jaxrs .model .PoLine .PaymentStatus .FULLY_PAID ;
71
+ import static org .folio .rest .jaxrs .model .PoLine .PaymentStatus .PAYMENT_NOT_REQUIRED ;
72
+ import static org .folio .rest .jaxrs .model .PoLine .ReceiptStatus .FULLY_RECEIVED ;
73
+ import static org .folio .rest .jaxrs .model .PoLine .ReceiptStatus .RECEIPT_NOT_REQUIRED ;
74
+ import static org .folio .service .exchange .ExchangeRateProviderResolver .RATE_KEY ;
77
75
78
76
public class HelperUtils {
79
77
@@ -189,7 +187,7 @@ public static int calculateInventoryItemsQuantity(CompositePoLine compPOL, List<
189
187
/**
190
188
* Calculates pieces quantity for list of locations and return map where piece format is a key and corresponding quantity of pieces as value.
191
189
*
192
- * @param compPOL composite PO Line
190
+ * @param compPOL composite PO Line
193
191
* @param locations list of locations to calculate quantity for
194
192
* @return quantity of pieces per piece format either required Inventory item for PO Line
195
193
*/
@@ -231,7 +229,7 @@ public static Map<Piece.Format, Integer> calculatePiecesWithItemIdQuantity(Compo
231
229
/**
232
230
* Calculates pieces quantity for specified locations based on piece format.
233
231
*
234
- * @param format piece format
232
+ * @param format piece format
235
233
* @param locations list of locations to calculate quantity for
236
234
* @return quantity of items expected in the inventory for PO Line
237
235
*/
@@ -244,6 +242,7 @@ public static int calculatePiecesQuantity(Piece.Format format, List<Location> lo
244
242
245
243
/**
246
244
* Calculates total estimated price. See MODORDERS-180 for more details.
245
+ *
247
246
* @param cost PO Line's cost
248
247
*/
249
248
public static MonetaryAmount calculateEstimatedPrice (Cost cost ) {
@@ -318,19 +317,34 @@ public static int getElectronicLocationsQuantity(List<Location> locations) {
318
317
.sum ();
319
318
}
320
319
320
+ /**
321
+ * Almost same as collectResultsOnSuccess with addition that each future itself returns a list and
322
+ * this implementation combines all elements of all lists into the single list.
323
+ * @param futures The list of futures to be combined
324
+ * @return Single list containing all elements returned from all futures
325
+ * @param <E> element type
326
+ * @param <T> list type
327
+ */
328
+ public static <E , T extends List <E >> Future <List <E >> combineResultListsOnSuccess (Collection <Future <T >> futures ) {
329
+ return collectResultsOnSuccess (futures )
330
+ .map (lists -> lists .stream ().flatMap (List ::stream ).toList ());
331
+ }
332
+
321
333
/**
322
334
* Wait for all requests completion and collect all resulting objects. In case any failed, complete resulting future with the exception
335
+ *
323
336
* @param futures list of futures and each produces resulting object on completion
324
- * @param <T> resulting type
337
+ * @param <T> resulting type
325
338
* @return resulting objects
326
339
*/
327
- public static <T > Future <List <T >> collectResultsOnSuccess (List <Future <T >> futures ) {
340
+ public static <T > Future <List <T >> collectResultsOnSuccess (Collection <Future <T >> futures ) {
328
341
return GenericCompositeFuture .join (new ArrayList <>(futures ))
329
342
.map (CompositeFuture ::list );
330
343
}
331
344
332
345
/**
333
346
* Transform list of id's to CQL query using 'or' operation
347
+ *
334
348
* @param ids list of id's
335
349
* @return String representing CQL query to get records by id's
336
350
*/
@@ -344,8 +358,9 @@ public static String convertIdsToCqlQuery(Collection<String> ids) {
344
358
345
359
/**
346
360
* Transform list of values for some property to CQL query using 'or' operation
347
- * @param values list of field values
348
- * @param fieldName the property name to search by
361
+ *
362
+ * @param values list of field values
363
+ * @param fieldName the property name to search by
349
364
* @param strictMatch indicates whether strict match mode (i.e. ==) should be used or not (i.e. =)
350
365
* @return String representing CQL query to get records by some property values
351
366
*/
@@ -365,6 +380,7 @@ public static int getPoLineLimit(JsonObject config) {
365
380
/**
366
381
* Convert {@link JsonObject} which actually represents org.folio.rest.acq.model.PurchaseOrder to {@link CompositePurchaseOrder}
367
382
* These objects are the same except PurchaseOrder doesn't contain poLines field.
383
+ *
368
384
* @param poJson {@link JsonObject} representing org.folio.rest.acq.model.PurchaseOrder
369
385
* @return {@link CompositePurchaseOrder}
370
386
*/
@@ -450,23 +466,24 @@ public static boolean isProductIdsExist(CompositePoLine compPOL) {
450
466
}
451
467
452
468
public static Void handleErrorResponse (Handler <AsyncResult <javax .ws .rs .core .Response >> asyncResultHandler , BaseHelper helper ,
453
- Throwable t ) {
469
+ Throwable t ) {
454
470
asyncResultHandler .handle (succeededFuture (helper .buildErrorResponse (t )));
455
471
return null ;
456
472
}
457
473
458
474
/**
459
475
* Check the number of titles per po line.
476
+ *
460
477
* @param lineIdTitles Map po line id -> list of titles
461
- * @param poLineById Map po line id -> composite po line
478
+ * @param poLineById Map po line id -> composite po line
462
479
*/
463
480
public static void verifyTitles (Map <String , List <Title >> lineIdTitles , Map <String , CompositePoLine > poLineById ) {
464
481
verifyAllTitlesExist (lineIdTitles , poLineById );
465
482
verifyNonPackageLinesHaveSingleTitle (lineIdTitles , poLineById );
466
483
}
467
484
468
485
private static void verifyNonPackageLinesHaveSingleTitle (Map <String , List <Title >> titles ,
469
- Map <String , CompositePoLine > poLineById ) {
486
+ Map <String , CompositePoLine > poLineById ) {
470
487
if (titles .keySet ().stream ().anyMatch (lineId -> titles .get (lineId ).size () > 1 && !poLineById .get (lineId ).getIsPackage ())) {
471
488
throw new HttpException (400 , MULTIPLE_NONPACKAGE_TITLES );
472
489
}
@@ -508,6 +525,7 @@ public static ConversionQuery buildConversionQuery(PoLine poLine, String systemC
508
525
/**
509
526
* Accepts response with collection of the elements and tries to extract the first one.
510
527
* In case the response is incorrect or empty, the {@link CompletionException} will be thrown
528
+ *
511
529
* @param response {@link JsonObject} representing service response which should contain array of objects
512
530
* @param propertyName name of the property which holds array of objects
513
531
* @return the first element of the array
@@ -517,7 +535,7 @@ public static JsonObject getFirstObjectFromResponse(JsonObject response, String
517
535
.flatMap (items -> items .stream ().findFirst ())
518
536
.map (JsonObject .class ::cast )
519
537
.orElseThrow (() -> new CompletionException (new NoInventoryRecordException (
520
- String .format ("No records of '%s' can be found" , propertyName ))));
538
+ String .format ("No records of '%s' can be found" , propertyName ))));
521
539
}
522
540
523
541
public static String extractId (JsonObject json ) {
0 commit comments