Acq: Make the distribution formula UI page like it was supposed to
[working/Evergreen.git] / Open-ILS / web / js / ui / default / conify / global / acq / distribution_formula.js
1 dojo.require("dojo.dnd.Container");
2 dojo.require("dojo.dnd.Source");
3 dojo.require('openils.widget.AutoGrid');
4 dojo.require('dijit.form.FilteringSelect');
5 dojo.require('openils.PermaCrud');
6 dojo.require('openils.widget.AutoFieldWidget');
7 dojo.requireLocalization('openils.conify', 'conify');
8 var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
9
10
11 var formCache = {};
12 var formula, entryTbody, entryTemplate, dndSource;
13 var virtualId = -1;
14 var pcrud;
15
16
17 function gridDataLoader() {
18     fListGrid.resetStore();
19     fListGrid.showLoadProgressIndicator();
20     fieldmapper.standardRequest(
21         ["open-ils.acq", "open-ils.acq.distribution_formula.ranged.retrieve"], {
22             "async": true,
23             "params": [
24                 openils.User.authtoken,
25                 fListGrid.displayOffset,
26                 fListGrid.displayLimit
27             ],
28             "onresponse": function(r) {
29                 var form = openils.Util.readResponse(r);
30                 formCache[form.id()] = form;
31                 fListGrid.store.newItem(form.toStoreItem());
32             },
33             "oncomplete": function() {
34                 fListGrid.hideLoadProgressIndicator();
35             }
36         }
37     );
38 }
39
40 function draw() {
41
42     pcrud = new openils.PermaCrud();
43
44     if(formulaId) {
45         openils.Util.hide('formula-list-div');
46         drawFormulaSummary();
47     } else {
48
49         openils.Util.hide('formula-entry-div');
50         fListGrid.onPostCreate = function(fmObject) {
51             location.href = location.href + '/' + fmObject.id();
52         }
53
54         fListGrid.dataLoader = gridDataLoader;
55         gridDataLoader();
56     }
57 }
58
59 function cloneSelectedFormula() {
60     var item = fListGrid.getSelectedItems()[0];
61     if(!item) return;
62     var formula = new fieldmapper.acqf().fromStoreItem(item);
63     fieldmapper.standardRequest(
64         ['open-ils.acq', 'open-ils.acq.distribution_formula.clone'],
65         {
66             asnyc : true,
67             params : [
68                 openils.User.authtoken, 
69                 formula.id(), 
70                 dojo.string.substitute(localeStrings.ACQ_DISTRIB_FORMULA_NAME_CLONE, [formula.name()])
71             ],
72             oncomplete : function(r) {
73                 if(r = openils.Util.readResponse(r)) {
74                     location.href = oilsBasePath + '/conify/global/acq/distribution_formula/' + r;
75                 }
76             }
77         }
78     );
79 }
80
81 openils.Util.addOnLoad(draw);
82
83 function getItemCount(rowIndex, item) {
84     if(!item) return '';
85     var form = formCache[this.grid.store.getValue(item, "id")];
86     if(!form) return 0;
87     var count = 0;
88     dojo.forEach(form.entries(), function(e) { count = count + e.item_count(); });
89     return count;
90 }
91
92 function byName(node, name) {
93     return dojo.query('[name='+name+']', node)[0];
94 }
95
96 function drawFormulaSummary() {
97     openils.Util.show('formula-entry-div');
98
99     var entries = pcrud.search('acqdfe', {formula: formulaId}, {order_by:{acqdfe : 'position'}});
100     formula = pcrud.retrieve('acqdf', formulaId);
101     formula.entries(entries);
102
103     dojo.byId('formula_head').innerHTML = formula.name();
104     dojo.byId('formula_head').onclick = function() {
105         var name = prompt(localeStrings.ACQ_DISTRIB_FORMULA_NAME_PROMPT, formula.name());
106         if(name && name != formula.name()) {
107             formula.name(name);
108             pcrud = new openils.PermaCrud();
109             pcrud.update(formula);
110             dojo.byId('formula_head').innerHTML = name;
111         }
112     }
113
114     dojo.forEach(entries, function(entry) { addEntry(entry); } );
115 }
116
117 function addEntry(entry) {
118
119     if(!entryTbody) {
120         entryTbody = dojo.byId('formula-entry-tbody');
121         entryTemplate = entryTbody.removeChild(dojo.byId('formula-entry-tempate'));
122         dndSource = new dojo.dnd.Source(entryTbody);
123         dndSource.selectAll(); 
124         dndSource.deleteSelectedNodes();
125         dndSource.clearItems();
126     }
127
128     if(!entry) {
129         entry = new fieldmapper.acqdfe();
130         entry.formula(formulaId);
131         entry.item_count(1);
132         entry.owning_lib(openils.User.user.ws_ou());
133         entry.id(virtualId--);
134         entry.isnew(true);
135         formula.entries().push(entry);
136     }
137
138     var row = entryTbody.appendChild(entryTemplate.cloneNode(true));
139     row.setAttribute('entry', entry.id());
140     dndSource.insertNodes(false, [row]);
141     byName(row, 'delete').onclick = function() {
142         entry.isdeleted(true);
143         entryTbody.removeChild(row);
144         dndSource.sync();
145     };
146
147     dojo.forEach(
148         ['owning_lib', 'location', 'item_count'],
149         function(field) {
150             new openils.widget.AutoFieldWidget({
151                 forceSync : true,
152                 fmField : field, 
153                 fmObject : entry,
154                 fmClass : 'acqdfe',
155                 parentNode : byName(row, field),
156                 orgDefaultsToWs : true,
157                 orgLimitPerms : ['ADMIN_ACQ_DISTRIB_FORMULA'],
158                 widgetClass : (field == 'item_count') ? 'dijit.form.NumberSpinner' : null,
159                 dijitArgs : (field == 'item_count') ? {min:1, places:0} : null
160             }).build(
161                 function(w, ww) {
162                     dojo.connect(w, 'onChange', 
163                         function(newVal) {
164                             entry[field]( newVal );
165                             entry.ischanged(true);
166                         }
167                     )
168                 }
169             );
170         }
171     );
172 }
173
174 function saveFormula() {
175     var pos = 1;
176     var updatedEntries = [];
177     var deletedEntries = [];
178
179     // remove deleted entries from consideration for collision protection
180     for(var i = 0; i < formula.entries().length; i++) {
181         if(formula.entries()[i].isdeleted())
182             deletedEntries.push(formula.entries().splice(i--, 1)[0])
183     }
184
185     // update entry positions and create temporary collision avoidance entries
186     dojo.forEach(
187         dndSource.getAllNodes(),
188         function(node) {
189
190             var entryId = node.getAttribute('entry');
191             var entry = formula.entries().filter(function(e) {return (e.id() == entryId)})[0];
192
193             if(entry.position() != pos) {
194
195                 // update the position
196                 var changedEntry = entry.clone();
197                 changedEntry.position(pos);
198                 changedEntry.ischanged(true);
199                 updatedEntries.push(changedEntry);
200
201                 // clear the virtual ID
202                 if(changedEntry.isnew())
203                     changedEntry.id(null); 
204
205                 var oldEntry = formula.entries().filter(function(e) {return (e.position() == pos)})[0];
206
207                 if(oldEntry) {
208                     // move the entry currently in that spot temporarily into negative territory
209                     var moveMe = oldEntry.clone();
210                     moveMe.ischanged(true);
211                     moveMe.position(moveMe.position() * -1); 
212                     updatedEntries.unshift(moveMe);
213                 }
214             }
215             pos++;
216         }
217     );
218
219     // finally, for every entry that changed w/o changing position
220     // throw it on the list for update
221     dojo.forEach(
222         formula.entries(),
223         function(entry) {
224             if(entry.ischanged() && !entry.isdeleted() && !entry.isnew()) {
225                 if(updatedEntries.filter(function(e) { return (e.id() == entry.id()) }).length == 0)
226                     updatedEntries.push(entry);
227             }
228         }
229     );
230
231     updatedEntries = deletedEntries.concat(updatedEntries);
232     if(updatedEntries.length) {
233         pcrud = new openils.PermaCrud();
234         try { 
235             pcrud.apply(updatedEntries);
236         } catch(E) {
237             alert('error updating: ' + E);
238             return;
239         }
240         location.href = location.href;
241     }
242 }
243
244