cosmetic
[Evergreen.git] / Open-ILS / xul / staff_client / server / cat / copy_editor.xul
1 <?xml version="1.0"?>
2 <!-- Application: Evergreen Staff Client -->
3 <!-- Screen: Copy Viewer/Editor -->
4
5 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
6 <!-- STYLESHEETS -->
7 <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
8 <?xml-stylesheet href="/xul/server/skin/evergreen.css" type="text/css"?>
9
10 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
11 <!-- LOCALIZATION -->
12 <!DOCTYPE window SYSTEM "chrome://evergreen/locale/lang.dtd">
13
14 <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
15 <!-- OVERLAYS -->
16 <?xul-overlay href="/xul/server/OpenILS/util_overlay.xul"?>
17
18 <window id="cat_copy_editor_win" 
19         onload="try { my_init(); } catch(E) { alert(E); }"
20         width="800" height="600"
21         title="Copies"
22         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
23
24         <!-- ///////////////////////////////////////////////////////////////////////////////////////////////////////////// -->
25         <!-- BEHAVIOR -->
26         <script type="text/javascript">
27                 var myPackageDir = 'evergreen'; var IAMXUL = true; var g = {};
28         </script>
29         <scripts id="openils_util_scripts"/>
30
31         <script type="text/javascript" src="/xul/server/main/JSAN.js"/>
32         <script>
33         <![CDATA[
34
35                 g.apply = function(field,value) {
36                         dump('field = ' + field + '  value = ' + value + '\n');
37                 }
38
39                 g.special_exception = {
40                         'Call Number' : function(label,value) {
41                                 g.network.request(
42                                         api.FM_ACN_RETRIEVE.app,
43                                         api.FM_ACN_RETRIEVE.method,
44                                         [ value ],
45                                         function(req) {
46                                                 var cn = '??? id = ' + value;
47                                                 try {
48                                                         cn = req.getResultObject().label();
49                                                 } catch(E) {
50                                                         g.error.sdump('D_ERROR','callnumber retrieve: ' + E);
51                                                 }
52                                                 label.setAttribute('value',cn);
53                                         }
54                                 );
55                         },
56                         'Creator' : function(label,value) {
57                                 g.network.request(
58                                         api.FM_AU_RETRIEVE_VIA_ID.app,
59                                         api.FM_AU_RETRIEVE_VIA_ID.method,
60                                         [ g.session, value ],
61                                         function(req) {
62                                                 var p = '??? id = ' + value;
63                                                 try {
64                                                         p = req.getResultObject();
65                                                         p = p.card().barcode() + ' : ' + p.family_name();
66
67                                                 } catch(E) {
68                                                         g.error.sdump('D_ERROR','patron retrieve: ' + E);
69                                                 }
70                                                 label.setAttribute('value',p);
71                                         }
72                                 );
73                         },
74                         'Last Editor' : function(label,value) {
75                                 g.network.request(
76                                         api.FM_AU_RETRIEVE_VIA_ID.app,
77                                         api.FM_AU_RETRIEVE_VIA_ID.method,
78                                         [ g.session, value ],
79                                         function(req) {
80                                                 var p = '??? id = ' + value;
81                                                 try {
82                                                         p = req.getResultObject();
83                                                         p = p.card().barcode() + ' : ' + p.family_name();
84
85                                                 } catch(E) {
86                                                         g.error.sdump('D_ERROR','patron retrieve: ' + E);
87                                                 }
88                                                 label.setAttribute('value',p);
89                                         }
90                                 );
91                         }
92
93                 }
94
95                 g.readonly_field_names = [
96                         [
97                                 "Barcode",               
98                                 {
99                                         render: 'fm.barcode();',
100                                 }
101                         ], 
102                         [
103                                 "Call Number",  
104                                 {
105                                         render: 'fm.call_number();',
106                                 }
107                         ],
108                 ];
109                 g.editable_field_names = [
110                          [
111                                 "Circulate as Type",    
112                                 {       
113                                         render: 'fm.circ_as_type();',
114                                         input: 'x = document.createElement("textbox"); x.addEventListener("change",function(ev) { g.apply("circ_as_type",ev.target.value); }, false);',
115                                 } 
116                         ],
117                         [
118                                 "Circulation Library",          
119                                 {       
120                                         render: 'fm.circ_lib().shortname();',
121                                         input: 'x = util.widgets.make_menulist( util.functional.map_list( util.functional.filter_list(data.list.my_aou, function(obj) { return data.hash.aout[ obj.ou_type() ].can_have_vols(); }), function(obj) { return [ obj.shortname(), obj.id() ]; }).sort() ); x.addEventListener("command",function(ev) { g.apply("circ_lib",ev.target.value); }, false);',
122                                 } 
123                         ],
124                         [
125                                 "Circulation Modifier",
126                                 {       
127                                         render: 'fm.circ_modifier();',
128                                         input: 'x = document.createElement("textbox"); x.addEventListener("change",function(ev) { g.apply("circ_modifier",ev.target.value); }, false);',
129                                 }
130                         ],
131                         [
132                                 "Circulate?",
133                                 {       
134                                         render: 'fm.circulate() ? "Yes" : "No";',
135                                         input: 'x = util.widgets.make_menulist( [ [ "Yes", "1" ], [ "No", "0" ] ] ); x.addEventListener("command",function(ev) { g.apply("circulate",ev.target.value); }, false);',
136                                 }
137                         ],
138                         [
139                                 "Copy Number",
140                                 { 
141                                         render: 'fm.copy_number();',
142                                         input: 'x = document.createElement("textbox"); x.addEventListener("change",function(ev) { g.apply("copy_number",ev.target.value); }, false);',
143                                 }
144                         ],
145                         [
146                                 "Creation Date",
147                                 { 
148                                         render: 'util.date.formatted_date( fm.create_date(), "%F");',
149                                 }
150                         ],
151                         [
152                                 "Creator",
153                                 { 
154                                         render: 'fm.creator();',
155                                 }
156                         ],
157                         [
158                                 "Deposit?",
159                                 { 
160                                         render: 'fm.deposit() ? "Yes" : "No";',
161                                         input: 'x = util.widgets.make_menulist( [ [ "Yes", "1" ], [ "No", "0" ] ] ); x.addEventListener("command",function(ev) { g.apply("deposit",ev.target.value); }, false);',
162                                 }
163                         ],
164                         [
165                                 "Deposit Amount",
166                                 { 
167                                         render: 'util.money.sanitize( fm.deposit_amount() );',
168                                         input: 'x = document.createElement("textbox"); x.addEventListener("change",function(ev) { g.apply("deposit_amount",ev.target.value); }, false);',
169                                 }
170                         ],
171                         [
172                                 "Last Edit Date",
173                                 { 
174                                         render: 'util.date.formatted_date( fm.edit_date(), "%F");',
175                                 }
176                         ],
177                         [
178                                 "Last Editor",
179                                 {
180                                         render: 'fm.editor();',
181                                 }
182                         ],
183                         [
184                                 "Fine Level",
185                                 {
186                                         render: 'switch(fm.fine_level()){ case 1: "Low"; break; case 2: "Normal"; break; case 3: "High"; break; }',
187                                         input: 'x = util.widgets.make_menulist( [ [ "Low", "1" ], [ "Normal", "2" ], [ "High", "3" ] ] ); x.addEventListener("command",function(ev) { g.apply("fine_level",ev.target.value); }, false);',
188                                 }
189                         ],
190                         [
191                                 "Holdable?",
192                                 { 
193                                         render: 'fm.holdable() ? "Yes" : "No";', 
194                                         input: 'x = util.widgets.make_menulist( [ [ "Yes", "1" ], [ "No", "0" ] ] ); x.addEventListener("command",function(ev) { g.apply("holdable",ev.target.value); }, false);',
195                                 }
196                         ],
197                         [
198                                 "Loan Duration",
199                                 { 
200                                         render: 'switch(fm.loan_duration()){ case 1: "Short"; break; case 2: "Normal"; break; case 3: "Long"; break; }',
201                                         input: 'x = util.widgets.make_menulist( [ [ "Short", "1" ], [ "Normal", "2" ], [ "Long", "3" ] ] ); x.addEventListener("command",function(ev) { g.apply("loan_duration",ev.target.value); }, false);',
202
203                                 }
204                         ],
205                         [
206                                 "Shelving Location",
207                                 { 
208                                         render: 'fm.location().name();', 
209                                         input: 'x = util.widgets.make_menulist( util.functional.map_list( data.list.acpl, function(obj) { return [ obj.name(), obj.id() ]; }).sort()); x.addEventListener("command",function(ev) { g.apply("location",ev.target.value); }, false);',
210
211                                 }
212                         ],
213                         [
214                                 "OPAC Visible?",
215                                 { 
216                                         render: 'fm.opac_visible() ? "Yes" : "No";', 
217                                         input: 'x = util.widgets.make_menulist( [ [ "Yes", "1" ], [ "No", "0" ] ] ); x.addEventListener("command",function(ev) { g.apply("opac_visible",ev.target.value); }, false);',
218                                 }
219                         ],
220                         [
221                                 "Price",
222                                 { 
223                                         render: 'util.money.sanitize( fm.price() );', 
224                                         input: 'x = document.createElement("textbox"); x.addEventListener("change",function(ev) { g.apply("deposit_amount",ev.target.value); }, false);',
225                                 }
226                         ],
227                         [
228                                 "Reference?",
229                                 { 
230                                         render: 'fm.ref() ? "Yes" : "No";', 
231                                         input: 'x = util.widgets.make_menulist( [ [ "Yes", "1" ], [ "No", "0" ] ] ); x.addEventListener("command",function(ev) { g.apply("ref",ev.target.value); }, false);',
232                                 }
233                         ],
234                         [
235                                 "Status",
236                                 { 
237                                         render: 'fm.status().name();', 
238                                         input: 'x = util.widgets.make_menulist( util.functional.map_list( data.list.ccs, function(obj) { return [ obj.name(), obj.id() ]; } ).sort() ); x.addEventListener("command",function(ev) { g.apply("status",ev.target.value); }, false);',
239
240
241                                 }
242                         ],
243                 ];
244
245                 function my_init() {
246                         try {
247                                 netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
248                                 if (typeof JSAN == 'undefined') { throw( "The JSAN library object is missing."); }
249                                 JSAN.errorLevel = "die"; // none, warn, or die
250                                 JSAN.addRepository('/xul/server/');
251                                 JSAN.use('util.error'); g.error = new util.error();
252                                 g.error.sdump('D_TRACE','my_init() for cat/copy_editor.xul');
253
254                                 g.cgi = new CGI();
255
256                                 g.session = g.cgi.param('session') || g.cgi.param('ses');
257
258                                 var copy_ids = [];
259                                 if (g.cgi.param('copy_ids')) copy_ids = JSON2js( g.cgi.param('copy_ids') );
260                                 if (!copy_ids) copy_ids = [];
261                                 if (window.xulG && window.xulG.copy_ids) copy_ids = copy_ids.concat( window.xulG.copy_ids );
262
263                                 if (g.cgi.param('edit')) { 
264                                         g.edit = true;
265                                         document.getElementById('caption').setAttribute('label','Copy Editor'); 
266                                         document.getElementById('nav').setAttribute('hidden','false'); 
267                                 }
268
269                                 JSAN.use('util.network'); g.network = new util.network();
270
271                                 if (copy_ids.length > 0) g.copies = g.network.request(
272                                         api.FM_ACP_FLESHED_BATCH_RETRIEVE.app,
273                                         api.FM_ACP_FLESHED_BATCH_RETRIEVE.method,
274                                         [ copy_ids ]
275                                 );
276
277                                 if (!g.copies) g.copies = [];
278                                 if (window.xulG && window.xulG.copies) g.copies = g.copies.concat( window.xulG.copies );
279
280                                 g.summarize( g.copies );
281                                 g.render();
282
283                         } catch(E) {
284                                 var err_msg = "!! This software has encountered an error.  Please tell your friendly " +
285                                         "system administrator or software developer the following:\ncat/copy_editor.xul\n" + E + '\n';
286                                 try { g.error.sdump('D_ERROR',err_msg); } catch(E) { dump(err_msg); dump(js2JSON(E)); }
287                                 alert(err_msg);
288                         }
289                 }
290
291                 g.summarize = function( copies ) {
292                         JSAN.use('util.date'); JSAN.use('util.money');
293                         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
294                         g.summary = {};
295                         g.field_names = g.readonly_field_names.concat( g.editable_field_names );
296                         for (var i = 0; i < g.field_names.length; i++) {
297                                 var field_name = g.field_names[i][0];
298                                 var render = g.field_names[i][1].render;
299                                 g.summary[ field_name ] = {};
300                                 for (var j = 0; j < copies.length; j++) {
301                                         var fm = copies[j];
302                                         var cmd = render || ('fm.' + field_name + '();');
303                                         dump(cmd + ' = ');
304                                         var value = '???';
305                                         try { value = eval( cmd ); } catch(E) { dump(E + '\n'); }
306                                         dump(value + '\n');
307                                         if (typeof value == 'object' && value != null) {
308                                                 dump('field_name = ' + field_name + '  value = ' + js2JSON(value) + '\n');
309                                                 /*
310                                                 try { value = value.id(); } catch(E) { 
311                                                         dump(E + '\n'); 
312                                                         try { dump(js2JSON(value) + '\n'); } catch(F) { dump(F); }
313                                                 }
314                                                 */
315                                         }
316                                         if (g.summary[ field_name ][ value ]) {
317                                                 g.summary[ field_name ][ value ]++;
318                                         } else {
319                                                 g.summary[ field_name ][ value ] = 1;
320                                         }
321                                 }
322                         }
323                         dump('summary = ' + js2JSON(g.summary) + '\n');
324                 }
325
326                 g.render = function() {
327
328                         JSAN.use('util.widgets'); JSAN.use('util.date'); JSAN.use('util.money'); JSAN.use('util.functional');
329                         JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
330
331                         /* clear */
332                         var cns = document.getElementById('call_number_summary');
333                         util.widgets.remove_children( cns );
334                         var bcs = document.getElementById('barcode_summary');
335                         util.widgets.remove_children( bcs );
336                         var rp = document.getElementById('right_pane');
337                         util.widgets.remove_children( rp );
338
339                         var grid = util.widgets.make_grid( [ { 'flex' : '1' }, {} ] );
340                         cns.appendChild(grid);
341                         for (var i in g.summary['Call Number']) {
342                                 var cn_id = i; var count = g.summary['Call Number'][i];
343                                 var row = document.createElement('row'); grid.lastChild.appendChild(row);
344                                 var cn_label = document.createElement('label'); row.appendChild(cn_label);
345                                 g.special_exception['Call Number']( cn_label, cn_id );
346                                 var count_label = document.createElement('label'); row.appendChild(count_label);
347                                 count_label.setAttribute('value',count + ' copies');
348                         }
349
350                         for (var i in g.summary['Barcode']) {
351                                 var bc = i;
352                                 var hbox = document.createElement('hbox'); bcs.appendChild(hbox);
353                                 var bc_label = document.createElement('label'); hbox.appendChild(bc_label);
354                                 bc_label.setAttribute('value',bc);
355                         }
356
357                         
358                         for (var i = 0; i < g.editable_field_names.length; i++) {
359                                 try {
360                                         var f = g.editable_field_names[i]; var fn = f[0];
361                                         var groupbox = document.createElement('groupbox'); rp.appendChild(groupbox);
362                                         var caption = document.createElement('caption'); groupbox.appendChild(caption);
363                                         caption.setAttribute('label',fn);
364                                         var vbox = document.createElement('vbox'); groupbox.appendChild(vbox);
365                                         var grid = util.widgets.make_grid( [ { 'flex' : 1 }, {} ] ); vbox.appendChild(grid);
366                                         grid.setAttribute('flex','1');
367                                         var rows = grid.lastChild;
368                                         for (var j in g.summary[fn]) {
369                                                 var value = j; var count = g.summary[fn][j];
370                                                 var row = document.createElement('row'); rows.appendChild(row);
371                                                 var label1 = document.createElement('label'); row.appendChild(label1);
372                                                 if (g.special_exception[ fn ]) {
373                                                         g.special_exception[ fn ]( label1, value );
374                                                 } else {
375                                                         label1.setAttribute('value',value);
376                                                 }
377                                                 var label2 = document.createElement('label'); row.appendChild(label2);
378                                                 label2.setAttribute('value',count + ' copies');
379                                         }
380                                         var hbox = document.createElement('hbox'); vbox.appendChild(hbox);
381                                         if (f[1].input && g.edit) {
382                                                 try {
383                                                         var spacer = document.createElement('spacer'); hbox.appendChild(spacer);
384                                                         spacer.setAttribute('flex','1');
385                                                         var x; eval( f[1].input );
386                                                         if (x) hbox.appendChild(x);
387
388                                                 } catch(E) {
389                                                         dump(E + '\n');
390                                                 }
391                                         }
392                                 } catch(E) {
393                                         g.error.sdump('D_ERROR','copy editor: ' + E + '\n');
394                                 }
395                         }
396                 }
397         ]]>
398         </script>
399
400         <groupbox flex="1" style="overflow: auto">
401                 <caption id="caption" label="Copy Viewer"/>
402                 <hbox id="nav" hidden="true"><spacer flex="1"/><button id="save" label="Modify these Copies"/></hbox>
403                 <hbox flex="1">
404                         <vbox style="overflow: scroll"> <!-- left pane -->
405                                 <groupbox id="gb_callnumbers">
406                                         <caption label="Call Numbers"/>
407                                         <vbox id="call_number_summary" flex="1"/>
408                                 </groupbox>
409                                 <groupbox id="gb_barcodes">
410                                         <caption label="Barcodes"/>
411                                         <vbox id="barcode_summary" flex="1"/>
412                                 </groupbox>
413                         </vbox>
414                         <splitter><grippy /></splitter>
415                         <vbox id="right_pane" style="overflow: scroll" flex="1"/> <!-- right pane -->
416                 </hbox>
417                 <spacer/>
418         </groupbox>
419
420 </window>
421