Skip to content

Commit

Permalink
[MODORDERS-983] - Receiving a piece on a closed/cancelled PO will reo…
Browse files Browse the repository at this point in the history
…pen the PO (#821)
  • Loading branch information
imerabishvili authored Jan 18, 2024
1 parent b4bb8a4 commit 2073932
Show file tree
Hide file tree
Showing 8 changed files with 314 additions and 19 deletions.
10 changes: 6 additions & 4 deletions src/main/java/org/folio/helper/CheckinReceivePiecesHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.folio.rest.core.exceptions.ErrorCodes.PIECE_UPDATE_FAILED;
import static org.folio.rest.core.exceptions.ErrorCodes.USER_HAS_NO_PERMISSIONS;
import static org.folio.rest.jaxrs.model.PoLine.ReceiptStatus.AWAITING_RECEIPT;
import static org.folio.rest.jaxrs.model.PoLine.ReceiptStatus.CANCELLED;
import static org.folio.rest.jaxrs.model.PoLine.ReceiptStatus.FULLY_RECEIVED;
import static org.folio.rest.jaxrs.model.PoLine.ReceiptStatus.ONGOING;
import static org.folio.rest.jaxrs.model.PoLine.ReceiptStatus.PARTIALLY_RECEIVED;
Expand Down Expand Up @@ -299,11 +300,12 @@ protected Future<Map<String, List<Piece>>> updateOrderAndPoLinesStatus(Map<Strin
// Skip status update if PO line status is Ongoing
List<Future<String>> futures = new ArrayList<>();
for (PoLine poLine : poLines) {
if (poLine.getReceiptStatus() != ONGOING) {
List<Piece> successfullyProcessedPieces = getSuccessfullyProcessedPieces(poLine.getId(), piecesGroupedByPoLine);
futures.add(calculatePoLineReceiptStatus(poLine, successfullyProcessedPieces, requestContext)
.compose(status -> purchaseOrderLineService.updatePoLineReceiptStatus(poLine, status, requestContext)));
if (poLine.getReceiptStatus() == CANCELLED || poLine.getReceiptStatus() == ONGOING) {
continue;
}
List<Piece> successfullyProcessedPieces = getSuccessfullyProcessedPieces(poLine.getId(), piecesGroupedByPoLine);
futures.add(calculatePoLineReceiptStatus(poLine, successfullyProcessedPieces, requestContext)
.compose(status -> purchaseOrderLineService.updatePoLineReceiptStatus(poLine, status, requestContext)));
}

return collectResultsOnSuccess(futures).map(updatedPoLines -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,13 @@ public void handle(Message<JsonObject> message) {
// 1. Get all pieces for poLineId
getPieces(query, requestContext)
.onSuccess(listOfPieces ->
// 2. Get PoLine for the poLineId which will be used to calculate PoLineReceiptStatus
purchaseOrderLineService.getOrderLineById(poLineIdUpdate, requestContext)
.map(poLine -> {
if (poLine.getReceiptStatus().equals(PoLine.ReceiptStatus.ONGOING)) {
promise.complete();
} else {
// 2. Get PoLine for the poLineId which will be used to calculate PoLineReceiptStatus
purchaseOrderLineService.getOrderLineById(poLineIdUpdate, requestContext)
.map(poLine -> {
if (poLine.getReceiptStatus() == ReceiptStatus.CANCELLED || poLine.getReceiptStatus() == ReceiptStatus.ONGOING) {
promise.complete();
return null;
}
calculatePoLineReceiptStatus(poLine, listOfPieces)
.compose(status -> purchaseOrderLineService.updatePoLineReceiptStatus(poLine, status, requestContext))
.map(updatedPoLineId -> {
Expand All @@ -87,13 +88,12 @@ public void handle(Message<JsonObject> message) {
logger.error("The error updating poLine by id {}", poLineIdUpdate, e);
promise.fail(e);
});
}
return null;
})
.onFailure(e -> {
logger.error("The error getting poLine by id {}", poLineIdUpdate, e);
promise.fail(e);
}))
return null;
})
.onFailure(e -> {
logger.error("The error getting poLine by id {}", poLineIdUpdate, e);
promise.fail(e);
}))
.onFailure(e -> {
logger.error("The error happened getting all pieces by poLine {}", poLineIdUpdate, e);
promise.fail(e);
Expand Down
48 changes: 48 additions & 0 deletions src/test/java/org/folio/rest/impl/CheckinReceivingApiTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ public class CheckinReceivingApiTest {
private static final String ITEM_STATUS_NAME = "name";
private static final String ITEM_STATUS = "status";
private static final String COMPOSITE_POLINE_ONGOING_ID = "6e2b169a-ebeb-4c3c-a2f2-6233ff9c59ae";
private static final String COMPOSITE_POLINE_CANCELED_ID = "1196fcd9-7607-447d-ae85-6e91883d7e4f";

private static boolean runningOnOwn;

Expand Down Expand Up @@ -350,6 +351,53 @@ void testReceiveOngoingOrder() {
verifyOrderStatusUpdateEvent(0);
}

@Test
void testReceiveCanceledOrder() {
logger.info("=== Test POST Receive - Ongoing PO Lines");

CompositePoLine poLines = getMockAsJson(POLINES_COLLECTION).getJsonArray("poLines").getJsonObject(10).mapTo(CompositePoLine.class);
MockServer.addMockTitles(Collections.singletonList(poLines));

ReceivingCollection receivingRq = getMockAsJson(RECEIVING_RQ_MOCK_DATA_PATH + "receive-physical-cancelled.json").mapTo(ReceivingCollection.class);
receivingRq.getToBeReceived().get(0).setPoLineId(COMPOSITE_POLINE_CANCELED_ID);

ReceivingResults results = verifyPostResponse(ORDERS_RECEIVING_ENDPOINT, JsonObject.mapFrom(receivingRq).encode(),
prepareHeaders(EXIST_CONFIG_X_OKAPI_TENANT_LIMIT_10), APPLICATION_JSON, 200).as(ReceivingResults.class);

assertThat(results.getTotalRecords(), equalTo(receivingRq.getTotalRecords()));

Map<String, Set<String>> pieceIdsByPol = verifyReceivingSuccessRs(results);

List<JsonObject> pieceSearches = getPieceSearches();
List<JsonObject> pieceUpdates = getPieceUpdates();
List<JsonObject> polSearches = getPoLineSearches();
List<JsonObject> polUpdates = getPoLineUpdates();

assertThat(pieceSearches, not(nullValue()));
assertThat(pieceUpdates, not(nullValue()));

assertThat(polSearches, not(nullValue()));

int expectedSearchRqQty = Math.floorDiv(receivingRq.getTotalRecords(), MAX_IDS_FOR_GET_RQ_15) + 1;

// The piece searches should be made 1 time: 1st time to get all required piece records
assertThat(pieceSearches, hasSize(expectedSearchRqQty));
assertThat(pieceUpdates, hasSize(receivingRq.getTotalRecords()));
assertThat(polSearches, hasSize(pieceIdsByPol.size()));

// check no status updates were performed and POL remained canceled
assertThat(polUpdates, nullValue());
polSearches.forEach(pol -> {
PoLine poLine = pol.mapTo(PoLineCollection.class).getPoLines().get(0);
assertThat(poLine.getCheckinItems(), is(false));
assertThat(poLine.getReceiptStatus(), is(PoLine.ReceiptStatus.CANCELLED));
assertThat(poLine.getReceiptDate(), is(notNullValue()));
});

// Verify no status updated for ongoing order
verifyOrderStatusUpdateEvent(0);
}


@Test
void testPostCheckInLocationId() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
{
"id": "1196fcd9-7607-447d-ae85-6e91883d7e4f",
"acquisitionMethod": "306489dd-0053-49ee-a068-c316444a8f55",
"alerts": [],
"cancellationRestriction": false,
"cancellationRestrictionNote": "ABCDEFGHIJKLMNOPQRSTUVW",
"claims": [],
"collection": false,
"contributors": [
{
"contributor": "Ed Mashburn",
"contributorNameTypeId": "fbdd42a8-e47d-4694-b448-cc571d1b44c3"
}
],
"cost": {
"currency": "USD",
"listUnitPrice": 24.99,
"quantityPhysical": 1
},
"description": "ABCDEFGH",
"details": {
"productIds": [
{
"productId": "9780764354113",
"productIdType": "8261054f-be78-422d-bd51-4ed9f33c3422"
}
],
"receivingNote": "ABCDEFGHIJKL",
"subscriptionFrom": "2018-10-09T00:00:00.000Z",
"subscriptionInterval": 824,
"subscriptionTo": "2020-10-09T00:00:00.000Z"
},
"donor": "ABCDEFGHIJKLM",
"fundDistribution": [
{
"code": "HIST",
"fundId": "fb7b70f1-b898-4924-a991-0e4b6312bb5f",
"encumbrance": "eb506834-6c70-4239-8d1a-6414a5b08ac3",
"distributionType": "percentage",
"value": 80.0
}
],
"locations": [
{
"locationId": "fcd64ce1-6995-48f0-840e-89ffa2288371",
"quantity": 1,
"quantityElectronic": 0,
"quantityPhysical": 1
},
{
"locationId": "53cf956f-c1df-410b-8bea-27f712cca7c0",
"quantity": 2,
"quantityElectronic": 0,
"quantityPhysical": 2
}
],
"orderFormat": "Physical Resource",
"paymentStatus": "Cancelled",
"physical": {
"createInventory": "Instance, Holding, Item",
"expectedReceiptDate": "2018-10-05T00:00:00.000Z",
"materialSupplier": "73d14bc5-d131-48c6-b380-f8e62f63c8b6",
"materialType": "2fa93835-ea37-479d-b133-1d2a2279fcd8",
"receiptDue": "2018-10-10T00:00:00.000Z",
"volumes": [
"vol. 1"
]
},
"poLineDescription": "ABCDEFGHIJKLMNOPQRSTUVWXY",
"poLineNumber": "1EFC97C6B7-1",
"publicationDate": "2017",
"publisher": "Schiffer Publishing",
"purchaseOrderId": "95d29d04-34b1-4fe0-a15e-1cd129143692",
"receiptDate": "2018-10-09T00:00:00.000+0000",
"receiptStatus": "Cancelled",
"reportingCodes": [],
"requester": "Leo Bulero",
"rush": true,
"selector": "ABCD",
"tags": {
"tagList": [
"important"
]
},
"titleOrPackage": "Kayak Fishing in the Northern Gulf Coast",
"vendorDetail": {
"instructions": "ABCDEFG",
"noteFromVendor": "ABCDEFGHIKJKLMNOP",
"referenceNumbers": [
{
"refNumber": "123456-78",
"refNumberType": "Vendor title number",
"vendorDetailsSource": "OrderLine"
}
],
"vendorAccount": "8910-25"
},
"metadata": {
"createdByUserId": "28d10cfc-d137-11e8-a8d5-f2801f1b9fd1",
"createdDate": "2014-07-06T00:00:00.000"
}
}
104 changes: 103 additions & 1 deletion src/test/resources/mockdata/lines/po_line_collection.json
Original file line number Diff line number Diff line change
Expand Up @@ -924,8 +924,110 @@
"createdByUserId": "28d10cfc-d137-11e8-a8d5-f2801f1b9fd1",
"createdDate": "2014-07-06T00:00:00.000"
}
},
{
"id": "1196fcd9-7607-447d-ae85-6e91883d7e4f",
"acquisitionMethod": "306489dd-0053-49ee-a068-c316444a8f55",
"alerts": [],
"cancellationRestriction": false,
"cancellationRestrictionNote": "ABCDEFGHIJKLMNOPQRSTUVW",
"claims": [],
"collection": false,
"contributors": [
{
"contributor": "Ed Mashburn",
"contributorNameTypeId": "fbdd42a8-e47d-4694-b448-cc571d1b44c3"
}
],
"cost": {
"currency": "USD",
"listUnitPrice": 24.99,
"quantityPhysical": 1
},
"description": "ABCDEFGH",
"details": {
"productIds": [
{
"productId": "9780764354113",
"productIdType": "8261054f-be78-422d-bd51-4ed9f33c3422"
}
],
"receivingNote": "ABCDEFGHIJKL",
"subscriptionFrom": "2018-10-09T00:00:00.000Z",
"subscriptionInterval": 824,
"subscriptionTo": "2020-10-09T00:00:00.000Z"
},
"donor": "ABCDEFGHIJKLM",
"fundDistribution": [
{
"code": "HIST",
"fundId": "fb7b70f1-b898-4924-a991-0e4b6312bb5f",
"encumbrance": "eb506834-6c70-4239-8d1a-6414a5b08ac3",
"distributionType": "percentage",
"value": 80.0
}
],
"locations": [
{
"locationId": "fcd64ce1-6995-48f0-840e-89ffa2288371",
"quantity": 1,
"quantityElectronic": 0,
"quantityPhysical": 1
},
{
"locationId": "53cf956f-c1df-410b-8bea-27f712cca7c0",
"quantity": 2,
"quantityElectronic": 0,
"quantityPhysical": 2
}
],
"orderFormat": "Physical Resource",
"paymentStatus": "Ongoing",
"physical": {
"createInventory": "Instance, Holding, Item",
"expectedReceiptDate": "2018-10-05T00:00:00.000Z",
"materialSupplier": "73d14bc5-d131-48c6-b380-f8e62f63c8b6",
"materialType": "2fa93835-ea37-479d-b133-1d2a2279fcd8",
"receiptDue": "2018-10-10T00:00:00.000Z",
"volumes": [
"vol. 1"
]
},
"poLineDescription": "ABCDEFGHIJKLMNOPQRSTUVWXY",
"poLineNumber": "1EFC97C6B7-1",
"publicationDate": "2017",
"publisher": "Schiffer Publishing",
"purchaseOrderId": "95d29d04-34b1-4fe0-a15e-1cd129143692",
"receiptDate": "2018-10-09T00:00:00.000+0000",
"receiptStatus": "Cancelled",
"reportingCodes": [],
"requester": "Leo Bulero",
"rush": true,
"selector": "ABCD",
"tags": {
"tagList": [
"important"
]
},
"titleOrPackage": "Kayak Fishing in the Northern Gulf Coast",
"vendorDetail": {
"instructions": "ABCDEFG",
"noteFromVendor": "ABCDEFGHIKJKLMNOP",
"referenceNumbers": [
{
"refNumber": "123456-78",
"refNumberType": "Vendor title number",
"vendorDetailsSource": "OrderLine"
}
],
"vendorAccount": "8910-25"
},
"metadata": {
"createdByUserId": "28d10cfc-d137-11e8-a8d5-f2801f1b9fd1",
"createdDate": "2014-07-06T00:00:00.000"
}
}

],
"totalRecords": 9
"totalRecords": 10
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"pieces": [
{
"id": "06a95f03-eb00-4248-9f2e-2bd05957ff05",
"poLineId": "1196fcd9-7607-447d-ae85-6e91883d7e4f",
"titleId": "9a665b22-9fe5-4c95-b4ee-837a5433c95d",
"receivingStatus": "Expected",
"receiptDate": "2018-10-09T00:00:00.000Z",
"receivedDate": "2019-03-05T08:06:58.473+0000"
}
],
"totalRecords": 1
}
10 changes: 9 additions & 1 deletion src/test/resources/mockdata/pieces/pieceRecordsCollection.json
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,14 @@
"receiptDate": "2018-10-09T00:00:00.000Z",
"receivedDate": "2019-03-05T08:06:58.473+0000"
},
{
"id": "06a95f03-eb00-4248-9f2e-2bd05957ff05",
"poLineId": "1196fcd9-7607-447d-ae85-6e91883d7e4f",
"titleId": "9a665b22-9fe5-4c95-b4ee-837a5433c95d",
"receivingStatus": "Expected",
"receiptDate": "2018-10-09T00:00:00.000Z",
"receivedDate": "2019-03-05T08:06:58.473+0000"
},
{
"id": "bf3c14fe-6eac-450a-90ca-391d0788a8a4",
"itemId": "86481a22-633e-4b97-8061-0dc9fdaaeaca",
Expand All @@ -494,5 +502,5 @@
"receivingStatus": "Received"
}
],
"totalRecords": 60
"totalRecords": 61
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"toBeReceived": [
{
"poLineId": "0dd8f1d2-ac2e-4155-a407-72071f6d5f4b",
"received": 1,
"receivedItems": [
{
"barcode": 21111111122,
"callNumber": "PR 8923 W6 L36 1990 c.3",
"comment": "Very important note",
"caption": "Vol. 1",
"itemStatus": "In process",
"locationId": "fcd64ce1-6995-48f0-840e-89ffa2288371",
"pieceId": "06a95f03-eb00-4248-9f2e-2bd05957ff05"
}
]
}
],
"totalRecords": 1
}

0 comments on commit 2073932

Please sign in to comment.