Skip to content

Commit

Permalink
[MODORDERS-1209]. Add claimPieceIds to job integration details
Browse files Browse the repository at this point in the history
  • Loading branch information
BKadirkhodjaev committed Dec 4, 2024
1 parent d25503e commit d41dd59
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 75 deletions.
57 changes: 36 additions & 21 deletions src/main/java/org/folio/service/claiming/ClaimingService.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ public class ClaimingService {

private static final Logger logger = LogManager.getLogger(ClaimingService.class);
private static final String JOB_STATUS = "status";
private static final String EXPORT_TYPE_SPECIFIC_PARAMETERS = "exportTypeSpecificParameters";
private static final String VENDOR_EDI_ORDERS_EXPORT_CONFIG = "vendorEdiOrdersExportConfig";
private static final String CLAIM_PIECE_IDS = "claimPieceIds";
private static final String EXPORT_TYPE_CLAIMS = "CLAIMS";
private static final String CANNOT_SEND_CLAIMS_PIECE_IDS_ARE_EMPTY = "Cannot send claims, piece ids are empty";
private static final String CANNOT_RETRIEVE_CONFIG_ENTRIES = "Cannot retrieve config entries";
Expand Down Expand Up @@ -115,19 +118,23 @@ private Future<Map<String, List<String>>> groupPieceIdsByVendorId(List<String> p
var uniquePiecePoLinePairs = pieces.stream()
.map(piece -> Pair.of(piece.getPoLineId(), piece.getId())).distinct()
.toList();
var pieceIdByVendorIdFutures = new ArrayList<Future<Pair<String, String>>>();
uniquePiecePoLinePairs.forEach(piecePoLinePairs -> {
var pieceIdByVendorIdFuture = pieceStorageService.getPieceById(piecePoLinePairs.getRight(), requestContext)
.compose(piece -> createVendorPiecePair(piecePoLinePairs, piece, requestContext));
if (Objects.nonNull(pieceIdByVendorIdFuture)) {
pieceIdByVendorIdFutures.add(pieceIdByVendorIdFuture);
}
});
return collectResultsOnSuccess(pieceIdByVendorIdFutures)
return collectResultsOnSuccess(createPieceIdByVendorFutures(uniquePiecePoLinePairs, requestContext))
.map(ClaimingService::transformAndGroupPieceIdsByVendorId);
});
}

private List<Future<Pair<String, String>>> createPieceIdByVendorFutures(List<Pair<String, String>> uniquePiecePoLinePairs, RequestContext requestContext) {
var pieceIdByVendorIdFutures = new ArrayList<Future<Pair<String, String>>>();
uniquePiecePoLinePairs.forEach(piecePoLinePairs -> {
var pieceIdByVendorIdFuture = pieceStorageService.getPieceById(piecePoLinePairs.getRight(), requestContext)
.compose(piece -> createVendorPiecePair(piecePoLinePairs, piece, requestContext));
if (Objects.nonNull(pieceIdByVendorIdFuture)) {
pieceIdByVendorIdFutures.add(pieceIdByVendorIdFuture);
}
});
return pieceIdByVendorIdFutures;
}

private Future<Pair<String, String>> createVendorPiecePair(Pair<String, String> piecePoLinePairs, Piece piece, RequestContext requestContext) {
if (Objects.nonNull(piece) && !piece.getReceivingStatus().equals(Piece.ReceivingStatus.LATE)) {
logger.info("createVendorPiecePair:: Ignoring processing of a piece not in LATE state, piece id: {}", piece.getId());
Expand Down Expand Up @@ -156,14 +163,7 @@ private Future<ClaimingResults> createJobsByVendor(JsonObject config, Map<String
logger.info("createJobsByVendor:: No jobs are created, pieceIdsByVendorId is empty");
return Future.succeededFuture(new ClaimingResults().withClaimingPieceResults(createErrorClaimingResults(pieceIdsByVendorId, CANNOT_GROUP_PIECES_BY_VENDOR_MESSAGE)));
}
var updatePiecesAndJobFutures = new ArrayList<Future<List<String>>>();
pieceIdsByVendorId.forEach((vendorId, pieceIds) -> config.stream()
.filter(entry -> isExportTypeClaimsAndCorrectVendorId(vendorId, entry) && Objects.nonNull(entry.getValue()))
.forEach(entry -> {
logger.info("createJobsByVendor:: Preparing job integration detail for vendor, vendor id: {}, pieces: {}, job key: {}", vendorId, pieceIds.size(), entry.getKey());
updatePiecesAndJobFutures.add(updatePiecesAndCreateJob(requestContext, pieceIds, entry));
}));
return collectResultsOnSuccess(updatePiecesAndJobFutures)
return collectResultsOnSuccess(createUpdatePiecesAndJobFutures(config, pieceIdsByVendorId, requestContext))
.map(updatedPieceLists -> {
if (CollectionUtils.isEmpty(updatedPieceLists)) {
logger.info("createJobsByVendor:: No pieces were processes for claiming");
Expand All @@ -175,6 +175,17 @@ private Future<ClaimingResults> createJobsByVendor(JsonObject config, Map<String
});
}

private List<Future<List<String>>> createUpdatePiecesAndJobFutures(JsonObject config, Map<String, List<String>> pieceIdsByVendorId, RequestContext requestContext) {
var updatePiecesAndJobFutures = new ArrayList<Future<List<String>>>();
pieceIdsByVendorId.forEach((vendorId, pieceIds) -> config.stream()
.filter(entry -> isExportTypeClaimsAndCorrectVendorId(vendorId, entry) && Objects.nonNull(entry.getValue()))
.forEach(entry -> {
logger.info("createJobsByVendor:: Preparing job integration detail for vendor, vendor id: {}, pieces: {}, job key: {}", vendorId, pieceIds.size(), entry.getKey());
updatePiecesAndJobFutures.add(updatePiecesAndCreateJob(pieceIds, entry, requestContext));
}));
return updatePiecesAndJobFutures;
}

private static ClaimingResults createEmptyClaimingResults(String message) {
return new ClaimingResults().withClaimingPieceResults(List.of(new ClaimingPieceResult().withError(new Error().withMessage(message))));
}
Expand All @@ -196,14 +207,18 @@ private static boolean isExportTypeClaimsAndCorrectVendorId(String vendorId, Map
return entry.getKey().startsWith(String.format("%s_%s", EXPORT_TYPE_CLAIMS, vendorId));
}

private Future<List<String>> updatePiecesAndCreateJob(RequestContext requestContext, List<String> pieceIds, Map.Entry<String, Object> entry) {
private Future<List<String>> updatePiecesAndCreateJob(List<String> pieceIds, Map.Entry<String, Object> entry,
RequestContext requestContext) {
logger.info("updatePiecesAndCreateJob:: Updating pieces and creating a job, job key: {}, count: {}", entry.getKey(), pieceIds.size());
return pieceUpdateFlowManager.updatePiecesStatuses(pieceIds, PieceBatchStatusCollection.ReceivingStatus.CLAIM_SENT, requestContext).map(pieceIds)
.compose(updatePieceIds -> createJob(entry.getKey(), entry.getValue(), requestContext).map(updatePieceIds));
return pieceUpdateFlowManager.updatePiecesStatuses(pieceIds, PieceBatchStatusCollection.ReceivingStatus.CLAIM_SENT, requestContext)
.compose(v -> createJob(entry.getKey(), entry.getValue(), pieceIds, requestContext).map(pieceIds));
}

private Future<Void> createJob(String configKey, Object configValue, RequestContext requestContext) {
private Future<Void> createJob(String configKey, Object configValue, List<String> pieceIds, RequestContext requestContext) {
var integrationDetail = new JsonObject(String.valueOf(configValue));
integrationDetail.getJsonObject(EXPORT_TYPE_SPECIFIC_PARAMETERS)
.getJsonObject(VENDOR_EDI_ORDERS_EXPORT_CONFIG)
.put(CLAIM_PIECE_IDS, pieceIds);
return restClient.post(resourcesPath(DATA_EXPORT_SPRING_CREATE_JOB), integrationDetail, Object.class, requestContext)
.map(response -> {
var createdJob = new JsonObject(String.valueOf(response));
Expand Down
42 changes: 19 additions & 23 deletions src/test/java/org/folio/rest/impl/ClaimingApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
Expand All @@ -36,14 +35,11 @@
import static org.folio.TestConstants.ORDERS_CLAIMING_ENDPOINT;
import static org.folio.TestUtils.getMinimalOrder;
import static org.folio.TestUtils.getMockAsJson;
import static org.folio.TestUtils.getMockData;
import static org.folio.orders.utils.ResourcePathResolver.ORGANIZATION_STORAGE;
import static org.folio.orders.utils.ResourcePathResolver.PIECES_STORAGE;
import static org.folio.orders.utils.ResourcePathResolver.PO_LINES_STORAGE;
import static org.folio.orders.utils.ResourcePathResolver.PURCHASE_ORDER_STORAGE;
import static org.folio.rest.impl.MockServer.BASE_MOCK_DATA_PATH;
import static org.folio.rest.impl.MockServer.ORGANIZATION_COLLECTION;
import static org.folio.rest.impl.MockServer.PIECE_RECORDS_MOCK_DATA_PATH;
import static org.folio.rest.impl.MockServer.PO_LINES_COLLECTION;
import static org.folio.rest.impl.MockServer.addMockEntry;
import static org.folio.rest.impl.MockServer.getDataExportSpringJobCreations;
Expand Down Expand Up @@ -93,9 +89,11 @@ static void after() {

private static Stream<Arguments> testPostOrdersClaimArgs() {
return Stream.of(
Arguments.of("One piece One vendor One Job", 0, 17, 69, new MockHitDto(3, 2, 2, 1, 1, 1, 1, 1),
Arguments.of("One piece One vendor One Job", 0, 17,
new MockHitDto(3, 2, 2, 1, 1, 1, 1, 1),
"send-claims-1-piece-1-vendor-1-job.json", EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10_CLAIMS, ClaimingPieceResult.Status.SUCCESS),
Arguments.of("One piece One vendor No Job", 0, 17, 69, null,
Arguments.of("One piece One vendor No Job", 0, 17,
null,
"send-claims-1-piece-1-vendor-1-job.json", EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10, ClaimingPieceResult.Status.FAILURE)
);
}
Expand Down Expand Up @@ -127,8 +125,8 @@ public MockHitDto(int pieceSearches, int polSearches, int purchaseOrderRetrieval

@ParameterizedTest
@MethodSource("testPostOrdersClaimArgs")
void testPostOrdersClaim(String name, int vendorIdx, int polIdx, int pieceIdx, MockHitDto dto,
String payloadFile, Header header, ClaimingPieceResult.Status expectedStatus) throws InterruptedException, IOException {
void testPostOrdersClaim(String name, int vendorIdx, int polIdx, MockHitDto dto,
String payloadFile, Header header, ClaimingPieceResult.Status expectedStatus) {
logger.info("Testing postOrdersClaim, name: {}", name);

var organization = getMockAsJson(ORGANIZATION_COLLECTION)
Expand All @@ -140,19 +138,15 @@ void testPostOrdersClaim(String name, int vendorIdx, int polIdx, int pieceIdx, M
.mapTo(CompositePoLine.class);
var purchaseOrder = getMinimalOrder(poLine)
.withVendor(organization.getId());
var piece = new JsonObject(getMockData(PIECE_RECORDS_MOCK_DATA_PATH + "pieceRecord-dcd0ba36-b660-4751-b9fe-c8ac61ff6f99.json"));

addMockEntry(ORGANIZATION_STORAGE, organization);
addMockEntry(PURCHASE_ORDER_STORAGE, purchaseOrder);
addMockEntry(PO_LINES_STORAGE, poLine);
addMockEntry(PIECES_STORAGE, piece);

var headers = prepareHeaders(header);
var mockDataPath = BASE_MOCK_DATA_PATH + CLAIMING_MOCK_DATA_FOLDER + payloadFile;
var request = JsonObject.mapFrom(getMockAsJson(mockDataPath).mapTo(ClaimingCollection.class)).encode();
var response = verifyPostResponse(ORDERS_CLAIMING_ENDPOINT, request, headers, APPLICATION_JSON, CREATED.code()).as(ClaimingResults.class);

Thread.sleep(1000);
var response = verifyPostResponse(ORDERS_CLAIMING_ENDPOINT, request, prepareHeaders(header), APPLICATION_JSON, CREATED.code())
.as(ClaimingResults.class);

var pieceSearches = getPieceSearches();
var polSearches = getPoLineSearches();
Expand All @@ -178,16 +172,18 @@ void testPostOrdersClaim(String name, int vendorIdx, int polIdx, int pieceIdx, M
assertThat(jobCreations, hasSize(dto.jobCreations));
assertThat(jobExecutions, hasSize(dto.jobExecutions));
assertThat(response.getClaimingPieceResults().size(), equalTo(dto.claimingResults));
jobCreations.forEach(job -> logger.info("Created job: {}", JsonObject.mapFrom(job).encodePrettily()));
}

response.getClaimingPieceResults().forEach(result -> {
assertThat(result.getPieceId(), not(nullValue()));
assertThat(result.getStatus(), is(expectedStatus));
if (expectedStatus == ClaimingPieceResult.Status.SUCCESS) {
assertThat(result.getError(), is(nullValue()));
} else {
assertThat(result.getError(), is(notNullValue()));
}
});
response.getClaimingPieceResults()
.forEach(result -> {
assertThat(result.getPieceId(), not(nullValue()));
assertThat(result.getStatus(), is(expectedStatus));
if (expectedStatus == ClaimingPieceResult.Status.SUCCESS) {
assertThat(result.getError(), is(nullValue()));
} else {
assertThat(result.getError(), is(notNullValue()));
}
});
}
}
54 changes: 24 additions & 30 deletions src/test/java/org/folio/rest/impl/MockServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,6 @@ private void handleGetFunds(RoutingContext ctx) {
serverResponse(ctx, 500, APPLICATION_JSON, INTERNAL_SERVER_ERROR.getReasonPhrase());
} else {
try {

List<String> ids = Collections.emptyList();
if (query.startsWith("id==")) {
ids = extractIdsFromQuery(query);
Expand Down Expand Up @@ -836,7 +835,6 @@ private void handleGetBudgets(RoutingContext ctx) {
serverResponse(ctx, 500, APPLICATION_JSON, INTERNAL_SERVER_ERROR.getReasonPhrase());
} else {
try {

List<String> ids = Collections.emptyList();
if (query.startsWith("fundId==")) {
ids = extractfundIdsFromQuery(query);
Expand Down Expand Up @@ -1210,8 +1208,7 @@ private void handleGetItemRecordsFromStorage(RoutingContext ctx) {
addServerRqRsData(HttpMethod.GET, ITEM_RECORDS, items);
serverResponse(ctx, 200, APPLICATION_JSON, items.encodePrettily());
} else {
JsonObject items;
items = new JsonObject().put("items", new JsonArray());
JsonObject items = new JsonObject().put("items", new JsonArray());
addServerRqRsData(HttpMethod.GET, ITEM_RECORDS, items);
serverResponse(ctx, 200, APPLICATION_JSON, items.encodePrettily());
}
Expand Down Expand Up @@ -1368,16 +1365,16 @@ private void handleGetLoanType(RoutingContext ctx) {
private void handleGetIdentifierType(RoutingContext ctx) {
logger.info("handleGetIdentifierType got: {}", ctx.request().path());
try {
// Filter result based on name from query
String query = ctx.request().getParam("query");
JsonObject entries = new JsonObject(getMockData(IDENTIFIER_TYPES_MOCK_DATA_PATH + "identifierTypes.json"));
if (query != null) {
String name = query.split("==")[1];
filterByKeyValue("name", name, entries.getJsonArray(IDENTIFIER_TYPES));
}
// Filter result based on name from query
String query = ctx.request().getParam("query");
JsonObject entries = new JsonObject(getMockData(IDENTIFIER_TYPES_MOCK_DATA_PATH + "identifierTypes.json"));
if (query != null) {
String name = query.split("==")[1];
filterByKeyValue("name", name, entries.getJsonArray(IDENTIFIER_TYPES));
}

serverResponse(ctx, 200, APPLICATION_JSON, entries.encodePrettily());
addServerRqRsData(HttpMethod.GET, IDENTIFIER_TYPES, entries);
serverResponse(ctx, 200, APPLICATION_JSON, entries.encodePrettily());
addServerRqRsData(HttpMethod.GET, IDENTIFIER_TYPES, entries);
} catch (IOException e) {
ctx.response()
.setStatusCode(404)
Expand Down Expand Up @@ -1409,10 +1406,8 @@ private void handleGetAccessProviders(RoutingContext ctx) {
} else if (getQuery(ACTIVE_ACCESS_PROVIDER_B).equals(query)) {
body = new JsonObject(getMockData(ORGANIZATIONS_MOCK_DATA_PATH + "one_access_providers_active.json"));
} else if (getQuery(ORGANIZATION_NOT_VENDOR).equals(query)) {
body = new JsonObject(
getMockData(ORGANIZATIONS_MOCK_DATA_PATH + "not_vendor.json"));
}
else {
body = new JsonObject(getMockData(ORGANIZATIONS_MOCK_DATA_PATH + "not_vendor.json"));
} else {
JsonArray organizations = new JsonArray();

// Search for Organizations by id
Expand Down Expand Up @@ -1907,7 +1902,11 @@ private void handleGetPieceById(RoutingContext ctx) {
String pieceId = ctx.request().getParam(ID);
logger.info("id: {}", pieceId);
try {
if (ID_DOES_NOT_EXIST.equals(pieceId)) {
if ("dcd0ba36-b660-4751-b9fe-c8ac61ff6f99".equals(pieceId)) {
JsonObject data = new JsonObject(getMockData(PIECE_RECORDS_MOCK_DATA_PATH + String.format("pieceRecord-%s.json", pieceId)));
logger.info("handleGetPieceById custom, data: {}", data.encodePrettily());
serverResponse(ctx, HttpStatus.HTTP_OK.toInt(), APPLICATION_JSON, data.encodePrettily());
} else if (ID_DOES_NOT_EXIST.equals(pieceId)) {
serverResponse(ctx, 404, APPLICATION_JSON, pieceId);
} else if (ID_FOR_INTERNAL_SERVER_ERROR.equals(pieceId)) {
serverResponse(ctx, 500, APPLICATION_JSON, pieceId);
Expand Down Expand Up @@ -1978,8 +1977,7 @@ private void handleGetPieces(RoutingContext ctx) {
// Filter piece records by receiving status
if (StringUtils.isNotEmpty(status)) {
Piece.ReceivingStatus receivingStatus = Piece.ReceivingStatus.fromValue(status);
pieces.getPieces()
.removeIf(piece -> receivingStatus != piece.getReceivingStatus());
pieces.getPieces().removeIf(piece -> receivingStatus != piece.getReceivingStatus());
}
} else if (requestQuery.contains("id==")) {
logger.info("handleGetPieces (by id)");
Expand Down Expand Up @@ -2027,7 +2025,6 @@ private void handleGetTitles(RoutingContext ctx) {
serverResponse(ctx, 500, APPLICATION_JSON, INTERNAL_SERVER_ERROR.getReasonPhrase());
} else {
try {

List<String> ids = Collections.emptyList();
if (query.contains("poLineId==")) {
ids = extractValuesFromQuery("poLineId", query);
Expand Down Expand Up @@ -2057,7 +2054,6 @@ private void handleGetRoutingListById(RoutingContext ctx) {
serverResponse(ctx, 500, APPLICATION_JSON, INTERNAL_SERVER_ERROR.getReasonPhrase());
} else {
try {

// Attempt to find title in mock server memory
JsonObject existantTitle = getMockEntry(ROUTING_LISTS, id).orElse(null);

Expand All @@ -2081,7 +2077,6 @@ private void handleGetRoutingLists(RoutingContext ctx) {
serverResponse(ctx, 500, APPLICATION_JSON, INTERNAL_SERVER_ERROR.getReasonPhrase());
} else {
try {

List<String> ids = Collections.emptyList();
if (query.contains("poLineId==")) {
ids = extractValuesFromQuery("poLineId", query);
Expand Down Expand Up @@ -2831,10 +2826,10 @@ private void handleGetRateOfExchange(RoutingContext ctx) {
private void handleGetFyRollovers(RoutingContext ctx) {
logger.info("handleGetFyRollovers got: {}", ctx.request().path());
try {
JsonObject entries = new JsonObject(getMockData(LEDGER_FY_ROLLOVERS_PATH + "ledger_fiscal_year_rollover_collection.json"));
JsonObject entries = new JsonObject(getMockData(LEDGER_FY_ROLLOVERS_PATH + "ledger_fiscal_year_rollover_collection.json"));

serverResponse(ctx, 200, APPLICATION_JSON, entries.encodePrettily());
addServerRqRsData(HttpMethod.GET, "ledgerFiscalYearRollovers", entries);
serverResponse(ctx, 200, APPLICATION_JSON, entries.encodePrettily());
addServerRqRsData(HttpMethod.GET, "ledgerFiscalYearRollovers", entries);

} catch (IOException e) {
String body = buildEmptyCollection("ledgerFiscalYearRollovers");
Expand All @@ -2846,11 +2841,10 @@ private void handleGetFyRollovers(RoutingContext ctx) {
private void handleGetFyRolloverErrors(RoutingContext ctx) {
logger.info("handleGetFyRolloverErrors got: {}", ctx.request().path());
try {
JsonObject entries = new JsonObject(getMockData(LEDGER_FY_ROLLOVERS_ERRORS_PATH + "ledger_fiscal_year_rollover_error_collection.json"));

serverResponse(ctx, 200, APPLICATION_JSON, entries.encodePrettily());
addServerRqRsData(HttpMethod.GET, "ledgerFiscalYearRolloverErrors", entries);
JsonObject entries = new JsonObject(getMockData(LEDGER_FY_ROLLOVERS_ERRORS_PATH + "ledger_fiscal_year_rollover_error_collection.json"));

serverResponse(ctx, 200, APPLICATION_JSON, entries.encodePrettily());
addServerRqRsData(HttpMethod.GET, "ledgerFiscalYearRolloverErrors", entries);
} catch (IOException e) {
ctx.response()
.setStatusCode(404)
Expand Down
Loading

0 comments on commit d41dd59

Please sign in to comment.