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

Ill patron request form mvp #109

Draft
wants to merge 12 commits into
base: ill_patron_request_form_mvp
Choose a base branch
from
4 changes: 4 additions & 0 deletions code/web/Drivers/Koha.php
Original file line number Diff line number Diff line change
Expand Up @@ -6977,6 +6977,10 @@ private function getKohaSystemPreference(string $preferenceName, $default = '')
return $preference;
}

public function getStaffClientBaseURL() {
return $this->getKohaSystemPreference('staffClientBaseURL');
}

public function getPluginStatus(string $pluginName) {
$this->initDatabaseConnection();
/** @noinspection SqlResolve */
Expand Down
39 changes: 39 additions & 0 deletions code/web/interface/themes/responsive/ILL/Form.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<form id="NewPatronRequest" method="post" action="/ILL/AJAX?method=postFormData" class="form form-horizontal">
<h1>ILL Request Form</h1>
<div class="col-tn-12 col-xs-12 col-sm-8 col-md-9 col-lg-9" id="main-content-with-sidebar">
<div class="form-group propertyRow"><label for="article_title">Article Title</label>
<input type=text name="article_title" id="article_title" />
</div>
<div class="form-group propertyRow"><label for="associated_id">Associated Id</label>
<input type=text name="associated_id" id="associated_id" />
</div>
<div class="form-group propertyRow"><label for="author">Author</label>
<input type=text name="author" id="author" />
</div>
<div class="form-group propertyRow"><label for="issn">Issn</label>
<input type=text name="issn" id="issn" />
</div>
<div class="form-group propertyRow"><label for="issue">Issue</label>
<input type=text name="issue" id="issue" />
</div>
<div class="form-group propertyRow"><label for="pages">pages</label>
<input type=text name="pages" id="pages" />
</div>
<div class="form-group propertyRow"><label for="publisher">publisher</label>
<input type=text name="publisher" id="publisher" />
</div>
<div class="form-group propertyRow"><label for="pubmedid">pubmedid</label>
<input type=text name="pubmedid" id="pubmedid" />
</div>
<div class="form-group propertyRow"><label for="title">title</label>
<input type=text name="title" id="title" />
</div>
<div class="form-group propertyRow"><label for="volume">volume</label>
<input type=text name="volume" id="volume" />
</div>
<div class="form-group propertyRow"><label for="year">year</label>
<input type=text name="year" id="year" />
</div>
<button type="submit">Submit</button>
</div>
</form>
75 changes: 75 additions & 0 deletions code/web/interface/themes/responsive/ILL/my-requests.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{*is in essence a copy of myMaterialRequests.tpl, is intended for use as proof of concept only *}

<div id="main-content">
{if !empty($profile->_web_note)}
<div class="row">
<div id="web_note" class="alert alert-info text-center col-xs-12">{$profile->_web_note}</div>
</div>
{/if}
{if !empty($accountMessages)}
{include file='systemMessages.tpl' messages=$accountMessages}
{/if}
{if !empty($ilsMessages)}
{include file='ilsMessages.tpl' messages=$ilsMessages}
{/if}

<h1>{translate text='My Materials Requests' isPublicFacing=true}</h1>

{* MDN 7/26/2019 Do not allow access for linked users *}
{* {include file="MyAccount/switch-linked-user-form.tpl" label="Viewing Requests for" actionPath="/MyAccount/ReadingHistory"}*}

{if !empty($error)}
<div class="alert alert-danger">{$error}</div>
{else}
{if $user->canSuggestMaterials()}
{if !empty($ILLRequests)}
{if count($ILLRequests) > 0}
<form method="post" action="/MaterialsRequest/IlsRequests">
<table id="requestedMaterials" class="table table-striped table-condensed tablesorter">
<thead>
<tr>
{if !empty($allowDeletingILSRequests)}
<th>&nbsp;</th>
{/if}
<th>{translate text="Summary" isPublicFacing=true}</th>
<th>{translate text="Suggested On" isPublicFacing=true}</th>
<th>{translate text="Staff Note" isPublicFacing=true}</th>
<th>{translate text="Status" isPublicFacing=true}</th>
</tr>
</thead>
<tbody>
{foreach from=$ILLRequests item=request}
<tr>
{if !empty($allowDeletingILSRequests)}
<td>
<input type="checkbox" name="delete_field" value="{$request.id}" title="{translate text="Select Request" inAttribute=true isPublicFacing=true}" aria-label="{translate text="Select Request" inAttribute=true isPublicFacing=true}"/>
</td>
{/if}
<td>{$request.summary}</td>
<td>{$request.requested_date}</td>
<td>{$request.staff_note}</td>
<td>{$request.status}</td>
</tr>
{/foreach}
</tbody>
</table>
{if !empty($allowDeletingILSRequests)}
<button type="submit" class="btn btn-sm btn-danger" name="submit">{translate text="Delete Selected" isPublicFacing=true}</button>
{/if}
</form>
<br/>
{else}
<div class="alert alert-warning">{translate text='There are no materials requests that meet your criteria.' isPublicFacing=true}</div>
{/if}
{/if}
<div id="createNewMaterialsRequest"><a href="/MaterialsRequest/NewRequestIls?patronId={$patronId}" class="btn btn-primary btn-sm">{translate text='Submit a New Materials Request' isPublicFacing=true}</a></div>
{else}
<div class="alert alert-warning">{translate text='You are not eligible to make Materials Requests at this time.' isPublicFacing=true}</div>
{/if}
{/if}
</div>
<script type="text/javascript">
{literal}
$("#requestedMaterials").tablesorter({cssAsc: 'sortAscHeader', cssDesc: 'sortDescHeader', cssHeader: 'unsortedHeader', headers: {0: { sorter: false}, 2: {sorter : 'date'}, 6: { sorter: false} } });
{/literal}
</script>
7 changes: 7 additions & 0 deletions code/web/interface/themes/responsive/Search/list.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@
{translate text="Can't find what you are looking for? Try our Materials Request Service." isPublicFacing=true} <a href="{$externalMaterialsRequestUrl}" class="btn btn-sm btn-info">{translate text='Submit Request' isPublicFacing=true}</a>
</p>
</div>
{elseif $materialRequestType == 4}
<div class="materialsRequestLink">
<h2>{translate text="Didn't find it?" isPublicFacing=true}</h2>
<p>
{translate text="Can't find what you are looking for? Try our Materials Request Service." isPublicFacing=true} <a href="/ILL/NewRequestForm" class="btn btn-sm btn-info">{translate text='Submit Request' isPublicFacing=true}</a>
</p>
</div>
{/if}
{/if}

Expand Down
73 changes: 73 additions & 0 deletions code/web/services/ILL/AJAX.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

require_once ROOT_DIR . '/Action.php';
require_once ROOT_DIR . '/Drivers/Koha.php';

/**
* ILLRequest AJAX Page, handles sending ILL Requests from Aspen to Koha.
*/
class ILL_AJAX extends Action
{
function launch()
{
$method = $_GET['method'];
if (method_exists($this, $method)) {
header('Content-type: application/json');
header('Cache-Control: no-cache, must-revalidate'); // HTTP/1.1
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
$result = $this->$method();
echo json_encode($result);
} else {
echo json_encode(['error' => 'invalid_method']);
}
}

function postFormData()
{
$user = UserAccount::getActiveUserObj();
$catalog = CatalogFactory::getCatalogConnectionInstance();
$reqBody = [
"ill_backend_id" => "FreeForm", // temporarily hard-coded
"patron_id" => $user->id,
"library_id" => $user->_homeLibrary->subdomain,
"extended_attributes" => [
['type' => 'article_title', 'value' => $_POST['article_title']],
['type' => 'associated_id', 'value' => $_POST['associated_id']],
['type' => 'author', 'value' => $_POST['author']],
['type' => 'issn', 'value' => $_POST['issn']],
['type' => 'issue', 'value' => $_POST['issue']],
['type' => 'pages', 'value' => $_POST['pages']],
['type' => 'publisher', 'value' => $_POST['publisher']],
['type' => 'pubmedid', 'value' => $_POST['pubmedid']],
['type' => 'title', 'value' => $_POST['title']],
['type' => 'volume', 'value' => $_POST['volume']],
['type' => 'year', 'value' => $_POST['year']]
]
];

$reqUrl = $catalog->getStaffClientBaseURL() . '/api/v1/ill/requests';
$credentials = $user->ils_username . ':' . $user->ils_password; // $user->ils_password is likely to be null -> TODO: need to find a way to safely get and pass this credential

$curl = curl_init($reqUrl);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($reqBody));
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: multipart/form-data']);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $credentials);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_exec($curl);

$err = curl_error($curl);
if(!empty($err)) {
return new AspenError('an error occurred while sending your request: ' . $err );
}

header('Location: ' . 'http://localhost:8083/ILL/NewRequestForm'); // goes back to the new request form -> TODO: add a success message to display
}

function getBreadcrumbs(): array
{
return [];
}
}
72 changes: 72 additions & 0 deletions code/web/services/ILL/MyRequests.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php
require_once ROOT_DIR . '/services/MyAccount/MyAccount.php';

class ILL_MyRequests extends MyAccount {

function launch() {
global $interface;

if (UserAccount::isLoggedIn()) {

// get the patron - uses logic from MaterialsRequest_MyRequests::launch() (should we?)
$user = UserAccount::getActiveUserObj();
$linkedUsers = $user->getLinkedUsers();
$patronId = empty($_REQUEST['patronId']) ? $user->id : $_REQUEST['patronId'];
$interface->assign('patronId', $patronId);

$patron = $user->getUserReferredTo($patronId);
if (count($linkedUsers) > 0) {
array_unshift($linkedUsers, $user);
$interface->assign('linkedUsers', $linkedUsers);
}
$interface->assign('selectedUser', $patronId); // needs to be set even when there is only one user so that the patronId hidden input gets a value in the reading history form.

// get the list of requests for the patron
$requests = $this->getRequestsBy($patron);
$interface->assign('ILLRequests', $requests);

$requestTemplate = 'my-requests.tpl'; // could get this from a catalogConnection (if set first)
$title = 'My Materials Requests';

$this->display($requestTemplate, $title);
} else {
header('Location: /MyAccount/Home?followupModule=MaterialsRequest&followupAction=MyRequests');
exit;
}
}

private function getRequestsBy($user) {
$catalog = CatalogFactory::getCatalogConnectionInstance();
$reqUrl = $catalog->getStaffClientBaseURL() . '/api/v1/ill/requests' . "?q={\"patron_id\":" . ($user->unique_ils_id) . "}";

$credentials = $user->ils_username . ':' . $user->ils_password; // $user->ils_password is likely to be null -> TODO: need to find a way to safely get and pass this credential

// fetch the ILL requests made by the user
$curl = curl_init($reqUrl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, $credentials);
$response = curl_exec($curl);

// handle any curl errors
$err = curl_error($curl);
if (!empty($err)) {
return new AspenError('an error occurred while sending your request: ' . $err);
}

// extract the request body into an associative array
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
$body = substr($response, $headerSize);
$requestList = json_decode($body, true);

// shut down the connection
curl_close($curl);
return $requestList;
}

function getBreadcrumbs(): array {
$breadcrumbs = [];
return $breadcrumbs;
}
}
19 changes: 19 additions & 0 deletions code/web/services/ILL/NewRequestForm.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

require_once ROOT_DIR . '/Action.php';

class ILL_NewRequestForm extends Action{
function launch() {
global $interface;
$title = 'ILL Request Form';
$interface->assign('title', $title);
$this->display('Form.tpl', $title);
}

function getBreadcrumbs(): array {
$breadcrumbs = [];
$breadcrumbs[] = new Breadcrumb('/Union/Search', 'Search Results');
$breadcrumbs[] = new Breadcrumb('/ILL/RequestForm', 'ILL Request Form');
return $breadcrumbs;
}
}
1 change: 1 addition & 0 deletions code/web/sys/LibraryLocation/Library.php
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ static function getObjectStructure($context = ''): array {
1 => 'Aspen Request System',
2 => 'ILS Request System',
3 => 'External Request Link',
4 => 'ILL Request System - Koha'
];
$catalog = CatalogFactory::getCatalogConnectionInstance();
if ($catalog == null || !$catalog->hasMaterialsRequestSupport()) {
Expand Down