teach vol/copy editor how to deal with copy alerts
authorGalen Charlton <gmc@esilibrary.com>
Wed, 9 Dec 2015 14:58:16 +0000 (09:58 -0500)
committerMike Rylander <mrylander@gmail.com>
Mon, 31 Jul 2017 14:12:51 +0000 (10:12 -0400)
Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Open-ILS/examples/fm_IDL.xml
Open-ILS/src/perlmods/lib/OpenILS/Application/Cat/AssetCommon.pm
Open-ILS/src/templates/staff/cat/volcopy/t_attr_edit.tt2
Open-ILS/src/templates/staff/cat/volcopy/t_copy_alerts.tt2 [new file with mode: 0644]
Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js

index f42ce3d..96b1786 100644 (file)
@@ -6854,6 +6854,7 @@ SELECT  usr,
                        <field reporter:label="Peer Records" name="peer_records" oils_persist:virtual="true" reporter:datatype="link"/>
                        <field reporter:label="Last Captured Hold" name="last_captured_hold" oils_persist:virtual="true" reporter:datatype="link"/>
                        <field reporter:label="Has Holds" name="holds_count" oils_persist:virtual="true" reporter:datatype="link"/>
+                       <field reporter:label="Copy Alerts" name="copy_alerts" oils_persist:virtual="true" reporter:datatype="link"/>
                </fields>
                <links>
                        <link field="age_protect" reltype="has_a" key="id" map="" class="crahp"/>
@@ -6879,6 +6880,7 @@ SELECT  usr,
                        <link field="last_captured_hold" reltype="has_a" key="current_copy" map="" class="alhr"/>
                        <link field="floating" reltype="has_a" key="id" map="" class="cfg"/>
                        <link field="holds_count" reltype="might_have" key="id" map="" class="hasholdscount"/>
+                       <link field="copy_alerts" reltype="has_many" key="copy" map="" class="aca"/>
                </links>
         <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
             <actions>
index 4b81a46..10b7dc4 100644 (file)
@@ -258,7 +258,40 @@ sub update_copy_notes {
     return undef;
 }
 
+sub update_copy_alerts {
+    my($class, $editor, $copy) = @_;
+
+    return undef if $copy->isdeleted;
+
+    my $evt;
+    my $incoming_copy_alerts = $copy->copy_alerts;
+
+    for my $incoming_copy_alert (@$incoming_copy_alerts) { 
+        next unless $incoming_copy_alert;
+
+        if ($incoming_copy_alert->isnew) {
+            next if ($incoming_copy_alert->isdeleted); # if it was added and deleted in the same session
+
+            my $new_copy_alert = Fieldmapper::asset::copy_alert->new();
+            $new_copy_alert->copy( $copy->id );
+            $new_copy_alert->temp( $incoming_copy_alert->temp );
+            $new_copy_alert->ack_time( $incoming_copy_alert->ack_time );
+            $new_copy_alert->note( $incoming_copy_alert->note );
+            $new_copy_alert->alert_type( $incoming_copy_alert->alert_type );
+            $new_copy_alert->create_staff( $incoming_copy_alert->create_staff || $editor->requestor->id );
+            $incoming_copy_alert = $editor->create_asset_copy_alert($new_copy_alert)
+                or return $editor->event;
 
+        } elsif ($incoming_copy_alert->ischanged) {
+            $incoming_copy_alert = $editor->update_asset_copy_alert($incoming_copy_alert)
+        } elsif ($incoming_copy_alert->isdeleted) {
+            $incoming_copy_alert = $editor->delete_asset_copy_alert($incoming_copy_alert->id)
+        }
+    
+    }
+
+    return undef;
+}
 
 sub update_copy {
     my($class, $editor, $override, $vol, $copy, $retarget_holds, $force_delete_empty_bib) = @_;
@@ -370,6 +403,8 @@ sub update_fleshed_copies {
 
         my $notes = $copy->notes;
         $copy->clear_notes;
+        my $copy_alerts = $copy->copy_alerts;
+        $copy->clear_copy_alerts;
 
         if( $copy->isdeleted ) {
             $evt = $class->delete_copy($editor, $override, $vol, $copy, $retarget_holds, $force_delete_empty_bib);
@@ -394,6 +429,8 @@ sub update_fleshed_copies {
 
         $copy->notes( $notes );
         $evt = $class->update_copy_notes($editor, $copy);
+        $copy->copy_alerts( $copy_alerts );
+        $evt = $class->update_copy_alerts($editor, $copy);
         return $evt if $evt;
     }
 
index 12f1f77..33dc769 100644 (file)
                       type="button">
                         [% l('Copy Notes') %]
                     </button>
+                    <button
+                      class="btn btn-default"
+                      ng-disabled="!defaults.copy_alerts"
+                      ng-click="copy_alerts_dialog(workingGridControls.selectedItems())"
+                      type="button">
+                        [% l('Copy Alerts') %]
+                    </button>
                 </div>
             </div>
 
diff --git a/Open-ILS/src/templates/staff/cat/volcopy/t_copy_alerts.tt2 b/Open-ILS/src/templates/staff/cat/volcopy/t_copy_alerts.tt2
new file mode 100644 (file)
index 0000000..043a5ea
--- /dev/null
@@ -0,0 +1,94 @@
+<form ng-submit="ok(copy_alert)" role="form">
+    <div class="modal-header">
+      <button type="button" class="close" ng-click="cancel()" 
+        aria-hidden="true">&times;</button>
+      <h4 class="modal-title">[% l('New Copy Alert') %]</h4>
+    </div>
+    <div class="modal-body">
+      <div class="row">
+        <div class="col-md-6 form-inline">
+          <label for="copy-alert-type-selector"> [% l('Type') %]</label>
+          <select id="copy-alert-type-selector" class="form-control"
+            ng-model="copy_alert.alert_type"
+            ng-options="at.id() as at.name() for at in alert_types">
+          </select>
+        </div>
+        <div class="col-md-3">
+          <label>
+            <input type="checkbox" ng-model="copy_alert.temp"/>
+            [% l('Temporary') %]
+          </label>
+        </div>
+      </div>
+      <div class="row pad-vert">
+        <div class="col-md-12">
+          <textarea class="form-control" 
+            ng-model="copy_alert.note" placeholder="[% l('Alert...') %]">
+          </textarea>
+        </div>
+      </div>
+    </div>
+    <div class="modal-footer">
+      <div class="row">
+        <div class="col-md-10 pull-right">
+          <input type="submit" class="btn btn-primary" value="[% l('OK') %]"/>
+          <button class="btn btn-warning" ng-click="cancel($event)">[% l('Cancel') %]</button>
+        </div>
+      </div>
+
+      <div class="row pad-vert" ng-if="copy_alert_list.length &gt; 0"> 
+        <div class="col-md-12">
+          <div class="row">
+            <div class="col-md-12">
+              <hr/>
+            </div>
+          </div>
+          <div class="row">
+            <div class="col-md-12">
+              <h4 class="pull-left">[% l('Existing Copy Alerts') %]</h4>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="row" ng-repeat="a in copy_alert_list" ng-init="temp = (a.temp() == 't'); note = a.note(); acked = (a.ack_time() !== null); alert_type = a.alert_type().id()">
+        <div class="col-md-12">
+          <div class="row">
+            <div class="col-md-6 form-inline">
+              <label for="copy-alert-type-select-{{a.id()}}">[% l('Type') %]</label>
+              <select id="copy-alert-type-select-{{a.id()}}" class="form-control"
+                      ng-model="alert_type"
+                      ng-change="a.alert_type(alert_type) && a.ischanged(1)"
+                      ng-options="at.id() as at.name() for at in alert_types">
+              </select>
+            </div>
+            <div class="col-md-3">
+              <label>
+                <input type="checkbox" ng-model="temp" ng-change="a.temp(temp ? 't' : 'f') && a.ischanged(1)" ng-disabled="acked"/>
+                [% l('Temporary') %]
+              </label>
+            </div>
+            <div class="col-md-3">
+              <label>
+                <input type="checkbox" ng-model="acked" ng-change="acked ? a.ack_time('now') : a.ack_time(null)"/>
+                [% l('Acknowledge?') %]
+              </label>
+            </div>
+          </div>
+          <div class="row pad-vert">
+            <div class="col-md-12">
+              <textarea class="form-control" ng-change="a.note(note) && a.ischanged(1)"
+                ng-model="note" placeholder="[% l('Alert...') %]" ng-disabled="acked">
+              </textarea>
+            </div>
+          </div>
+          <div class="row">
+            <div class="col-md-12">
+              <hr/>
+            </div>
+          </div>
+        </div>
+      </div>
+
+    </div>
+</form>
index 644be2f..f687402 100644 (file)
@@ -136,6 +136,21 @@ function(egCore , $q) {
         );
     };
 
+    service.get_copy_alert_types = function(orgs) {
+        return egCore.pcrud.search('ccat',
+            { active : 't' },
+            {},
+            { atomic : true }
+        );
+    };
+
+    service.get_copy_alerts = function(copy_id) {
+        return egCore.pcrud.search('aca', { copy : copy_id, ack_time : null },
+            { flesh : 1, flesh_fields : { aca : ['alert_type'] } },
+            { atomic : true }
+        );
+    };
+
     service.get_locations = function(orgs) {
         return egCore.pcrud.search('acpl',
             {owning_lib : orgs},
@@ -255,6 +270,10 @@ function(egCore , $q) {
 
         if (!cp.parts()) cp.parts([]); // just in case...
 
+        service.get_copy_alerts(cp.id()).then(function(aca) {
+            cp.copy_alerts(aca);
+        });
+
         var lib = cp.call_number().owning_lib();
         var cn = cp.call_number().id();
 
@@ -786,6 +805,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
         auto_gen_barcode : false,
         statcats : true,
         copy_notes : true,
+        copy_alerts : true,
         attributes : {
             status : true,
             loan_duration : true,
@@ -1658,6 +1678,63 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
         });
     }
 
+    $scope.copy_alerts_dialog = function(copy_list) {
+        if (!angular.isArray(copy_list)) copy_list = [copy_list];
+
+        return $modal.open({
+            templateUrl: './cat/volcopy/t_copy_alerts',
+            animation: true,
+            controller:
+                   ['$scope','$modalInstance',
+            function($scope , $modalInstance) {
+
+                itemSvc.get_copy_alert_types().then(function(ccat) {
+                    $scope.alert_types = ccat;
+                });
+
+                $scope.focusNote = true;
+                $scope.copy_alert = {
+                    create_staff : egCore.auth.user().id(),
+                    note         : '',
+                    temp         : false
+                };
+
+                if (copy_list.length == 1) {
+                    $scope.copy_alert_list = copy_list[0].copy_alerts();
+                }
+
+                $scope.ok = function(copy_alert) {
+
+                    if (typeof(copy_alert.note) != 'undefined' &&
+                        copy_alert.note != '') {
+                        angular.forEach(copy_list, function (cp) {
+                            var a = new egCore.idl.aca();
+                            a.isnew(1);
+                            a.create_staff(copy_alert.create_staff);
+                            a.note(copy_alert.note);
+                            a.temp(copy_alert.temp ? 't' : 'f');
+                            a.copy(cp.id());
+                            a.ack_time(null);
+                            a.alert_type(
+                                $scope.alert_types.filter(function(at) {
+                                    return at.id() == copy_alert.alert_type;
+                                })[0]
+                            );
+                            cp.copy_alerts().push( a );
+                        });
+                    }
+
+                    $modalInstance.close();
+                }
+
+                $scope.cancel = function($event) {
+                    $modalInstance.dismiss();
+                    $event.preventDefault();
+                }
+            }]
+        });
+    }
+
 }])
 
 .directive("egVolTemplate", function () {
@@ -1676,6 +1753,7 @@ function($scope , $q , $window , $routeParams , $location , $timeout , egCore ,
                     auto_gen_barcode : false,
                     statcats : true,
                     copy_notes : true,
+                    copy_alerts : true,
                     attributes : {
                         status : true,
                         loan_duration : true,