added much control over holds during placement and after the fact
authorerickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 13 Mar 2006 22:11:55 +0000 (22:11 +0000)
committererickson <erickson@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Mon, 13 Mar 2006 22:11:55 +0000 (22:11 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@3349 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/perlmods/OpenILS/Application/Actor.pm
Open-ILS/web/opac/common/js/config.js
Open-ILS/web/opac/common/js/opac_utils.js
Open-ILS/web/opac/skin/default/js/holds.js
Open-ILS/web/opac/skin/default/js/myopac.js
Open-ILS/web/opac/skin/default/xml/common/holds.xml
Open-ILS/web/opac/skin/default/xml/myopac/myopac_holds.xml
Open-ILS/xul/staff_client/server/admin/adminlib.js

index 25b2653..777b0ee 100644 (file)
@@ -133,6 +133,38 @@ sub ou_settings {
        return { map { ($_->name,$_->value) } @$s };
 }
 
+__PACKAGE__->register_method (
+       method          => "ou_setting_delete",
+       api_name                => 'open-ils.actor.org_setting.delete',
+       signature       => q/
+               Deletes a specific org unit setting for a specific location
+               @param authtoken The login session key
+               @param orgid The org unit whose setting we're changing
+               @param setting The name of the setting to delete
+               @return True value on success.
+       /
+);
+
+sub ou_setting_delete {
+       my( $self, $conn, $authtoken, $orgid, $setting ) = @_;
+       my( $reqr, $evt) = $U->checkses($authtoken);
+       return $evt if $evt;
+       $evt = $U->check_perms($reqr->id, $orgid, 'UPDATE_ORG_SETTING');
+       return $evt if $evt;
+
+       my $id = $U->storagereq(
+               'open-ils.storage.id_list.actor.org_unit_setting.search_where', 
+               { name => $setting, org_unit => $orgid } );
+
+       $logger->debug("Retrieved setting $id in org unit setting delete");
+
+       my $s = $U->storagereq(
+               'open-ils.storage.direct.actor.org_unit_setting.delete', $id );
+
+       $logger->activity("User ".$reqr->id." deleted org unit setting $id") if $s;
+       return $s;
+}
+
 
 
 __PACKAGE__->register_method(
index b0a8acf..6f593c5 100644 (file)
@@ -117,6 +117,7 @@ G.ui                = {} /* cache of UI components */
 
 /* regexes */
 var REGEX_BARCODE = /^\d+/; /* starts with a number */
+var REGEX_PHONE = /^\d{3}-\d{3}-\d{4}$/; /* 111-222-3333 */
 
 
 /* call me after page init and I will load references 
index a623ca5..81bd4ba 100644 (file)
@@ -749,4 +749,11 @@ function goHome() {
 }
 
 
+function buildOrgSel(selector, org, offset) {
+       insertSelectorVal( selector, -1, 
+               org.name(), org.id(), null, findOrgDepth(org) - offset );
+       for( var c in org.children() )
+               buildOrgSel( selector, org.children()[c], offset);
+}
+
 
index fa37c47..95d193d 100644 (file)
@@ -86,10 +86,13 @@ function _holdsDrawWindow(recid, type) {
                $('holds_format').appendChild(text(' '));
        }
 
-       appendClear( $('holds_phone'), text(holdRecipient.day_phone()));
+       $('holds_phone').value = holdRecipient.day_phone();
        appendClear( $('holds_email'), text(holdRecipient.email()));
        $('holds_cancel').onclick = showCanvas;
        $('holds_submit').onclick = holdsPlaceHold; 
+
+       appendClear($('holds_physical_desc'), text(rec.physical_description()));
+       if(hold.hold_type() == 'M') hideMe($('hold_physical_desc_row'));
 }
 
 
@@ -111,8 +114,10 @@ function holdsBuildOrgSelector(node) {
        var selector = $('holds_org_selector');
        var index = selector.options.length;
 
-       var indent = findOrgType(node.ou_type()).depth() - 1;
-       setSelectorVal( selector, index, node.name(), node.id(), null, indent );
+       var type = findOrgType(node.ou_type());
+       var indent = type.depth() - 1;
+       var opt = setSelectorVal( selector, index, node.name(), node.id(), null, indent );
+       if(!type.can_have_vols()) opt.disabled = true;
        
        if( node.id() == holdRecipient.home_ou() ) {
                selector.selectedIndex = index;
@@ -131,13 +136,32 @@ function holdsPlaceHold() {
                $('holds_org_selector').selectedIndex].value;
 
        var hold = new ahr();
+
+
+       if( $('holds_enable_phone').checked ) {
+               var phone = $('holds_phone').value;
+               if( !phone.match(REGEX_PHONE) ) {
+                       alert($('holds_bad_phone').textContent);
+                       return;
+               }
+               hold.phone_notify(phone);
+
+       } else {
+               hold.phone_notify(null);
+       }
+
+       if( $('holds_enable_email').checked ) 
+               hold.email_notify(1);
+       else
+               hold.email_notify(0);
+
+
+
        hold.pickup_lib(org); 
        hold.request_lib(org); 
        hold.requestor(holdRequestor.id());
        hold.usr(holdRecipient.id());
        hold.hold_type('T');
-       hold.email_notify(holdRecipient.email());
-       hold.phone_notify(holdRecipient.day_phone());
        hold.target(currentHoldRecord);
        
        var req = new Request( CREATE_HOLD, holdRequestor.session, hold );
index 9dd9a46..81e78c2 100644 (file)
@@ -249,6 +249,7 @@ function myOPACDrawHolds(r) {
 
                var h = holds[i];
                holdCache[h.id()] = h;
+
                var row = holdsTemplateRow.cloneNode(true);
                row.id = "myopac_holds_row_" + h.id() + '_' + h.target();
 
@@ -257,17 +258,25 @@ function myOPACDrawHolds(r) {
                form.id = "myopac_holds_form_" + h.id() + '_' + h.target();
                if(formats) form.appendChild(text(formats));
 
-               $n(row, "myopac_holds_location").
-                       appendChild(text(findOrgUnit(h.pickup_lib()).name()));
+               var orglink = $n(row, "myopac_holds_location");
+               orglink.appendChild(text(findOrgUnit(h.pickup_lib()).name()));
+               orglink.setAttribute('href', 'javascript:myOPACChangeHoldPickupLib('+h.id()+');');
 
                if(h.email_notify()) 
                        $n(row, "myopac_holds_email_link").checked = true;
                else
                        $n(row, "myopac_holds_email_link").checked = false;
 
+               var plink = $n(row, "myopac_holds_phone_link");
+
+               if( h.phone_notify() ) {
+                       plink.appendChild(text(h.phone_notify()));
+                       $n(row, 'myopac_holds_enable_phone').checked = true;
+               } else {
+                       $n(row, 'myopac_holds_enable_phone').checked = false;
+               }
 
-               $n(row, "myopac_holds_phone_link").
-                       appendChild(text(h.phone_notify()));
+               plink.setAttribute('href', 'javascript:myOPACChangeHoldPhone('+h.id()+');');
                tbody.appendChild(row);
 
                $n(row,'myopac_holds_cancel_link').setAttribute(
@@ -278,6 +287,78 @@ function myOPACDrawHolds(r) {
        }
 }
 
+var holdsOrgRowTemplate;
+function myOPACChangeHoldPickupLib(holdid) {
+       var hold = holdCache[holdid];
+       var row = $('myopac_holds_row_' + holdid + '_' + hold.target());
+       if(!holdsOrgRowTemplate)
+               holdsOrgRowTemplate = $('myopac_holds_org_row').cloneNode(true);
+       var orgrow = holdsOrgRowTemplate;
+       var tbody = row.parentNode;
+       if( row.nextSibling ) tbody.insertBefore(orgrow, row.nextSibling);
+       else tbody.appendChild(orgrow);
+       var selector = $n(orgrow, 'myopac_holds_org_selector');
+       buildOrgSel( selector, globalOrgTree, 0 );
+       setSelector( selector, hold.pickup_lib() );
+
+       for( var i = 0; i != selector.options.length; i++ ) {
+               var ou = findOrgUnit(selector.options[i].value);
+               var t = findOrgType(ou.ou_type());
+               if(!t.can_have_vols()) selector.options[i].disabled = true;
+       }
+
+       unHideMe(orgrow);
+
+       $n(orgrow, 'myopac_hold_org_update_submit').onclick = 
+               function(){myOPACUpdateHoldPickupLib(tbody, orgrow, hold);} 
+       $n(orgrow, 'myopac_hold_org_update_cancel').onclick = 
+               function(){tbody.removeChild(orgrow);}
+}
+
+function myOPACUpdateHoldPickupLib( tbody, orgrow, hold ) {
+
+       if( hold.capture_time() ) {
+               alert($('myopac_cannot_change_pickup').textContent);
+               return;
+       }
+
+       var org = getSelectorVal($n(orgrow, 'myopac_holds_org_selector'));
+       hold.pickup_lib(org);
+       tbody.removeChild(orgrow);
+       myOPACUpdateHold(hold);
+}
+
+
+function myOPACUpdateHold(hold) {
+       var req = new Request(UPDATE_HOLD, G.user.session, hold);
+       req.send(true);
+       var x = req.result();
+       holdsTemplateRow = null
+       myOPACShowHolds();
+}
+
+
+function myOPACChangeHoldPhone(holdid) {
+       var hold = holdCache[holdid];
+       var phone;
+
+       var origphone = hold.phone_notify();
+       if(!origphone) origphone = G.user.day_phone();
+
+       phone = prompt($('myopac_hold_phone_change').innerHTML, origphone);
+       if(!phone) return;
+       if( phone == hold.phone_notify() ) return;
+       if( !phone.match(REGEX_PHONE) ) {
+               alert($('myopac_bad_phone').textContent);
+               myOPACChangeHoldPhone(holdid);
+               return;
+       }
+
+       hold.phone_notify(phone);
+       myOPACUpdateHold(hold);
+}
+
+
 function myopacChangeEmailNotify(node) {
        var id = node.parentNode.parentNode.id.replace(/myopac_holds_row_/,"").replace(/_\d+$/,"");
        var hold = holdCache[id];
@@ -296,11 +377,24 @@ function myopacChangeEmailNotify(node) {
                node.checked = true;
        }
 
-       var req = new Request(UPDATE_HOLD, G.user.session, hold);
-       req.send(true);
-       var x = req.result();
-       holdsTemplateRow = null
-       myOPACShowHolds();
+       myOPACUpdateHold(hold);
+}
+
+function myopacChangePhoneNotify(node) {
+       var id = node.parentNode.parentNode.id.replace(/myopac_holds_row_/,"").replace(/_\d+$/,"");
+       var hold = holdCache[id];
+
+       if(!node.checked) {
+               if(!confirm($('myopac_hold_phone_verify').innerHTML)) {
+                       node.checked = true;
+                       return;
+               }
+       }
+
+       if( hold.phone_notify() ) hold.phone_notify("");
+       else myOPACChangeHoldPhone(id);
+
+       myOPACUpdateHold(hold);
 }
 
 function myOPACCancelHold(holdid) {
index b1f3904..41907a2 100644 (file)
@@ -24,7 +24,7 @@
        <div id='holds_box' class='hide_me non_canvas' style='margin-top: 6px;'>
        
                <br/><br/>
-               <table width='75%'>
+               <table width='90%'>
                        <tbody>
                                <tr>
                                        <td class='holds_cell color_1' 
                                        <td class='holds_cell'>&common.format;:</td>
                                        <td class='holds_cell' id='holds_format'> </td>
                                </tr>
+                               <tr id='hold_physical_desc_row'>
+                                       <td class='holds_cell'>Physical Description:</td>
+                                       <td class='holds_cell' id='holds_physical_desc'> </td>
+                               </tr>
                                <tr>
                                        <td class='holds_cell'>&opac.holds.contactPhone;:</td>
+                                       <!--
                                        <td class='holds_cell' id='holds_phone'> </td>
+                                       -->
+                                       <td class='holds_cell'>
+                                               <input id='holds_phone' size='13' maxlength='12'/>
+                                               <span style='margin-left: 4px; font-size: 7pt;'>(XXX-YYY-ZZZZ)</span>
+                                       </td>
+                               </tr>
+                               <tr>
+                                       <td class='holds_cell'>Enable phone notifications for this hold?</td>
+                                       <td class='holds_cell'>
+                                               <input type='checkbox' id='holds_enable_phone' checked='checked'/>
+                                       </td>
                                </tr>
+
                                <tr>
                                        <td class='holds_cell'>&opac.holds.concactEmail;:</td>
                                        <td class='holds_cell' id='holds_email'> </td>
                                </tr>
                                <tr>
+                                       <td class='holds_cell'>Enable email notifications for this hold?</td>
+                                       <td class='holds_cell'>
+                                               <input type='checkbox' id='holds_enable_email' checked='checked'/>
+                                       </td>
+                               </tr>
+                               <tr>
                                        <td class='holds_cell'>&opac.holds.pickupLocation;</td>
                                        <td class='holds_cell'>
                                                <select id='holds_org_selector'> </select>
        
                <div class='hide_me' id='holds_success'>&opac.holds.success;</div>
                <div class='hide_me' id='holds_failure'>&opac.holds.failure;</div>
+               <span class='hide_me' id='holds_bad_phone'>
+                       The phone number does not have the correct format.
+                       The expected format is XXX-YYY-ZZZZ
+               </span>
        
        </div>
 </div>
index 31b5878..4be7ff0 100644 (file)
@@ -3,55 +3,64 @@
 
        <script language='javascript' src='../js/holds.js'> </script>
 
-       <table class='light_border data_grid'>
+       <table class='light_border data_grid data_grid_center'>
 
                <thead class='color_3'>
                        <tr>
-                               <td width='40%'>Title</td>
-                               <td width='20%'>Author</td>
+                               <td width='30%'>Title</td>
+                               <td width='30%'>Author</td>
                                <td>Formats</td>
-                               <td align='center'>Pickup Location</td>
-                               <td align='center'>Enable Email Notification</td>
-                               <td align='center'>Notification Phone Number</td>
-                               <td align='center'>Cancel This Hold</td>
+                               <td>Pickup Location</td>
+                               <td>Enable Email Notification</td>
+                               <td>Enable Phone Notification</td>
+                               <td>Notification Phone Number</td>
+                               <td>Cancel This Hold</td>
                        </tr>
                </thead>
 
                <tbody id='myopac_holds_tbody'>
 
+                       <tr id='myopac_holds_org_row' class='hide_me' style='padding: 6px; border: 3px solid #E0F0E0;'>
+                               <td style='padding: 4px;' colspan='10'>
+                                       <select name='myopac_holds_org_selector'> </select>
+                                       <input name='myopac_hold_org_update_submit' type='submit' value='Submit'> </input>
+                                       <input name='myopac_hold_org_update_cancel' type='submit' value='Cancel'> </input>
+                               </td>
+                       </tr>
+
                        <tr id='myopac_holds_none' class='hide_me'>
-                               <td colspan='10' align='center'><b>You have no items on hold at this time</b></td>
+                               <td colspan='10'><b>You have no items on hold at this time</b></td>
                        </tr>
                        <tr id='myopac_holds_loading'><td>Loading...</td></tr>
 
-                       <tr id='myopac_holds_row' class='light_border hide_me'>
+                       <tr id='myopac_holds_row' class='hide_me'>
 
-                               <td name='myopac_holds_title' class='light_border'>
+                               <td name='myopac_holds_title'>
                                        <a href='javascript:void(0);' name='myopac_holds_title_link'> </a>
                                </td>
 
-                               <td name='myopac_holds_author' class='light_border'>
+                               <td name='myopac_holds_author'>
                                        <a href='javascript:void(0);' name='myopac_holds_author_link'> </a>
                                </td>
 
-                               <td align='center' name='myopac_holds_formats' class='light_border'> </td>
+                               <td name='myopac_holds_formats'> </td>
 
-                               <td align='center' name='myopac_holds_location' class='light_border'> </td>
+                               <td><a name='myopac_holds_location' class='classic_link'/></td>
 
-                               <!--
-                               <td align='center' name='myopac_holds_email' class='light_border'>
-                                       <a href='javascript:void(0);' name='myopac_holds_email_link'></a>
-                               </td>
-                               -->
-                               <td align='center' class='light_border'>
+                               <td>
                                        <input type='checkbox' name='myopac_holds_email_link' onclick='myopacChangeEmailNotify(this);'/>
                                </td>
 
-                               <td align='center' name='myopac_holds_phone' class='light_border'>
+                               <td>
+                                       <input type='checkbox' name='myopac_holds_enable_phone' 
+                                               onclick='myopacChangePhoneNotify(this);'/>
+                               </td>
+
+                               <td name='myopac_holds_phone' class='classic_link'>
                                        <a href='javascript:void(0);' name='myopac_holds_phone_link'></a>
                                </td>
 
-                               <td align='center' name='myopac_holds_cancel' class='light_border'>
+                               <td name='myopac_holds_cancel'>
                                        <a href='javascript:void(0);' 
                                                name='myopac_holds_cancel_link' class='classic_link'>Cancel</a>
                                </td>
        <div class='hide_me' id='myopac_holds_cancel_verify'>Are you sure you wish to cancel the selected hold?</div>
 
        <span class='hide_me' id='myopac_hold_email_verify'>
-               Are you sure you wish to set/unset the email notification for this hold?
+               Are you sure you wish to the email notification setting for this hold?
        </span>
 
+       <span class='hide_me' id='myopac_hold_phone_change'>
+               Enter the new hold notification phone number or click 'Cancel' to keep the current phone number.
+               The required format is XXX-YYY-ZZZZ.
+       </span>
+       <span class='hide_me' id='myopac_bad_phone'>
+               The phone number does not have the correct format.  
+               The required format is XXX-YYY-ZZZZ
+       </span>
+
+       <span class='hide_me' id='myopac_hold_phone_verify'>
+               Are you sure you with to disable phone notifications for this hold?
+       </span>
+
+       <span class='hide_me' id='myopac_cannot_change_pickup'>
+               The selected hold is either in transit or has arrived at the pickup location.
+               The pickup location for this hold cannot be changed.
+       </span>
 
 </div>
 
index efce1a1..5f42695 100644 (file)
@@ -52,12 +52,17 @@ function fetchHighestPermOrgs( session, userId, perms ) {
 /* offset is the depth of the highest org 
        in the tree we're building 
   */
-function buildOrgSel(selector, org, offset) {
+
+/* XXX Moved to opac_utils.js */
+
+/*
+function buildOrgSel(selector, org, offset) { 
        insertSelectorVal( selector, -1, 
                org.name(), org.id(), null, findOrgDepth(org) - offset );
        for( var c in org.children() )
                buildOrgSel( selector, org.children()[c], offset);
 }
+*/
 
 /** removes all child nodes in 'tbody' that have the attribute 'key' defined */
 function cleanTbody(tbody, key) {