Context

Override functionality allows the user to perform an action that should be otherwise blocked. 

Currently, there's only one type of check-out override - when the item is not loanable, we can make a call to POST /circulation/override-check-out-by-barcode to override this block and create a loan. There is also an endpoint for overriding renewals of items that are not renewable, declared lost, aged to lost etc. (POST /circulation/override-renewal-by-barcode).

Requirements

Users need to be able to apply different kinds of overrides in multiple steps. Specifically, override of patron blocks will be added () as well as override of item blocks (). The desired check-out flow should look like this:

Proposed changes to mod-circulation

Get rid of the "override" endpoints.

These endpoints should be removed:

Endpoints that are responsible for regular borrowing, requests and renewals will also be responsible for overrides now:

  1. POST /circulation/check-out-by-barcode
  2. POST /circulation/renew-by-barcode
  3. POST /circulation/renew-by-id
  4. POST /circulation/requests
  5. PUT /circulation/requests

UI might need to make two calls to the same endpoint in order to complete the action. First - to get the list of overridable blocks, second - to override these block after user's decision.

Return full list of overridable blocks

Endpoints (1-5) should return a full list of blocks that have to be overridden in order for action to be completed. When checking for blocks these processes shouldn't fail immediately when they find the first block. They should check for all blocks instead and include the results in the response. Typically, in case of an error the response structure looks like this:


{
	"errors": [{
		"message": "Error message",
		"parameters": [{
			"key": "key-1",
			"value": "value-1"
		}, {
			"key": "key-2",
			"value": "value-2"
		}],
		"overridableBlock": {
			"name": "patronBlock",
			"missingPermissions": [
				"circulation.override-patron-block",
				"circulation.override-item-limit-block"
			]
		}
	}
}


An overridable error will contain a new property overridableBlock with following properties:

Non-overridable errors will not contain this new property.

If response contains overridable errors only, the client will know that requested action can be completed by overriding corresponding blocks. Presence of non-overridable errors in the response indicates that there is no point in trying to override the blocks.

Expect a list of blocks that user wants to override

Request bodies of endpoints (1-5) need to include a list of blocks that the requester wants to override. New (optional) field should be added to JSON schemas:

"overrideBlocks": {
  "description": "Blocks that need to be overridden",
  "type": "object",
  "properties": {
    "itemNotLoanableBlock" : {
      "description": "Parameters for overriding of the 'item not loanable' block",
      "type": "object",
      "properties": {
        "dueDate": {
          "description": "Due date for a new loan",
          "type": "string",
          "format": "date-time"
        }
      },
      "required": [
        "dueDate"
      ]
    },
    "patronBlock": {
      "description": "Parameters for overriding of the patron block",
      "type": "object",
      "properties": {
        ...
      }
    },
    "itemLimitBlock": {
      "description": "Parameters for overriding of the 'item limit' block",
      "type": "object",
      "properties": {
        ...
      }
    }
  }
}

List of the appropriate blocks and their parameters may be dependent on the endpoint.

In case when this parameter is included in the request, the server should override all of the specified blocks if the user has sufficient permissions.

Managing permissions

Each overridable action will be associated with a user permission that is required in order to override this action. These permissions need to be part of permissionsDesired rather than permissionsRequired which will allow to handle them in the code. For example, new permissions for POST /circulation/check-out-by-barcode:

"permissionsDesired": [
  "circulation.override-patron-block",
  "circulation.override-item-limit-block",
  "circulation.override-item-not-loanable-block"
]