diff --git a/service/grails-app/domain/org/olf/rs/statemodel/Status.groovy b/service/grails-app/domain/org/olf/rs/statemodel/Status.groovy index a5d7c724b..e571deaf9 100644 --- a/service/grails-app/domain/org/olf/rs/statemodel/Status.groovy +++ b/service/grails-app/domain/org/olf/rs/statemodel/Status.groovy @@ -41,6 +41,7 @@ class Status implements MultiTenant { public static final String PATRON_REQUEST_WILL_SUPPLY = "REQ_WILL_SUPPLY"; public static final String PATRON_REQUEST_DELIVERED = "REQ_DELIVERED"; public static final String PATRON_REQUEST_COMPLETE = "REQ_COMPLETE"; + public static final String PATRON_REQUEST_REREQUESTED = "REQ_REREQUESTED"; public static final String REQUESTER_LOANED_DIGITALLY = "REQ_LOANED_DIGITALLY"; diff --git a/service/grails-app/services/org/olf/rs/RerequestService.groovy b/service/grails-app/services/org/olf/rs/RerequestService.groovy new file mode 100644 index 000000000..01046f942 --- /dev/null +++ b/service/grails-app/services/org/olf/rs/RerequestService.groovy @@ -0,0 +1,28 @@ +package org.olf.rs + +/** + * Handle creating a new request from an existing one + */ + + +public class RerequestService { + public static List preserveFields = ['author','edition','isbn','isRequester','issn','issue','neededBy','numberOfPages','oclcNumber','patronEmail','patronGivenName','patronIdentifier','patronNote','patronReference','patronSurname','patronType','pickLocation','pickupLocationSlug','placeOfPublication','publicationDate','publisher','requestingInstitutionSymbol','sponsoringBody','startPage','stateModel','subtitle','systemInstanceIdentifier','title','volume']; + + public createNewRequestFromExisting(PatronRequest originalRequest, List copyFields, Map changeSet) { + PatronRequest newRequest = new PatronRequest(); + copyFields.each { + if (changeSet.containsKey(it)) { + newRequest[it] = changeSet.get(it); + } else { + newRequest[it] = originalRequest[it]; + } + } + originalRequest.succeededBy = newRequest; + newRequest.precededBy = originalRequest; + newRequest.save(); + originalRequest.save(); + + return newRequest; + } + +} diff --git a/service/grails-app/services/org/olf/rs/statemodel/actions/iso18626/ActionISO18626RequesterService.groovy b/service/grails-app/services/org/olf/rs/statemodel/actions/iso18626/ActionISO18626RequesterService.groovy index 4f6087ff1..1121eb3e2 100644 --- a/service/grails-app/services/org/olf/rs/statemodel/actions/iso18626/ActionISO18626RequesterService.groovy +++ b/service/grails-app/services/org/olf/rs/statemodel/actions/iso18626/ActionISO18626RequesterService.groovy @@ -1,4 +1,8 @@ -package org.olf.rs.statemodel.actions.iso18626; +package org.olf.rs.statemodel.actions.iso18626 + +import org.olf.rs.RerequestService +import org.olf.rs.SettingsService +import org.olf.rs.statemodel.StateModel; import java.util.regex.Matcher; @@ -18,8 +22,11 @@ import org.olf.rs.referenceData.SettingsData; public abstract class ActionISO18626RequesterService extends ActionISO18626Service { private static final String VOLUME_STATUS_AWAITING_TEMPORARY_ITEM_CREATION = 'awaiting_temporary_item_creation'; + private static final String SETTING_YES = 'yes'; StatusService statusService; + SettingsService settingsService; + RerequestService rerequestService; @Override ActionResultDetails performAction(PatronRequest request, Object parameters, ActionResultDetails actionResultDetails) { @@ -138,19 +145,45 @@ public abstract class ActionISO18626RequesterService extends ActionISO18626Servi } if (incomingStatus != null) { - handleStatusChange(request, incomingStatus, actionResultDetails); + handleStatusChange(request, incomingStatus, parameters, actionResultDetails); } return(actionResultDetails); } // ISO18626 states are RequestReceived, ExpectToSupply, WillSupply, Loaned Overdue, Recalled, RetryPossible, Unfilled, CopyCompleted, LoanCompleted, CompletedWithoutReturn and Cancelled - private void handleStatusChange(PatronRequest request, Map statusInfo, ActionResultDetails actionResultDetails) { + private void handleStatusChange(PatronRequest request, Map statusInfo, Object parameters, ActionResultDetails actionResultDetails) { log.debug("handleStatusChange(${request.id},${statusInfo})"); if (statusInfo.status) { // Set the qualifier on the result actionResultDetails.qualifier = statusInfo.status; + + // Special case for Unfilled + if (request.stateModel.shortcode.equalsIgnoreCase(StateModel.MODEL_REQUESTER)) { + if (statusInfo.status == "Unfilled") { + log.debug("Handling Unfilled status"); + if (parameters.messageInfo.reasonUnfilled == "transfer") { + log.debug("Unfilled result with reason 'transfer'"); + String pattern = /transferToCluster:(.+?)(#seq:.+#)?/ + String note = parameters.messageInfo.note; + if (note) { + def matcher = note =~ pattern; + if (matcher.matches()) { + String newCluster = matcher.group(1); + log.debug("Pattern match for transferring request to new cluster ${newCluster}"); + if (settingsService.hasSettingValue(SettingsData.SETTING_AUTO_REREQUEST, SETTING_YES)) { + //Trigger Re-Request here + actionResultDetails.qualifier = "UnfilledTransfer"; //To transition to Rerequested state + PatronRequest newRequest = rerequestService.createNewRequestFromExisting(request, RerequestService.preserveFields, ["systemInstanceIdentifier":newCluster]); + } + } else { + log.debug("reasonUnfilled was 'transfer', but a valid cluster id was not found in note: ${note}"); + } + } + } + } + } } } } diff --git a/service/grails-app/services/org/olf/rs/statemodel/actions/iso18626/ActionPatronRequestISO18626StatusChangeService.groovy b/service/grails-app/services/org/olf/rs/statemodel/actions/iso18626/ActionPatronRequestISO18626StatusChangeService.groovy index e1664bbda..7d0468b93 100644 --- a/service/grails-app/services/org/olf/rs/statemodel/actions/iso18626/ActionPatronRequestISO18626StatusChangeService.groovy +++ b/service/grails-app/services/org/olf/rs/statemodel/actions/iso18626/ActionPatronRequestISO18626StatusChangeService.groovy @@ -1,6 +1,8 @@ package org.olf.rs.statemodel.actions.iso18626 import org.olf.rs.PatronRequest +import org.olf.rs.RerequestService +import org.olf.rs.SettingsService import org.olf.rs.iso18626.ReasonForMessage import org.olf.rs.statemodel.ActionEventResultQualifier import org.olf.rs.statemodel.ActionResult @@ -16,6 +18,8 @@ import org.olf.rs.statemodel.StateModel */ public class ActionPatronRequestISO18626StatusChangeService extends ActionISO18626RequesterService { + SettingsService settingsService; + @Override String name() { return(ReasonForMessage.MESSAGE_REASON_STATUS_CHANGE) @@ -23,6 +27,7 @@ public class ActionPatronRequestISO18626StatusChangeService extends ActionISO186 @Override ActionResultDetails performAction(PatronRequest request, Object parameters, ActionResultDetails actionResultDetails) { + log.debug("ActionPatronRequestISO18626StatusChangeService performAction()"); // We have a hack where we use this message to verify that the last one sent was actually received or not if (!checkForLastSequence(request, parameters.messageInfo?.note, actionResultDetails)) { // A normal message diff --git a/service/grails-app/services/org/olf/rs/statemodel/events/EventStatusReqEndOfRotaReviewedIndService.groovy b/service/grails-app/services/org/olf/rs/statemodel/events/EventStatusReqEndOfRotaReviewedIndService.groovy new file mode 100644 index 000000000..a1015dfd9 --- /dev/null +++ b/service/grails-app/services/org/olf/rs/statemodel/events/EventStatusReqEndOfRotaReviewedIndService.groovy @@ -0,0 +1,26 @@ +package org.olf.rs.statemodel.events + +import org.olf.rs.PatronRequest +import org.olf.rs.referenceData.RefdataValueData +import org.olf.rs.statemodel.EventFetchRequestMethod +import org.olf.rs.statemodel.EventResultDetails + +class EventStatusReqEndOfRotaReviewedIndService extends EventTriggerNoticesService { + + @Override + String name() { + return(Events.EVENT_STATUS_REQ_END_OF_ROTA_REVIEWED_INDICATION); + } + + @Override + EventFetchRequestMethod fetchRequestMethod() { + return(EventFetchRequestMethod.PAYLOAD_ID); + } + + @Override + EventResultDetails processEvent(PatronRequest request, Map eventData, EventResultDetails eventResultDetails) { + triggerNotice(request, RefdataValueData.NOTICE_TRIGGER_END_OF_ROTA_REVIEWED); + + return eventResultDetails; + } +} diff --git a/service/grails-app/services/org/olf/rs/statemodel/events/EventStatusReqUnfilledIndService.groovy b/service/grails-app/services/org/olf/rs/statemodel/events/EventStatusReqUnfilledIndService.groovy index 582648151..72983c15b 100644 --- a/service/grails-app/services/org/olf/rs/statemodel/events/EventStatusReqUnfilledIndService.groovy +++ b/service/grails-app/services/org/olf/rs/statemodel/events/EventStatusReqUnfilledIndService.groovy @@ -1,5 +1,7 @@ -package org.olf.rs.statemodel.events; +package org.olf.rs.statemodel.events +import org.olf.rs.PatronRequest +import org.olf.rs.statemodel.EventResultDetails; import org.olf.rs.statemodel.Events; /** @@ -9,6 +11,11 @@ import org.olf.rs.statemodel.Events; */ public class EventStatusReqUnfilledIndService extends EventSendToNextLenderService { + @Override + EventResultDetails processEvent(PatronRequest request, Map eventData, EventResultDetails eventResultDetails) { + super.processEvent(request, eventData, eventResultDetails); + } + @Override String name() { return(Events.EVENT_STATUS_REQ_UNFILLED_INDICATION); diff --git a/service/src/integration-test/groovy/org/olf/RSLifecycleSpec.groovy b/service/src/integration-test/groovy/org/olf/RSLifecycleSpec.groovy index c20265ccb..a02037ad3 100644 --- a/service/src/integration-test/groovy/org/olf/RSLifecycleSpec.groovy +++ b/service/src/integration-test/groovy/org/olf/RSLifecycleSpec.groovy @@ -131,7 +131,7 @@ class RSLifecycleSpec extends TestBase { def cleanup() { } - + /* // For the given tenant, block up to timeout ms until the given request is found in the given state private String waitForRequestState(String tenant, long timeout, String patron_reference, String required_state) { long start_time = System.currentTimeMillis(); @@ -173,6 +173,61 @@ class RSLifecycleSpec extends TestBase { return request_id; } + */ + private String waitForRequestState(String tenant, long timeout, String patron_reference, String required_state) { + Map params = [ + 'max':'100', + 'offset':'0', + 'match':'patronReference', + 'term':patron_reference + ]; + return waitForRequestStateParams(tenant, timeout, params, required_state); + } + + private String waitForRequestStateById(String tenant, long timeout, String id, String required_state) { + Map params = [ + 'max':'1', + 'offset':'0', + 'match':'id', + 'term':id + ]; + return waitForRequestStateParams(tenant, timeout, params, required_state); + } + + private String waitForRequestStateParams(String tenant, long timeout, Map params, String required_state) { + long start_time = System.currentTimeMillis(); + String request_id = null; + String request_state = null; + long elapsed = 0; + while ( ( required_state != request_state ) && + ( elapsed < timeout ) ) { + + setHeaders(['X-Okapi-Tenant': tenant]); + // https://east-okapi.folio-dev.indexdata.com/rs/patronrequests?filters=isRequester%3D%3Dtrue&match=patronGivenName&perPage=100&sort=dateCreated%3Bdesc&stats=true&term=Michelle + def resp = doGet("${baseUrl}rs/patronrequests", + params) + if (resp?.size() == 1) { + request_id = resp[0].id + request_state = resp[0].state?.code + } else { + log.debug("waitForRequestState: Request with params ${params} not found"); + } + + if (required_state != request_state) { + // Request not found OR not yet in required state + log.debug("Not yet found.. sleeping"); + Thread.sleep(1000); + } + elapsed = System.currentTimeMillis() - start_time + } + log.debug("Found request on tenant ${tenant} with params ${params} in state ${request_state} after ${elapsed} milliseconds"); + + if ( required_state != request_state ) { + throw new Exception("Expected ${required_state} but timed out waiting, current state is ${request_state}"); + } + + return request_id; + } // For the given tenant fetch the specified request private Map fetchRequest(String tenant, String requestId) { @@ -325,7 +380,7 @@ class RSLifecycleSpec extends TestBase { where: tenant_id | changes_needed | changes_needed_hidden - 'RSInstOne' | [ 'auto_responder_status':'off', 'auto_responder_cancel': 'off', 'routing_adapter':'static', 'static_routes':'SYMBOL:ISIL:RST3,SYMBOL:ISIL:RST2'] | ['requester_returnables_state_model':'PatronRequest', 'responder_returnables_state_model':'Responder', 'requester_non_returnables_state_model':'NonreturnableRequester', 'responder_non_returnables_state_model':'NonreturnableResponder', 'requester_digital_returnables_state_model':'DigitalReturnableRequester', 'state_model_responder_cdl':'CDLResponder'] + 'RSInstOne' | [ 'auto_responder_status':'off', 'auto_responder_cancel': 'off', 'routing_adapter':'static', 'static_routes':'SYMBOL:ISIL:RST3,SYMBOL:ISIL:RST2', 'auto_rerequest':'yes'] | ['requester_returnables_state_model':'PatronRequest', 'responder_returnables_state_model':'Responder', 'requester_non_returnables_state_model':'NonreturnableRequester', 'responder_non_returnables_state_model':'NonreturnableResponder', 'requester_digital_returnables_state_model':'DigitalReturnableRequester', 'state_model_responder_cdl':'CDLResponder'] 'RSInstTwo' | [ 'auto_responder_status':'off', 'auto_responder_cancel': 'off', 'routing_adapter':'static', 'static_routes':'SYMBOL:ISIL:RST1,SYMBOL:ISIL:RST3'] | ['requester_returnables_state_model':'PatronRequest', 'responder_returnables_state_model':'Responder', 'requester_non_returnables_state_model':'NonreturnableRequester', 'responder_non_returnables_state_model':'NonreturnableResponder', 'requester_digital_returnables_state_model':'DigitalReturnableRequester', 'state_model_responder_cdl':'CDLResponder'] 'RSInstThree' | [ 'auto_responder_status':'off', 'auto_responder_cancel': 'off', 'routing_adapter':'static', 'static_routes':'SYMBOL:ISIL:RST1'] | ['requester_returnables_state_model':'PatronRequest', 'responder_returnables_state_model':'Responder', 'requester_non_returnables_state_model':'NonreturnableRequester', 'responder_non_returnables_state_model':'NonreturnableResponder', 'requester_digital_returnables_state_model':'DigitalReturnableRequester', 'state_model_responder_cdl':'CDLResponder'] @@ -820,6 +875,14 @@ class RSLifecycleSpec extends TestBase { "RSInstOne" | "RSInstThree" | 7 | false | "nrSupplierCannotSupply.json" | Status.PATRON_REQUEST_REQUEST_SENT_TO_SUPPLIER | Status.RESPONDER_UNFILLED | "RSInstTwo" | Status.RESPONDER_IDLE | "URL" | "Copy" | "{}" "RSInstOne" | null | 8 | true | "null" | Status.PATRON_REQUEST_REQUEST_SENT_TO_SUPPLIER | null | "RSInstThree" | Status.RESPONDER_IDLE | "URL" | "Copy" | null "RSInstOne" | "RSInstThree" | 8 | true | "nrRequesterCancel.json" | Status.PATRON_REQUEST_CANCELLED | Status.RESPONDER_CANCELLED | null | null | null | null | "{}" + // "RSInstOne" | null | 9 | true | null | Status.PATRON_REQUEST_REQUEST_SENT_TO_SUPPLIER | null | "RSInstThree" | Status.RESPONDER_IDLE | null | null | null + // "RSInstOne" | "RSInstThree" | 9 | false | "supplierAnswerYes.json" | Status.PATRON_REQUEST_EXPECTS_TO_SUPPLY | Status.RESPONDER_NEW_AWAIT_PULL_SLIP | null | null | null | null | "{}" + // "RSInstOne" | "RSInstThree" | 9 | false | "supplierCannotSupplyTransfer.json" | Status.PATRON_REQUEST_REREQUESTED | Status.RESPONDER_UNFILLED | null | null | null | null | "{}" + // "RSInstThree" | null | 10 | true | null | Status.PATRON_REQUEST_REQUEST_SENT_TO_SUPPLIER | null | "RSInstOne" | Status.RESPONDER_IDLE | null | null | null + // "RSInstThree" | "RSInstOne" | 10 | false | "supplierCannotSupply.json" | Status.PATRON_REQUEST_END_OF_ROTA | Status.RESPONDER_UNFILLED | "RSInstOne" | Status.RESPONDER_IDLE | null | null | "{}" + + + } void "test Dynamic Groovy"() { @@ -1852,7 +1915,7 @@ class DosomethingSimple { } void "Test transmission of copyright and publication type to supplier"( - String copyrightType, String publicationType, String patronIdentifier) { + String copyrightType, String publicationType, String patronIdentifier) { String requesterTenantId = "RSInstOne"; String responderTenantId = "RSInstThree"; String patronReference = 'ref-' + patronIdentifier + randomCrap(6); @@ -1895,4 +1958,51 @@ class DosomethingSimple { // Look for responder request w/ patron reference // check for copyright and publication type in responder request } + + void "Test automatic rerequest to different cluster id"() { + String patronIdentifier = "ABCD-EFG-HIJK-0001"; + String requesterTenantId = "RSInstOne"; + String responderTenantId = "RSInstThree"; + String requestTitle = "YA Bad Book"; + String requestAuthor = "Mr. Boringman"; + String requestSymbol = "ISIL:RST1" + String patronReference = "ref-" + patronIdentifier + randomCrap(6); + + when: "do the thing" + + Map request = [ + requestingInstitutionSymbol: requestSymbol, + title: requestTitle, + author: requestAuthor, + patronIdentifier: patronIdentifier, + isRequester: true, + patronReference: patronReference, + systemInstanceIdentifier: "123-456-789", + tags: ['RS-REREQUEST-TEST-1'] + ]; + + setHeaders([ 'X-Okapi-Tenant': requesterTenantId ]); + doPost("${baseUrl}/rs/patronrequests".toString(), request); + + String requesterRequestId = waitForRequestState(requesterTenantId, 10000, patronReference, Status.PATRON_REQUEST_REQUEST_SENT_TO_SUPPLIER); + + String responderRequestId = waitForRequestState(responderTenantId, 10000, patronReference, Status.RESPONDER_IDLE); + + String jsonPayload = new File("src/integration-test/resources/scenarios/supplierCannotSupplyTransfer.json").text; + String performActionUrl = "${baseUrl}/rs/patronrequests/${responderRequestId}/performAction".toString(); + log.debug("Posting supplierCannotSupplyTransfer payload to ${performActionUrl}"); + doPost(performActionUrl, jsonPayload); + + waitForRequestStateById(responderTenantId, 10000, responderRequestId, Status.RESPONDER_UNFILLED); + + waitForRequestStateById(requesterTenantId, 10000, requesterRequestId, Status.PATRON_REQUEST_REREQUESTED); + + + + then: + assert(true); + + + + } } diff --git a/service/src/integration-test/resources/scenarios/supplierCannotSupplyTransfer.json b/service/src/integration-test/resources/scenarios/supplierCannotSupplyTransfer.json new file mode 100644 index 000000000..6ffc4bfe2 --- /dev/null +++ b/service/src/integration-test/resources/scenarios/supplierCannotSupplyTransfer.json @@ -0,0 +1,7 @@ +{ + "action": "supplierCannotSupply", + "actionParams": { + "reason": "transfer", + "note": "transferToCluster:2334455667" + } +} \ No newline at end of file diff --git a/service/src/main/groovy/org/olf/rs/referenceData/ActionEventResultData.groovy b/service/src/main/groovy/org/olf/rs/referenceData/ActionEventResultData.groovy index 9746448f3..359feb240 100644 --- a/service/src/main/groovy/org/olf/rs/referenceData/ActionEventResultData.groovy +++ b/service/src/main/groovy/org/olf/rs/referenceData/ActionEventResultData.groovy @@ -131,6 +131,17 @@ public class ActionEventResultData { nextActionEvent: null ]; + private static Map requesterISO18626UnfilledTransfer = [ + code: 'requesterISO18626UnfilledTransfer', + description: 'An incoming ISO-18626 message for the requester has said that the status is Unfilled, but the reason is "transfer"', + result: true, + status: Status.PATRON_REQUEST_REREQUESTED, + qualifier: 'UnfilledTransfer', + saveRestoreState: null, + updateRotaLocation: true, + nextActionEvent: null + ]; + private static Map responderISO18626AgreeConditions = [ code: 'responderISO18626AgreeConditions', description: 'Requester has said they want to agree to the conditions', @@ -1001,6 +1012,7 @@ public class ActionEventResultData { requesterISO18626Conditional, requesterISO18626Loaned, requesterISO18626Unfilled, + requesterISO18626UnfilledTransfer, defaultNoStatusChangeOK ] ]; @@ -1047,6 +1059,7 @@ public class ActionEventResultData { requesterISO18626Conditional, requesterISO18626ExpectToSupply, requesterISO18626Unfilled, + requesterISO18626UnfilledTransfer, defaultNoStatusChangeOK ] ]; diff --git a/service/src/main/groovy/org/olf/rs/referenceData/RefdataValueData.groovy b/service/src/main/groovy/org/olf/rs/referenceData/RefdataValueData.groovy index 43cb75555..69f24995d 100644 --- a/service/src/main/groovy/org/olf/rs/referenceData/RefdataValueData.groovy +++ b/service/src/main/groovy/org/olf/rs/referenceData/RefdataValueData.groovy @@ -126,6 +126,7 @@ public class RefdataValueData { // Notice triggers public static final String NOTICE_TRIGGER_END_OF_ROTA = 'End of rota'; + public static final String NOTICE_TRIGGER_END_OF_ROTA_REVIEWED = 'End of rota reviewed'; public static final String NOTICE_TRIGGER_LOANED_DIGITALLY = 'Loaned digitally'; public static final String NOTICE_TRIGGER_OVER_LIMIT = 'Over limit'; public static final String NOTICE_TRIGGER_NEW_HOST_LMS_LOCATION = 'New Host LMS Location'; @@ -279,6 +280,7 @@ public class RefdataValueData { RefdataValue.lookupOrCreate(VOCABULARY_CANNOT_SUPPLY_REASONS, 'No longer available', 'unavailable'); RefdataValue.lookupOrCreate(VOCABULARY_CANNOT_SUPPLY_REASONS, 'Missing', 'missing'); RefdataValue.lookupOrCreate(VOCABULARY_CANNOT_SUPPLY_REASONS, 'Incorrect', 'incorrect'); + RefdataValue.lookupOrCreate(VOCABULARY_CANNOT_SUPPLY_REASONS, 'Transfer', 'transfer'); RefdataValue.lookupOrCreate(VOCABULARY_CANNOT_SUPPLY_REASONS, 'Other', 'other'); RefdataValue.lookupOrCreate(VOCABULARY_CANCELLATION_REASONS, 'Requested item is locally available', 'available_locally'); diff --git a/service/src/main/groovy/org/olf/rs/referenceData/SettingsData.groovy b/service/src/main/groovy/org/olf/rs/referenceData/SettingsData.groovy index 9fd07fa3d..c3216b2d1 100644 --- a/service/src/main/groovy/org/olf/rs/referenceData/SettingsData.groovy +++ b/service/src/main/groovy/org/olf/rs/referenceData/SettingsData.groovy @@ -125,6 +125,7 @@ public class SettingsData { public static final String SETTING_STALE_REQUEST_3_EXCLUDE_WEEKEND = 'stale_request_3_exclude_weekend'; public static final String SETTING_CHECK_DUPLICATE_TIME = 'check_duplicate_time'; public static final String SETTING_AUTO_RESPONDER_REQUESTER_NON_RETURNABLE = 'auto_responder_requester_non_ret'; + public static final String SETTING_AUTO_REREQUEST = 'auto_rerequest'; // Settings for the chat section public static final String SETTING_CHAT_AUTO_READ = 'chat_auto_read'; @@ -296,6 +297,8 @@ public class SettingsData { ensureAppSetting(SETTING_CHECK_DUPLICATE_TIME, SECTION_AUTO_RESPONDER, SETTING_TYPE_STRING, null, '0'); + ensureAppSetting(SETTING_AUTO_REREQUEST, SECTION_AUTO_RESPONDER, SETTING_TYPE_REF_DATA, RefdataValueData.VOCABULARY_YES_NO, null, referenceDataService.lookup(RefdataValueData.VOCABULARY_YES_NO, RefdataValueData.YES_NO_NO).value); + ensureAppSetting(SETTING_CHAT_AUTO_READ, SECTION_CHAT, SETTING_TYPE_REF_DATA, RefdataValueData.VOCABULARY_CHAT_AUTO_READ, 'on'); ensureAppSetting(SETTING_ROUTING_ADAPTER, SECTION_ROUTING, SETTING_TYPE_REF_DATA, RefdataValueData.VOCABULARY_REQUEST_ROUTING_ADAPTER, null, referenceDataService.lookup(RefdataValueData.VOCABULARY_REQUEST_ROUTING_ADAPTER, RefdataValueData.REQUEST_ROUTING_ADAPTER_FOLIO_SHARED_INDEX).value); diff --git a/service/src/main/groovy/org/olf/rs/referenceData/StateModelData.groovy b/service/src/main/groovy/org/olf/rs/referenceData/StateModelData.groovy index 5f2339976..f37da2503 100644 --- a/service/src/main/groovy/org/olf/rs/referenceData/StateModelData.groovy +++ b/service/src/main/groovy/org/olf/rs/referenceData/StateModelData.groovy @@ -58,6 +58,7 @@ public class StateModelData { [ status : Status.PATRON_REQUEST_DUPLICATE_REVIEW ], [ status : Status.PATRON_REQUEST_END_OF_ROTA, isTerminal : true ], [ status : Status.PATRON_REQUEST_END_OF_ROTA_REVIEWED, isTerminal : true ], + [ status : Status.PATRON_REQUEST_REREQUESTED, isTerminal : true ], [ status : Status.PATRON_REQUEST_ERROR ], [ status : Status.PATRON_REQUEST_EXPECTS_TO_SUPPLY ], [ status : Status.PATRON_REQUEST_FILLED_LOCALLY, isTerminal : true ], diff --git a/service/src/main/groovy/org/olf/rs/referenceData/StatusData.groovy b/service/src/main/groovy/org/olf/rs/referenceData/StatusData.groovy index e503faef2..81aadd532 100644 --- a/service/src/main/groovy/org/olf/rs/referenceData/StatusData.groovy +++ b/service/src/main/groovy/org/olf/rs/referenceData/StatusData.groovy @@ -43,6 +43,7 @@ public class StatusData { Status.ensure(Status.PATRON_REQUEST_EXPECTS_TO_SUPPLY, StatusStage.ACTIVE, '0070', true, null, false, null, [ tags.ACTIVE_PATRON ]); Status.ensure(Status.PATRON_REQUEST_UNFILLED, StatusStage.COMPLETED, '0075', true); + // Add in the ability to tag states with meaningful semantics for reporting // model, code, presSeq, visible, needsAttention, terminal, tags Status.ensure(Status.PATRON_REQUEST_SHIPPED, StatusStage.ACTIVE_SHIPPED, '0076', true, null, false, null, [ tags.ACTIVE_PATRON ]); @@ -59,6 +60,8 @@ public class StatusData { Status.ensure(Status.PATRON_REQUEST_END_OF_ROTA_REVIEWED, StatusStage.COMPLETED, '0080', true, null, true, 3); Status.ensure(Status.PATRON_REQUEST_CANCELLED, StatusStage.COMPLETED, '9998', true, null, true, 4); Status.ensure(Status.PATRON_REQUEST_ERROR, StatusStage.ACTIVE, '9999', true, true); + Status.ensure(Status.PATRON_REQUEST_REREQUESTED, StatusStage.COMPLETED, '10001', true, null, true, 3); + // Digital Returnable Requester Status.ensure(Status.REQUESTER_LOANED_DIGITALLY, StatusStage.ACTIVE_SHIPPED, '0076', true, null, false, null, [ tags.ACTIVE_BORROW, tags.ACTIVE_PATRON ]);