]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/cat/util.js
entry points for Transfer Title Holds functionality
[working/Evergreen.git] / Open-ILS / xul / staff_client / server / cat / util.js
1 dump('entering cat/util.js\n');
2
3 function $(id) { return document.getElementById(id); }
4
5 if (typeof cat == 'undefined') var cat = {};
6 cat.util = {};
7
8 cat.util.EXPORT_OK    = [ 
9     'spawn_copy_editor', 'add_copies_to_bucket', 'show_in_opac', 'spawn_spine_editor', 'transfer_copies', 
10     'transfer_title_holds', 'mark_item_missing', 'mark_item_damaged', 'replace_barcode', 'fast_item_add', 
11     'make_bookable', 'edit_new_brsrc', 'edit_new_bresv'
12 ];
13 cat.util.EXPORT_TAGS    = { ':all' : cat.util.EXPORT_OK };
14
15 cat.util.replace_barcode = function(old_bc) {
16     try {
17         JSAN.use('util.network');
18         var network = new util.network();
19
20         if (!old_bc) old_bc = window.prompt($("catStrings").getString('staff.cat.util.replace_barcode.old_bc_window_prompt.prompt'),
21             '',
22             $("catStrings").getString('staff.cat.util.replace_barcode.old_bc_window_prompt.title'));
23         if (!old_bc) return;
24
25         var copy;
26         try {
27             copy = network.simple_request('FM_ACP_RETRIEVE_VIA_BARCODE',[ old_bc ]);
28             if (typeof copy.ilsevent != 'undefined') throw(copy); 
29             if (!copy) throw(copy);
30         } catch(E) {
31             alert($("catStrings").getFormattedString('staff.cat.util.replace_barcode.error_alert', [old_bc]) + '\n');
32             return old_bc;
33         }
34     
35         // Why did I want to do this twice?  Because this copy is more fleshed?
36         try {
37             copy = network.simple_request('FM_ACP_RETRIEVE',[ copy.id() ]);
38             if (typeof copy.ilsevent != 'undefined') throw(copy);
39             if (!copy) throw(copy);
40         } catch(E) {
41             try {
42                 alert($("catStrings").getFormattedString('staff.cat.util.replace_barcode.error_alert', [old_bc]) +
43                      '\n' + (typeof E.ilsevent == 'undefined' ? '' : E.textcode + ' : ' + E.desc));
44             } catch(F) {
45                 alert(E + '\n' + F);
46             }
47             return old_bc;
48         }
49     
50         var new_bc = window.prompt($("catStrings").getString('staff.cat.util.replace_barcode.new_bc_window_prompt.prompt'),
51             '',
52             $("catStrings").getString('staff.cat.util.replace_barcode.new_bc_window_prompt.title'));
53         new_bc = String( new_bc ).replace(/\s/g,'');
54         /* Casting a possibly null input value to a String turns it into "null" */
55         if (!new_bc || new_bc == 'null') {
56             alert($("catStrings").getString('staff.cat.util.replace_barcode.new_bc.failed'));
57             return old_bc;
58         }
59     
60         var test = network.simple_request('FM_ACP_RETRIEVE_VIA_BARCODE',[ new_bc ]);
61         if (typeof test.ilsevent == 'undefined') {
62             alert('Rename aborted.  Another copy has barcode "' + new_bc + '".');
63             return old_bc;
64         } else {
65             if (test.ilsevent != 1502 /* ASSET_COPY_NOT_FOUND */) {
66                 obj.error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.util.replace_barcode.testing_error', [new_bc]), test);
67                 return old_bc;
68             }    
69         }
70
71         copy.barcode(new_bc); copy.ischanged('1');
72         var r = network.simple_request('FM_ACP_FLESHED_BATCH_UPDATE', [ ses(), [ copy ] ]);
73         if (typeof r.ilsevent != 'undefined') { 
74             if (r.ilsevent != 0) {
75                 if (r.ilsevent == 5000 /* PERM_FAILURE */) {
76                     alert($("catStrings").getString('staff.cat.util.replace_barcode.insufficient_permission_for_rename'));
77                     return old_bc;
78                 } else {
79                     obj.error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.util.replace_barcode.item_rename_error'),r);
80                     return old_bc;
81                 }
82             }
83         }
84
85         return new_bc;
86     } catch(E) {
87         JSAN.use('util.error'); var error = new util.error();
88         error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.util.replace_barcode.rename_error'),E);
89         return old_bc;
90     }
91 }
92
93 cat.util.transfer_title_holds = function(old_targets) {
94     JSAN.use('OpenILS.data'); var data = new OpenILS.data();
95     JSAN.use('util.network'); var network = new util.network();
96     try {
97         data.stash_retrieve();
98         var target = data.marked_record_for_hold_transfer;
99         if (!target) {
100             var m = $("catStrings").getString('staff.cat.opac.title_for_hold_transfer.destination_needed.label');
101             alert(m);
102             return;
103         }
104         var robj = network.simple_request('TRANSFER_TITLE_HOLDS',[ ses(), target, old_targets ]);
105         if (robj == 1) {
106             var m = $("catStrings").getString('staff.cat.opac.title_for_hold_transfer.success.label');
107             alert(m);
108         } else {
109             var m = $("catStrings").getString('staff.cat.opac.title_for_hold_transfer.failure.label');
110             alert(m);
111         }
112     } catch(E) {
113         alert('Error in cat.util.transfer_title.holds(): ' + E);
114     }
115 }
116
117 cat.util.transfer_copies = function(params) {
118     JSAN.use('util.error'); var error = new util.error();
119     JSAN.use('OpenILS.data'); var data = new OpenILS.data();
120     JSAN.use('util.network'); var network = new util.network();
121     try {
122         data.stash_retrieve();
123         if (!data.marked_volume) {
124             alert($("catStrings").getString('staff.cat.util.transfer_copies.unmarked_volume_alert'));
125             return;
126         }
127         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
128         var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto">';
129         if (!params.message) {
130             params.message = $("catStrings").getFormattedString('staff.cat.util.transfer_copies.params_message', [data.hash.aou[ params.owning_lib ].shortname(), params.volume_label]);
131             //params.message = 'Transfer items from their original volumes to ';
132             //params.message += data.hash.aou[ params.owning_lib ].shortname() + "'s volume labelled ";
133             //params.message += '"' + params.volume_label + '" on the following record (and change their circ libs to match)?';
134         }
135
136         xml += '<description>' + params.message.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;') + '</description>';
137         xml += '<hbox><button label="' + $("catStrings").getString('staff.cat.util.transfer_copies.transfer.label')+ '" name="fancy_submit"/>';
138         xml += '<button label="' + $("catStrings").getString('staff.cat.util.transfer_copies.cancel.label');
139         xml += '" accesskey="'+ $("catStrings").getString('staff.cat.util.transfer_copies.cancel.accesskey') +'" name="fancy_cancel"/></hbox>';
140         xml += '<iframe style="overflow: scroll" flex="1" src="' + urls.XUL_BIB_BRIEF + '?docid=' + params.docid + '"/>';
141         xml += '</vbox>';
142         //data.temp_transfer = xml; data.stash('temp_transfer');
143         JSAN.use('util.window'); var win = new util.window();
144         var fancy_prompt_data = win.open(
145             urls.XUL_FANCY_PROMPT,
146             //+ '?xml_in_stash=temp_transfer'
147             //+ '&title=' + window.escape('Item Transfer'),
148             'fancy_prompt', 'chrome,resizable,modal,width=500,height=300',
149             { 'xml' : xml, 'title' : $("catStrings").getString('staff.cat.util.transfer_copies.window_title') }
150         );
151         if (fancy_prompt_data.fancy_status == 'incomplete') { alert($("catStrings").getString('staff.cat.util.transfer_copies.aborted_transfer')); return; }
152
153         JSAN.use('util.functional');
154
155         var copies = network.simple_request('FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative', [ params.copy_ids ]);
156
157         for (var i = 0; i < copies.length; i++) {
158             copies[i].call_number( data.marked_volume );
159             copies[i].circ_lib( params.owning_lib );
160             copies[i].ischanged( 1 );
161         }
162
163         var robj = network.simple_request(
164             'FM_ACP_FLESHED_BATCH_UPDATE', 
165             [ ses(), copies, true ], 
166             null,
167             {
168                 'title' : $("catStrings").getString('staff.cat.util.transfer_copies.override_transfer_failure'),
169                 'overridable_events' : [
170                     1208 /* TITLE_LAST_COPY */,
171                     1227 /* COPY_DELETE_WARNING */,
172                 ]
173             }
174         );
175         
176         if (typeof robj.ilsevent != 'undefined') {
177             throw(robj);
178         } else {
179             alert($("catStrings").getString('staff.cat.util.transfer_copies.successful_transfer'));
180         }
181
182     } catch(E) {
183         error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.util.transfer_copies.transfer_error'),E);
184     }
185 }
186
187 cat.util.spawn_spine_editor = function(selection_list) {
188     JSAN.use('util.error'); var error = new util.error();
189     try {
190         JSAN.use('util.functional');
191         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
192         data.temp_barcodes_for_labels = util.functional.map_list( selection_list, function(o){return o.barcode;}) ; 
193         data.stash('temp_barcodes_for_labels');
194         xulG.new_tab(
195             xulG.url_prefix( urls.XUL_SPINE_LABEL ),
196             { 'tab_name' : $("catStrings").getString('staff.cat.util.spine_editor.tab_name') },
197             {}
198         );
199     } catch(E) {
200         error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.util.spine_editor.spine_editor_error'),E);
201     }
202 }
203
204 cat.util.show_in_opac = function(selection_list) {
205     JSAN.use('util.error'); var error = new util.error();
206     JSAN.use('util.network'); var network = new util.network();
207     var doc_id; var seen = {};
208     try {
209         for (var i = 0; i < selection_list.length; i++) {
210             doc_id = selection_list[i].doc_id;
211             if (!doc_id) {
212                 var barcode = selection_list[i].barcode;
213                 doc_id = network.simple_request('FM_BRE_ID_VIA_BARCODE',[barcode]);
214                 if (typeof doc_id.ils_event != 'undefined' || doc_id == -1) {
215                     alert($("catStrings").getFormattedString('staff.cat.util.show_in_opac.unknown_barcode', [barcode]));
216                     continue;
217                 }
218             }
219             if (doc_id == -1 ) {
220                 continue; /* pre-cat */
221             }
222             if (typeof seen[doc_id] != 'undefined') {
223                 continue;
224             }
225             seen[doc_id] = true;
226             var opac_url = xulG.url_prefix( urls.opac_rdetail ) + '?r=' + doc_id;
227             var content_params = { 
228                 'session' : ses(),
229                 'authtime' : ses('authtime'),
230                 'opac_url' : opac_url,
231             };
232             xulG.new_tab(
233                 xulG.url_prefix(urls.XUL_OPAC_WRAPPER), 
234                 {'tab_name':'Retrieving title...'}, 
235                 content_params
236             );
237         }
238     } catch(E) {
239         error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.util.show_in_opac.catalog_error_for_doc_id', [doc_id]),E);
240     }
241 }
242
243 cat.util.add_copies_to_bucket = function(selection_list) {
244     JSAN.use('util.functional');
245     JSAN.use('util.window'); var win = new util.window();
246     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
247     data.cb_temp_copy_ids = js2JSON(
248         util.functional.map_list(
249             selection_list,
250             function (o) {
251                 if (typeof o.copy_id != 'undefined' && o.copy_id != null) {
252                     return o.copy_id;
253                 } else {
254                     return o;
255                 }
256             }
257         )
258     );
259     data.stash('cb_temp_copy_ids');
260     win.open( 
261         xulG.url_prefix(urls.XUL_COPY_BUCKETS_QUICK),
262         'sel_bucket_win' + win.window_name_increment(),
263         'chrome,resizable,center'
264     );
265 }
266
267 cat.util.add_titles_to_bucket = function(record_ids) {
268     JSAN.use('util.window'); var win = new util.window();
269     win.open(
270         xulG.url_prefix(urls.XUL_RECORD_BUCKETS_QUICK),
271         'sel_bucket_win' + win.window_name_increment(),
272         'chrome,resizable,modal,center',
273         {
274             record_ids: record_ids 
275         }
276     );
277 }
278
279 cat.util.spawn_copy_editor = function(params) {
280     try {
281         if (!params.copy_ids && !params.copies) return;
282         if (params.copy_ids && params.copy_ids.length == 0) return;
283         if (params.copies && params.copies.length == 0) return;
284         if (params.copy_ids) params.copy_ids = js2JSON(params.copy_ids); // legacy
285         if (!params.caller_handles_update) params.handle_update = 1; // legacy
286
287         var obj = {};
288         JSAN.use('util.network'); obj.network = new util.network();
289         JSAN.use('util.error'); obj.error = new util.error();
290     
291         var title = '';
292         if (params.copy_ids && params.copy_ids.length > 1 && params.edit == 1)
293             title = $("catStrings").getString('staff.cat.util.copy_editor.batch_edit');
294         else if(params.copies && params.copies.length > 1 && params.edit == 1)
295             title = $("catStrings").getString('staff.cat.util.copy_editor.batch_view');
296         else if(params.copy_ids && params.copy_ids.length == 1)
297             title = $("catStrings").getString('staff.cat.util.copy_editor.edit');
298         else
299             title = $("catStrings").getString('staff.cat.util.copy_editor.view');
300
301         JSAN.use('util.window'); var win = new util.window();
302         var my_xulG = win.open(
303             (urls.XUL_COPY_EDITOR),
304             title,
305             'chrome,modal,resizable',
306             params
307         );
308         if (!my_xulG.copies && params.edit) {
309         } else {
310             return my_xulG.copies;
311         }
312         return [];
313     } catch(E) {
314         JSAN.use('util.error'); var error = new util.error();
315         error.standard_unexpected_error_alert('error in cat.util.spawn_copy_editor',E);
316     }
317 }
318
319 cat.util.mark_item_damaged = function(copy_ids) {
320     var error;
321     try {
322         JSAN.use('util.error'); error = new util.error();
323         JSAN.use('util.functional');
324         JSAN.use('util.network'); var network = new util.network();
325         var copies = network.simple_request('FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative', [ copy_ids ]);
326         if (typeof copies.ilsevent != 'undefined') throw(copies);
327         var magic_status = false;
328         for (var i = 0; i < copies.length; i++) {
329             var status = copies[i].status(); if (typeof status == 'object') status = status.id();
330             if (typeof my_constants.magical_statuses[ status ] != 'undefined') 
331                 if (my_constants.magical_statuses[ status ].block_mark_item_damaged) magic_status = true;
332         }
333         if (magic_status) {
334         
335             error.yns_alert($("catStrings").getString('staff.cat.util.mark_item_damaged.af_message'),
336                 $("catStrings").getString('staff.cat.util.mark_item_damaged.af_title'),
337                 $("catStrings").getString('staff.cat.util.mark_item_damaged.af_ok_label'), null, null,
338                 $("catStrings").getString('staff.cat.util.mark_item_damaged.af_confirm_action'));
339
340         } else {
341
342             var r = error.yns_alert($("catStrings").getFormattedString('staff.cat.util.mark_item_damaged.md_message', [util.functional.map_list( copies, function(o) { return o.barcode(); } ).join(", ")]),
343                 $("catStrings").getString('staff.cat.util.mark_item_damaged.md_title'),
344                 $("catStrings").getString('staff.cat.util.mark_item_damaged.md_ok_label'),
345                 $("catStrings").getString('staff.cat.util.mark_item_damaged.md_cancel_label'), null,
346                 $("catStrings").getString('staff.cat.util.mark_item_damaged.md_confirm_action'));
347
348             if (r == 0) {
349                 var count = 0;
350                 for (var i = 0; i < copies.length; i++) {
351                     try {
352
353                         var my_circ = network.simple_request('FM_CIRC_RETRIEVE_VIA_COPY',[ses(),copies[i].id(),1]);
354                         if (typeof my_circ.ilsevent == 'undefined') { 
355                             JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
356                             my_circ = my_circ[0];
357                             if (typeof my_circ != 'undefined') {
358                                 if (! my_circ.checkin_time() ) {
359                                     var due_date = my_circ.due_date() ? my_circ.due_date().substr(0,10) : null;
360                                     var auto_checkin = String( data.hash.aous['circ.auto_checkin_on_mark_damage'] ) == 'true';
361                                     /* short-circuit this behavior.  We don't want to mark an item damaged and still have it circulating.  At least for now.  Wait until someone asks for it. */
362                                     auto_checkin = true; 
363                                     JSAN.use('patron.util');
364                                     var patron_obj = patron.util.retrieve_fleshed_au_via_id( ses(), my_circ.usr() );
365                                     var patron_name = patron.util.format_name( patron_obj ) + ' : ' + patron_obj.card().barcode();
366                                     var msg = $("catStrings").getFormattedString('staff.cat.util.mark_item_damaged.item_circulating_to_patron', [ 
367                                         copies[i].barcode(),
368                                         patron_name,
369                                         my_circ.due_date().substr(0,10)]); // FIXME: need to replace date handling
370                                     JSAN.use('util.date'); var today = util.date.formatted_date(new Date(),'%F');
371                                     var r2 = auto_checkin ? 1 : error.yns_alert(
372                                         msg,
373                                         document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.title'),
374                                         document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.no_checkin'),
375                                         document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.normal_checkin'),
376                                         due_date ? (today > due_date ? document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.forgiving_checkin') : null) : null,
377                                         document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.confirm_action')
378                                     );
379                                     JSAN.use('circ.util');
380                                     switch(r2) {
381                                         case 1:
382                                             circ.util.checkin_via_barcode( ses(), { 'barcode' : copies[i].barcode(), 'noop' : 1 } );
383                                         break;
384                                         case 2:
385                                             circ.util.checkin_via_barcode( ses(), { 'barcode' : copies[i].barcode(), 'noop' : 1 }, due_date );
386                                         break;
387                                     }
388                                 }
389                             }
390                         }
391
392                         var robj = network.simple_request('MARK_ITEM_DAMAGED',[ses(),copies[i].id()]);
393                         if (typeof robj.ilsevent != 'undefined') {
394                             switch(robj.textcode) {
395                                 case 'DAMAGE_CHARGE' :
396                                     var params = {};
397                                     JSAN.use('util.money');
398                                     var circ_obj = robj.payload.circ;
399                                     var patron_obj = circ_obj.usr();
400                                     JSAN.use('patron.util'); 
401                                     var patron_name = patron.util.format_name( patron_obj ) + ' : ' + patron_obj.card().barcode(); 
402                                     var r1 = error.yns_alert( 
403                                         $("catStrings").getFormattedString('staff.cat.util.mark_item_damaged.charge_patron_prompt.message', [  
404                                             copies[i].barcode(),  
405                                             patron_name,  
406                                             circ_obj.checkin_time().substr(0,10), // FIXME: need to replace with something better 
407                                             util.money.sanitize(robj.payload.charge) ]), 
408                                         $("catStrings").getString('staff.cat.util.mark_item_damaged.charge_patron_prompt.title'), 
409                                         $("catStrings").getString('staff.cat.util.mark_item_damaged.charge_patron_prompt.ok_label'), 
410                                         $("catStrings").getString('staff.cat.util.mark_item_damaged.charge_patron_prompt.change_amount_label'), 
411                                         $("catStrings").getString('staff.cat.util.mark_item_damaged.charge_patron_prompt.cancel_label'), 
412                                         $("catStrings").getString('staff.cat.util.mark_item_damaged.charge_patron_prompt.confirm_action')); 
413                                     if (r1 == 0) {
414                                         params.apply_fines = 'apply';
415                                     } else if (r1 == 1) { 
416                                         JSAN.use('util.window'); var win = new util.window();
417                                         var my_xulG = win.open(
418                                             urls.XUL_PATRON_BILL_WIZARD,
419                                             'billwizard',
420                                             'chrome,resizable,modal',
421                                             { 
422                                                 'patron' : patron_obj, 
423                                                 'patron_id' : patron_obj.id(), 
424                                                 'circ' : circ_obj, 
425                                                 'xact_id' : circ_obj.id(), 
426                                                 'do_not_process_bill' : true,
427                                                 /* 'override_default_billing_type' : 7, FIXME: maybe reintroduce this with an org setting for the specific btype? */
428                                                 'override_default_price' : util.money.sanitize( robj.payload.charge ) 
429                                             }
430                                         );
431
432                                         params.apply_fines = my_xulG.proceed ? 'apply' : 'noapply';
433                                         if (my_xulG.proceed) {
434                                             params.override_amount = my_xulG.amount;
435                                             params.override_btype = my_xulG.cbt_id;
436                                             params.override_note = my_xulG.note;
437                                         }
438                                     } else {
439                                         params.apply_fines = 'noapply';
440                                     }
441                                     robj = network.simple_request('MARK_ITEM_DAMAGED',[ ses(), copies[i].id(), params ]);
442                                     if (typeof robj.ilsevent != 'undefined') { throw(robj); }
443                                     break;
444                                 default: throw(robj);
445                             }
446                         }
447                         count++;
448                     } catch(E) {
449                         error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.util.mark_item_damaged.marking_error', [copies[i].barcode()]),E);
450                     }
451                 }
452                 alert(count == 1 ? $("catStrings").getString('staff.cat.util.mark_item_damaged.one_item_damaged') :
453                     $("catStrings").getFormattedString('staff.cat.util.mark_item_damaged.multiple_item_damaged', [count]));
454             }
455         }
456
457     } catch(E) {
458         if (error) error.standard_unexpected_error_alert('cat.util.mark_item_damaged',E); else alert('FIXME: ' + E);
459     }
460 }
461
462 cat.util.mark_item_missing = function(copy_ids) {
463     var error;
464     try {
465         JSAN.use('util.error'); error = new util.error();
466         JSAN.use('util.functional');
467         JSAN.use('util.network'); var network = new util.network();
468         var copies = network.simple_request('FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative', [ copy_ids ]);
469         if (typeof copies.ilsevent != 'undefined') throw(copies);
470         var magic_status = false;
471         for (var i = 0; i < copies.length; i++) {
472             var status = copies[i].status(); if (typeof status == 'object') status = status.id();
473             if (typeof my_constants.magical_statuses[ status ] != 'undefined') 
474                 if (my_constants.magical_statuses[ status ].block_mark_item_action) magic_status = true;
475         }
476         if (magic_status) {
477         
478             error.yns_alert($("catStrings").getString('staff.cat.util.mark_item_missing.af_message'),
479                 $("catStrings").getString('staff.cat.util.mark_item_missing.af_title'),
480                 $("catStrings").getString('staff.cat.util.mark_item_missing.af_ok_label'), null, null,
481                 $("catStrings").getString('staff.cat.util.mark_item_missing.af_confirm_action'));
482
483         } else {
484
485             var r = error.yns_alert($("catStrings").getFormattedString('staff.cat.util.mark_item_missing.ms_message', [util.functional.map_list( copies, function(o) { return o.barcode(); } ).join(", ")]),
486                 $("catStrings").getString('staff.cat.util.mark_item_missing.ms_title'),
487                 $("catStrings").getString('staff.cat.util.mark_item_missing.ms_ok_label'),
488                 $("catStrings").getString('staff.cat.util.mark_item_missing.ms_cancel_label'), null,
489                 $("catStrings").getString('staff.cat.util.mark_item_missing.ms_confirm_action'));
490
491             if (r == 0) {
492                 var count = 0;
493                 for (var i = 0; i < copies.length; i++) {
494                     try {
495                         var robj = network.simple_request('MARK_ITEM_MISSING',[ses(),copies[i].id()]);
496                         if (typeof robj.ilsevent != 'undefined') throw(robj);
497                         count++;
498                     } catch(E) {
499                         error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.util.mark_item_missing.marking_error', [copies[i].barcode()]),E);
500                     }
501                 }
502                 alert(count == 1 ? $("catStrings").getString('staff.cat.util.mark_item_missing.one_item_missing') :
503                     $("catStrings").getFormattedString('staff.cat.util.mark_item_missing.multiple_item_missing', [count]));
504             }
505         }
506
507     } catch(E) {
508         if (error) error.standard_unexpected_error_alert('cat.util.mark_item_missing',E); else alert('FIXME: ' + E);
509     }
510 }
511
512 cat.util.fast_item_add = function(doc_id,cn_label,cp_barcode) {
513     var error;
514     try {
515
516         JSAN.use('util.error'); error = new util.error();
517         JSAN.use('util.network'); var network = new util.network();
518
519         var acn_id = network.simple_request(
520             'FM_ACN_FIND_OR_CREATE',
521             [ ses(), cn_label, doc_id, ses('ws_ou') ]
522         );
523
524         if (typeof acn_id.ilsevent != 'undefined') {
525             error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.stash_and_close.problem_with_volume', [cn]), acn_id);
526             return;
527         }
528
529         var copy_obj = new acp();
530         copy_obj.id( -1 );
531         copy_obj.isnew('1');
532         copy_obj.barcode( cp_barcode );
533         copy_obj.call_number( acn_id );
534         copy_obj.circ_lib( ses('ws_ou') );
535         /* FIXME -- use constants */
536         copy_obj.deposit(0);
537         copy_obj.price(0);
538         copy_obj.deposit_amount(0);
539         copy_obj.fine_level(2);
540         copy_obj.loan_duration(2);
541         copy_obj.location(1);
542         copy_obj.status(0);
543         copy_obj.circulate(get_db_true());
544         copy_obj.holdable(get_db_true());
545         copy_obj.opac_visible(get_db_true());
546         copy_obj.ref(get_db_false());
547
548         JSAN.use('util.window'); var win = new util.window();
549         JSAN.use('cat.util');
550         return cat.util.spawn_copy_editor( { 'handle_update' : 1, 'edit' : 1, 'docid' : doc_id, 'copies' : [ copy_obj ] });
551
552     } catch(E) {
553         if (error) error.standard_unexpected_error_alert('cat.util.fast_item_add',E); else alert('FIXME: ' + E);
554     }
555 }
556
557 cat.util.make_bookable = function(copy_ids) {
558     var results = fieldmapper.standardRequest(
559         ["open-ils.booking", "open-ils.booking.resources.create_from_copies"],
560         [ses(), copy_ids]
561     );
562     if (results == null) {
563         alert(document.getElementById("catStrings").getString(
564             "staff.cat.copy_browser.make_bookable.create_failed_silent"
565         ));
566     }
567     else if (typeof results.ilsevent != "undefined") {
568         alert(document.getElementById("catStrings").getFormattedString(
569             "staff.cat.copy_browser.make_bookable.create_failed",
570             [results.ilsevent, results.textcode, results.desc, results.debug]
571         ));
572     }
573     return results;
574 }
575
576 cat.util.edit_new_brsrc = function(brsrc_list) {
577     /* Spawn new tab to allow editing new resources. */
578     try {
579         xulG.resultant_brsrc = brsrc_list.map(function(o) { return o[0]; });
580         xulG.new_tab(
581             urls.XUL_BROWSER + "?url=" + window.escape(
582                 xulG.url_prefix("/eg/conify/global/booking/resource")
583             ), {
584                 "tab_name": offlineStrings.getString(
585                     "menu.cmd_booking_resource.tab"
586                  ),
587                 "browser" : true
588             }, {
589                 "no_xulG": false,
590                 "show_print_button": false,
591                 "show_nav_buttons": true,
592                 "passthru_content_params": xulG
593             }
594         );
595     } catch(E) {
596         alert(
597             document.getElementById("catStrings").getFormattedString(
598                 "staff.cat.copy_browser.make_bookable.newtab_failed"
599             ), E
600         );
601     }
602 }
603
604 cat.util.edit_new_bresv = function(booking_results) {
605     /* Spawn new tab to allow editing new reservations. */
606     try {
607         if (xulG.auth == undefined) {
608             xulG.auth = {"session": {"key": ses()}};
609         }
610         xulG.bresv_interface_opts = {"booking_results": booking_results};
611         xulG.new_tab(
612             xulG.url_prefix("/eg/booking/reservation"),
613             {
614                 "tab_name": offlineStrings.getString(
615                     "menu.cmd_booking_reservation.tab"
616                  ),
617                 "browser" : false
618             }, xulG
619         );
620     } catch(E) {
621         alert(
622             document.getElementById("catStrings").getString(
623                 "staff.cat.copy_browser.make_bookable.newtab_failed"
624             ) + E
625         );
626     }
627 }
628
629 dump('exiting cat/util.js\n');