webstaff: Ability to generate a count of predictions, edit issuances, and add a singl...
authorMike Rylander <mrylander@gmail.com>
Tue, 16 May 2017 16:50:24 +0000 (12:50 -0400)
committerGalen Charlton <gmc@equinoxinitiative.org>
Tue, 30 May 2017 16:06:45 +0000 (12:06 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/templates/staff/serials/index.tt2
Open-ILS/src/templates/staff/serials/t_holding_code_dialog.tt2
Open-ILS/src/templates/staff/serials/t_view_items_grid.tt2
Open-ILS/web/js/ui/default/staff/serials/directives/view-items-grid.js
Open-ILS/web/js/ui/default/staff/serials/services/core.js

index c95ed74..0555ed4 100644 (file)
@@ -23,7 +23,9 @@ angular.module('egCoreMod').run(['egStrings', function(s) {
     s.SERIALS_ISSUANCE_SUCCESS_SAVE = "[% l('Issuance saved') %]";
     s.SERIALS_DISTRIBUTION_SUCCESS_LINK_MFHD = "[% l('Distribution linked to MFHD') %]";
     s.SERIALS_DISTRIBUTION_FAIL_LINK_MFHD = "[% l('Failed to link distribution to MFHD') %]";
-    s.SERIALS_EDIT_SISS_HC = "[% l('Edit issuance information') %]";
+    s.SERIALS_EDIT_SISS_HC = "[% l('Edit issue information') %]";
+    s.SERIALS_ISSUANCE_PREDICT = "[% l('Predict New Issues: Initial Values') %]";
+    s.SERIALS_ISSUANCE_ADD = "[% l('Add folloing issue') %]";
 }]);
 </script>
 [% END %]
index a093f0d..3a382d2 100644 (file)
 </div>
 
 <div class="modal-footer">
-    <input type="submit" class="btn btn-primary" value='{{ save_label || "[% l('Save') %]" }}'></input>
-    <button class="btn btn-warning" ng-click="cancel()">[% l('Cancel') %]</button>
+  <div class="row">
+    <div class="col-md-4" ng-show="request_count">
+      <h4>[% l('Prediction count') %]</h4>
+    </div>
+    <div class="col-md-3" ng-show="request_count">
+      <input class="form-control" ng-model="count" type="number"/>
+    </div>
+    <div class="col-md-5">
+      <input type="submit" class="btn btn-primary" value='{{ save_label || "[% l('Save') %]" }}'></input>
+      <button class="btn btn-warning" ng-click="cancel()">[% l('Cancel') %]</button>
+    </div>
+  </div>
 </div>
 </form>
index bb7ce17..0fed1a1 100644 (file)
@@ -1,15 +1,17 @@
 <div>
   <eg-grid
-    id-field="index"
+    id-field="id"
     features="-display,-sort,-multisort"
     items-provider="itemGridProvider"
     grid-controls="itemGridControls"
     persist-key="serials.view_item_grid">
 
-    <eg-grid-action handler="add_issuance" disabled="need_one_selected"
-      label="[% l('Add following issuance') %]"></eg-grid-action>
+    <eg-grid-menu-item handler="add_issuances" standalone="true" label="[% l('Predict New Issues') %]"></eg-grid-menu-item>
+
+    <eg-grid-action handler="following_issuance" disabled="need_one_selected"
+      label="[% l('Add following issue') %]"></eg-grid-action>
     <eg-grid-action handler="edit_issuance_holding_code"
-      label="[% l('Edit issuance holding codes') %]"></eg-grid-action>
+      label="[% l('Edit issue holding codes') %]"></eg-grid-action>
     <eg-grid-action handler="delete_items"
       label="[% l('Delete items') %]"></eg-grid-action>
 
@@ -28,6 +30,8 @@
     <eg-grid-field label="[% l('Display Grouping') %]" path="stream.distribution.display_grouping"></eg-grid-field>
     <eg-grid-field label="[% l('Subscription ID') %]" path="stream.distribution.subscription.id"></eg-grid-field>
     <eg-grid-field label="[% l('Distribution ID') %]" path="stream.distribution.id"></eg-grid-field>
+    <eg-grid-field label="[% l('Stream ID') %]" path="stream.id"></eg-grid-field>
+    <eg-grid-field label="[% l('Item ID') %]" path="id"></eg-grid-field>
   </eg-grid>
 </div>
 
index 9944d14..9b854bd 100644 (file)
@@ -48,10 +48,29 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider ,
                     item.issuance.holding_code = JSON.stringify(result.holding_code);
                     item.issuance.holding_type = result.type;
                     item.issuance.date_published = result.date.toISOString();
-
-                    // TODO: fetch label with make_predictions
-
-                    edits.push( egCore.idl.fromHash('siss',item.issuance) );
+                    item.issuance.editor = egCore.auth.user();
+                    item.issuance.edit_date = 'now';
+
+                    return $q.when(egCore.idl.fromHash('siss',item.issuance));
+                }).then(function(iss) {
+                    return egCore.net.request(
+                        'open-ils.serial',
+                        'open-ils.serial.make_prediction_values',
+                        egCore.auth.token(),
+                        { ssub_id : $scope.ssubId,
+                          num_to_predict : 0,
+                          include_base_issuance : 1,
+                          base_issuance : iss
+                        }
+                    ).then( function(resp) {
+                        var evt = egCore.evt.parse(resp);
+                        if (evt) { // any way to just throw or return this to the error handler?
+                            ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE);
+                        } else {
+                            iss.label(resp[0].label);
+                            edits.push(iss);
+                        }
+                    });
                 })
             );
         });
@@ -74,25 +93,97 @@ function($scope , $q , egSerialsCoreSvc , egCore , egGridDataProvider ,
                 function(resp) {
                     var evt = egCore.evt.parse(resp);
                     if (evt) { // any way to just throw or return this to the error handler?
-                        console.log('failure',resp);
                         ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE);
                     } else {
-                        console.log('success',resp);
                         ngToast.success(egCore.strings.SERIALS_ISSUANCE_SUCCESS_SAVE);
+                        return reload($scope.ssubId);
                     }
                 },
                 function(resp) {
-                    console.log('failure',resp);
                     ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE);
                 }
             );
     }
 
 
-    $scope.add_issuance = function (items) {
-        egSerialsCoreSvc.new_holding_code({
+    $scope.following_issuance = function (items) {
+        return egSerialsCoreSvc.new_holding_code({
+            title : egCore.strings.SERIALS_ISSUANCE_ADD,
             prev_iss : egCore.idl.fromHash('siss',items[0].issuance)
-        }).then(function(hc) { console.log(hc) });
+        }).then(function(hc) {
+            console.log(hc)
+            return egCore.net.request(
+                'open-ils.serial',
+                'open-ils.serial.make_predictions',
+                egCore.auth.token(),
+                { ssub_id : $scope.ssubId,
+                  num_to_predict : 1,
+                  base_issuance : egCore.idl.fromHash('siss',items[0].issuance)
+                }
+            ).then(
+                function(resp) {
+                    var evt = egCore.evt.parse(resp);
+                    if (evt) { // any way to just throw or return this to the error handler?
+                        ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE);
+                    } else {
+                        ngToast.success(egCore.strings.SERIALS_ISSUANCE_SUCCESS_SAVE);
+                        return reload($scope.ssubId);
+                    }
+                },
+                function(resp) {
+                    ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE);
+                }
+            );
+        });
+    }
+
+    $scope.add_issuances = function () {
+        var lastItem = egSerialsCoreSvc.itemList[egSerialsCoreSvc.itemList.length - 1];
+
+        var base_iss;
+        if (lastItem) {
+            lastItem = egCore.idl.fromHash('siss', lastItem.issuance);
+        } else {
+            base_iss = new egCore.idl.siss();
+            base_iss.creator( egCore.auth.user().id() );
+            base_iss.editor( egCore.auth.user().id() );
+            base_iss.date_published( hc.date );
+            base_iss.subscription( $scope.ssubId );
+            base_iss.caption_and_pattern( hc.scap );
+            base_iss.holding_code( JSON.stringify(hc.holding_code) );
+            base_iss.holding_type( hc.type );
+        }
+
+        return egSerialsCoreSvc.new_holding_code({
+            title : egCore.strings.SERIALS_ISSUANCE_PREDICT,
+            request_count : true,
+            prev_iss : lastItem
+        }).then(function(hc) {
+            console.log(hc)
+            return egCore.net.request(
+                'open-ils.serial',
+                'open-ils.serial.make_predictions',
+                egCore.auth.token(),
+                { ssub_id : $scope.ssubId,
+                  include_base_issuance : lastItem ? 0 : 1,
+                  num_to_predict : hc.count,
+                  base_issuance : base_iss || lastItem
+                }
+            ).then(
+                function(resp) {
+                    var evt = egCore.evt.parse(resp);
+                    if (evt) { // any way to just throw or return this to the error handler?
+                        ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE);
+                    } else {
+                        ngToast.success(egCore.strings.SERIALS_ISSUANCE_SUCCESS_SAVE);
+                        return reload($scope.ssubId);
+                    }
+                },
+                function(resp) {
+                    ngToast.danger(egCore.strings.SERIALS_ISSUANCE_FAIL_SAVE);
+                }
+            );
+        });
     }
 
     $scope.need_one_selected = function() {
index d2e93fd..2669501 100644 (file)
@@ -159,7 +159,16 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
                 });
             });
 
-            service.itemList = egCore.idl.toHash(list);
+            var hashList = egCore.idl.toHash(list);
+            angular.forEach(hashList, function (item) {
+                item['issuance.date_published'] = item.issuance.date_published;
+            });
+
+            // ... then sort it
+            service.itemList.length = 0;
+            angular.extend(service.itemList,
+                orderByFilter(hashList, ['"issuance.date_published"', '"id"'])
+            );
             return $q.when(list);
         });
     }
@@ -170,40 +179,65 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
         var date = args.date;
         var prev_iss = args.prev_iss;
         var curr_iss = args.curr_iss;
+        var link = '1.1';
 
         var sub = service.get_ssub(service.subId);
-        if (!sub) return $q.reject();
+        if (!sub) return {};
 
         var scap;
-        var tmp = sub.scaps().filter(function (scap) {
-            return (scap.type() == type && scap.active() == 't');
-        });
-        if (angular.isArray(tmp) && tmp[0]) scap = tmp[0];
-
-        if (!scap) return $q.reject();
-
-        var others = [], enums = [], chrons = [], freq = '';
-        var pat = JSON.parse(scap.pattern_code()).slice(4); // just the part we care about
-
-        var freq_index = pat.indexOf('w');
-        if (freq_index > -1) {
-            freq = pat[freq_index + 1];
-        }
-
-        var link = '1.1';
         if (prev_iss) { // we're predicting
             var old_link_parts = JSON.parse(prev_iss.holding_code())[3].split('.');
             var olink = old_link_parts[0];
             var oseq = parseInt(old_link_parts[1]) + 1;
             link = [olink,oseq].join('.');
 
-            date = new Date(
-                new Date(prev_iss.date_published()).getTime() + service.freq_offset[freq]
-            );
+            if (prev_iss.holding_type())
+                type = prev_iss.holding_type();
+
+            if (prev_iss.caption_and_pattern()) {
+                var tmp = sub.scaps().filter(function (s) {
+                    return (s.id() == prev_iss.caption_and_pattern());
+                });
+                if (angular.isArray(tmp) && tmp[0]) scap = tmp[0];
+            }
+
+            date = new Date(prev_iss.date_published());
         } else if (curr_iss) { // we're editing
+            if (curr_iss.holding_type())
+                type = curr_iss.holding_type();
+
+            if (curr_iss.caption_and_pattern()) {
+                var tmp = sub.scaps().filter(function (s) {
+                    return (s.id() == curr_iss.caption_and_pattern());
+                });
+                if (angular.isArray(tmp) && tmp[0]) scap = tmp[0];
+            }
+
             date = new Date(curr_iss.date_published());
         }
-        
+
+        if (!scap) {
+            var tmp = sub.scaps().filter(function (s) {
+                return (s.type() == type && s.active() == 't');
+            });
+            if (angular.isArray(tmp) && tmp[0]) scap = tmp[0];
+        }
+
+        if (!scap) return {};
+
+        var others = [], enums = [], chrons = [], freq = '';
+        var pat = JSON.parse(scap.pattern_code()).slice(4); // just the part we care about
+
+        var freq_index = pat.indexOf('w');
+        if (freq_index > -1) {
+            freq = pat[freq_index + 1];
+            if (prev_iss) {
+                date = new Date(
+                    date.getTime() + service.freq_offset[freq]
+                );
+            }
+        }
+       
         if (!date) date = new Date();
 
         for (var i = 0; i < pat.length; i++) {
@@ -255,6 +289,7 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
 
         return {
             holding_code : ["4","1","8",link],
+            scap         : scap.id(),
             type         : type,
             date         : date,
             enums        : enums,
@@ -266,6 +301,7 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
 
     service.new_holding_code = function (options) {
         if (options === undefined) options = {};
+        options.count = options.count || 1;
 
         return $uibModal.open({
             templateUrl: './serials/t_holding_code_dialog',
@@ -276,6 +312,8 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
                 ['$scope', '$uibModalInstance', function($scope, $uibModalInstance) {
                 $scope.focusMe = true;
                 $scope.title = options.title;
+                $scope.request_count = options.request_count;
+                $scope.count = 1;
                 $scope.save_label = options.save_label;
                 $scope.pubdate = options.date || new Date();
                 $scope.type = options.type || 'basic';
@@ -289,15 +327,18 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
                             prev_iss : options.prev_iss,
                             curr_iss : options.curr_iss
                         });
+
                         if ($scope.args.type && $scope.type != $scope.args.type)
                             $scope.type = $scope.args.type;
                         if ($scope.args.date)
                             $scope.pubdate = $scope.args.date;
+
                         delete options.prev_iss; // only use this once
                         delete options.curr_iss; // only use this once
                     }
                 }
 
+                $scope.$watch('count',function (n,o) { options.count = n });
                 $scope.$watch('type',refresh);
                 $scope.$watch('pubdate',refresh);
 
@@ -314,7 +355,7 @@ function(egCore , orderByFilter , $q , $filter , $uibModal) {
                     args.holding_code.push(e.value);
                 }
             );
-
+            args.count = options.count;
             return $q.when(args);
         });
     }