]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/web/js/ui/default/acq/invoice/view.js
More Invoice UI work. This covers:
[working/Evergreen.git] / Open-ILS / web / js / ui / default / acq / invoice / view.js
1 dojo.require('dojo.date.locale');
2 dojo.require('dojo.date.stamp');
3 dojo.require('dijit.form.CheckBox');
4 dojo.require('dijit.form.CurrencyTextBox');
5 dojo.require('dijit.form.NumberTextBox');
6 dojo.require('openils.User');
7 dojo.require('openils.Util');
8 dojo.require('openils.CGI');
9 dojo.require('openils.PermaCrud');
10 dojo.require('openils.widget.EditPane');
11 dojo.require('openils.widget.AutoFieldWidget');
12
13 dojo.requireLocalization('openils.acq', 'acq');
14 var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
15
16 var fundLabelFormat = ['${0} (${1})', 'code', 'year'];
17 var fundSearchFormat = ['${0} (${1})', 'code', 'year'];
18
19 var cgi = new openils.CGI();
20 var pcrud = new openils.PermaCrud();
21 var attachLi;
22 var attachPo;
23 var invoice;
24 var itemTbody;
25 var itemTemplate;
26 var entryTemplate;
27 var totalAmountBox;
28 var invoicePane;
29 var itemTypes;
30
31 function nodeByName(name, context) {
32     return dojo.query('[name='+name+']', context)[0];
33 }
34
35 function init() {
36
37     attachLi = cgi.param('attach_li');
38     attachPo = cgi.param('attach_po');
39
40     itemTypes = pcrud.retrieveAll('aiit');
41
42     if(cgi.param('create')) {
43         renderInvoice();
44
45     } else {
46         fieldmapper.standardRequest(
47             ['open-ils.acq', 'open-ils.acq.invoice.retrieve'],
48             {
49                 params : [openils.User.authtoken, invoiceId],
50                 oncomplete : function(r) {
51                     invoice = openils.Util.readResponse(r);     
52                     renderInvoice();
53                 }
54             }
55         );
56     }
57 }
58
59 function renderInvoice() {
60
61     // in create mode, let the LI or PO render the invoice with seed data
62     if( !(cgi.param('create') && (attachPo || attachLi)) ) {
63         invoicePane = drawInvoicePane(dojo.byId('acq-view-invoice-div'), invoice);
64     }
65
66     dojo.byId('acq-invoice-new-item').onclick = function() {
67         addInvoiceItem(new fieldmapper.acqii()); 
68     }
69
70     addToTotal(0);
71
72     if(invoice) {
73         dojo.forEach(
74             invoice.items(),
75             function(item) {
76                 addInvoiceItem(item);
77             }
78         );
79
80         dojo.forEach(
81             invoice.entries(),
82             function(entry) {
83                 addInvoiceEntry(entry);
84             }
85         );
86     }
87
88     if(attachLi) doAttachLi();
89     if(attachPo) doAttachPo();
90 }
91
92 function doAttachLi() {
93
94     fieldmapper.standardRequest(
95         ["open-ils.acq", "open-ils.acq.lineitem.retrieve"], {
96             async: true,
97             params: [openils.User.authtoken, attachLi, {
98                 clear_marc : true,
99                 flesh_attrs : true,
100                 flesh_po : true,
101             }],
102             oncomplete: function(r) { 
103                 lineitem = openils.Util.readResponse(r);
104
105                 if(cgi.param('create')) {
106                     // render the invoice using some seed data from the Lineitem
107                     var invoiceArgs = {provider : lineitem.provider(), shipper : lineitem.provider()}; 
108                     invoicePane = drawInvoicePane(dojo.byId('acq-view-invoice-div'), null, invoiceArgs);
109                 }
110
111                 var entry = new fieldmapper.acqie();
112                 entry.isnew(true);
113                 entry.lineitem(lineitem);
114                 addInvoiceEntry(entry);
115             }
116         }
117     );
118 }
119
120 function doAttachPo() {
121     fieldmapper.standardRequest(
122         ['open-ils.acq', 'open-ils.acq.purchase_order.retrieve'],
123         {   async: true,
124             params: [openils.User.authtoken, attachPo, {
125                 flesh_lineitems : true,
126                 clear_marc : true
127             }],
128             oncomplete: function(r) {
129                 var po = openils.Util.readResponse(r);
130
131                 if(cgi.param('create')) {
132                     // render the invoice using some seed data from the PO
133                     var invoiceArgs = {provider : po.provider(), shipper : po.provider()}; 
134                     invoicePane = drawInvoicePane(dojo.byId('acq-view-invoice-div'), null, invoiceArgs);
135                 }
136
137                 dojo.forEach(po.lineitems(), 
138                     function(lineitem) {
139                         var entry = new fieldmapper.acqie();
140                         entry.isnew(true);
141                         entry.lineitem(lineitem);
142                         addInvoiceEntry(entry);
143                     }
144                 );
145             }
146         }
147     );
148 }
149
150 function addToTotal(amount) {
151
152     var oldTotal = 0;
153     if(totalAmountBox) {
154         oldTotal = totalAmountBox.attr('value');
155     } else {
156         totalAmountBox = new dijit.form.CurrencyTextBox(
157             {style : 'width: 5em'}, dojo.byId('acq-invoice-total-invoiced'));
158     }
159
160     totalAmountBox.attr('value', Number(oldTotal + amount));
161 }
162
163 function addInvoiceItem(item) {
164     itemTbody = dojo.byId('acq-invoice-item-tbody');
165     if(itemTemplate == null) {
166         itemTemplate = itemTbody.removeChild(dojo.byId('acq-invoice-item-template'));
167     }
168
169     var row = itemTemplate.cloneNode(true);
170     var itemType = itemTypes.filter(function(t) { return (t.code() == item.inv_item_type()) })[0];
171
172     new dijit.form.TextBox({}, nodeByName('title', row));
173     new dijit.form.TextBox({}, nodeByName('author', row));
174     new dijit.form.CurrencyTextBox({required : true, style : 'width: 5em'}, nodeByName('cost_billed', row));
175
176
177     var fundDebit = item.fund_debit();
178     var fundFilter = {active : 't'};
179     if(fundDebit) {
180         
181         // If a fund debit exists, this item has been "applied" to the invoice
182         fundFilter = {'-or' : [{id : fundDebit.fund()}, fundFilter]}
183
184     } else {
185
186         fundDebit = new fieldmapper.acqfdeb();
187         //new dijit.form.CheckBox({}, nodeByName('prorate', row));
188     }
189
190     var itemType = itemTypes.filter(function(t) { return (t.code() == item.inv_item_type()) })[0];
191
192     var fundWidget = new openils.widget.AutoFieldWidget({
193         fmObject : fundDebit,
194         fmField : 'fund',
195         labelFormat : fundLabelFormat,
196         searchFormat : fundSearchFormat,
197         searchFilter : fundFilter,
198         dijitArgs : 
199             (!item.fund_debit() && itemType && openils.Util.isTrue(itemType.prorate())) ? 
200                 {disabled : true} : {},
201         parentNode : nodeByName('fund', row)
202     });
203     fundWidget.build();
204
205
206     new openils.widget.AutoFieldWidget({
207         fmObject : item,
208         fmField : 'inv_item_type',
209         parentNode : nodeByName('inv_item_type', row),
210         dijitArgs : {required : true}
211     }).build(
212         function(w, ww) {
213             // When the inv_item_type is set to prorate=true, don't allow the user the edit the fund
214             // since this charge will be prorated against (potentially) multiple funds
215             dojo.connect(w, 'onChange', 
216                 function() {
217                     if(!item.fund_debit()) {
218                         var itemType = itemTypes.filter(function(t) { return (t.code() == w.attr('value')) })[0];
219                         if(openils.Util.isTrue(itemType.prorate())) {
220                             fundWidget.widget.attr('disabled', true);
221                             fundWidget.widget.attr('value', '');
222                         } else {
223                             fundWidget.widget.attr('disabled', false);
224                         }
225                     }
226                 }
227             );
228         }
229     );
230
231     nodeByName('delete', row).onclick = function() {
232         // TODO: confirm, etc.
233         itemTbody.removeChild(row);
234     }
235
236     itemTbody.appendChild(row);
237 }
238
239 function addInvoiceEntry(entry) {
240     entryTbody = dojo.byId('acq-invoice-entry-tbody');
241     if(entryTemplate == null) {
242         entryTemplate = entryTbody.removeChild(dojo.byId('acq-invoice-entry-template'));
243     }
244
245     if(dojo.query('[lineitem=' + entry.lineitem().id() +']', entryTbody)[0])
246         // Is it ever valid to have multiple entries for 1 lineitem in a single invoice?
247         return;
248
249     var row = entryTemplate.cloneNode(true);
250     row.setAttribute('lineitem', entry.lineitem().id());
251     var lineitem = entry.lineitem();
252
253     var idents = [];
254     if(liMarcAttr(lineitem, 'isbn')) idents.push(liMarcAttr(lineitem, 'isbn'));
255     if(liMarcAttr(lineitem, 'upc')) idents.push(liMarcAttr(lineitem, 'upc'));
256     if(liMarcAttr(lineitem, 'issn')) idents.push(liMarcAttr(lineitem, 'issn'));
257
258     nodeByName('title', row).innerHTML = liMarcAttr(lineitem, 'title');
259     nodeByName('author', row).innerHTML = liMarcAttr(lineitem, 'author');
260     nodeByName('idents', row).innerHTML = idents.join(',');
261
262     if(entry.purchase_order()) {
263         openils.Util.show(nodeByName('purchase_order_span', row), 'inline');
264         nodeByName('purchase_order', row).innerHTML = entry.purchase_order().name();
265         nodeByName('purchase_order', row).onclick = function() {
266             location.href = oilsBasePath + '/acq/po/view/ ' + entry.purchase_order().id();
267         }
268     }
269
270     new dijit.form.NumberTextBox(
271         {value : entry.inv_item_count(), required : true, constraints : {min: 0}, style : 'width:5em'}, 
272         nodeByName('inv_item_count', row));
273
274     new dijit.form.NumberTextBox(
275         {value : entry.phys_item_count(), required : true, constraints : {min: 0}, style : 'width:5em'}, 
276         nodeByName('phys_item_count', row));
277
278     new dijit.form.CurrencyTextBox(
279         {value : entry.cost_billed(), required : true, style : 'width: 5em'}, 
280         nodeByName('cost_billed', row));
281
282     nodeByName('detach', row).onclick = function() {
283         // TODO: confirm, etc.
284         entryTbody.removeChild(row);
285     }
286
287     entryTbody.appendChild(row);
288 }
289
290 function liMarcAttr(lineitem, name) {
291     var attr = lineitem.attributes().filter(
292         function(attr) { 
293             if(
294                 attr.attr_type() == 'lineitem_marc_attr_definition' && 
295                 attr.attr_name() == name) 
296                     return attr 
297         } 
298     )[0];
299     return (attr) ? attr.attr_value() : '';
300 }
301
302
303
304 openils.Util.addOnLoad(init);
305
306