webstaff: Copy editing!
authorMike Rylander <mrylander@gmail.com>
Tue, 18 Aug 2015 21:27:47 +0000 (17:27 -0400)
committerJason Stephenson <jstephenson@mvlc.org>
Mon, 14 Sep 2015 19:44:15 +0000 (15:44 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Galen Charlton <gmc@esilibrary.com>
Signed-off-by: Jason Stephenson <jstephenson@mvlc.org>
Open-ILS/src/templates/staff/cat/volcopy/t_edit.tt2
Open-ILS/web/js/ui/default/staff/cat/volcopy/app.js

index 7ccd43f..b616e03 100644 (file)
@@ -5,7 +5,7 @@
 <accordion close-others="false">
     <accordion-group heading="Volume Editor" is-open="show_vols">
 
-        <div collapse="hide_vols" class="container-fluid">
+        <div class="container-fluid">
             <div class="row">
                 <div class="col-xs-1">[% l('Library') %]</div>
                 <div class="col-xs-1">[% l('Volumes') %]</div>
     </accordion-group>
     <accordion-group heading="Copy Editor" is-open="show_copies">
 
-    <div collapse="hide_vols" class="container-fluid">
+        <ul ng-model="copytab" class="nav nav-tabs">
+          <li ng-class="{active : copytab == 'working'}">
+            <a ng-click="copytab='working'" >[% l('Working Copies') %]</a>
+          </li>
+          <li ng-class="{active : copytab == 'complete'}">
+            <a ng-click="copytab='complete'" >[% l('Completed Copies') %]</a>
+          </li>
+        </ul>
+
+<div class="tab-content">
+  <div class="tab-pane active">
+    <div ng-show="copytab == 'working'">
+
+    <div class="container-fluid"> <!-- working copy editor -->
         <div class="row">
             <div class="col-lg-4">
 
                 <eg-grid
                   id-field="id"
                   idl-class="acp"
-                  features="startSelected,-pagination,-actions,-menu,-picker,-index"
-                  main-label="[% l('Working Copies') %]"
+                  features="startSelected,-pagination,-actions,-picker,-index"
                   items-provider="workingGridDataProvider"
                   grid-controls="workingGridControls"
                   persist-key="cat.volcopy.copies">
+
+                  <eg-grid-menu-item handler="workingToComplete"
+                   label="[% l('Store Selected') %]"></eg-grid-menu-item>
+
                 
                   <eg-grid-field label="[% l('Barcode') %]"     path='barcode' visible></eg-grid-field>
                   <eg-grid-field label="[% l('Created') %]"     path="create_date" visible></eg-grid-field>
@@ -63,6 +79,7 @@
 
                         <div class="col-md-4">
                             <div class="container-fluid"> <!-- first column -->
+
                                 <div class="row">
                                     <div class="col-md-12">
                                         <b>[% l('Circulate?') %]</b>
                                         </div>
                                     </div>
                                 </div>
-                            </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Circulation Library') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <eg-org-selector selected="working.circ_lib" disableTest="cant_have_vols"></eg-org-selector>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Shelving Location') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <select
+                                            ng-model="working.location"
+                                            ng-options="l.name() for l in location_list track by idTracker(l)"
+                                        ></select>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Circulation Modifier') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <select
+                                            ng-model="working.circ_modifier"
+                                            ng-options="m.name() for m in circ_mod_list track by tracker(m,'code')"
+                                        ></select>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Circulate as Type') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <select
+                                            ng-model="working.circ_as_type"
+                                            ng-options="t.value() for t in circ_type_list track by tracker(t,'code')"
+                                        ></select>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Holdable?') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <div class="container-fluid">
+                                            <div class="row">
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.holdable" value="t"/>
+                                                        [% l('Yes') %]
+                                                    </label>
+                                                </div>
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.holdable" value="f"/>
+                                                        [% l('No') %]
+                                                    </label>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Loan Duration') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <select ng-model="working.loan_duration">
+                                            <option value="1">[% l('Short') %]</option>
+                                            <option value="2" selected>[% l('Normal') %]</option>
+                                            <option value="3">[% l('Extended') %]</option>
+                                        </select>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Fine Level') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <select ng-model="working.fine_level">
+                                            <option value="1">[% l('Low') %]</option>
+                                            <option value="2" selected>[% l('Normal') %]</option>
+                                            <option value="3">[% l('High') %]</option>
+                                        </select>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Age-based Hold Protection') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <select
+                                            ng-model="working.age_protect"
+                                            ng-options="a.name() for a in age_protect_list track by idTracker(a)"
+                                        ></select>
+                                    </div>
+                                </div>
+
+                            </div> <!-- first column -->
                         </div>
 
                         <div class="col-md-4">
                             <div class="container-fluid"> <!-- second column -->
+
                                 <div class="row">
                                     <div class="col-md-12">
                                         <b>[% l('Status') %]</b>
                                     <div class="col-md-12">
                                         <select
                                             ng-model="working.status"
-                                            ng-change="updateWorkingStatus()"
                                             ng-options="s.name() for s in status_list track by idTracker(s)"
                                         ></select>
                                     </div>
                                 </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Reference?') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <div class="container-fluid">
+                                            <div class="row">
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.ref" value="t"/>
+                                                        [% l('Yes') %]
+                                                    </label>
+                                                </div>
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.ref" value="f"/>
+                                                        [% l('No') %]
+                                                    </label>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('OPAC Visible?') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <div class="container-fluid">
+                                            <div class="row">
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.opac_visible" value="t"/>
+                                                        [% l('Yes') %]
+                                                    </label>
+                                                </div>
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.opac_visible" value="f"/>
+                                                        [% l('No') %]
+                                                    </label>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Price') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <input ng-model="working.price" type="text"/>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Cost') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <input ng-model="working.cost" type="text"/>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Deposit?') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <div class="container-fluid">
+                                            <div class="row">
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.deposit" value="t"/>
+                                                        [% l('Yes') %]
+                                                    </label>
+                                                </div>
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.deposit" value="f"/>
+                                                        [% l('No') %]
+                                                    </label>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Deposit Amount') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <input ng-model="working.deposit_amount" type="text"/>
+                                    </div>
+                                </div>
+
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <b>[% l('Quality') %]</b>
+                                    </div>
+                                </div>
+                                <div class="row">
+                                    <div class="col-md-12">
+                                        <div class="container-fluid">
+                                            <div class="row">
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.mint_condition" value="t"/>
+                                                        [% l('Good') %]
+                                                    </label>
+                                                </div>
+                                                <div class="col-xs-6">
+                                                    <label>
+                                                        <input type="radio" ng-model="working.mint_condition" value="f"/>
+                                                        [% l('Damaged') %]
+                                                    </label>
+                                                </div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+
                             </div>
                         </div>
 
         </div>
     </div>
 
+    </div>
+    <div ng-show="copytab == 'complete'">
+       <eg-grid
+         id-field="id"
+         idl-class="acp"
+         features="-pagination,-actions,-picker,-index"
+         items-provider="completedGridDataProvider"
+         grid-controls="completedGridControls"
+         persist-key="cat.volcopy.copies.complete">
+       
+         <eg-grid-menu-item handler="completeToWorking"
+          label="[% l('Edit Selected') %]"></eg-grid-menu-item>
+
+         <eg-grid-menu-item handler="saveAndExit"
+          label="[% l('Save & Exit') %]"></eg-grid-menu-item>
+
+         <eg-grid-field label="[% l('Barcode') %]"     path='barcode' visible></eg-grid-field>
+         <eg-grid-field label="[% l('Created') %]"     path="create_date" visible></eg-grid-field>
+         <eg-grid-field label="[% l('Activated') %]"   path="active_date" visible></eg-grid-field>
+         <eg-grid-field label="[% l('Call Number') %]" path="call_number.label" visible></eg-grid-field>
+         <eg-grid-field label="[% l('Circ Library') %]" flesher="orgById" path="circ_lib.name" visible></eg-grid-field>
+         <eg-grid-field label="[% l('Shelving Location') %]" flesher="locationById" path="location.name" visible></eg-grid-field>
+         <eg-grid-field label="[% l('Circ Modifier') %]" path="circ_modifier" visible></eg-grid-field>
+         <eg-grid-field label="[% l('Circulate?') %]"  path="circulate" visible></eg-grid-field>
+         <eg-grid-field label="[% l('Holdable?') %]"   path="circulate" visible></eg-grid-field>
+         <eg-grid-field label="[% l('Reference?') %]"  path="ref" visible></eg-grid-field>
+         <eg-grid-field label="[% l('Status') %]"      flesher="statusById" path="status.name" visible></eg-grid-field>
+         <eg-grid-field label="[% l('OPAC Visible') %]" path="opac_visible" visible></eg-grid-field>
+       
+       </eg-grid>
+    </div>
+  </div>
+</div>
+
     </accordion-group>
 </accordion>
index 59a736e..5127c4f 100644 (file)
@@ -62,6 +62,13 @@ function(egCore , $q) {
 
     };
 
+    service.get_locations = function(orgs) {
+        return egCore.pcrud.search('acpl',
+            {owning_lib : orgs},
+            null, {atomic : true}
+        );
+    };
+
     service.get_suffixes = function(org) {
         if (egCore.env.acns)
             return $q.when(egCore.env.acns.list);
@@ -89,6 +96,45 @@ function(egCore , $q) {
 
     };
 
+    service.get_circ_mods = function() {
+        if (egCore.env.ccm)
+            return $q.when(egCore.env.ccm.list);
+
+        return egCore.pcrud.retrieveAll('ccm', {}, {atomic : true}).then(
+            function(list) {
+                egCore.env.absorbList(list, 'ccm');
+                return list;
+            }
+        );
+
+    };
+
+    service.get_circ_types = function() {
+        if (egCore.env.citm)
+            return $q.when(egCore.env.citm.list);
+
+        return egCore.pcrud.retrieveAll('citm', {}, {atomic : true}).then(
+            function(list) {
+                egCore.env.absorbList(list, 'citm');
+                return list;
+            }
+        );
+
+    };
+
+    service.get_age_protects = function() {
+        if (egCore.env.crahp)
+            return $q.when(egCore.env.crahp.list);
+
+        return egCore.pcrud.retrieveAll('crahp', {}, {atomic : true}).then(
+            function(list) {
+                egCore.env.absorbList(list, 'crahp');
+                return list;
+            }
+        );
+
+    };
+
     service.bmp_parts = {};
     service.get_parts = function(rec) {
         if (service.bmp_parts[rec])
@@ -107,7 +153,7 @@ function(egCore , $q) {
     service.flesh = {   
         flesh : 3, 
         flesh_fields : {
-            acp : ['call_number','parts','location'],
+            acp : ['call_number','parts'],
             acn : ['label_class','prefix','suffix']
         }
     }
@@ -314,6 +360,11 @@ function(egCore , $q) {
                 $scope.orig_cn_count = $scope.cn_count;
 
                 $scope.owning_lib = egCore.org.get($scope.lib);
+                $scope.$watch('owning_lib', function (l) {
+                    angular.forEach( $scope.struct[$scope.first_cn], function (cp) {
+                        cp.call_number().owning_lib( $scope.owning_lib.id() );
+                    });
+                });
 
                 $scope.cant_have_vols = function (id) { return !egCore.org.CanHaveVolumes(id); };
 
@@ -324,13 +375,13 @@ function(egCore , $q) {
                             var cn = new egCore.idl.acn();
                             cn.id( --$scope.new_cn_id );
                             cn.isnew( true );
-                            cn.owning_lib( $scope.owning_lib );
+                            cn.owning_lib( $scope.owning_lib.id() );
                             cn.record( $scope.full_cn.record() );
 
                             var cp = new egCore.idl.acp();
                             cp.id( --$scope.new_cp_id );
                             cp.isnew( true );
-                            cp.circ_lib( $scope.owning_lib );
+                            cp.circ_lib( $scope.owning_lib.id() );
                             cp.call_number( cn );
 
                             $scope.struct[cn.id()] = [cp];
@@ -369,7 +420,52 @@ function($scope , $q , $routeParams , $location , $timeout , egCore , egNet , eg
     $scope.show_vols = true;
     $scope.show_copies = true;
 
-    $scope.idTracker = function (x) { if (x) return x.id() };
+    $scope.tracker = function (x,f) { if (x) return x[f]() };
+    $scope.idTracker = function (x) { if (x) return $scope.tracker(x,'id') };
+    $scope.cant_have_vols = function (id) { return !egCore.org.CanHaveVolumes(id); };
+
+    $scope.orgById = function (id) { return egCore.org.get(id) }
+    $scope.statusById = function (id) {
+        return $scope.status_list.filter( function (s) { return s.id() == id } )[0];
+    }
+    $scope.locationById = function (id) {
+        return $scope.location_cache[''+id];
+    }
+
+    $scope.workingToComplete = function () {
+        angular.forEach( $scope.workingGridControls.selectedItems(), function (c) {
+            angular.forEach( itemSvc.copies, function (w, i) {
+                if (c === w)
+                    $scope.completed_copies = $scope.completed_copies.concat(itemSvc.copies.splice(i,1));
+            });
+        });
+    }
+
+    $scope.completeToWorking = function () {
+        angular.forEach( $scope.completedGridControls.selectedItems(), function (c) {
+            angular.forEach( $scope.completed_copies, function (w, i) {
+                if (c === w)
+                    itemSvc.copies = itemSvc.copies.concat($scope.completed_copies.splice(i,1));
+            });
+        });
+    }
+
+    createSimpleUpdateWatcher = function (field) {
+        $scope.$watch('working.' + field, function () {
+            var newval = $scope.working[field];
+            if (angular.isObject(newval)) { // we'll use the pkey
+                if (newval.id) newval = newval.id();
+                else if (newval.code) newval = newval.code();
+            }
+
+            if ($scope.workingGridControls && $scope.workingGridControls.selectedItems) {
+                angular.forEach(
+                    $scope.workingGridControls.selectedItems(),
+                    function (cp) { cp[field](newval); cp.ischanged(1); }
+                );
+            }
+        });
+    }
 
     $timeout(function(){
 
@@ -379,10 +475,23 @@ function($scope , $q , $routeParams , $location , $timeout , egCore , egNet , eg
     if (dataKey && dataKey.length > 0) {
         $scope.working = {};
 
+        $scope.copytab = 'working';
         $scope.tab = 'edit';
         $scope.summaryRecord = null;
         $scope.record_id = null;
         $scope.data = {};
+        $scope.completed_copies = [];
+        $scope.location_orgs = [];
+        $scope.location_cache = {};
+
+        $scope.completedGridDataProvider = egGridDataProvider.instance({
+            get : function(offset, count) {
+                //return provider.arrayNotifier(itemSvc.copies, offset, count);
+                return this.arrayNotifier($scope.completed_copies, offset, count);
+            }
+        });
+
+        $scope.completedGridControls = {};
 
         $scope.workingGridDataProvider = egGridDataProvider.instance({
             get : function(offset, count) {
@@ -431,20 +540,83 @@ function($scope , $q , $routeParams , $location , $timeout , egCore , egNet , eg
         });
 
         $scope.$watch('data.copies.length', function () {
-            console.log('data.copies.length changed');
+            if ($scope.data.copies) {
+                var base_orgs = $scope.data.copies.map(function(cp){
+                    return cp.circ_lib()
+                }).filter(function(e,i,a){
+                    return a.lastIndexOf(e) === i;
+                });
+
+                var all_orgs = [];
+                angular.forEach(base_orgs, function(o) {
+                    all_orgs = all_orgs.concat( egCore.org.fullPath(o, true) );
+                });
+
+                var final_orgs = all_orgs.filter(function(e,i,a){
+                    return a.lastIndexOf(e) === i;
+                }).sort(function(a,b){return b-a});
+
+                if ($scope.location_orgs.toString() != final_orgs.toString()) {
+                    $scope.location_orgs = final_orgs;
+                    if ($scope.location_orgs.length) {
+                        itemSvc.get_locations($scope.location_orgs).then(function(list){
+                            angular.forEach(list, function(l) {
+                                $scope.location_cache[ ''+l.id() ] = l;
+                            });
+                            $scope.location_list = list;
+                        });
+                    }
+                }
+            }
+
             $scope.workingGridDataProvider.refresh();
         });
 
+        $scope.$watch('completed_copies.length', function () {
+            $scope.completedGridDataProvider.refresh();
+        });
+
+        $scope.location_list = [];
+        itemSvc.get_locations().then(function(list){
+            $scope.location_list = list;
+        });
+        createSimpleUpdateWatcher('location');
+
         $scope.status_list = [];
         itemSvc.get_statuses().then(function(list){
             $scope.status_list = list;
         });
-        $scope.updateWorkingStatus = function () {
-            angular.forEach(
-                $scope.workingGridControls.selectedItems(),
-                function (cp) { cp.status($scope.working.status.id()); cp.ischanged(1); }
-            );
-        };
+        createSimpleUpdateWatcher('status');
+
+        $scope.circ_mod_list = [];
+        itemSvc.get_circ_mods().then(function(list){
+            $scope.circ_mod_list = list;
+        });
+        createSimpleUpdateWatcher('circ_modifier');
+
+        $scope.circ_type_list = [];
+        itemSvc.get_circ_types().then(function(list){
+            $scope.circ_type_list = list;
+        });
+        createSimpleUpdateWatcher('circ_as_type');
+
+        $scope.age_protect_list = [];
+        itemSvc.get_age_protects().then(function(list){
+            $scope.age_protect_list = list;
+        });
+        createSimpleUpdateWatcher('age_protect');
+
+        createSimpleUpdateWatcher('circulate');
+        createSimpleUpdateWatcher('holdable');
+        createSimpleUpdateWatcher('fine_level');
+        createSimpleUpdateWatcher('loan_duration');
+        createSimpleUpdateWatcher('cost');
+        createSimpleUpdateWatcher('deposit');
+        createSimpleUpdateWatcher('deposit_amount');
+        createSimpleUpdateWatcher('mint_condition');
+        createSimpleUpdateWatcher('opac_visible');
+        createSimpleUpdateWatcher('ref');
+
     }
 
     });