diff --git a/service/build.gradle b/service/build.gradle index 580c8d664..1278d5763 100644 --- a/service/build.gradle +++ b/service/build.gradle @@ -216,6 +216,10 @@ dependencies { // Iso java classes implementation 'org.olf.rs.iso18626:iso18626-client:1.2' + + implementation("com.ibm.icu:icu4j:78.2") + implementation("com.github.zafarkhaja:java-semver:0.10.2") + implementation("org.antlr:antlr4-runtime:4.9.2") } bootRun { diff --git a/service/grails-app/domain/org/olf/rs/statemodel/ActionEventResultList.groovy b/service/grails-app/domain/org/olf/rs/statemodel/ActionEventResultList.groovy index 3ecaf6d93..e56c5b9bd 100644 --- a/service/grails-app/domain/org/olf/rs/statemodel/ActionEventResultList.groovy +++ b/service/grails-app/domain/org/olf/rs/statemodel/ActionEventResultList.groovy @@ -55,6 +55,7 @@ class ActionEventResultList implements MultiTenant { // SLNP requester event lists static public final String SLNP_REQUESTER_CANCEL = 'slnpRequesterCancel'; + static public final String SLNP_REQUESTER_CLOSE_MANUAL = 'slnpRequesterCloseManual' static public final String SLNP_REQUESTER_RECEIVED = 'slnpRequesterReceived'; static public final String SLNP_REQUESTER_ABORTED = 'slnpRequesterAborted'; static public final String SLNP_REQUESTER_ISO_18626_STATUS_CHANGE = 'slnpRequesterISO18626StatusChange'; @@ -65,6 +66,7 @@ class ActionEventResultList implements MultiTenant { // SLNP responder event lists static public final String SLNP_RESPONDER_RESPOND_YES = 'slnpResponderRespondYes' static public final String SLNP_RESPONDER_CANNOT_SUPPLY = 'slnpResponderCannotSupply' + static public final String SLNP_RESPONDER_CLOSE_MANUAL = 'slnpResponderCloseManual' static public final String SLNP_RESPONDER_ABORT_SUPPLY = 'slnpResponderAbortSupply' static public final String SLNP_RESPONDER_SUPPLIER_PRINT_PULL_SLIP = "slnpResponderSupplierPrintPullSlip" static public final String SLNP_RESPONDER_SUPPLIER_FILL_AND_MARK_SHIPPED = "slnpResponderSupplierFillAndMarkShipped" @@ -77,11 +79,13 @@ class ActionEventResultList implements MultiTenant { static public final String SLNP_NON_RETURNABLE_REQUESTER_RECEIVED = 'slnpNonReturnableRequesterReceived'; static public final String SLNP_NON_RETURNABLE_REQUESTER_MANUALLY_MARK_SUPPLIED = 'slnpNonReturnableRequesterManuallyMarkSupplied'; static public final String SLNP_NON_RETURNABLE_REQUESTER_MANUALLY_MARK_AVAILABLE = 'slnpNonReturnableRequesterManuallyMarkAvailable'; + static public final String SLNP_NON_RETURNABLE_REQUESTER_CLOSE_MANUAL = 'slnpNonReturnableRequesterCloseManual' // SLNP responder non returnable event lists static public final String SLNP_NON_RETURNABLE_RESPONDER_CANNOT_SUPPLY = 'slnpNonReturnableResponderCannotSupply' static public final String SLNP_NON_RETURNABLE_RESPONDER_SUPPLIER_PRINT_PULL_SLIP = "slnpNonReturnableResponderSupplierPrintPullSlip" static public final String SLNP_NON_RETURNABLE_RESPONDER_SUPPLIER_SUPPLIES_DOCUMENT = "slnpNonReturnableResponderSupplierSuppliesDocument" + static public final String SLNP_NON_RETURNABLE_RESPONDER_CLOSE_MANUAL = "slnpNonReturnableResponderSupplierCloseManual" // The responder lists static public final String RESPONDER_ADD_CONDITIONAL = 'responderAddConditional'; diff --git a/service/grails-app/services/org/olf/rs/statemodel/actions/ActionManualCloseService.groovy b/service/grails-app/services/org/olf/rs/statemodel/actions/ActionManualCloseService.groovy index 3dd7d4aca..571c0d794 100644 --- a/service/grails-app/services/org/olf/rs/statemodel/actions/ActionManualCloseService.groovy +++ b/service/grails-app/services/org/olf/rs/statemodel/actions/ActionManualCloseService.groovy @@ -4,7 +4,8 @@ import org.olf.rs.PatronRequest; import org.olf.rs.statemodel.AbstractAction; import org.olf.rs.statemodel.ActionResult; import org.olf.rs.statemodel.ActionResultDetails; -import org.olf.rs.statemodel.Actions; +import org.olf.rs.statemodel.Actions +import org.olf.rs.statemodel.StateModel; import org.olf.rs.statemodel.Status; import org.olf.rs.statemodel.StatusService; @@ -32,8 +33,8 @@ public class ActionManualCloseService extends AbstractAction { // Have we been supplied a valid close status if (closeStatus && closeStatus.terminal) { reshareActionService.sendMessage(request, [note: "The ${request.isRequester ? 'requester' : 'responder'} has manually closed this request."], actionResultDetails); - actionResultDetails.auditMessage = 'Manually closed'; - actionResultDetails.qualifier = parameters.terminalState; + actionResultDetails.auditMessage = 'Manually closed' ; + actionResultDetails.qualifier = parameters.terminalState ; } else { actionResultDetails.result = ActionResult.INVALID_PARAMETERS; actionResultDetails.auditMessage = "Attemped manualClose action with non-terminal state: ${s} ${parameters?.terminalState}"; diff --git a/service/src/integration-test/groovy/org/olf/SLNPStateModelSpec.groovy b/service/src/integration-test/groovy/org/olf/SLNPStateModelSpec.groovy index a2035e0fe..cb54a556b 100644 --- a/service/src/integration-test/groovy/org/olf/SLNPStateModelSpec.groovy +++ b/service/src/integration-test/groovy/org/olf/SLNPStateModelSpec.groovy @@ -654,6 +654,7 @@ class SLNPStateModelSpec extends TestBase { String initialState, String resultState, String action, + String testQualifier, String jsonFileName, Boolean isRequester) { when: "Performing the action" @@ -685,7 +686,7 @@ class SLNPStateModelSpec extends TestBase { performAction(slnpPatronRequest?.id, jsonFileName); // Validate result status after performed action - NewStatusResult newResultStatus = statusService.lookupStatus(slnpPatronRequest, action, null, true, true); + NewStatusResult newResultStatus = statusService.lookupStatus(slnpPatronRequest, action, testQualifier, true, true); validateStateTransition(newResultStatus, resultState); } @@ -693,22 +694,25 @@ class SLNPStateModelSpec extends TestBase { assert true; where: - tenantId | requestTitle | requestAuthor | requestSystemId | requestPatronId | requestSymbol | initialState | resultState | action | jsonFileName | isRequester - 'RSSlnpOne' | 'request1' | 'test1' | '1234-5678-9123-1231' | '9876-1231' | 'ISIL:RSS1' | 'SLNP_REQ_IDLE' | 'SLNP_REQ_CANCELLED' | Actions.ACTION_REQUESTER_REQUESTER_CANCEL | 'slnpRequesterCancel' | true - 'RSSlnpOne' | 'request2' | 'test2' | '1234-5678-9123-1232' | '9876-1232' | 'ISIL:RSS1' | 'SLNP_REQ_ABORTED' | 'SLNP_REQ_CANCELLED' | Actions.ACTION_SLNP_REQUESTER_HANDLE_ABORT | 'slnpRequesterHandleAbort' | true - 'RSSlnpOne' | 'request3' | 'test3' | '1234-5678-9123-1233' | '9876-1233' | 'ISIL:RSS1' | 'SLNP_REQ_SHIPPED' | 'SLNP_REQ_CHECKED_IN' | Actions.ACTION_SLNP_REQUESTER_REQUESTER_RECEIVED | 'slnpRequesterRequesterReceived' | true - 'RSSlnpOne' | 'request4' | 'test4' | '1234-5678-9123-1234' | '9876-1235' | 'ISIL:RSS1' | 'SLNP_REQ_CHECKED_IN' | 'SLNP_REQ_AWAITING_RETURN_SHIPPING' | Actions.ACTION_REQUESTER_PATRON_RETURNED_ITEM | 'patronReturnedItem' | true - 'RSSlnpOne' | 'request41' | 'test41' | '1234-5678-9123-1234' | '9876-1235' | 'ISIL:RSS1' | 'SLNP_REQ_CHECKED_IN' | 'SLNP_REQ_COMPLETE' | Actions.ACTION_REQUESTER_PATRON_RETURNED_ITEM_AND_SHIPPED | 'patronReturnedItemAndShippedReturn' | true - 'RSSlnpOne' | 'request5' | 'test5' | '1234-5678-9123-1235' | '9876-1237' | 'ISIL:RSS1' | 'SLNP_REQ_AWAITING_RETURN_SHIPPING' | 'SLNP_REQ_COMPLETE' | Actions.ACTION_REQUESTER_SHIPPED_RETURN | 'shippedReturn' | true - 'RSSlnpOne' | 'request6' | 'test6' | '1234-5678-9123-1299' | '9876-1299' | 'ISIL:RSS1' | 'SLNP_REQ_CHECKED_IN' | 'SLNP_REQ_ITEM_LOST' | Actions.ACTION_SLNP_REQUESTER_MARK_ITEM_LOST | 'slnpRequesterMarkItemLost' | true - 'RSSlnpOne' | 'respond1' | 'test8' | '1234-5678-9123-1238' | '9876-1238' | 'ISIL:RSS1' | 'SLNP_RES_IDLE' | 'SLNP_RES_AWAIT_PICKING' | Actions.ACTION_SLNP_RESPONDER_RESPOND_YES | 'slnpSupplierAnswerYes' | false - 'RSSlnpOne' | 'respond2' | 'test9' | '1234-5678-9123-1239' | '9876-1239' | 'ISIL:RSS1' | 'SLNP_RES_IDLE' | 'SLNP_RES_UNFILLED' | Actions.ACTION_RESPONDER_SUPPLIER_CANNOT_SUPPLY | 'supplierCannotSupply' | false - 'RSSlnpOne' | 'respond3' | 'test10' | '1234-5678-9123-1240' | '9876-1240' | 'ISIL:RSS1' | 'SLNP_RES_IDLE' | 'SLNP_RES_ABORTED' | Actions.ACTION_SLNP_RESPONDER_ABORT_SUPPLY | 'slnpResponderAbortSupply' | false - 'RSSlnpOne' | 'respond5' | 'test12' | '1234-5678-9123-1246' | '9876-1246' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_ITEM_SHIPPED' | Actions.ACTION_SLNP_RESPONDER_SUPPLIER_FILL_AND_MARK_SHIPPED | 'slnpSupplierFillAndMarkShipped' | false - 'RSSlnpOne' | 'respond7' | 'test14' | '1234-5678-9123-1248' | '9876-1248' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_UNFILLED' | Actions.ACTION_RESPONDER_SUPPLIER_CANNOT_SUPPLY | 'supplierCannotSupply' | false - 'RSSlnpOne' | 'respond8' | 'test15' | '1234-5678-9123-1244' | '9876-1244' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_ABORTED' | Actions.ACTION_SLNP_RESPONDER_ABORT_SUPPLY | 'slnpResponderAbortSupply' | false - 'RSSlnpOne' | 'respond9' | 'test16' | '1234-5678-9123-1242' | '9876-1242' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_AWAIT_PICKING' | Actions.ACTION_RESPONDER_SUPPLIER_PRINT_PULL_SLIP | 'supplierPrintPullSlip' | false - 'RSSlnpThree' | 'respond10' | 'test17' | '1234-5678-9123-1252' | '9876-4444' | 'ISIL:RSS3' | 'SLNP_RES_ITEM_SHIPPED' | 'SLNP_RES_COMPLETE' | Actions.ACTION_SLNP_RESPONDER_SUPPLIER_CHECKOUT_OF_RESHARE | 'slnpSupplierCheckOutOfReshare' | false + tenantId | requestTitle | requestAuthor | requestSystemId | requestPatronId | requestSymbol | initialState | resultState | action | testQualifier | jsonFileName | isRequester + 'RSSlnpOne' | 'request1' | 'test1' | '1234-5678-9123-1231' | '9876-1231' | 'ISIL:RSS1' | 'SLNP_REQ_IDLE' | 'SLNP_REQ_CANCELLED' | Actions.ACTION_REQUESTER_REQUESTER_CANCEL | null | 'slnpRequesterCancel' | true + 'RSSlnpOne' | 'request2' | 'test2' | '1234-5678-9123-1232' | '9876-1232' | 'ISIL:RSS1' | 'SLNP_REQ_ABORTED' | 'SLNP_REQ_CANCELLED' | Actions.ACTION_SLNP_REQUESTER_HANDLE_ABORT | null | 'slnpRequesterHandleAbort' | true + 'RSSlnpOne' | 'request3' | 'test3' | '1234-5678-9123-1233' | '9876-1233' | 'ISIL:RSS1' | 'SLNP_REQ_SHIPPED' | 'SLNP_REQ_CHECKED_IN' | Actions.ACTION_SLNP_REQUESTER_REQUESTER_RECEIVED | null | 'slnpRequesterRequesterReceived' | true + 'RSSlnpOne' | 'request4' | 'test4' | '1234-5678-9123-1234' | '9876-1235' | 'ISIL:RSS1' | 'SLNP_REQ_CHECKED_IN' | 'SLNP_REQ_AWAITING_RETURN_SHIPPING' | Actions.ACTION_REQUESTER_PATRON_RETURNED_ITEM | null | 'patronReturnedItem' | true + 'RSSlnpOne' | 'request41' | 'test41' | '1234-5678-9123-1234' | '9876-1235' | 'ISIL:RSS1' | 'SLNP_REQ_CHECKED_IN' | 'SLNP_REQ_COMPLETE' | Actions.ACTION_REQUESTER_PATRON_RETURNED_ITEM_AND_SHIPPED | null | 'patronReturnedItemAndShippedReturn' | true + 'RSSlnpOne' | 'request5' | 'test5' | '1234-5678-9123-1235' | '9876-1237' | 'ISIL:RSS1' | 'SLNP_REQ_AWAITING_RETURN_SHIPPING' | 'SLNP_REQ_COMPLETE' | Actions.ACTION_REQUESTER_SHIPPED_RETURN | null | 'shippedReturn' | true + 'RSSlnpOne' | 'request6' | 'test6' | '1234-5678-9123-1299' | '9876-1299' | 'ISIL:RSS1' | 'SLNP_REQ_CHECKED_IN' | 'SLNP_REQ_ITEM_LOST' | Actions.ACTION_SLNP_REQUESTER_MARK_ITEM_LOST | null | 'slnpRequesterMarkItemLost' | true + 'RSSlnpOne' | 'respond1' | 'test8' | '1234-5678-9123-1238' | '9876-1238' | 'ISIL:RSS1' | 'SLNP_RES_IDLE' | 'SLNP_RES_AWAIT_PICKING' | Actions.ACTION_SLNP_RESPONDER_RESPOND_YES | null | 'slnpSupplierAnswerYes' | false + 'RSSlnpOne' | 'respond2' | 'test9' | '1234-5678-9123-1239' | '9876-1239' | 'ISIL:RSS1' | 'SLNP_RES_IDLE' | 'SLNP_RES_UNFILLED' | Actions.ACTION_RESPONDER_SUPPLIER_CANNOT_SUPPLY | null | 'supplierCannotSupply' | false + 'RSSlnpOne' | 'respond3' | 'test10' | '1234-5678-9123-1240' | '9876-1240' | 'ISIL:RSS1' | 'SLNP_RES_IDLE' | 'SLNP_RES_ABORTED' | Actions.ACTION_SLNP_RESPONDER_ABORT_SUPPLY | null | 'slnpResponderAbortSupply' | false + 'RSSlnpOne' | 'respond5' | 'test12' | '1234-5678-9123-1246' | '9876-1246' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_ITEM_SHIPPED' | Actions.ACTION_SLNP_RESPONDER_SUPPLIER_FILL_AND_MARK_SHIPPED | null | 'slnpSupplierFillAndMarkShipped' | false + 'RSSlnpOne' | 'respond7' | 'test14' | '1234-5678-9123-1248' | '9876-1248' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_UNFILLED' | Actions.ACTION_RESPONDER_SUPPLIER_CANNOT_SUPPLY | null | 'supplierCannotSupply' | false + 'RSSlnpOne' | 'respond8' | 'test15' | '1234-5678-9123-1244' | '9876-1244' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_ABORTED' | Actions.ACTION_SLNP_RESPONDER_ABORT_SUPPLY | null | 'slnpResponderAbortSupply' | false + 'RSSlnpOne' | 'respond9' | 'test16' | '1234-5678-9123-1242' | '9876-1242' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_AWAIT_PICKING' | Actions.ACTION_RESPONDER_SUPPLIER_PRINT_PULL_SLIP | null | 'supplierPrintPullSlip' | false + 'RSSlnpThree' | 'respond10' | 'test17' | '1234-5678-9123-1252' | '9876-4444' | 'ISIL:RSS3' | 'SLNP_RES_ITEM_SHIPPED' | 'SLNP_RES_COMPLETE' | Actions.ACTION_SLNP_RESPONDER_SUPPLIER_CHECKOUT_OF_RESHARE | null | 'slnpSupplierCheckOutOfReshare' | false + 'RSSlnpOne' | 'request7' | 'test18' | '1234-5678-9123-1250' | '9876-4445' | 'ISIL:RSS1' | 'SLNP_REQ_IDLE' | 'SLNP_REQ_CANCELLED' | Actions.ACTION_MANUAL_CLOSE | Status.SLNP_REQUESTER_CANCELLED | 'slnpRequesterManualCloseCancel' | true + 'RSSlnpThree' | 'respond11' | 'test19' | '1234-5678-9123-1253' | '9876-4446' | 'ISIL:RSS3' | 'SLNP_RES_ITEM_SHIPPED' | 'SLNP_RES_COMPLETE' | Actions.ACTION_MANUAL_CLOSE | Status.SLNP_RESPONDER_COMPLETE | 'slnpResponderManualCloseComplete' | false + } void "Test event responder new SLNP patron request inidication service"( @@ -778,6 +782,7 @@ class SLNPStateModelSpec extends TestBase { String requestSymbol, String initialState, String resultState, + String testQualifier, String action, String jsonFileName, Boolean isRequester) { @@ -810,7 +815,7 @@ class SLNPStateModelSpec extends TestBase { performAction(slnpPatronRequest?.id, jsonFileName) // Validate result status after performed action - NewStatusResult newResultStatus = statusService.lookupStatus(slnpPatronRequest, action, null, true, true) + NewStatusResult newResultStatus = statusService.lookupStatus(slnpPatronRequest, action, testQualifier, true, true) validateStateTransition(newResultStatus, resultState) } @@ -818,16 +823,19 @@ class SLNPStateModelSpec extends TestBase { assert true; where: - tenantId | requestTitle | requestAuthor | requestSystemId | requestPatronId | requestSymbol | initialState | resultState | action | jsonFileName | isRequester - 'RSSlnpOne' | 'request1nrs' | 'test1nrs' | '1234-5678-9123-2221' | '9876-7771' | 'ISIL:RSS1' | 'SLNP_REQ_IDLE' | 'SLNP_REQ_CANCELLED' | Actions.ACTION_REQUESTER_REQUESTER_CANCEL | 'slnpRequesterCancel' | true - 'RSSlnpOne' | 'request2nrs' | 'test2nrs' | '1234-5678-9123-2222' | '9876-7772' | 'ISIL:RSS1' | 'SLNP_REQ_ABORTED' | 'SLNP_REQ_CANCELLED' | Actions.ACTION_SLNP_REQUESTER_HANDLE_ABORT | 'slnpRequesterHandleAbort' | true - 'RSSlnpOne' | 'request3nrs' | 'test3nrs' | '1234-5678-9123-2223' | '9876-7773' | 'ISIL:RSS1' | 'SLNP_REQ_DOCUMENT_AVAILABLE' | 'SLNP_REQ_DOCUMENT_SUPPLIED' | Actions.ACTION_SLNP_NON_RETURNABLE_REQUESTER_REQUESTER_RECEIVED | 'slnpNonReturnableRequesterRequesterReceived' | true - 'RSSlnpOne' | 'request4nrs' | 'test4nrs' | '1234-5678-9123-2224' | '9876-7774' | 'ISIL:RSS1' | 'SLNP_REQ_IDLE' | 'SLNP_REQ_DOCUMENT_SUPPLIED' | Actions.ACTION_SLNP_NON_RETURNABLE_REQUESTER_MANUALLY_MARK_SUPPLIED | 'manuallyMarkSupplied' | true - 'RSSlnpOne' | 'request5nrs' | 'test5nrs' | '1234-5678-9123-2234' | '9876-7274' | 'ISIL:RSS1' | 'SLNP_REQ_IDLE' | 'SLNP_REQ_DOCUMENT_AVAILABLE' | Actions.ACTION_SLNP_NON_RETURNABLE_REQUESTER_MANUALLY_MARK_AVAILABLE | 'manuallyMarkAvailable' | true - 'RSSlnpOne' | 'supply1nrs' | 'test5nrs' | '1234-5678-9123-2225' | '9876-7775' | 'ISIL:RSS1' | 'SLNP_RES_NEW_AWAIT_PULL_SLIP' | 'SLNP_RES_AWAIT_PICKING' | Actions.ACTION_RESPONDER_SUPPLIER_PRINT_PULL_SLIP | 'supplierPrintPullSlip' | false - 'RSSlnpOne' | 'supply2nrs' | 'test6nrs' | '1234-5678-9123-2226' | '9876-7776' | 'ISIL:RSS1' | 'SLNP_RES_NEW_AWAIT_PULL_SLIP' | 'SLNP_RES_UNFILLED' | Actions.ACTION_RESPONDER_SUPPLIER_CANNOT_SUPPLY | 'supplierCannotSupply' | false - 'RSSlnpOne' | 'supply3nrs' | 'test7nrs' | '1234-5678-9123-2217' | '9876-7717' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_DOCUMENT_SUPPLIED' | Actions.ACTION_SLNP_RESPONDER_SUPPLIER_SUPPLIES_DOCUMENT | 'slnpNonReturnableSupplierSuppliesDocument' | false - 'RSSlnpOne' | 'supply4nrs' | 'test8nrs' | '1234-5678-9123-2218' | '9876-7718' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_UNFILLED' | Actions.ACTION_RESPONDER_SUPPLIER_CANNOT_SUPPLY | 'supplierCannotSupply' | false + tenantId | requestTitle | requestAuthor | requestSystemId | requestPatronId | requestSymbol | initialState | resultState | testQualifier | action | jsonFileName | isRequester + 'RSSlnpOne' | 'request1nrs' | 'test1nrs' | '1234-5678-9123-2221' | '9876-7771' | 'ISIL:RSS1' | 'SLNP_REQ_IDLE' | 'SLNP_REQ_CANCELLED' | null | Actions.ACTION_REQUESTER_REQUESTER_CANCEL | 'slnpRequesterCancel' | true + 'RSSlnpOne' | 'request2nrs' | 'test2nrs' | '1234-5678-9123-2222' | '9876-7772' | 'ISIL:RSS1' | 'SLNP_REQ_ABORTED' | 'SLNP_REQ_CANCELLED' | null | Actions.ACTION_SLNP_REQUESTER_HANDLE_ABORT | 'slnpRequesterHandleAbort' | true + 'RSSlnpOne' | 'request3nrs' | 'test3nrs' | '1234-5678-9123-2223' | '9876-7773' | 'ISIL:RSS1' | 'SLNP_REQ_DOCUMENT_AVAILABLE' | 'SLNP_REQ_DOCUMENT_SUPPLIED' | null | Actions.ACTION_SLNP_NON_RETURNABLE_REQUESTER_REQUESTER_RECEIVED | 'slnpNonReturnableRequesterRequesterReceived' | true + 'RSSlnpOne' | 'request4nrs' | 'test4nrs' | '1234-5678-9123-2224' | '9876-7774' | 'ISIL:RSS1' | 'SLNP_REQ_IDLE' | 'SLNP_REQ_DOCUMENT_SUPPLIED' | null | Actions.ACTION_SLNP_NON_RETURNABLE_REQUESTER_MANUALLY_MARK_SUPPLIED | 'manuallyMarkSupplied' | true + 'RSSlnpOne' | 'supply1nrs' | 'test5nrs' | '1234-5678-9123-2225' | '9876-7775' | 'ISIL:RSS1' | 'SLNP_RES_NEW_AWAIT_PULL_SLIP' | 'SLNP_RES_AWAIT_PICKING' | null | Actions.ACTION_RESPONDER_SUPPLIER_PRINT_PULL_SLIP | 'supplierPrintPullSlip' | false + 'RSSlnpOne' | 'supply2nrs' | 'test6nrs' | '1234-5678-9123-2226' | '9876-7776' | 'ISIL:RSS1' | 'SLNP_RES_NEW_AWAIT_PULL_SLIP' | 'SLNP_RES_UNFILLED' | null | Actions.ACTION_RESPONDER_SUPPLIER_CANNOT_SUPPLY | 'supplierCannotSupply' | false + 'RSSlnpOne' | 'supply3nrs' | 'test7nrs' | '1234-5678-9123-2217' | '9876-7717' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_DOCUMENT_SUPPLIED' | null | Actions.ACTION_SLNP_RESPONDER_SUPPLIER_SUPPLIES_DOCUMENT | 'slnpNonReturnableSupplierSuppliesDocument' | false + 'RSSlnpOne' | 'supply4nrs' | 'test8nrs' | '1234-5678-9123-2218' | '9876-7718' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_UNFILLED' | null | Actions.ACTION_RESPONDER_SUPPLIER_CANNOT_SUPPLY | 'supplierCannotSupply' | false + 'RSSlnpOne' | 'supply5nrs' | 'test9nrs' | '1234-5678-9123-2219' | '9876-7719' | 'ISIL:RSS1' | 'SLNP_RES_AWAIT_PICKING' | 'SLNP_RES_UNFILLED' | Status.SLNP_RESPONDER_UNFILLED | Actions.ACTION_MANUAL_CLOSE | 'manualCloseSLNPSupplierUnfilled' | false + 'RSSlnpOne' | 'request5nrs' | 'test10nrs' | '1234-5678-9123-2220' | '9876-7720' | 'ISIL:RSS1' | 'SLNP_REQ_IDLE' | 'SLNP_REQ_DOCUMENT_SUPPLIED' | Status.SLNP_REQUESTER_DOCUMENT_SUPPLIED | Actions.ACTION_MANUAL_CLOSE | 'manualCloseSLNPDocumentSupplied' | true + + } void "Test end to end actions and events from supplier to requester for nonreturnables"( diff --git a/service/src/integration-test/resources/scenarios/manualCloseSLNPDocumentSupplied.json b/service/src/integration-test/resources/scenarios/manualCloseSLNPDocumentSupplied.json new file mode 100644 index 000000000..b2be21855 --- /dev/null +++ b/service/src/integration-test/resources/scenarios/manualCloseSLNPDocumentSupplied.json @@ -0,0 +1,4 @@ +{ + "action": "manualClose", + "actionParams": { "terminalState" : "SLNP_REQ_DOCUMENT_SUPPLIED" } +} \ No newline at end of file diff --git a/service/src/integration-test/resources/scenarios/manualCloseSLNPSupplierUnfilled.json b/service/src/integration-test/resources/scenarios/manualCloseSLNPSupplierUnfilled.json new file mode 100644 index 000000000..2010ab99d --- /dev/null +++ b/service/src/integration-test/resources/scenarios/manualCloseSLNPSupplierUnfilled.json @@ -0,0 +1,4 @@ +{ + "action": "manualClose", + "actionParams": { "terminalState" : "SLNP_RES_UNFILLED" } +} \ No newline at end of file diff --git a/service/src/integration-test/resources/scenarios/slnpRequesterManualCloseCancel.json b/service/src/integration-test/resources/scenarios/slnpRequesterManualCloseCancel.json new file mode 100644 index 000000000..44cb1d284 --- /dev/null +++ b/service/src/integration-test/resources/scenarios/slnpRequesterManualCloseCancel.json @@ -0,0 +1,4 @@ +{ + "action": "manualClose", + "actionParams": { "terminalState" : "SLNP_REQ_CANCELLED" } +} \ No newline at end of file diff --git a/service/src/integration-test/resources/scenarios/slnpResponderManualCloseComplete.json b/service/src/integration-test/resources/scenarios/slnpResponderManualCloseComplete.json new file mode 100644 index 000000000..a3ad74040 --- /dev/null +++ b/service/src/integration-test/resources/scenarios/slnpResponderManualCloseComplete.json @@ -0,0 +1,4 @@ +{ + "action": "manualClose", + "actionParams": { "terminalState" : "SLNP_RES_COMPLETE" } +} \ No newline at end of file diff --git a/service/src/main/groovy/org/olf/rs/referenceData/SLNPNonReturnablesStateModelData.groovy b/service/src/main/groovy/org/olf/rs/referenceData/SLNPNonReturnablesStateModelData.groovy index b7a2f2aa5..904109be1 100644 --- a/service/src/main/groovy/org/olf/rs/referenceData/SLNPNonReturnablesStateModelData.groovy +++ b/service/src/main/groovy/org/olf/rs/referenceData/SLNPNonReturnablesStateModelData.groovy @@ -75,6 +75,37 @@ public class SLNPNonReturnablesStateModelData { nextActionEvent : null ]; + private static Map slnpNonReturnableRequesterManualCloseCancelled = [ + code: 'slnpNonReturnableRequesterManualCloseCancelled', + description: 'Manually closing because the request is cancelled', + result: true, + status: Status.SLNP_REQUESTER_CANCELLED, + qualifier: Status.SLNP_REQUESTER_CANCELLED, + saveRestoreState: null, + nextActionEvent : null + ]; + + private static Map slnpNonReturnableRequesterManualCloseDocumentSupplied = [ + code: 'slnpNonReturnableRequesterManualCloseDocumentSupplied', + description: 'Manually closing because the document was supplied', + result: true, + status: Status.SLNP_REQUESTER_DOCUMENT_SUPPLIED, + qualifier: Status.SLNP_REQUESTER_DOCUMENT_SUPPLIED, + saveRestoreState: null, + nextActionEvent : null + ]; + + private static Map slnpNonReturnableRequesterManualClosePatronInvalid = [ + code: 'slnpNonReturnableRequesterManualClosePatronInvalid', + description: 'Manually closing because the patron is invalid', + result: true, + status: Status.SLNP_REQUESTER_PATRON_INVALID, + qualifier: Status.SLNP_REQUESTER_PATRON_INVALID, + saveRestoreState: null, + nextActionEvent : null + ]; + + private static Map slnpNonReturnableResponderSupplierSuppliesDocument = [ code: 'slnpNonReturnableResponderSupplierSuppliesDocument', description: 'The document has been uploaded to a server in ZFL to fill the request. No message is sent.', @@ -85,6 +116,50 @@ public class SLNPNonReturnablesStateModelData { nextActionEvent : null ]; + private static Map slnpNonReturnableResponderManualCloseUnfilled = [ + code: 'slnpNonReturnableResponderManualCloseUnfilled', + description: 'Manually closing because the request was unfilled', + result: true, + status: Status.SLNP_RESPONDER_UNFILLED, + qualifier: Status.SLNP_RESPONDER_UNFILLED, + saveRestoreState: null, + nextActionEvent : null + ]; + + private static Map slnpNonReturnableResponderManualCloseAborted = [ + code: 'slnpNonReturnableResponderManualCloseAborted', + description: 'Manually closing because the request was aborted', + result: true, + status: Status.SLNP_RESPONDER_ABORTED, + qualifier: Status.SLNP_RESPONDER_ABORTED, + saveRestoreState: null, + nextActionEvent : null + ]; + + private static Map slnpNonReturnableResponderManualCloseComplete = [ + code: 'slnpNonReturnableResponderManualCloseComplete', + description: 'Manually closing because the request was completed', + result: true, + status: Status.SLNP_RESPONDER_COMPLETE, + qualifier: Status.SLNP_RESPONDER_COMPLETE, + saveRestoreState: null, + nextActionEvent : null + ]; + + + //Define Lists + + private static Map slnpNonReturnableResponderCloseManualList = [ + code: ActionEventResultList.SLNP_NON_RETURNABLE_RESPONDER_CLOSE_MANUAL, + description: 'The responder is terminating this request', + model: StateModel.MODEL_SLNP_RESPONDER, + results: [ + slnpNonReturnableResponderManualCloseUnfilled, + slnpNonReturnableResponderManualCloseAborted, + slnpNonReturnableResponderManualCloseComplete + ] + ]; + // Requester Event lists private static Map slnpNonReturnableRequesterCancelList = [ @@ -145,6 +220,17 @@ public class SLNPNonReturnablesStateModelData { ] ]; + private static Map slnpNonReturnableRequesterCloseManualList = [ + code: ActionEventResultList.SLNP_NON_RETURNABLE_REQUESTER_CLOSE_MANUAL, + description: 'The requester is terminating this request', + model: StateModel.MODEL_SLNP_NON_RETURNABLE_REQUESTER, + results: [ + slnpNonReturnableRequesterManualCloseCancelled, + slnpNonReturnableRequesterManualCloseDocumentSupplied, + slnpNonReturnableRequesterManualClosePatronInvalid, + ] + ]; + // Responder Event lists private static Map slnpNonReturnableResponderRespondCannotSupplyList = [ @@ -181,10 +267,12 @@ public class SLNPNonReturnablesStateModelData { slnpNonReturnableRequesterReceivedList, slnpNonReturnableRequesterManuallyMarkSuppliedList, slnpNonReturnableRequesterManuallyMarkAvailableList, + slnpNonReturnableRequesterCloseManualList, slnpNonReturnableResponderRespondCannotSupplyList, slnpNonReturnableResponderSupplierPrintPullSlipList, - slnpNonReturnableResponderSupplierSuppliesDocumentList + slnpNonReturnableResponderSupplierSuppliesDocumentList, + slnpNonReturnableResponderCloseManualList ]; public static void loadStatusData() { @@ -241,8 +329,14 @@ public class SLNPNonReturnablesStateModelData { // SLNP_RES_AWAIT_PICKING OR "Searching" AvailableAction.ensure(StateModel.MODEL_SLNP_NON_RETURNABLE_RESPONDER, Status.SLNP_RESPONDER_AWAIT_PICKING, Actions.ACTION_SLNP_RESPONDER_SUPPLIER_SUPPLIES_DOCUMENT, AvailableAction.TRIGGER_TYPE_MANUAL, ActionEventResultList.SLNP_NON_RETURNABLE_RESPONDER_SUPPLIER_SUPPLIES_DOCUMENT); AvailableAction.ensure(StateModel.MODEL_SLNP_NON_RETURNABLE_RESPONDER, Status.SLNP_RESPONDER_AWAIT_PICKING, Actions.ACTION_RESPONDER_SUPPLIER_CANNOT_SUPPLY, AvailableAction.TRIGGER_TYPE_MANUAL, ActionEventResultList.SLNP_NON_RETURNABLE_RESPONDER_CANNOT_SUPPLY); + + // Manual Close + AvailableActionData.assignToNonTerminalStates(StateModel.MODEL_SLNP_NON_RETURNABLE_REQUESTER, Actions.ACTION_MANUAL_CLOSE, AvailableAction.TRIGGER_TYPE_MANUAL, ActionEventResultList.SLNP_NON_RETURNABLE_REQUESTER_CLOSE_MANUAL) + AvailableActionData.assignToNonTerminalStates(StateModel.MODEL_SLNP_NON_RETURNABLE_RESPONDER, Actions.ACTION_MANUAL_CLOSE, AvailableAction.TRIGGER_TYPE_MANUAL, ActionEventResultList.SLNP_NON_RETURNABLE_RESPONDER_CLOSE_MANUAL) } + + public static void loadActionEventData() { ActionEvent.ensure(Actions.ACTION_SLNP_NON_RETURNABLE_REQUESTER_REQUESTER_RECEIVED, 'Mark received and complete the request. This action is for BVB.', true, StateModel.MODEL_SLNP_NON_RETURNABLE_REQUESTER.capitalize() + Actions.ACTION_SLNP_NON_RETURNABLE_REQUESTER_REQUESTER_RECEIVED.capitalize(), ActionEventResultList.SLNP_NON_RETURNABLE_REQUESTER_RECEIVED, true); ActionEvent.ensure(Actions.ACTION_SLNP_RESPONDER_SUPPLIER_SUPPLIES_DOCUMENT, 'The document has been uploaded to a server in ZFL to fill the request. No message is sent.', true, StateModel.MODEL_SLNP_NON_RETURNABLE_RESPONDER.capitalize() + Actions.ACTION_SLNP_RESPONDER_SUPPLIER_SUPPLIES_DOCUMENT.capitalize(), ActionEventResultList.SLNP_NON_RETURNABLE_RESPONDER_SUPPLIER_SUPPLIES_DOCUMENT, true); diff --git a/service/src/main/groovy/org/olf/rs/referenceData/SLNPStateModelData.groovy b/service/src/main/groovy/org/olf/rs/referenceData/SLNPStateModelData.groovy index ce9a76cbe..55664819b 100644 --- a/service/src/main/groovy/org/olf/rs/referenceData/SLNPStateModelData.groovy +++ b/service/src/main/groovy/org/olf/rs/referenceData/SLNPStateModelData.groovy @@ -124,6 +124,46 @@ public class SLNPStateModelData { nextActionEvent : null ]; + private static Map slnpRequesterManualCloseCancelled = [ + code: 'slnpRequesterManualCloseCancelled', + description: 'Requester is closing this request as cancelled', + result: true, + status: Status.SLNP_REQUESTER_CANCELLED, + qualifier: Status.SLNP_REQUESTER_CANCELLED, + saveRestoreState: null, + nextActionEvent: null + ]; + + private static Map slnpRequesterManualCloseComplete = [ + code: 'slnpRequesterManualCloseComplete', + description: 'Requester is closing this request as completed', + result: true, + status: Status.SLNP_REQUESTER_COMPLETE, + qualifier: Status.SLNP_REQUESTER_COMPLETE, + saveRestoreState: null, + nextActionEvent: null + ]; + + private static Map slnpRequesterManualCloseItemLost = [ + code: 'slnpRequesterManualCloseItemLost', + description: 'Requester is closing this request as lost', + result: true, + status: Status.SLNP_REQUESTER_ITEM_LOST, + qualifier: Status.SLNP_REQUESTER_ITEM_LOST, + saveRestoreState: null, + nextActionEvent: null + ]; + + private static Map slnpRequesterManualClosePatronInvalid = [ + code: 'slnpRequesterManualClosePatronInvalid', + description: 'Requester is closing this request due to invalid patron', + result: true, + status: Status.SLNP_REQUESTER_PATRON_INVALID, + qualifier: Status.SLNP_REQUESTER_PATRON_INVALID, + saveRestoreState: null, + nextActionEvent: null + ]; + public static Map slnpResponderRespondYes = [ code: 'slnpResponderRespondYes', description: 'Item has been located and we expect to supply, staff is awaiting printing pull slip', @@ -244,6 +284,7 @@ public class SLNPStateModelData { nextActionEvent: null ]; + private static Map slnpResponderNewPatronRequestIndRequestItemUnfilled = [ code: 'slnpResponderNewPatronRequestIndRequestItemUnfilled', description: 'Event triggered by incoming request, respond with message Unfilled', @@ -254,6 +295,36 @@ public class SLNPStateModelData { nextActionEvent: null ]; + private static Map slnpResponderManualCloseUnfilled = [ + code: 'slnpResponderManualCloseUnfilled', + description: 'Responder is closing this request as unfilled', + result: true, + status: Status.SLNP_RESPONDER_UNFILLED, + qualifier: Status.SLNP_RESPONDER_UNFILLED, //Qualifier matches state name? + saveRestoreState: null, + nextActionEvent: null + ] + + private static Map slnpResponderManualCloseAborted = [ + code: 'slnpResponderManualCloseAborted', + description: 'Responder is closing this request as aborted', + result: true, + status: Status.SLNP_RESPONDER_ABORTED, + qualifier: Status.SLNP_RESPONDER_ABORTED, //Qualifier matches state name? + saveRestoreState: null, + nextActionEvent: null + ] + + private static Map slnpResponderManualCloseComplete = [ + code: 'slnpResponderManualCloseComplete', + description: 'Responder is closing this request as completed', + result: true, + status: Status.SLNP_RESPONDER_COMPLETE, + qualifier: Status.SLNP_RESPONDER_COMPLETE, //Qualifier matches state name? + saveRestoreState: null, + nextActionEvent: null + ] + // SLNP Requester lists private static Map slnpRequesterCancelList = [ @@ -321,6 +392,18 @@ public class SLNPStateModelData { ] ]; + private static Map slnpRequesterCloseManualList = [ + code: ActionEventResultList.SLNP_REQUESTER_CLOSE_MANUAL, + description: 'The requester is terminating this request', + model: StateModel.MODEL_SLNP_REQUESTER, + results: [ + slnpRequesterManualCloseCancelled, + slnpRequesterManualCloseComplete, + slnpRequesterManualCloseItemLost, + slnpRequesterManualClosePatronInvalid + ] + ] + // SLNP responder lists private static Map slnpResponderRespondYesList = [ code: ActionEventResultList.SLNP_RESPONDER_RESPOND_YES, @@ -390,6 +473,17 @@ public class SLNPStateModelData { ] ]; + private static Map slnpResponderCloseManualList = [ + code: ActionEventResultList.SLNP_RESPONDER_CLOSE_MANUAL, + description: 'The responder is terminating this request', + model: StateModel.MODEL_SLNP_RESPONDER, + results: [ + slnpResponderManualCloseUnfilled, + slnpResponderManualCloseAborted, + slnpResponderManualCloseComplete + ] + ] + private static Map[] resultLists = [ slnpRequesterCancelList, slnpRequesterReceivedList, @@ -397,6 +491,7 @@ public class SLNPStateModelData { slnpRequesterCheckedInList, slnpRequesterShippedReturnList, slnpRequesterISO18626StatusChangeList, + slnpRequesterCloseManualList, slnpResponderRespondYesList, slnpResponderRespondCannotSupplyList, slnpResponderAbortSupplyList, @@ -404,7 +499,8 @@ public class SLNPStateModelData { slnpResponderSupplierFillAndMarkShippedList, slnpResponderCheckoutOfReshareList, slnpResponderNewPatronRequestIndList, - slnpRequesterMarkItemLostList + slnpRequesterMarkItemLostList, + slnpResponderCloseManualList ]; public static void loadStatusData() { @@ -500,6 +596,10 @@ public class SLNPStateModelData { // SLNP_REQ_AWAITING_RETURN_SHIPPING OR "Awaiting return shipping" AvailableAction.ensure(StateModel.MODEL_SLNP_REQUESTER, Status.SLNP_REQUESTER_AWAITING_RETURN_SHIPPING, Actions.ACTION_REQUESTER_SHIPPED_RETURN, AvailableAction.TRIGGER_TYPE_MANUAL, ActionEventResultList.SLNP_REQUESTER_SHIPPED_RETURN, null, Boolean.TRUE, Boolean.FALSE); + + // Manual close + AvailableActionData.assignToNonTerminalStates(StateModel.MODEL_SLNP_REQUESTER, Actions.ACTION_MANUAL_CLOSE, AvailableAction.TRIGGER_TYPE_MANUAL, ActionEventResultList.SLNP_REQUESTER_CLOSE_MANUAL) + AvailableActionData.assignToNonTerminalStates(StateModel.MODEL_SLNP_RESPONDER, Actions.ACTION_MANUAL_CLOSE, AvailableAction.TRIGGER_TYPE_MANUAL, ActionEventResultList.SLNP_RESPONDER_CLOSE_MANUAL) } public static void loadActionEventData() { diff --git a/tools/testing/docker-compose-apple-m2.yml b/tools/testing/docker-compose-apple-m2.yml index 5e58d10d4..e17c1bcbe 100644 --- a/tools/testing/docker-compose-apple-m2.yml +++ b/tools/testing/docker-compose-apple-m2.yml @@ -62,7 +62,7 @@ services: minio: container_name: minio_tests hostname: docker.for.mac.localhost - image: docker.io/bitnami/minio:2023.3.24 + image: docker.io/bitnamilegacy/minio:2023.3.24 environment: - MINIO_ROOT_USER=DEVDEVDEV001 - MINIO_ROOT_PASSWORD=DEVDEVDEV001 @@ -78,7 +78,7 @@ services: setup: container_name: minio_setup - image: docker.io/bitnami/minio:2024.3.30 + image: docker.io/bitnamilegacy/minio:2024.3.30 depends_on: - minio volumes: @@ -119,4 +119,4 @@ services: networks: kafka_net: - driver: "bridge" \ No newline at end of file + driver: "bridge" diff --git a/tools/testing/docker-compose.yml b/tools/testing/docker-compose.yml index 2a52395dd..941927e0a 100644 --- a/tools/testing/docker-compose.yml +++ b/tools/testing/docker-compose.yml @@ -1,4 +1,3 @@ -version: "2.1" volumes: lsp_pgdata: @@ -60,7 +59,7 @@ services: minio: container_name: minio_tests hostname: minio - image: docker.io/bitnami/minio:2023.3.24 + image: docker.io/bitnamilegacy/minio:2023.3.24 environment: - MINIO_ROOT_USER=DEVDEVDEV001 - MINIO_ROOT_PASSWORD=DEVDEVDEV001 @@ -76,7 +75,7 @@ services: setup: container_name: minio_setup - image: docker.io/bitnami/minio:2023.3.24 + image: docker.io/bitnamilegacy/minio:2023.3.24 depends_on: - minio volumes: