<link field="billing_location" reltype="has_a" key="id" map="" class="aou"/>
</links>
</class>
- <class id="aun" controller="open-ils.cstore" oils_obj:fieldmapper="actor::usr_note" oils_persist:tablename="actor.usr_note" reporter:label="User Note">
+ <class id="aun" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="actor::usr_note" oils_persist:tablename="actor.usr_note" reporter:label="User Note">
<fields oils_persist:primary="id" oils_persist:sequence="actor.usr_note_id_seq">
<field reporter:label="Creation Date/Time" name="create_date" reporter:datatype="timestamp"/>
<field reporter:label="Creating Staff" name="creator" reporter:datatype="link"/>
<link field="usr" reltype="has_a" key="id" map="" class="au"/>
<link field="creator" reltype="has_a" key="id" map="" class="au"/>
</links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <create permission="UPDATE_USER" context_field="owner">
+ <context link="usr" field="home_ou"/>
+ </create>
+ <!-- note: public notes are still accessible via API -->
+ <retrieve permission="UPDATE_USER">
+ <context link="usr" field="home_ou"/>
+ </retrieve>
+ <update permission="UPDATE_USER">
+ <context link="usr" field="home_ou"/>
+ </update>
+ <delete permission="UPDATE_USER">
+ <context link="usr" field="home_ou"/>
+ </delete>
+ </actions>
+ </permacrud>
</class>
<class id="aupr" controller="open-ils.cstore" oils_obj:fieldmapper="actor::usr_password_reset" oils_persist:tablename="actor.usr_password_reset" reporter:label="User password reset requests">
<fields oils_persist:primary="id" oils_persist:sequence="actor.usr_password_reset_id_seq">
<option value="bills_current">[% l('Bills, Current') %]</option>
<option value="bills_historical">[% l('Bills, Historical') %]</option>
<option value="bill_payment">[% l('Bills, Payment') %]</option>
+ <option value="patron_note">[% l('Patron Note') %]</option>
</select>
</div>
<div class="col-md-7">
</a>
<ul class="dropdown-menu">
<li>
- <a href="./circ/patron/{{patron().id()}}/credentials">
- [% l('Test Password') %]
+ <a href="./circ/patron/{{patron().id()}}/alerts">
+ [% l('Display Alert and Messages') %]
</a>
</li>
<li>
- <a href="./circ/patron/{{patron().id()}}/alerts">
- [% l('Display Alert and Messages') %]
+ <a href="./circ/patron/{{patron().id()}}/notes">
+ [% l('Notes') %]
+ </a>
+ </li>
+ <li>
+ <a href="./circ/patron/{{patron().id()}}/credentials">
+ [% l('Test Password') %]
</a>
</li>
</ul>
--- /dev/null
+<form ng-submit="ok(args)" role="form">
+ <div class="modal-header">
+ <button type="button" class="close" ng-click="cancel()"
+ aria-hidden="true">×</button>
+ <h4 class="modal-title">[% l('Create a new note') %]</h4>
+ </div>
+ <div class="modal-body">
+ <div class="form-group row">
+ <div class="col-md-3">
+ <label for="note-title">[% l('Title') %]</label>
+ </div>
+ <div class="col-md-9">
+ <input type="text" class="form-control" focus-me='focusNote' required
+ id="note-title" ng-model="args.title" placeholder="[% l('Title...') %]"/>
+ </div>
+ </div>
+ <div class="form-group row">
+ <div class="col-md-3">
+ <label for="note-pub">[% l('Patron Visible?') %]</label>
+ </div>
+ <div class="col-md-9">
+ <input type="checkbox" class="checkbox"
+ id="note-pub" ng-model="args.pub"/>
+ </div>
+ </div>
+ <div class="form-group row">
+ <div class="col-md-3">
+ <label for="note-value">[% l('Value') %]</label>
+ </div>
+ <div class="col-md-9">
+ <textarea class="form-control" required
+ id="note-value" ng-model="args.value" placeholder="[% l('Value...') %]">
+ </textarea>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <input type="submit" class="btn btn-primary" value="[% l('OK') %]"/>
+ <button class="btn btn-warning" ng-click="cancel()">[% l('Cancel') %]</button>
+ </div>
+ </div> <!-- modal-content -->
+</form>
<input type="number" class="form-control" focus-me='focusMe' required
id="noncat-title" ng-model="count" placeholder="[% l('Count...') %]"/>
</div>
+ </div>
<div class="modal-footer">
<input type="submit" class="btn btn-primary"
ng-disabled="form.$invalid" value="[% l('OK') %]"/>
--- /dev/null
+<div class="row">
+ <div class="col-md-12">
+ <button class="btn btn-default" ng-click="newNote()">
+ [% l('Add New Note') %]
+ </button>
+ </div>
+</div>
+
+<div class="row pad-vert" ng-repeat="note in notes">
+ <div class="col-md-12">
+ <div class="row">
+ <div class="col-md-6 strong-text">{{note.title()}}</div>
+ <div class="col-md-6">
+ <div class="pull-right">
+ <span class="pad-horiz alert alert-warning" ng-if="note.pub() == 't'">[% l('Patron Visible') %]</span>
+ <span class="pad-horiz alert alert-info" ng-if="note.pub() == 'f'">[% l('Staff Only') %]</span>
+ <span class="pad-horiz">{{note.create_date() | date:'short'}}</span>
+ <span>[% l('Created by [_1]', '{{note.creator().usrname()}}') %]</span>
+ </div>
+ </div>
+ </div>
+ <div class="row">
+ <!-- hmm, not sure why the margin-left is needed.. the well? -->
+ <div class="col-md-12 well" style="margin-left:12px">
+ <div class="row">
+ <div class="col-md-8">
+ <div class="">{{note.value()}}</div>
+ </div>
+ <div class="col-md-4">
+ <div class="pull-right">
+ <button ng-click="printNote(note)" class="btn btn-default">
+ [% l('Print') %]
+ </button>
+ <button ng-click="deleteNote(note)" class="btn btn-warning">
+ [% l('Delete') %]
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <hr/>
+</div>
--- /dev/null
+<h3>[% l(
+ 'Pertaining to [_1], [_2] [_3] : [_4]',
+ '{{note.usr.family_name}}',
+ '{{note.usr.first_given_name}}',
+ '{{note.usr.second_given_name}}',
+ '{{note.usr.card.barcode}}') %]</h3>
+
+<p>[% l('Created on [_1]', '{{note.create_date | date:"short"}}') %]</p>
+<b>{{note.title}}</b>
+<br/>
+<p>{{note.value}}</p>
// TODO: consider moving the template-specific bits directly
// into the templates or storing template- specific script files
// alongside the templates
+ var seed_user = {
+ first_given_name : 'Slow',
+ second_given_name : 'Joe',
+ family_name : 'Jones',
+ card : {
+ barcode : '30393830393'
+ }
+ }
$scope.preview_scope = {
current_location : egCore.idl.toHash(
egCore.org.get(egCore.auth.user().ws_ou())),
change_given : 0,
payment_type : 'cash_payment',
payment_note : 'Here is a payment note',
+ note : {
+ create_date : '2024-12-25T12:01:03',
+ title : 'Test Note Title',
+ usr : seed_user,
+ value : 'This patron is super nice!'
+ }
}
$scope.preview_scope.payments = [
{amount : 1.00, xact : $scope.preview_scope.transactions[0]},
resolve : resolver
});
+ $routeProvider.when('/circ/patron/:id/notes', {
+ templateUrl: './circ/patron/t_notes',
+ controller: 'PatronNotesCtrl',
+ resolve : resolver
+ });
+
$routeProvider.otherwise({redirectTo : '/circ/patron/search'});
})
}])
+.controller('PatronNotesCtrl',
+ ['$scope','$routeParams','$location','egCore','patronSvc','$modal',
+function($scope, $routeParams , $location , egCore , patronSvc , $modal) {
+ $scope.initTab('other', $routeParams.id);
+ var usr_id = $routeParams.id;
+
+ function refreshPage() {
+ $scope.notes = [];
+ egCore.pcrud.search('aun',
+ {usr : usr_id},
+ {flesh : 1, flesh_fields : {aun : ['creator']}},
+ {authoritative : true})
+ .then(null, null, function(note) {
+ $scope.notes.push(note);
+ });
+ }
+
+ $scope.newNote = function() {
+ $modal.open({
+ templateUrl: './circ/patron/t_new_note_dialog',
+ controller:
+ ['$scope', '$modalInstance',
+ function($scope, $modalInstance) {
+ $scope.focusNote = true;
+ $scope.args = {};
+ $scope.ok = function(count) { $modalInstance.close($scope.args) }
+ $scope.cancel = function () { $modalInstance.dismiss() }
+ }],
+ }).result.then(
+ function(args) {
+ if (!args.value) return;
+ var note = new egCore.idl.aun();
+ note.usr(usr_id);
+ note.title(args.title);
+ note.value(args.value);
+ note.pub(args.pub ? 't' : 'f');
+ note.creator(egCore.auth.user().id());
+ egCore.pcrud.create(note).then(function() {refreshPage()});
+ }
+ );
+ }
+
+ $scope.deleteNote = function(note) {
+ egCore.pcrud.remove(note).then(function() {refreshPage()});
+ }
+ $scope.printNote = function(note) {
+ var hash = egCore.idl.toHash(note);
+ hash.usr = egCore.idl.toHash($scope.patron());
+ egCore.hatch.printFromTemplate(
+ 'default', 'patron_note', {note : hash});
+ }
+
+ refreshPage();
+}])