]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/server/cat/util.js
assume auto-checkin for now for Mark Item Damaged
[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         'mark_item_missing', 'mark_item_damaged', 'replace_barcode', 'fast_item_add'
11 ];
12 cat.util.EXPORT_TAGS    = { ':all' : cat.util.EXPORT_OK };
13
14 cat.util.replace_barcode = function(old_bc) {
15         try {
16                 JSAN.use('util.network');
17                 var network = new util.network();
18
19                 if (!old_bc) old_bc = window.prompt($("catStrings").getString('staff.cat.util.replace_barcode.old_bc_window_prompt.prompt'),
20                         '',
21                         $("catStrings").getString('staff.cat.util.replace_barcode.old_bc_window_prompt.title'));
22                 if (!old_bc) return;
23
24                 var copy;
25         try {
26                         copy = network.simple_request('FM_ACP_RETRIEVE_VIA_BARCODE',[ old_bc ]);
27                         if (typeof copy.ilsevent != 'undefined') throw(copy); 
28                         if (!copy) throw(copy);
29                 } catch(E) {
30                         alert($("catStrings").getFormattedString('staff.cat.util.replace_barcode.error_alert', [old_bc]) + '\n');
31                         return old_bc;
32                 }
33         
34                 // Why did I want to do this twice?  Because this copy is more fleshed?
35                 try {
36                         copy = network.simple_request('FM_ACP_RETRIEVE',[ copy.id() ]);
37                         if (typeof copy.ilsevent != 'undefined') throw(copy);
38                         if (!copy) throw(copy);
39                 } catch(E) {
40                         try {
41                                 alert($("catStrings").getFormattedString('staff.cat.util.replace_barcode.error_alert', [old_bc]) +
42                                          '\n' + (typeof E.ilsevent == 'undefined' ? '' : E.textcode + ' : ' + E.desc));
43                         } catch(F) {
44                                 alert(E + '\n' + F);
45                         }
46                         return old_bc;
47                 }
48         
49                 var new_bc = window.prompt($("catStrings").getString('staff.cat.util.replace_barcode.new_bc_window_prompt.prompt'),
50                         '',
51                         $("catStrings").getString('staff.cat.util.replace_barcode.new_bc_window_prompt.title'));
52                 new_bc = String( new_bc ).replace(/\s/g,'');
53                 /* Casting a possibly null input value to a String turns it into "null" */
54                 if (!new_bc || new_bc == 'null') {
55                         alert($("catStrings").getString('staff.cat.util.replace_barcode.new_bc.failed'));
56                         return old_bc;
57                 }
58         
59                 var test = network.simple_request('FM_ACP_RETRIEVE_VIA_BARCODE',[ new_bc ]);
60                 if (typeof test.ilsevent == 'undefined') {
61                         alert('Rename aborted.  Another copy has barcode "' + new_bc + '".');
62                         return old_bc;
63                 } else {
64                         if (test.ilsevent != 1502 /* ASSET_COPY_NOT_FOUND */) {
65                                 obj.error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.util.replace_barcode.testing_error', [new_bc]), test);
66                                 return old_bc;
67                         }       
68                 }
69
70                 copy.barcode(new_bc); copy.ischanged('1');
71                 var r = network.simple_request('FM_ACP_FLESHED_BATCH_UPDATE', [ ses(), [ copy ] ]);
72                 if (typeof r.ilsevent != 'undefined') { 
73                         if (r.ilsevent != 0) {
74                                 if (r.ilsevent == 5000 /* PERM_FAILURE */) {
75                                         alert($("catStrings").getString('staff.cat.util.replace_barcode.insufficient_permission_for_rename'));
76                                         return old_bc;
77                                 } else {
78                                         obj.error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.util.replace_barcode.item_rename_error'),r);
79                                         return old_bc;
80                                 }
81                         }
82                 }
83
84                 return new_bc;
85         } catch(E) {
86                 JSAN.use('util.error'); var error = new util.error();
87                 error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.util.replace_barcode.rename_error'),E);
88                 return old_bc;
89         }
90 }
91
92 cat.util.transfer_copies = function(params) {
93         JSAN.use('util.error'); var error = new util.error();
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                 if (!data.marked_volume) {
99                         alert($("catStrings").getString('staff.cat.util.transfer_copies.unmarked_volume_alert'));
100                         return;
101                 }
102                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
103                 var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" flex="1" style="overflow: auto">';
104                 if (!params.message) {
105                         params.message = $("catStrings").getFormattedString('staff.cat.util.transfer_copies.params_message', [data.hash.aou[ params.owning_lib ].shortname(), params.volume_label]);
106                         //params.message = 'Transfer items from their original volumes to ';
107                         //params.message += data.hash.aou[ params.owning_lib ].shortname() + "'s volume labelled ";
108                         //params.message += '"' + params.volume_label + '" on the following record (and change their circ libs to match)?';
109                 }
110
111                 xml += '<description>' + params.message.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;') + '</description>';
112                 xml += '<hbox><button label="' + $("catStrings").getString('staff.cat.util.transfer_copies.transfer.label')+ '" name="fancy_submit"/>';
113                 xml += '<button label="' + $("catStrings").getString('staff.cat.util.transfer_copies.cancel.label');
114                 xml += '" accesskey="'+ $("catStrings").getString('staff.cat.util.transfer_copies.cancel.accesskey') +'" name="fancy_cancel"/></hbox>';
115                 xml += '<iframe style="overflow: scroll" flex="1" src="' + urls.XUL_BIB_BRIEF + '?docid=' + params.docid + '"/>';
116                 xml += '</vbox>';
117                 //data.temp_transfer = xml; data.stash('temp_transfer');
118                 JSAN.use('util.window'); var win = new util.window();
119                 var fancy_prompt_data = win.open(
120                         urls.XUL_FANCY_PROMPT,
121                         //+ '?xml_in_stash=temp_transfer'
122                         //+ '&title=' + window.escape('Item Transfer'),
123                         'fancy_prompt', 'chrome,resizable,modal,width=500,height=300',
124                         { 'xml' : xml, 'title' : $("catStrings").getString('staff.cat.util.transfer_copies.window_title') }
125                 );
126                 if (fancy_prompt_data.fancy_status == 'incomplete') { alert($("catStrings").getString('staff.cat.util.transfer_copies.aborted_transfer')); return; }
127
128                 JSAN.use('util.functional');
129
130                 var copies = network.simple_request('FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative', [ params.copy_ids ]);
131
132                 for (var i = 0; i < copies.length; i++) {
133                         copies[i].call_number( data.marked_volume );
134                         copies[i].circ_lib( params.owning_lib );
135                         copies[i].ischanged( 1 );
136                 }
137
138                 var robj = network.simple_request(
139                         'FM_ACP_FLESHED_BATCH_UPDATE', 
140                         [ ses(), copies, true ], 
141                         null,
142                         {
143                                 'title' : $("catStrings").getString('staff.cat.util.transfer_copies.override_transfer_failure'),
144                                 'overridable_events' : [
145                                         1208 /* TITLE_LAST_COPY */,
146                                         1227 /* COPY_DELETE_WARNING */,
147                                 ]
148                         }
149                 );
150                 
151                 if (typeof robj.ilsevent != 'undefined') {
152                         throw(robj);
153                 } else {
154                         alert($("catStrings").getString('staff.cat.util.transfer_copies.successful_transfer'));
155                 }
156
157         } catch(E) {
158                 error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.util.transfer_copies.transfer_error'),E);
159         }
160 }
161
162 cat.util.spawn_spine_editor = function(selection_list) {
163         JSAN.use('util.error'); var error = new util.error();
164         try {
165                 JSAN.use('util.functional');
166                 JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
167                 data.temp_barcodes_for_labels = util.functional.map_list( selection_list, function(o){return o.barcode;}) ; 
168                 data.stash('temp_barcodes_for_labels');
169                 xulG.new_tab(
170                         xulG.url_prefix( urls.XUL_SPINE_LABEL ),
171                         { 'tab_name' : $("catStrings").getString('staff.cat.util.spine_editor.tab_name') },
172                         {}
173                 );
174         } catch(E) {
175                 error.standard_unexpected_error_alert($("catStrings").getString('staff.cat.util.spine_editor.spine_editor_error'),E);
176         }
177 }
178
179 cat.util.show_in_opac = function(selection_list) {
180         JSAN.use('util.error'); var error = new util.error();
181         var doc_id; var seen = {};
182         try {
183                 for (var i = 0; i < selection_list.length; i++) {
184                         doc_id = selection_list[i].doc_id;
185                         if (!doc_id) {
186                                 alert($("catStrings").getFormattedString('staff.cat.util.show_in_opac.unknown_barcode', [selection_list[i].barcode]));
187                                 continue;
188                         }
189                         if (typeof seen[doc_id] != 'undefined') {
190                                 continue;
191                         }
192                         seen[doc_id] = true;
193                         var opac_url = xulG.url_prefix( urls.opac_rdetail ) + '?r=' + doc_id;
194                         var content_params = { 
195                                 'session' : ses(),
196                                 'authtime' : ses('authtime'),
197                                 'opac_url' : opac_url,
198                         };
199                         xulG.new_tab(
200                                 xulG.url_prefix(urls.XUL_OPAC_WRAPPER), 
201                                 {'tab_name':'Retrieving title...'}, 
202                                 content_params
203                         );
204                 }
205         } catch(E) {
206                 error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.util.show_in_opac.catalog_error_for_doc_id', [doc_id]),E);
207         }
208 }
209
210 cat.util.add_copies_to_bucket = function(selection_list) {
211         JSAN.use('util.functional');
212         JSAN.use('util.window'); var win = new util.window();
213         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
214         data.cb_temp_copy_ids = js2JSON(
215                 util.functional.map_list(
216                         selection_list,
217                         function (o) {
218                                 if (typeof o.copy_id != 'undefined' && o.copy_id != null) {
219                                         return o.copy_id;
220                                 } else {
221                                         return o;
222                                 }
223                         }
224                 )
225         );
226         data.stash('cb_temp_copy_ids');
227         win.open( 
228                 xulG.url_prefix(urls.XUL_COPY_BUCKETS_QUICK),
229                 'sel_bucket_win' + win.window_name_increment(),
230                 'chrome,resizable,center'
231         );
232 }
233
234 cat.util.spawn_copy_editor = function(params) {
235         try {
236         if (!params.copy_ids && !params.copies) return;
237                 if (params.copy_ids && params.copy_ids.length == 0) return;
238                 if (params.copies && params.copies.length == 0) return;
239         if (params.copy_ids) params.copy_ids = js2JSON(params.copy_ids); // legacy
240         if (!params.caller_handles_update) params.handle_update = 1; // legacy
241
242                 var obj = {};
243                 JSAN.use('util.network'); obj.network = new util.network();
244                 JSAN.use('util.error'); obj.error = new util.error();
245         
246                 var title = '';
247                 if (params.copy_ids && params.copy_ids.length > 1 && params.edit == 1)
248                         title = $("catStrings").getString('staff.cat.util.copy_editor.batch_edit');
249                 else if(params.copies && params.copies.length > 1 && params.edit == 1)
250                         title = $("catStrings").getString('staff.cat.util.copy_editor.batch_view');
251                 else if(params.copy_ids && params.copy_ids.length == 1)
252                         title = $("catStrings").getString('staff.cat.util.copy_editor.edit');
253                 else
254                         title = $("catStrings").getString('staff.cat.util.copy_editor.view');
255
256                 JSAN.use('util.window'); var win = new util.window();
257                 var my_xulG = win.open(
258                         (urls.XUL_COPY_EDITOR),
259                         title,
260                         'chrome,modal,resizable',
261             params
262                 );
263                 if (!my_xulG.copies && params.edit) {
264             alert(typeof params.no_copies_modified_msg != 'undefined' ? params.no_copies_modified_msg : $("catStrings").getString('staff.cat.util.copy_editor.not_modified'));
265         } else {
266             return my_xulG.copies;
267         }
268         return [];
269         } catch(E) {
270                 JSAN.use('util.error'); var error = new util.error();
271                 error.standard_unexpected_error_alert('error in cat.util.spawn_copy_editor',E);
272         }
273 }
274
275 cat.util.mark_item_damaged = function(copy_ids) {
276         var error;
277         try {
278                 JSAN.use('util.error'); error = new util.error();
279                 JSAN.use('util.functional');
280                 JSAN.use('util.network'); var network = new util.network();
281                 var copies = network.simple_request('FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative', [ copy_ids ]);
282                 if (typeof copies.ilsevent != 'undefined') throw(copies);
283                 var magic_status = false;
284                 for (var i = 0; i < copies.length; i++) {
285                         var status = copies[i].status(); if (typeof status == 'object') status = status.id();
286                         if (typeof my_constants.magical_statuses[ status ] != 'undefined') 
287                                 if (my_constants.magical_statuses[ status ].block_mark_item_damaged) magic_status = true;
288                 }
289                 if (magic_status) {
290                 
291                         error.yns_alert($("catStrings").getString('staff.cat.util.mark_item_damaged.af_message'),
292                                 $("catStrings").getString('staff.cat.util.mark_item_damaged.af_title'),
293                                 $("catStrings").getString('staff.cat.util.mark_item_damaged.af_ok_label'), null, null,
294                                 $("catStrings").getString('staff.cat.util.mark_item_damaged.af_confirm_action'));
295
296                 } else {
297
298                         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(", ")]),
299                                 $("catStrings").getString('staff.cat.util.mark_item_damaged.md_title'),
300                                 $("catStrings").getString('staff.cat.util.mark_item_damaged.md_ok_label'),
301                                 $("catStrings").getString('staff.cat.util.mark_item_damaged.md_cancel_label'), null,
302                                 $("catStrings").getString('staff.cat.util.mark_item_damaged.md_confirm_action'));
303
304                         if (r == 0) {
305                                 var count = 0;
306                                 for (var i = 0; i < copies.length; i++) {
307                                         try {
308
309                         var my_circ = network.simple_request('FM_CIRC_RETRIEVE_VIA_COPY',[ses(),copies[i].id(),1]);
310                         if (typeof my_circ.ilsevent == 'undefined') { 
311                             JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.stash_retrieve();
312                             my_circ = my_circ[0];
313                             if (typeof my_circ != 'undefined') {
314                                 if (! my_circ.checkin_time() ) {
315                                     var due_date = my_circ.due_date() ? my_circ.due_date().substr(0,10) : null;
316                                     var auto_checkin = String( data.hash.aous['circ.auto_checkin_on_mark_damage'] ) == 'true';
317                                     /* 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. */
318                                     auto_checkin = true; 
319                                     JSAN.use('patron.util');
320                                     var patron_obj = patron.util.retrieve_fleshed_au_via_id( ses(), my_circ.usr() );
321                                     var patron_name = ( patron_obj.prefix() ? patron_obj.prefix() + ' ' : '') +
322                                         patron_obj.family_name() + ', ' +
323                                         patron_obj.first_given_name() + ' ' +
324                                         ( patron_obj.second_given_name() ? patron_obj.second_given_name() + ' ' : '' ) +
325                                         ( patron_obj.suffix() ? patron_obj.suffix() : '')
326                                         + ' : ' + patron_obj.card().barcode()
327                                     var msg = $("catStrings").getFormattedString('staff.cat.util.mark_item_damaged.item_circulating_to_patron', [ 
328                                         copies[i].barcode(),
329                                         patron_name,
330                                         my_circ.due_date().substr(0,10)]); // FIXME: need to replace date handling
331                                     JSAN.use('util.date'); var today = util.date.formatted_date(new Date(),'%F');
332                                     var r2 = auto_checkin ? 1 : error.yns_alert(
333                                         msg,
334                                         document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.title'),
335                                         document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.no_checkin'),
336                                         document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.normal_checkin'),
337                                         due_date ? (today > due_date ? document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.forgiving_checkin') : null) : null,
338                                         document.getElementById('catStrings').getString('staff.cat.util.mark_item_damaged.checkin.confirm_action')
339                                     );
340                                     JSAN.use('circ.util');
341                                     switch(r2) {
342                                         case 1:
343                                             circ.util.checkin_via_barcode( ses(), { 'barcode' : copies[i].barcode(), 'noop' : 1 } );
344                                         break;
345                                         case 2:
346                                             circ.util.checkin_via_barcode( ses(), { 'barcode' : copies[i].barcode(), 'noop' : 1 }, due_date );
347                                         break;
348                                     }
349                                 }
350                             }
351                         }
352
353                                                 var robj = network.simple_request('MARK_ITEM_DAMAGED',[ses(),copies[i].id()]);
354                                                 if (typeof robj.ilsevent != 'undefined') {
355                             switch(robj.textcode) {
356                                 case 'DAMAGE_CHARGE' :
357                                     JSAN.use('util.money');
358                                     var circ_obj = robj.payload.circ;
359                                     var patron_obj = circ_obj.usr();
360                                     var patron_name = ( patron_obj.prefix() ? patron_obj.prefix() + ' ' : '') +
361                                         patron_obj.family_name() + ', ' +
362                                         patron_obj.first_given_name() + ' ' +
363                                         ( patron_obj.second_given_name() ? patron_obj.second_given_name() + ' ' : '' ) +
364                                         ( patron_obj.suffix() ? patron_obj.suffix() : '')
365                                         + ' : ' + patron_obj.card().barcode()
366
367                                     var r1 = error.yns_alert(
368                                         $("catStrings").getFormattedString('staff.cat.util.mark_item_damaged.charge_patron_prompt.message', [ 
369                                             copies[i].barcode(), 
370                                             patron_name, 
371                                             circ_obj.checkin_time().substr(0,10), // FIXME: need to replace with something better
372                                             util.money.sanitize(robj.payload.charge) ]),
373                                         $("catStrings").getString('staff.cat.util.mark_item_damaged.charge_patron_prompt.title'),
374                                         $("catStrings").getString('staff.cat.util.mark_item_damaged.charge_patron_prompt.ok_label'),
375                                         $("catStrings").getString('staff.cat.util.mark_item_damaged.charge_patron_prompt.cancel_label'), null,
376                                         $("catStrings").getString('staff.cat.util.mark_item_damaged.charge_patron_prompt.confirm_action'));
377
378                                     robj = network.simple_request('MARK_ITEM_DAMAGED',[ ses(), copies[i].id(), {'apply_fines' : r1 == 0 ? 'apply' : 'noapply'} ]);
379                                                             if (typeof robj.ilsevent != 'undefined') { throw(robj); }
380                                     break;
381                                 default: throw(robj);
382                             }
383                         }
384                                                 count++;
385                                         } catch(E) {
386                                                 error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.util.mark_item_damaged.marking_error', [copies[i].barcode()]),E);
387                                         }
388                                 }
389                                 alert(count == 1 ? $("catStrings").getString('staff.cat.util.mark_item_damaged.one_item_damaged') :
390                                         $("catStrings").getFormattedString('staff.cat.util.mark_item_damaged.multiple_item_damaged', [count]));
391                         }
392                 }
393
394         } catch(E) {
395                 if (error) error.standard_unexpected_error_alert('cat.util.mark_item_damaged',E); else alert('FIXME: ' + E);
396         }
397 }
398
399 cat.util.mark_item_missing = function(copy_ids) {
400         var error;
401         try {
402                 JSAN.use('util.error'); error = new util.error();
403                 JSAN.use('util.functional');
404                 JSAN.use('util.network'); var network = new util.network();
405                 var copies = network.simple_request('FM_ACP_FLESHED_BATCH_RETRIEVE.authoritative', [ copy_ids ]);
406                 if (typeof copies.ilsevent != 'undefined') throw(copies);
407                 var magic_status = false;
408                 for (var i = 0; i < copies.length; i++) {
409                         var status = copies[i].status(); if (typeof status == 'object') status = status.id();
410                         if (typeof my_constants.magical_statuses[ status ] != 'undefined') 
411                                 if (my_constants.magical_statuses[ status ].block_mark_item_action) magic_status = true;
412                 }
413                 if (magic_status) {
414                 
415                         error.yns_alert($("catStrings").getString('staff.cat.util.mark_item_missing.af_message'),
416                                 $("catStrings").getString('staff.cat.util.mark_item_missing.af_title'),
417                                 $("catStrings").getString('staff.cat.util.mark_item_missing.af_ok_label'), null, null,
418                                 $("catStrings").getString('staff.cat.util.mark_item_missing.af_confirm_action'));
419
420                 } else {
421
422                         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(", ")]),
423                                 $("catStrings").getString('staff.cat.util.mark_item_missing.ms_title'),
424                                 $("catStrings").getString('staff.cat.util.mark_item_missing.ms_ok_label'),
425                                 $("catStrings").getString('staff.cat.util.mark_item_missing.ms_cancel_label'), null,
426                                 $("catStrings").getString('staff.cat.util.mark_item_missing.ms_confirm_action'));
427
428                         if (r == 0) {
429                                 var count = 0;
430                                 for (var i = 0; i < copies.length; i++) {
431                                         try {
432                                                 var robj = network.simple_request('MARK_ITEM_MISSING',[ses(),copies[i].id()]);
433                                                 if (typeof robj.ilsevent != 'undefined') throw(robj);
434                                                 count++;
435                                         } catch(E) {
436                                                 error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.util.mark_item_missing.marking_error', [copies[i].barcode()]),E);
437                                         }
438                                 }
439                                 alert(count == 1 ? $("catStrings").getString('staff.cat.util.mark_item_missing.one_item_missing') :
440                                         $("catStrings").getFormattedString('staff.cat.util.mark_item_missing.multiple_item_missing', [count]));
441                         }
442                 }
443
444         } catch(E) {
445                 if (error) error.standard_unexpected_error_alert('cat.util.mark_item_missing',E); else alert('FIXME: ' + E);
446         }
447 }
448
449 cat.util.fast_item_add = function(doc_id,cn_label,cp_barcode) {
450         var error;
451         try {
452
453                 JSAN.use('util.error'); error = new util.error();
454                 JSAN.use('util.network'); var network = new util.network();
455
456         var acn_id = network.simple_request(
457             'FM_ACN_FIND_OR_CREATE',
458             [ ses(), cn_label, doc_id, ses('ws_ou') ]
459         );
460
461         if (typeof acn_id.ilsevent != 'undefined') {
462             error.standard_unexpected_error_alert($("catStrings").getFormattedString('staff.cat.volume_copy_creator.stash_and_close.problem_with_volume', [cn]), acn_id);
463             return;
464         }
465
466         var copy_obj = new acp();
467         copy_obj.id( -1 );
468         copy_obj.isnew('1');
469         copy_obj.barcode( cp_barcode );
470         copy_obj.call_number( acn_id );
471         copy_obj.circ_lib( ses('ws_ou') );
472         /* FIXME -- use constants */
473         copy_obj.deposit(0);
474         copy_obj.price(0);
475         copy_obj.deposit_amount(0);
476         copy_obj.fine_level(2);
477         copy_obj.loan_duration(2);
478         copy_obj.location(1);
479         copy_obj.status(0);
480         copy_obj.circulate(get_db_true());
481         copy_obj.holdable(get_db_true());
482         copy_obj.opac_visible(get_db_true());
483         copy_obj.ref(get_db_false());
484
485                 JSAN.use('util.window'); var win = new util.window();
486         JSAN.use('cat.util');
487         return cat.util.spawn_copy_editor( { 'handle_update' : 1, 'edit' : 1, 'docid' : doc_id, 'copies' : [ copy_obj ] });
488
489         } catch(E) {
490                 if (error) error.standard_unexpected_error_alert('cat.util.fast_item_add',E); else alert('FIXME: ' + E);
491         }
492 }
493 dump('exiting cat/util.js\n');