Serial note perms and edit support user/dbwells/lp-796795_serial_note_improvements
authorDan Wells <dbw2@calvin.edu>
Mon, 13 Jun 2011 18:16:47 +0000 (14:16 -0400)
committerDan Wells <dbw2@calvin.edu>
Mon, 13 Jun 2011 19:55:50 +0000 (15:55 -0400)
This expands the interface to allow for editing notes on serials
objects.  At some point we will likely want to track edit dates as
well, but this gets the ball rolling.

Also renames some methods from 'create' to 'update' to match new
capabilities and make the overall API more consistent, and adds perm
checks based on related objects.

Signed-off-by: Dan Wells <dbw2@calvin.edu>
Open-ILS/src/perlmods/lib/OpenILS/Application/Serial.pm
Open-ILS/xul/staff_client/chrome/content/main/constants.js
Open-ILS/xul/staff_client/server/locale/en-US/serial.properties
Open-ILS/xul/staff_client/server/serial/notes.xul

index a2bab96..7acc52d 100644 (file)
@@ -1943,39 +1943,39 @@ sub fetch_notes {
 }
 
 __PACKAGE__->register_method(
-    method      => 'create_note',
-    api_name        => 'open-ils.serial.item_note.create',
+    method      => 'update_note',
+    api_name        => 'open-ils.serial.item_note.update',
     signature   => q/
-        Creates a new item note
+        Updates or creates an item note
         @param authtoken The login session key
-        @param note The note object to create
-        @return The id of the new note object
+        @param note The note object to update or create
+        @return The id of the note object
     /
 );
 
 __PACKAGE__->register_method(
-    method      => 'create_note',
-    api_name        => 'open-ils.serial.subscription_note.create',
+    method      => 'update_note',
+    api_name        => 'open-ils.serial.subscription_note.update',
     signature   => q/
-        Creates a new subscription note
+        Updates or creates a subscription note
         @param authtoken The login session key
-        @param note The note object to create
-        @return The id of the new note object
+        @param note The note object to update or create
+        @return The id of the note object
     /
 );
 
 __PACKAGE__->register_method(
-    method      => 'create_note',
-    api_name        => 'open-ils.serial.distribution_note.create',
+    method      => 'update_note',
+    api_name        => 'open-ils.serial.distribution_note.update',
     signature   => q/
-        Creates a new distribution note
+        Updates or creates a distribution note
         @param authtoken The login session key
-        @param note The note object to create
-        @return The id of the new note object
+        @param note The note object to update or create
+        @return The id of the note object
     /
 );
 
-sub create_note {
+sub update_note {
     my( $self, $connection, $authtoken, $note ) = @_;
 
     $self->api_name =~ /serial\.(\w*)_note/;
@@ -1984,22 +1984,42 @@ sub create_note {
     my $e = new_editor(xact=>1, authtoken=>$authtoken);
     return $e->event unless $e->checkauth;
 
-    # FIXME: restore permission support
-#    my $item = $e->retrieve_serial_item(
-#        [
-#            $note->item
-#        ]
-#    );
-#
-#    return $e->event unless
-#        $e->allowed('CREATE_COPY_NOTE', $item->call_number->owning_lib);
+    if ($type eq 'item') {
+        my $sitem = $e->retrieve_serial_item([
+            $note->item, {
+                "flesh" => 2, "flesh_fields" => {
+                    "sitem" => ["stream"], "sstr" => ["distribution"]
+                }
+            }
+        ]) or return $e->die_event;
 
-    $note->create_date('now');
-    $note->creator($e->requestor->id);
-    $note->pub( ($U->is_true($note->pub)) ? 't' : 'f' );
-    $note->clear_id;
+        return $e->die_event unless $e->allowed(
+            "ADMIN_SERIAL_ITEM", $sitem->stream->distribution->holding_lib
+        );
+    } elsif ($type eq 'distribution') {
+        my $sdist = $e->retrieve_serial_distribution($note->distribution)
+            or return $e->die_event;
+
+        return $e->die_event unless
+            $e->allowed("ADMIN_SERIAL_DISTRIBUTION", $sdist->holding_lib);
+    } else { # subscription
+        my $sub = $e->retrieve_serial_subscription($note->subscription)
+            or return $e->die_event;
+
+        return $e->die_event unless
+            $e->allowed("ADMIN_SERIAL_SUBSCRIPTION", $sub->owning_lib);
+    }
 
-    my $method = "create_serial_${type}_note";
+    $note->pub( ($U->is_true($note->pub)) ? 't' : 'f' );
+    my $method;
+    if ($note->isnew) {
+        $note->create_date('now');
+        $note->creator($e->requestor->id);
+        $note->clear_id;
+        $method = "create_serial_${type}_note";
+    } else {
+        $method = "update_serial_${type}_note";
+    }
     $e->$method($note) or return $e->event;
     $e->commit;
     return $note->id;
@@ -2052,11 +2072,31 @@ sub delete_note {
         $noteid,
     ]) or return $e->die_event;
 
-# FIXME: restore permissions check
-#    if( $note->creator ne $e->requestor->id ) {
-#        return $e->die_event unless
-#            $e->allowed('DELETE_COPY_NOTE', $note->item->call_number->owning_lib);
-#    }
+    if ($type eq 'item') {
+        my $sitem = $e->retrieve_serial_item([
+            $note->item, {
+                "flesh" => 2, "flesh_fields" => {
+                    "sitem" => ["stream"], "sstr" => ["distribution"]
+                }
+            }
+        ]) or return $e->die_event;
+
+        return $e->die_event unless $e->allowed(
+            "ADMIN_SERIAL_ITEM", $sitem->stream->distribution->holding_lib
+        );
+    } elsif ($type eq 'distribution') {
+        my $sdist = $e->retrieve_serial_distribution($note->distribution)
+            or return $e->die_event;
+
+        return $e->die_event unless
+            $e->allowed("ADMIN_SERIAL_DISTRIBUTION", $sdist->holding_lib);
+    } else { # subscription
+        my $sub = $e->retrieve_serial_subscription($note->subscription)
+            or return $e->die_event;
+
+        return $e->die_event unless
+            $e->allowed("ADMIN_SERIAL_SUBSCRIPTION", $sub->owning_lib);
+    }
 
     $method = "delete_serial_${type}_note";
     $e->$method($note) or return $e->die_event;
index 9961357..6743d95 100644 (file)
@@ -298,10 +298,10 @@ var api = {
     'FM_SDIST_SEARCH' : { 'app' : 'open-ils.pcrud', 'method' : 'open-ils.pcrud.search.sdist'},
     'FM_SDIST_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_tree.retrieve', 'secure' : false },
     'FM_SDIST_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_tree.retrieve.authoritative', 'secure' : false },
-    'FM_SDISTN_CREATE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_note.create' },
+    'FM_SDISTN_UPDATE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_note.update' },
     'FM_SDISTN_DELETE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_note.delete', 'secure' : false },
     'FM_SDISTN_RETRIEVE_ALL' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.distribution_note.retrieve.all', 'secure' : false },
-    'FM_SIN_CREATE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.item_note.create' },
+    'FM_SIN_UPDATE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.item_note.update' },
     'FM_SIN_DELETE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.item_note.delete', 'secure' : false },
     'FM_SIN_RETRIEVE_ALL' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.item_note.retrieve.all', 'secure' : false },
     'FM_SISS_FLESHED_BATCH_RETRIEVE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.issuance.fleshed.batch.retrieve', 'secure' : false },
@@ -325,7 +325,7 @@ var api = {
     'FM_SSUB_FLESHED_BATCH_RETRIEVE.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription.fleshed.batch.retrieve.authoritative', 'secure' : false },
     'FM_SSUB_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription_tree.retrieve', 'secure' : false },
     'FM_SSUB_TREE_LIST_RETRIEVE_VIA_RECORD_ID_AND_ORG_IDS.authoritative' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription_tree.retrieve.authoritative', 'secure' : false },
-    'FM_SSUBN_CREATE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription_note.create' },
+    'FM_SSUBN_UPDATE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription_note.update' },
     'FM_SSUBN_DELETE' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription_note.delete', 'secure' : false },
     'FM_SSUBN_RETRIEVE_ALL' : { 'app' : 'open-ils.serial', 'method' : 'open-ils.serial.subscription_note.retrieve.all', 'secure' : false },
     'RETRIEVE_Z3950_SERVICES' : { 'app' : 'open-ils.search', 'method' : 'open-ils.search.z3950.retrieve_services', 'secure' : false },
index 603cfb1..dd51ce8 100644 (file)
@@ -83,6 +83,9 @@ staff.serial.manage_subs.delete_ssub.confirm=Are you sure you would like to dele
 staff.serial.manage_subs.delete_ssub.confirm.plural=Are you sure you would like to delete these %1$s subscriptions?
 staff.serial.manage_subs.delete_ssub.title=Delete Subscriptions?
 staff.serial.manage_subs.delete_ssub.override=Override Delete Failure? Doing so will delete all related data as well!
+staff.serial.notes.do_edit_note.label=Edit This Note
+staff.serial.notes.edit_note.label=Edit Note
+staff.serial.notes.edit_note.accesskey=E
 staff.serial.required_fields_alert=These fields are required: 
 batch_receive.bib_lookup.empty=Enter a search term.
 batch_receive.bib_lookup.multiple=Multiple matching records found. Please use a more specific identifier, or use the catalog to find the exact record you want.
index 8f7ae26..ef13e8e 100644 (file)
 
                                /* button bar */
                                var hb = document.createElement('hbox'); np.appendChild(hb);
+                                       var btn0 = document.createElement('button'); hb.appendChild(btn0);
+                                               btn0.setAttribute('label', $('serialStrings').getString('staff.serial.notes.do_edit_note.label'));
+                                               btn0.setAttribute('image',"/xul/server/skin/media/images/up_arrow.gif");
+
+                                               btn0.addEventListener(
+                                                       'command',
+                                                       function(index){ return function() { new_note(index) } }(i),
+                                                       false
+                                               );
                                        var btn1 = document.createElement('button'); hb.appendChild(btn1);
                                                btn1.setAttribute('label', $('catStrings').getString('staff.cat.copy_notes.delete_note.label'));
                                                btn1.setAttribute('image',"/xul/server/skin/media/images/up_arrow.gif");
 
                                                btn1.addEventListener(
                                                        'command',
-                                                       function(id){ return function() { 
+                                                       function(index){ return function() { 
                                                                var r = g.error.yns_alert(
-                                                                       $('catStrings').getFormattedString('staff.cat.copy_notes.delete_note.prompt.msg', [g.notes[id].title(), g.notes[id].create_date().toString().substr(0,10)]),
+                                                                       $('catStrings').getFormattedString('staff.cat.copy_notes.delete_note.prompt.msg', [g.notes[index].title(), g.notes[index].create_date().toString().substr(0,10)]),
                                                                        $('catStrings').getString('staff.cat.copy_notes.delete_note.prompt.title'),
                                                                        $('catStrings').getString('staff.cat.copy_notes.delete_note.prompt.yes'),
                                                                        $('catStrings').getString('staff.cat.copy_notes.delete_note.prompt.no'),
                                                                        $('commonStrings').getString('common.confirm')
                                                                ); 
                                                                if (r == 0) {
-                                                                       g.network.simple_request('FM_'+g.function_type+'_DELETE',[ses(),g.notes[id].id()]);
+                                                                       g.network.simple_request('FM_'+g.function_type+'_DELETE',[ses(),g.notes[index].id()]);
                                                                        setTimeout(function() { 
                                                                                alert($('catStrings').getString('staff.cat.copy_notes.delete_note.success'));
                                                                                refresh(); },0
 
                }
                
-               function new_note() {
+               function new_note(index) {
+                       var public = false;
+                       var title = '';
+                       var value = '';
+                       var edit_mode; // for clarity
+                       var label_text;
+                       var button_accesskey;
+
+                       if (typeof index != 'undefined') {
+                               edit_mode = true;
+                               public = get_bool(g.notes[index].pub());
+                               title = g.notes[index].title();
+                               value = g.notes[index].value();
+                               label_text = $('serialStrings').getString('staff.serial.notes.edit_note.label');
+                               button_accesskey = $('serialStrings').getString('staff.serial.notes.edit_note.accesskey');
+                       } else {
+                               label_text = $('catStrings').getString('staff.cat.copy_notes.new_note.add_note.label');
+                               button_accesskey = $('catStrings').getString('staff.cat.copy_notes.new_note.add_note.accesskey');
+                       }
+
                        try {
                                netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect UniversalBrowserWrite");
                                var xml = '<groupbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1"> \
-                                       <caption label="' + $('catStrings').getString('staff.cat.copy_notes.new_note.label') + '"/> \
+                                       <caption label="' + label_text + '"/> \
                                        <grid flex="1"><columns><column/><column flex="1"/></columns> \
                                                <rows> \
-                                                       <row><label value="' + $('catStrings').getString('staff.cat.copy_notes.new_note.public') + '"/><checkbox id="pub" name="fancy_data" checked="false"/></row> \
-                                                       <row><label value="' + $('catStrings').getString('staff.cat.copy_notes.new_note.title') + '"/><textbox id="title" name="fancy_data" context="clipboard"/></row> \
-                                                       <row><label value="' + $('catStrings').getString('staff.cat.copy_notes.new_note.note') + '"/><textbox multiline="true" id="note" name="fancy_data" context="clipboard"/></row> \
+                                                       <row><label value="' + $('catStrings').getString('staff.cat.copy_notes.new_note.public') + '"/><checkbox id="pub" name="fancy_data" checked="' + public + '"/></row> \
+                                                       <row><label value="' + $('catStrings').getString('staff.cat.copy_notes.new_note.title') + '"/><textbox id="title" name="fancy_data" context="clipboard" value="' + title + '"/></row> \
+                                                       <row><label value="' + $('catStrings').getString('staff.cat.copy_notes.new_note.note') + '"/><textbox multiline="true" id="note" name="fancy_data" context="clipboard" value="' + value + '"/></row> \
                                                        <row><spacer/><hbox> \
                                                                <button label="' + $('catStrings').getString('staff.cat.copy_notes.new_note.cancel.label') + '" name="fancy_cancel" accesskey="' + $('catStrings').getString('staff.cat.copy_notes.new_note.cancel.accesskey') + '"/> \
-                                                               <button label="' + $('catStrings').getString('staff.cat.copy_notes.new_note.add_note.label') + '" accesskey="' + $('catStrings').getString('staff.cat.copy_notes.new_note.add_note.accesskey') + '" name="fancy_submit"/></hbox></row> \
+                                                               <button label="' + label_text + '" accesskey="' + button_accesskey + '" name="fancy_submit"/></hbox></row> \
                                                </rows></grid></groupbox>';
                                //g.data.init({'via':'stash'});
                                //g.data.temp_note_xml = xml; g.data.stash('temp_note_xml');
                                        //+ '&focus=' + window.escape('title')
                                        //+ '&title=' + window.escape('Add Note'),
                                        'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
-                                       { 'xml' : xml, 'focus' : 'title', 'title' : $('catStrings').getString('staff.cat.copy_notes.new_note.add_note.label') }
+                                       { 'xml' : xml, 'focus' : 'title', 'title' : label_text }
                                );
                                //g.data.init({'via':'stash'});
                                if (fancy_prompt_data.fancy_status == 'complete') {
                                        //alert(js2JSON(g.data.fancy_prompt_data));
-                                       var note = new g.constructor();
-                                       note.isnew(1);
+                                       var note;
+                                       if (edit_mode) {
+                                               note = g.notes[index];
+                                       } else {
+                                               note = new g.constructor();
+                                               note.isnew(1);
+                                       }
                                        note.title( fancy_prompt_data.title );
                                        note.value( fancy_prompt_data.note );
                                        note.pub( get_bool( fancy_prompt_data.pub ) ? get_db_true() : get_db_false() );
                                        note[g.object_type]( g.object_id );
-                                       var r = g.network.simple_request('FM_'+g.function_type+'_CREATE',[ ses(), note ]);
+                                       var r = g.network.simple_request('FM_'+g.function_type+'_UPDATE',[ ses(), note ]);
                                        if (typeof r.ilsevent != 'undefined') throw(r);
                                        setTimeout(function() {
                                                refresh();},0
        </script>
 
        <messagecatalog id="catStrings" src="/xul/server/locale/<!--#echo var='locale'-->/cat.properties" />
-       <messagecatalog id="circStrings" src="/xul/server/locale/<!--#echo var='locale'-->/circ.properties" />
+       <messagecatalog id="serialStrings" src="/xul/server/locale/<!--#echo var='locale'-->/serial.properties" />
 
        <stack hidden="true" id="note_template" flex="1">
                <groupbox flex="1" style="background-color: black;"/>