Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Books from New Bookshelf Workflow #338

Closed
wants to merge 14 commits into from
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -457,3 +457,42 @@ curl --location --request POST 'http://localhost:9001/mod-workflow/events/workfl
--form 'username="***"' \
--form 'password="***"'
```

## remove-books-from-nbs

Remove items from new bookshelf location for provided CSV of call numbers.

```shell
fw config set okapi-internal ***
fw config set bcn-mail-from ***
```

These variables are required when triggering the workflow:

| Variable Name | Allowed Values | Short Description |
| -------------- | -------------- | ----------------- |
| path | directory path | The directory on the system where the CSV file is stored within on the server and contain the `tenantPath` (include trailing slash after the directory). |
Dbreck-TAMU marked this conversation as resolved.
Show resolved Hide resolved
| file | file name | The file path within the specified directory path representing the CSV file to process (do not prefix with a starting slash). |
| emailTo | e-mail address | An e-mail address used as the "TO" in the sent e-mails. |
| username | string | Okapi login username. |
| password | string | Okapi login password. |
| logLevel | [INFO,DEBUG] | Desired log level |

To build and activate:
```shell
fw build remove-books-from-nbs
fw activate remove-books-from-nbs
```

Trigger the workflow using an **HTTP** request such as with **Curl**:
```shell
curl --location --request POST 'http://localhost:9001/mod-workflow/events/workflow/remove-books-from-nbs/start' \
--header 'Content-Type: multipart/form-data' \
--header 'X-Okapi-Tenant: diku' \
--form 'logLevel="INFO"' \
--form 'emailTo="[email protected]"' \
--form 'file=@"itemBarcodes.csv"' \
--form 'path="/mnt/workflows/${tenantId}/remove-books-from-nbs/"' \
--form 'username="***"' \
--form 'password="***"'
```
8 changes: 8 additions & 0 deletions remove-books-from-nbs/nodes/buildEmail.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "7b3f51ce-4c5c-4263-8511-d4f90dec8177",
"name": "Build email report",
"description": "",
"deserializeAs": "ScriptTask",
"scriptFormat": "javascript",
"code": "buildEmail.js"
}
8 changes: 8 additions & 0 deletions remove-books-from-nbs/nodes/convertCSVtoJSONArray.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "02cdf90c-8ca4-4aef-8bb5-a9c0242a9fd6",
"name": "Convert CSV to barcode array",
"description": "",
"deserializeAs": "ScriptTask",
"scriptFormat": "javascript",
"code": "convertCSVtoJSONArray.js"
}
16 changes: 16 additions & 0 deletions remove-books-from-nbs/nodes/deleteCSV.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"id": "d3ad0b52-bb37-4884-8ef8-4b54898d4f83",
"name": "Delete Barcodes CSV input file",
"description": "",
"deserializeAs": "FileTask",
"inputVariables": [
{
"key": "inputFilePath",
"type": "PROCESS"
}
],
"outputVariable": {},
"path": "${inputFilePath}",
"op": "DELETE",
"asyncBefore": true
}
24 changes: 24 additions & 0 deletions remove-books-from-nbs/nodes/email.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"id": "efc2d48a-54b2-46d6-bce0-7f4c5eec433b",
"name": "Email Barcode List",
"description": "Email list of barcodes removed from new bookshelf.",
"deserializeAs": "EmailTask",
"inputVariables": [
{
"key": "emailTo",
"type": "PROCESS"
},
{
"key": "email",
"type": "LOCAL",
"spin": true
}
],
"outputVariable": {},
"mailTo": "${emailTo}",
"mailFrom": "${{bcn-mail-from}}",
"mailSubject": "${email.subject}",
"mailText": "${email.text}",
"mailMarkup": "${email.markup}",
"asyncBefore": true
}
6 changes: 6 additions & 0 deletions remove-books-from-nbs/nodes/end.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"id": "997e56ba-3821-4422-b491-e89ba8a5739d",
"name": "End",
"description": "End of the workflow.",
"deserializeAs": "EndEvent"
}
8 changes: 8 additions & 0 deletions remove-books-from-nbs/nodes/handleItemLookupResponse.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "08bfbba4-d572-43c5-b274-f00f1476adfe",
"name": "Handle item lookup by barcode response",
"description": "",
"deserializeAs": "ScriptTask",
"scriptFormat": "javascript",
"code": "handleItemLookupResponse.js"
}
8 changes: 8 additions & 0 deletions remove-books-from-nbs/nodes/itemLookupEndSubProcess.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "67f75a13-2ba3-48fc-8849-70fd069cd013",
"name": "End NBS Items Lookup",
"description": "",
"type": "NONE",
"deserializeAs": "EndEvent",
"asyncBefore": true
}
24 changes: 24 additions & 0 deletions remove-books-from-nbs/nodes/itemLookupRequest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"id": "f21bcb7c-283c-4a16-9411-fcc526a4ed6f",
"name": "Lookup item by barcode",
"description": "",
"deserializeAs": "RequestTask",
"request": {
"url": "{{okapi-internal}}/inventory/items?query=barcode==${barcode}",
"method": "GET",
"accept": "application/json"
},
"inputVariables": [
{
"key": "barcode",
"type": "PROCESS"
}
],
"headerOutputVariables": [],
"outputVariable": {
"key": "itemsResponse",
"type": "LOCAL",
"spin": true
},
"asyncBefore": true
}
8 changes: 8 additions & 0 deletions remove-books-from-nbs/nodes/itemLookupStartSubProcess.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "882d2100-8bc0-4c53-be8a-d9b40283a21f",
"name": "Start NBS Items Lookup",
"description": "",
"type": "NONE",
"deserializeAs": "StartEvent",
"asyncBefore": true
}
18 changes: 18 additions & 0 deletions remove-books-from-nbs/nodes/itemLookupSubprocess.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"id": "d7c46475-9194-4c6d-8703-772a8e57cba3",
"name": "New Bookshelf Items Lookup Subprocess",
"description": "Subprocess to lokup items on new bookshelf",
"type": "EMBEDDED",
"deserializeAs": "Subprocess",
"nodes": [
"{{mod-workflow}}/startEvent/882d2100-8bc0-4c53-be8a-d9b40283a21f",
"{{mod-workflow}}/requestTask/f21bcb7c-283c-4a16-9411-fcc526a4ed6f",
"{{mod-workflow}}/scriptTask/08bfbba4-d572-43c5-b274-f00f1476adfe",
"{{mod-workflow}}/endEvent/67f75a13-2ba3-48fc-8849-70fd069cd013"
],
"loopRef": {
"dataInputRefExpression": "${barcodes.elements()}",
"inputDataName": "barcode",
"parallel": false
}
}
8 changes: 8 additions & 0 deletions remove-books-from-nbs/nodes/itemUpdateEndSubProcess.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "a92cdf8e-76e2-4bb3-becb-66f675f0d499",
"name": "End NBS Items Update",
"description": "",
"type": "NONE",
"deserializeAs": "EndEvent",
"asyncBefore": true
}
25 changes: 25 additions & 0 deletions remove-books-from-nbs/nodes/itemUpdateRequest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"id": "a3aad69c-0aae-4d3b-8513-84ab85a6c179",
"name": "Update item",
"description": "",
"deserializeAs": "RequestTask",
"request": {
"url": "{{okapi-internal}}/inventory/items/${item.prop('id').stringValue()}",
"method": "PUT",
"contentType": "application/json",
"accept": "application/json",
"bodyTemplate": "${item}"
},
"inputVariables": [
{
"key": "item",
"type": "PROCESS"
}
],
"headerOutputVariables": [],
"outputVariable": {
"key": "itemUpdateResponse",
"type": "LOCAL"
},
"asyncBefore": true
}
8 changes: 8 additions & 0 deletions remove-books-from-nbs/nodes/itemUpdateStartSubProcess.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"id": "f315e725-f834-490b-acee-77d6ba9721b1",
"name": "Start NBS Items Update",
"description": "",
"type": "NONE",
"deserializeAs": "StartEvent",
"asyncBefore": true
}
17 changes: 17 additions & 0 deletions remove-books-from-nbs/nodes/itemUpdateSubprocess.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"id": "db5cd3d2-a3f8-4e5e-830b-e0e3f23d5fa9",
"name": "New Bookshelf Items Update Subprocess",
"description": "Subprocess to update items on new bookshelf",
"type": "EMBEDDED",
"deserializeAs": "Subprocess",
"nodes": [
"{{mod-workflow}}/startEvent/f315e725-f834-490b-acee-77d6ba9721b1",
"{{mod-workflow}}/requestTask/a3aad69c-0aae-4d3b-8513-84ab85a6c179",
"{{mod-workflow}}/endEvent/a92cdf8e-76e2-4bb3-becb-66f675f0d499"
],
"loopRef": {
"dataInputRefExpression": "${itemsToRemove.elements()}",
"inputDataName": "item",
"parallel": false
}
}
45 changes: 45 additions & 0 deletions remove-books-from-nbs/nodes/js/buildEmail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
var itemsRemoved = JSON.parse(itemsToRemove);

var emailSubject = 'Items removed from new bookshelf';
var emailMarkup = '<p>A total of <strong>' + itemsRemoved.length + '</strong> items have been successfully processed.</p>\n';
var emailText = '';

emailMarkup += '<p>';
for (var i = 0; i < itemsRemoved.length; ++i) {
var item = itemsRemoved[i];
emailMarkup += '<p>Item: ' + item.title + '</p>';
emailMarkup += '<ul>';
emailMarkup += '<li>\tid: ' + item.id + '</li>';
emailMarkup += '<li>\thrid: ' + item.hrid + '</li>';
emailMarkup += '<li>\tbarcode: ' + item.barcode + '</li>';
emailMarkup += '<li>\tcall number: ' + item.callNumber + '</li>';
emailMarkup += '</ul>';
}
emailMarkup += '</p>';

emailText = emailMarkup.replace(/<\/p>/ig, '\n')
.replace(/<\/li>/ig, '\n')
.replace(/<\/ul>/ig, '\n')
.replace(/<\/[^>]+>/ig, '')
.replace(/<[^>]+>/ig, '');

emailMarkup = emailMarkup.replace(/\t/ig, '')
.replace(/\n/ig, '');

if (logLevel === 'INFO' || logLevel === 'DEBUG') {
print('emailTo = ' + emailTo);

if (logLevel === 'DEBUG') {
print('emailSubject = ' + emailSubject);
print('emailText = ' + emailText);
print('emailMarkup = ' + emailMarkup);
}
}

var email = {
subject: emailSubject,
text: emailText,
markup: emailMarkup
};

execution.setVariableLocal('email', S(JSON.stringify(email)));
29 changes: 29 additions & 0 deletions remove-books-from-nbs/nodes/js/convertCSVtoJSONArray.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
var MappingUtility = Java.type("org.folio.rest.utility.MappingUtility");
var barcodesJSON = MappingUtility.mapCsvToJson(barcodesCSV);

if (logLevel === "DEBUG") {
print('\nbarcodesJSON = ' + barcodesJSON + '\n');
}

var barcodesJSONArray = JSON.parse(barcodesJSON);

var barcodes = [];

for (var i = 0; i < barcodesJSONArray.length; i++) {
var barcode = barcodesJSONArray[i].barcode.trim();
if (barcode.length > 0) {
barcodes.push(barcode);
}
}

if (logLevel === "DEBUG") {
print('\nbarcodes = ' + barcodes + '\n');
}

execution.setVariable('barcodes', S(JSON.stringify(barcodes)));

var itemsToRemove = [];
var itemsSkipped = [];

execution.setVariable('itemsToRemove', S(JSON.stringify(itemsToRemove)));
execution.setVariable('itemsSkipped', S(JSON.stringify(itemsSkipped)));
33 changes: 33 additions & 0 deletions remove-books-from-nbs/nodes/js/handleItemLookupResponse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
var itemsToRemoveArray = JSON.parse(itemsToRemove);
var itemsSkippedArray = JSON.parse(itemsSkipped);


if (logLevel === "DEBUG") {
print('\nitemsResponse = ' + itemsResponse + '\n');
}

var responseItems = JSON.parse(itemsResponse).items;

if (responseItems.length > 0) {
var item = responseItems[0];

var updated = Date.parse(item.metadata.updatedDate);
var now = new Date().getTime();
var duration = (now - updated) / 1000 / 60 / 60 / 24;

if (item.effectiveLocation.name === 'Evans nbs' && duration >= 30) {
item.temporaryLocation = item.permanentLocation;
item.temporaryLoanType = item.permanentLoanType;
itemsToRemoveArray.push(item);
} else {
itemsSkippedArray.push(item);
}
}

if (logLevel === "DEBUG") {
print('\nitemsToRemove = ' + JSON.stringify(itemsToRemoveArray) + '\n');
print('\nitemsSkipped = ' + JSON.stringify(itemsSkippedArray) + '\n');
}

execution.setVariable('itemsToRemove', S(JSON.stringify(itemsToRemoveArray)));
execution.setVariable('itemsSkipped', S(JSON.stringify(itemsSkippedArray)));
34 changes: 34 additions & 0 deletions remove-books-from-nbs/nodes/login.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"id": "00f3edaf-bc3e-4bf5-bdbc-2de6c6d7f972",
"name": "Login",
"description": "Get Login Token",
"deserializeAs": "RequestTask",
"request": {
"url": "{{okapi}}/authn/login",
"method": "POST",
"contentType": "application/json",
"accept": "application/json",
"bodyTemplate": "{\"username\": \"${username}\",\"password\": \"${password}\"}"
},
"inputVariables": [
{
"key": "username",
"type": "PROCESS"
},
{
"key": "password",
"type": "PROCESS"
}
],
"headerOutputVariables": [
{
"key": "X-Okapi-Token",
"type": "PROCESS"
}
],
"outputVariable": {
"key": "loginResponse",
"type": "PROCESS"
},
"asyncBefore": true
}
Loading