}
});
+
+ // 2012-07-26 - Joseph Lewis, Is this needed anymore? It isn't referenced
+ // anywhere that I see.
dojo._hasResource["openils.FeedTemplate"] = true;
dojo.provide("openils.FeedTemplate");
dojo.declare('openils.FeedTemplate', null, {
* ---------------------------------------------------------------------------
*/
+// 2012-07-26 Joseph Lewis -- Can or should this be replaced with dojo's builtin
+// functions? dojo.queryToObject?
if(!dojo._hasResource["openils.CGI"]) {
dojo._hasResource["openils.CGI"] = true;
-
\ No newline at end of file
+
--- /dev/null
+dojo.provide("openils.tests.functions.AuthorityControlSet");
+
+//Import in the code being tested.
+dojo.require("openils.AuthorityControlSet");
+
+doh.register("openils.tests.functions.AuthorityControlSet", [
+
+ function test_constructor(doh) {
+ // summary:
+ // Simply tests that the Constructor works, and the file has loaded
+
+ var acs = new openils.AuthorityControlSet();
+ doh.assertTrue(acs != null);
+ },
+
+ function test_alwaysFalse(doh) {
+ // summary:
+ // A simple test of the alwaysFalse function
+ // description:
+ // A simple test of the alwaysFalse function
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_isTrue(doh) {
+ // summary:
+ // A simple test of the isTrue function
+ // description:
+ // A simple test of the isTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.AutoSuggestStore");
+
+//Import in the code being tested.
+dojo.require("openils.AutoSuggestStore");
+
+doh.register("openils.tests.functions.AutoSuggestStore", [
+
+ function test_constructor(doh) {
+ // summary:
+ // Simply tests that the Constructor works, and the file has loaded
+
+ var acs = new openils.AutoSuggestStore();
+ doh.assertTrue(acs != null);
+ },
+
+ function test_alwaysFalse(doh) {
+ // summary:
+ // A simple test of the alwaysFalse function
+ // description:
+ // A simple test of the alwaysFalse function
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_isTrue(doh) {
+ // summary:
+ // A simple test of the isTrue function
+ // description:
+ // A simple test of the isTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.BibTemplate");
+
+//Import in the code being tested.
+dojo.require("openils.BibTemplate");
+
+doh.register("openils.tests.functions.BibTemplate", [
+
+ function test_constructor(doh) {
+ // summary:
+ // Simply tests that the Constructor works, and the file has loaded
+
+ var acs = new openils.BibTemplate();
+ doh.assertTrue(acs != null);
+ },
+
+ function test_default_constructor(doh) {
+ var acs = new openils.BibTemplate();
+ doh.assertTrue(acs != null);
+ doh.assertTrue(acs.org_unit == '-');
+ doh.assertTrue(acs.sync == false);
+ doh.assertTrue(acs.nodelay == false);
+ },
+
+ function test_alwaysFalse(doh) {
+ // summary:
+ // A simple test of the alwaysFalse function
+ // description:
+ // A simple test of the alwaysFalse function
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_isTrue(doh) {
+ // summary:
+ // A simple test of the isTrue function
+ // description:
+ // A simple test of the isTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.BibTemplate");
+
+//Import in the code being tested.
+dojo.require("openils.BibTemplate");
+
+doh.register("openils.tests.functions.BibTemplate", [
+
+ function test_constructor(doh) {
+ // summary:
+ // Simply tests that the Constructor works, and the file has loaded
+
+ var acs = new openils.BibTemplate();
+ doh.assertTrue(acs != null);
+ },
+
+ function test_default_constructor(doh) {
+ var acs = new openils.BibTemplate();
+ doh.assertTrue(acs != null);
+ doh.assertTrue(acs.org_unit == '-');
+ doh.assertTrue(
+ },
+
+ function test_alwaysFalse(doh) {
+ // summary:
+ // A simple test of the alwaysFalse function
+ // description:
+ // A simple test of the alwaysFalse function
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_isTrue(doh) {
+ // summary:
+ // A simple test of the isTrue function
+ // description:
+ // A simple test of the isTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.CGI");
+
+//Import in the code being tested.
+dojo.require("openils.CGI");
+
+doh.register("openils.tests.functions.CGI", [
+
+ function test_constructor(doh) {
+ // summary:
+ // Simply tests that the Constructor works, and the file has loaded
+ // description:
+ //
+
+ var acs = new openils.CGI();
+ doh.assertTrue(acs != null);
+ },
+
+ function test_keys(doh) {
+ // summary:
+ // Tests the key fetching mechanism of CGI
+ // description:
+ // CGI.js will return the key part of the query string: ?key=value&
+
+ var acs = new openils.CGI();
+
+ // Being we're using dojo's test framework this should be true.
+ var dojoKeys = dojo.queryToObject(location.search.replace(/^\?/,""));
+
+
+ doh.assertTrue(acs.keys().length == Object.keys(dojoKeys).length);
+ },
+
+ function test_params(doh) {
+ // summary:
+ // Tests all of the params in the CGI script
+ // description:
+ // CGI.js will return the values part of the query string
+
+ var acs = new openils.CGI();
+ var keys = acs.keys();
+
+ var dojoVersion = dojo.queryToObject(location.search.replace(/^\?/,""));
+
+ for(var i = 0; i < keys.length; i++)
+ {
+ doh.assertTrue(acs.param(keys[i]) == dojoVersion[keys[i]]);
+ }
+ },
+
+ function test_toString(doh) {
+ // summary:
+ // Tests to make sure the toString actually reports something,
+ // anything.
+ // description:
+ // The tostring method is supposed to only be for debugging, but
+ // shoudld still pass.
+
+ var acs = new openils.CGI();
+
+ if(acs.keys().length == 0)
+ doh.assertTrue(acs.toString() == "");
+ else
+ doh.assertTrue(acs.toString() != "");
+ },
+
+ function test_alwaysFalse(doh) {
+ // summary:
+ // A simple test of the doh assertFalse function
+ // description:
+ // A simple test of the doh assertFalse function
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_isTrue(doh) {
+ // summary:
+ // A simple test of the assertTrue function
+ // description:
+ // A simple test of the assertTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.CopyLocation");
+
+//Import in the code being tested.
+dojo.require("openils.CopyLocation");
+
+
+doh.register("openils.tests.functions.CopyLocation", [
+
+ function test_loaded(doh) {
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+
+ doh.assertTrue(openils.CopyLocation.createStore != null);
+ doh.assertTrue(openils.CopyLocation.retrieve != null);
+ },
+
+ function test_assertFalse(doh) {
+ // summary:
+ // A simple test of the doh assertFalse function.
+ // description:
+ // A simple test of the doh assertFalse function.
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_assertTrue(doh) {
+ // summary:
+ // A simple test of the assertTrue function.
+ // description:
+ // A simple test of the assertTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.DojoPatch");
+
+//Import in the code being tested.
+dojo.require("openils.DojoPatch");
+
+doh.register("openils.tests.functions.DojoPatch", [
+
+ function test_alwaysFalse(doh) {
+ // summary:
+ // A simple test of the alwaysFalse function
+ // description:
+ // A simple test of the alwaysFalse function
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_isTrue(doh) {
+ // summary:
+ // A simple test of the isTrue function
+ // description:
+ // A simple test of the isTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.DojoPatch");
+
+//Import in the code being tested.
+dojo.require("openils.DojoPatch");
+
+doh.register("openils.tests.functions.DojoPatch", [
+
+ function test_constructor(doh) {
+ // summary:
+ // Simply tests that the Constructor works, and the file has loaded
+
+ var acs = new openils.BibTemplate();
+ doh.assertTrue(acs != null);
+ },
+
+ function test_default_constructor(doh) {
+ var acs = new openils.BibTemplate();
+ doh.assertTrue(acs != null);
+ doh.assertTrue(acs.org_unit == '-');
+ doh.assertTrue(acs.sync == false);
+ doh.assertTrue(acs.nodelay == false);
+ },
+
+ function test_alwaysFalse(doh) {
+ // summary:
+ // A simple test of the alwaysFalse function
+ // description:
+ // A simple test of the alwaysFalse function
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_isTrue(doh) {
+ // summary:
+ // A simple test of the isTrue function
+ // description:
+ // A simple test of the isTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.Event");
+
+// Import in the code being tested.
+dojo.require("openils.Event");
+
+
+doh.register("openils.tests.functions.Event", [
+
+ function test_loaded(doh) {
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+
+ doh.assertTrue(openils.Event != null);
+ },
+
+ function test_parse(doh) {
+ // summary:
+ // Tests the parse function of the event
+ // description:
+ // "parse" - Parses a proposed event object. If this object is an
+ // event, a new openils.Event is returned. Otherwise,
+ // null is returned
+
+ // Test a blank object
+ var obj = {};
+ doh.assertTrue(openils.Event.parse(obj) == null);
+
+ // Test nothing
+ doh.assertTrue(openils.Event.parse() == null);
+
+ // Test something that looks like an event
+ var evt = {
+ ilsevent:"Who is John Galt?",
+ textcode:"I would tell him to shrug."
+ };
+
+ doh.assertTrue(openils.Event.parse(evt) != null);
+ },
+
+ function test_parse_and_raise(doh) {
+ // summary:
+ // Tests the parse and raise function of Event
+ // description:
+ // If the provided object is a non-success event, the
+ // event is thrown as an exception.
+
+
+ },
+
+ function test_assertFalse(doh) {
+ // summary:
+ // A simple test of the doh assertFalse function.
+ // description:
+ // A simple test of the doh assertFalse function.
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_assertTrue(doh) {
+ // summary:
+ // A simple test of the assertTrue function.
+ // description:
+ // A simple test of the assertTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.Event");
+
+//Import in the code being tested.
+dojo.require("openils.Event");
+
+
+doh.register("openils.tests.functions.Event", [
+
+ function test_loaded(doh) {
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+
+ doh.assertTrue(openils.Event != null);
+ },
+
+ function test_parse(doh) {
+ // summary:
+ // Tests the parse function of the event
+ // description:
+ // "parse" - Parses a proposed event object. If this object is an
+ // event, a new openils.Event is returned. Otherwise,
+ // null is returned
+
+ // Test a blank object
+ var obj = {};
+ doh.assertTrue(openils.Event.parse(obj) == null);
+
+ // Test nothing
+ doh.assertTrue(openils.Event.parse() == null);
+
+ // Test something that looks like an event
+ var evt = {
+ ilsevent:"Who is John Galt?",
+ textcode:"I would tell him to shrug."
+ };
+
+ doh.assertTrue(openils.Event.parse(evt) != null);
+ },
+
+ function test_parse_and_raise(doh) {
+ // summary:
+ // Tests the parse and raise function of Event
+ // description:
+ // If the provided object is a non-success event, the
+ // event is thrown as an exception.
+
+
+ },
+
+ function test_assertFalse(doh) {
+ // summary:
+ // A simple test of the doh assertFalse function.
+ // description:
+ // A simple test of the doh assertFalse function.
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_assertTrue(doh) {
+ // summary:
+ // A simple test of the assertTrue function.
+ // description:
+ // A simple test of the assertTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.FlattenerStore");
+
+// Import in the code being tested.
+dojo.require("openils.FlattenerStore");
+
+
+doh.register("openils.tests.functions.FlattenerStore", [
+
+ function test_loaded(doh) {
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+
+ doh.assertTrue(openils.FlattenerStore != null);
+ },
+
+ function test_FlattenerStoreError(doh){
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+ doh.assertTrue(openils.FlattenerStoreError != null);
+ },
+
+ function test_FlattenerStoreError_toString(doh){
+ // summary:
+ // Tests toString of FlattenerStoreError
+ // description:
+ // "openils.FlattenerStore: " + this.message
+
+ var msg = "Walden Pond";
+ var fse = new FlattenerStoreError(msg);
+
+ doh.assertTrue(fse.toString().indexOf(msg) != -1);
+ },
+
+ function test_vars(doh) {
+ // summary:
+ // Simplest test, checks all vars have been overwritten on init.
+ // description:
+ //
+
+ var testobj = "JUST A TEST";
+
+ var init = {
+ "fmClass": testobj,
+ "mapClause": testobj,
+ "sloClause": testobj,
+ "limit": -100,
+ "offset": -10,
+ "baseSort": testobj,
+ "defaultSort": testobj
+ };
+
+ var fs = new openils.FlattenerStore(init);
+
+ for(var x in Object.keys(fs))
+ doh.assertTrue(fs[x] === init[x]);
+ },
+
+ function test_getValue(doh)
+ {
+ // summary:
+ // Performs a getValue against a null
+ // description:
+ //
+
+ try {
+
+ } catch(err) {
+
+ }
+ },
+
+
+
+ /* *** Begin dojo.data.api.Read methods *** */
+
+ "getValue": function(
+ /* object */ item,
+ /* string */ attribute,
+ /* anything */ defaultValue) {
+ //console.log("getValue(" + lazy(item) + ", " + attribute + ", " + defaultValue + ")")
+ if (!this.isItem(item))
+ throw new FlattenerStoreError("getValue(): bad item " + item);
+ else if (typeof attribute != "string")
+ throw new FlattenerStoreError("getValue(): bad attribute");
+
+ var value = item[attribute];
+ return (typeof value == "undefined") ? defaultValue : value;
+ },
+
+ "getValues": function(/* object */ item, /* string */ attribute) {
+ //console.log("getValues(" + item + ", " + attribute + ")");
+ if (!this.isItem(item) || typeof attribute != "string")
+ throw new FlattenerStoreError("bad arguments");
+
+ var result = this.getValue(item, attribute, []);
+ return dojo.isArray(result) ? result : [result];
+ },
+
+ "getAttributes": function(/* object */ item) {
+ //console.log("getAttributes(" + item + ")");
+ if (!this.isItem(item))
+ throw new FlattenerStoreError("getAttributes(): bad args");
+ else
+ return this._display_attributes();
+ },
+
+ "hasAttribute": function(/* object */ item, /* string */ attribute) {
+ //console.log("hasAttribute(" + item + ", " + attribute + ")");
+ if (!this.isItem(item) || typeof attribute != "string") {
+ throw new FlattenerStoreError("hasAttribute(): bad args");
+ } else {
+ return dojo.indexOf(this._display_attributes(), attribute) > -1;
+ }
+ },
+
+ "containsValue": function(
+ /* object */ item,
+ /* string */ attribute,
+ /* anything */ value) {
+ //console.log("containsValue(" + item + ", " + attribute + ", " + value + ")");
+ if (!this.isItem(item) || typeof attribute != "string")
+ throw new FlattenerStoreError("bad data");
+ else
+ return (
+ dojo.indexOf(this.getValues(item, attribute), value) >= -1
+ );
+ },
+
+
+ function test_isItem(doh)
+ {
+ // summary:
+ // Tests to see if the thing is an item or not.
+ // description:
+ //
+
+ var testobj = "JUST A TEST";
+
+ var init = {
+ "fmClass": testobj,
+ "mapClause": ["field"],
+ "sloClause": testobj,
+ "limit": -100,
+ "offset": -10,
+ "baseSort": testobj,
+ "defaultSort": testobj
+ };
+
+ var fs = new openils.FlattenerStore(init);
+
+ doh.assertFalse(fs.isItem());
+ doh.assertFalse(fs.isItem(1));
+ doh.assertFalse(fs.isItem({}));
+ doh.assertTrue(fs.isItem({"field":"value"}));
+ },
+
+
+
+ function test_isItemLoaded(doh)
+ {
+ // summary:
+ // Tests to see if the thing is an item or not.
+ // description:
+ //
+
+ var testobj = "JUST A TEST";
+
+ var init = {
+ "fmClass": testobj,
+ "mapClause": ["field"],
+ "sloClause": testobj,
+ "limit": -100,
+ "offset": -10,
+ "baseSort": testobj,
+ "defaultSort": testobj
+ };
+
+ var fs = new openils.FlattenerStore(init);
+ var obj = {"field":"value"};
+ //fs.fmIdentifier = "field";
+ console.log("Identifier is: " + fs.fmIdentifier);
+
+ doh.assertFalse(fs.isItemLoaded(null));
+ doh.assertFalse(fs.isItemLoaded(obj));
+
+ fs._current_items = [obj];
+ doh.assertTrue(fs.isItemLoaded(obj));
+ },
+
+
+
+ "loadItem": function(/* object */ keywordArgs) {
+ if (!keywordArgs.force && this.isItemLoaded(keywordArgs.item))
+ return;
+
+ keywordArgs.identity = this.getIdentity(keywordArgs.item);
+ return this.fetchItemByIdentity(keywordArgs);
+ },
+
+ /* *** Begin dojo.data.api.Identity methods *** */
+
+ "getIdentity": function(/* object */ item) {
+ if (!this.isItem(item))
+ throw new FlattenerStoreError("not an item");
+
+ return item[this.fmIdentifier];
+ },
+
+ "getIdentityAttributes": function(/* object */ item) {
+ // console.log("getIdentityAttributes(" + item + ")");
+ return [this.fmIdentifier];
+ },
+
+
+
+ /* dojo.data.api.Write - only very partially implemented, because
+ * for FlattenerGrid, the intended client of this store, we don't
+ * need most of the methods. */
+
+ "deleteItem": function(item) {
+ //console.log("deleteItem()");
+
+ var identity = this.getIdentity(item);
+ delete this._current_items[identity]; /* safe even if missing */
+
+ this.onDelete(item);
+ },
+
+ "setValue": function(item, attribute, value) {
+ /* Silently do nothing when setValue()'s caller wants to change
+ * the identifier. They must be confused anyway. */
+ if (attribute == this.fmIdentifier)
+ return;
+
+ var old_value = dojo.clone(item[attribute]);
+
+ item[attribute] = dojo.clone(value);
+ this.onSet(item, attribute, old_value, value);
+ },
+
+ "setValues": function(item, attribute, values) {
+ console.warn("[unimplemented] setValues()"); /* unneeded */
+ },
+
+ "newItem": function(keywordArgs, parentInfo) {
+ console.warn("[unimplemented] newItem()"); /* unneeded */
+ },
+
+ "unsetAttribute": function() {
+ console.warn("[unimplemented] unsetAttribute()"); /* unneeded */
+ },
+
+ "save": function() {
+ console.warn("[unimplemented] save()"); /* unneeded */
+ },
+
+ "revert": function() {
+ console.warn("[unimplemented] revert()"); /* unneeded */
+ },
+
+ "isDirty": function() { /* I /think/ this will be ok for our purposes */
+ console.info("[stub] isDirty() will always return false");
+
+ return false;
+ },
+
+ /* dojo.data.api.Notification - Keep these no-op methods because
+ * clients will dojo.connect() to them. */
+
+ "onNew" : function(item) { /* no-op */ },
+ "onDelete" : function(item) { /* no-op */ },
+ "onSet": function(item, attr, oldval, newval) { /* no-op */ },
+
+ /* *** Classes implementing any Dojo APIs do this to list which
+ * APIs they're implementing. *** */
+
+ "getFeatures": function() {
+ return {
+ "dojo.data.api.Read": true,
+ "dojo.data.api.Identity": true,
+ "dojo.data.api.Notification": true,
+ "dojo.data.api.Write": true /* well, only partly */
+ };
+ }
+ });
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ function test_assertFalse(doh) {
+ // summary:
+ // A simple test of the doh assertFalse function.
+ // description:
+ // A simple test of the doh assertFalse function.
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_assertTrue(doh) {
+ // summary:
+ // A simple test of the assertTrue function.
+ // description:
+ // A simple test of the assertTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.FlattenerStore");
+
+// Import in the code being tested.
+dojo.require("openils.FlattenerStore");
+
+
+doh.register("openils.tests.functions.FlattenerStore", [
+
+ function test_loaded(doh) {
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+
+ doh.assertTrue(openils.FlattenerStore != null);
+ },
+
+ function test_FlattenerStoreError(doh){
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+ doh.assertTrue(openils.FlattenerStoreError != null);
+ },
+
+ function test_FlattenerStoreError_toString(doh){
+ // summary:
+ // Tests toString of FlattenerStoreError
+ // description:
+ // "openils.FlattenerStore: " + this.message
+
+ var msg = "Walden Pond";
+ var fse = new FlattenerStoreError(msg);
+
+ doh.assertTrue(fse.toString().indexOf(msg) != -1);
+ },
+
+ function test_vars(doh) {
+ // summary:
+ // Simplest test, checks all vars have been overwritten on init.
+ // description:
+ //
+
+ var testobj = "JUST A TEST";
+
+ var init = {
+ "fmClass": testobj,
+ "mapClause": testobj,
+ "sloClause": testobj,
+ "limit": -100,
+ "offset": -10,
+ "baseSort": testobj,
+ "defaultSort": testobj
+ };
+
+ var fs = new openils.FlattenerStore(init);
+
+ for(var x in Object.keys(fs))
+ doh.assertTrue(fs[x] === init[x]);
+ },
+
+ function test_getValue(doh)
+ {
+ // summary:
+ // Performs a getValue against a null
+ // description:
+ //
+
+ try {
+
+ } catch(err) {
+
+ }
+ },
+
+
+
+ /* *** Begin dojo.data.api.Read methods *** */
+
+ "getValue": function(
+ /* object */ item,
+ /* string */ attribute,
+ /* anything */ defaultValue) {
+ //console.log("getValue(" + lazy(item) + ", " + attribute + ", " + defaultValue + ")")
+ if (!this.isItem(item))
+ throw new FlattenerStoreError("getValue(): bad item " + item);
+ else if (typeof attribute != "string")
+ throw new FlattenerStoreError("getValue(): bad attribute");
+
+ var value = item[attribute];
+ return (typeof value == "undefined") ? defaultValue : value;
+ },
+
+ "getValues": function(/* object */ item, /* string */ attribute) {
+ //console.log("getValues(" + item + ", " + attribute + ")");
+ if (!this.isItem(item) || typeof attribute != "string")
+ throw new FlattenerStoreError("bad arguments");
+
+ var result = this.getValue(item, attribute, []);
+ return dojo.isArray(result) ? result : [result];
+ },
+
+ "getAttributes": function(/* object */ item) {
+ //console.log("getAttributes(" + item + ")");
+ if (!this.isItem(item))
+ throw new FlattenerStoreError("getAttributes(): bad args");
+ else
+ return this._display_attributes();
+ },
+
+ "hasAttribute": function(/* object */ item, /* string */ attribute) {
+ //console.log("hasAttribute(" + item + ", " + attribute + ")");
+ if (!this.isItem(item) || typeof attribute != "string") {
+ throw new FlattenerStoreError("hasAttribute(): bad args");
+ } else {
+ return dojo.indexOf(this._display_attributes(), attribute) > -1;
+ }
+ },
+
+ "containsValue": function(
+ /* object */ item,
+ /* string */ attribute,
+ /* anything */ value) {
+ //console.log("containsValue(" + item + ", " + attribute + ", " + value + ")");
+ if (!this.isItem(item) || typeof attribute != "string")
+ throw new FlattenerStoreError("bad data");
+ else
+ return (
+ dojo.indexOf(this.getValues(item, attribute), value) >= -1
+ );
+ },
+
+
+ function test_isItem(doh)
+ {
+ // summary:
+ // Tests to see if the thing is an item or not.
+ // description:
+ //
+
+ var testobj = "JUST A TEST";
+
+ var init = {
+ "fmClass": testobj,
+ "mapClause": ["field"],
+ "sloClause": testobj,
+ "limit": -100,
+ "offset": -10,
+ "baseSort": testobj,
+ "defaultSort": testobj
+ };
+
+ var fs = new openils.FlattenerStore(init);
+
+ doh.assertFalse(fs.isItem());
+ doh.assertFalse(fs.isItem(1));
+ doh.assertFalse(fs.isItem({}));
+ doh.assertTrue(fs.isItem({"field":"value"}));
+ },
+
+
+
+ function test_isItemLoaded(doh)
+ {
+ // summary:
+ // Tests to see if the thing is an item or not.
+ // description:
+ //
+
+ var testobj = "JUST A TEST";
+
+ var init = {
+ "fmClass": testobj,
+ "mapClause": ["field"],
+ "sloClause": testobj,
+ "limit": -100,
+ "offset": -10,
+ "baseSort": testobj,
+ "defaultSort": testobj
+ };
+
+ var fs = new openils.FlattenerStore(init);
+ var obj = {"field":"value"};
+ //fs.fmIdentifier = "field";
+ console.log(fs.fmIdentifier);
+
+ doh.assertFalse(fs.isItemLoaded(null));
+ doh.assertFalse(fs.isItemLoaded(obj));
+
+ fs._current_items = [obj];
+ doh.assertTrue(fs.isItemLoaded(obj));
+ },
+
+
+
+ "loadItem": function(/* object */ keywordArgs) {
+ if (!keywordArgs.force && this.isItemLoaded(keywordArgs.item))
+ return;
+
+ keywordArgs.identity = this.getIdentity(keywordArgs.item);
+ return this.fetchItemByIdentity(keywordArgs);
+ },
+
+ /* *** Begin dojo.data.api.Identity methods *** */
+
+ "getIdentity": function(/* object */ item) {
+ if (!this.isItem(item))
+ throw new FlattenerStoreError("not an item");
+
+ return item[this.fmIdentifier];
+ },
+
+ "getIdentityAttributes": function(/* object */ item) {
+ // console.log("getIdentityAttributes(" + item + ")");
+ return [this.fmIdentifier];
+ },
+
+ "fetchItemByIdentity": function(/* object */ keywordArgs) {
+ var callback_scope = keywordArgs.scope || dojo.global;
+ var identity = keywordArgs.identity;
+
+ if (typeof identity == "undefined")
+ throw new FlattenerStoreError(
+ "fetchItemByIdentity() needs identity in keywordArgs"
+ );
+
+ /* First of force's two implications:
+ * fetch even if already loaded. */
+ if (this._current_items[identity] && !keywordArgs.force) {
+ keywordArgs.onItem.call(
+ callback_scope, this._current_items[identity]
+ );
+
+ return;
+ }
+
+ var post_params = this._prepare_flattener_params(keywordArgs);
+
+ var process_fetch_one = dojo.hitch(
+ this, function(obj, when) {
+ if (when < this._last_fetch) /* Stale response. Discard. */
+ return;
+
+ if (dojo.isArray(obj)) {
+ if (obj.length <= 1) {
+ obj = obj.pop() || null; /* safe enough */
+ /* Second of force's two implications: call setValue
+ * ourselves. Makes a DataGrid update. */
+ if (keywordArgs.force && obj &&
+ (origitem = this._current_items[identity])) {
+ for (var prop in origitem)
+ this.setValue(origitem, prop, obj[prop]);
+ }
+ if (keywordArgs.onItem)
+ keywordArgs.onItem.call(callback_scope, obj);
+ } else {
+ var e = new FlattenerStoreError("Too many results");
+ if (keywordArgs.onError)
+ keywordArgs.onError.call(callback_scope, e);
+ else
+ throw e;
+ }
+ } else {
+ var e = new FlattenerStoreError("Bad response");
+ if (keywordArgs.onError)
+ keywordArgs.onError.call(callback_scope, e);
+ else
+ throw e;
+ }
+ }
+ );
+
+ var fetch_time = this._last_fetch = (new Date().getTime());
+
+ dojo.xhrPost({
+ "url": this._flattener_url,
+ "content": post_params,
+ "handleAs": "json",
+ "sync": false,
+ "preventCache": true,
+ "headers": {"Accept": "application/json"},
+ "load": function(obj){ process_fetch_one(obj, fetch_time); }
+ });
+ },
+
+ /* dojo.data.api.Write - only very partially implemented, because
+ * for FlattenerGrid, the intended client of this store, we don't
+ * need most of the methods. */
+
+ "deleteItem": function(item) {
+ //console.log("deleteItem()");
+
+ var identity = this.getIdentity(item);
+ delete this._current_items[identity]; /* safe even if missing */
+
+ this.onDelete(item);
+ },
+
+ "setValue": function(item, attribute, value) {
+ /* Silently do nothing when setValue()'s caller wants to change
+ * the identifier. They must be confused anyway. */
+ if (attribute == this.fmIdentifier)
+ return;
+
+ var old_value = dojo.clone(item[attribute]);
+
+ item[attribute] = dojo.clone(value);
+ this.onSet(item, attribute, old_value, value);
+ },
+
+ "setValues": function(item, attribute, values) {
+ console.warn("[unimplemented] setValues()"); /* unneeded */
+ },
+
+ "newItem": function(keywordArgs, parentInfo) {
+ console.warn("[unimplemented] newItem()"); /* unneeded */
+ },
+
+ "unsetAttribute": function() {
+ console.warn("[unimplemented] unsetAttribute()"); /* unneeded */
+ },
+
+ "save": function() {
+ console.warn("[unimplemented] save()"); /* unneeded */
+ },
+
+ "revert": function() {
+ console.warn("[unimplemented] revert()"); /* unneeded */
+ },
+
+ "isDirty": function() { /* I /think/ this will be ok for our purposes */
+ console.info("[stub] isDirty() will always return false");
+
+ return false;
+ },
+
+ /* dojo.data.api.Notification - Keep these no-op methods because
+ * clients will dojo.connect() to them. */
+
+ "onNew" : function(item) { /* no-op */ },
+ "onDelete" : function(item) { /* no-op */ },
+ "onSet": function(item, attr, oldval, newval) { /* no-op */ },
+
+ /* *** Classes implementing any Dojo APIs do this to list which
+ * APIs they're implementing. *** */
+
+ "getFeatures": function() {
+ return {
+ "dojo.data.api.Read": true,
+ "dojo.data.api.Identity": true,
+ "dojo.data.api.Notification": true,
+ "dojo.data.api.Write": true /* well, only partly */
+ };
+ }
+ });
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ function test_assertFalse(doh) {
+ // summary:
+ // A simple test of the doh assertFalse function.
+ // description:
+ // A simple test of the doh assertFalse function.
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_assertTrue(doh) {
+ // summary:
+ // A simple test of the assertTrue function.
+ // description:
+ // A simple test of the assertTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.Util");
+
+//Import in the code being tested.
+dojo.require("openils.Util");
+
+doh.register("openils.tests.functions.Util", [
+
+function test_timestampAsDateObj(doh) {
+ // summary:
+ // Tests the ability to convert timestamps to date objects.
+ // description:
+ // This functions
+ var res = openils.Util.timeStampAsDateObj("2012-06-04T12:01:02-0700");
+ var res2 = openils.Util.timeStampAsDateObj("2012-06-04T12:01:02-0800");
+
+ doh.assertTrue(res.getFullYear() == 2012);
+ doh.assertTrue(res.getMonth() == 5);
+ doh.assertTrue(res.getDate() == 4);
+ //Will fail depending on where you are, as JS translates to local
+ //time.
+ //doh.assertTrue(res.getHours() == 13);
+ doh.assertTrue(res.getMinutes() == 1);
+ doh.assertTrue(res.getSeconds() == 2);
+ doh.assertTrue(res.getHours() - res2.getHours() == -1);
+},
+
+function test_userFullName(doh) {
+ /** The full name fields
+
+ openils.Util._userFullNameFields = [
+ "prefix", "first_given_name", "second_given_name",
+ "family_name", "suffix", "alias", "usrname"
+ ];**/
+
+ var test_user = {
+ prefix: function(){return "Mr.";},
+ first_given_name: function(){return "DENT";},
+ second_given_name: function(){return "Arthur";},
+ family_name: function(){return "dent";},
+ suffix: function(){return "jr";},
+ alias: function(){return "The Sandwich Maker";},
+ usrname: function(){return "dentarthurdent";}
+ };
+
+ var names = openils.Util.userFullName(test_user);
+
+ console.log(names);
+
+ doh.assertTrue(names.indexOf(test_user.prefix()) != -1);
+ doh.assertTrue(names.indexOf(test_user.first_given_name()) != -1);
+ doh.assertTrue(names.indexOf(test_user.second_given_name()) != -1);
+ doh.assertTrue(names.indexOf(test_user.family_name()) != -1);
+ doh.assertTrue(names.indexOf(test_user.suffix()) != -1);
+ doh.assertTrue(names.indexOf(test_user.alias()) != -1);
+ doh.assertTrue(names.indexOf(test_user.usrname()) != -1);
+
+ doh.assertTrue(names.length == Object.keys(test_user).length);
+
+},
+
+
+function test_userFullNameHash(doh) {
+
+ var test_user = {
+ prefix: function(){return "Mr.";},
+ first_given_name: function(){return "DENT";},
+ second_given_name: function(){return "Arthur";},
+ family_name: function(){return "dent";},
+ suffix: function(){return "jr";},
+ alias: function(){return "The Sandwich Maker";},
+ usrname: function(){return "dentarthurdent";}
+ };
+
+ var names = openils.Util.userFullNameHash(test_user);
+
+ console.log(names);
+
+ doh.assertTrue(names.prefix == test_user.prefix());
+ doh.assertTrue(names.first_given_name == test_user.first_given_name());
+ doh.assertTrue(names.second_given_name == test_user.second_given_name());
+ doh.assertTrue(names.family_name == test_user.family_name());
+ doh.assertTrue(names.suffix == test_user.suffix());
+ doh.assertTrue(names.alias == test_user.alias());
+ doh.assertTrue(names.usrname == test_user.usrname());
+
+
+ doh.assertTrue(Object.keys(names).length == Object.keys(test_user).length);
+
+},
+
+
+function test_addOnLoad(doh) {
+ //TODO IMPLEMENT ME
+ //doh.assertTrue(false);
+},
+
+
+function test_arrayContains(doh) {
+ array = ["hello", 1, 1.0, false, 'a', [], {key: 'value'}, ['nonemptyset']];
+
+ doh.assertTrue(openils.Util.arrayContains(array, "hello"));
+ doh.assertTrue(openils.Util.arrayContains(array, 1));
+ doh.assertTrue(openils.Util.arrayContains(array, 1.0));
+ doh.assertTrue(openils.Util.arrayContains(array, false));
+ doh.assertTrue(openils.Util.arrayContains(array, 'a'));
+ doh.assertTrue(openils.Util.arrayContains(array, []));
+ //doh.assertTrue(openils.Util.arrayContains(array, {key: 'value'}));
+ //doh.assertTrue(openils.Util.arrayContains(array, ['nonemptyset']));
+
+ doh.assertFalse(openils.Util.arrayContains(array, "world"));
+},
+
+function test_selectorValue(doh) {
+ //TODO IMPLEMENT ME
+ //doh.assertTrue(false);
+},
+
+
+function test_getKeyCode(doh) {
+ var evt1 = {charCode:'a'};
+ var evt2 = {which:'a'};
+ var evt3 = {keyCode:'a'};
+
+ doh.assertTrue(openils.Util.getCharCode(null) == -1);
+ doh.assertTrue(openils.Util.getCharCode(evt1) == 'a');
+ doh.assertTrue(openils.Util.getCharCode(evt2) == 'a');
+ doh.assertTrue(openils.Util.getCharCode(evt3) == 'a');
+},
+
+
+function test_registerEnterHandler(doh) {
+ //TODO IMPLEMENT ME
+ //doh.assertTrue(false);
+},
+
+
+function test_readResponse(doh) {
+ //TODO IMPLEMENT ME
+ //doh.assertTrue(false);
+},
+
+
+function test_addCSSClass(doh) {
+ //TODO IMPLEMENT ME
+ //doh.assertTrue(false);
+},
+
+function test_removeCSSClass(doh) {
+ //TODO IMPLEMENT ME
+ //doh.assertTrue(false);
+},
+
+
+function test_objectSort(doh) {
+ var obj_list = [{
+ id: function(){return 2;},
+ name: function(){return "y";}
+ }, {
+ id: function(){return 1;},
+ name: function(){return "z";}
+ }, {
+ id: function(){return 3;},
+ name: function(){return "x";}
+ }];
+
+ var i_sorted = openils.Util.objectSort(obj_list, "id");
+ var n_sorted = openils.Util.objectSort(obj_list, "name");
+ var i_sorted_default = openils.Util.objectSort(obj_list);
+ var non_sortable = openils.Util.objectSort("Ian Malcolm with the candlestck on Isla Nubar!");
+
+ doh.assertTrue(i_sorted.length == obj_list.length);
+ doh.assertTrue(n_sorted.length == obj_list.length);
+ doh.assertTrue(i_sorted_default.length == obj_list.length);
+ doh.assertTrue(non_sortable.length == 0);
+ doh.assertTrue(non_sortable == []);
+
+ doh.assertTrue(i_sorted[1]['id']() > i_sorted[2]['id']());
+ doh.assertTrue(i_sorted[2]['id']() > i_sorted[3]['id']());
+
+ doh.assertTrue(n_sorted[1]['name']() > n_sorted[2]['name']());
+ doh.assertTrue(n_sorted[2]['name']() > n_sorted[3]['name']());
+
+ doh.assertTrue(i_sorted_default[1]['id']() > i_sorted_default[2]['id']());
+ doh.assertTrue(i_sorted_default[2]['id']() > i_sorted_default[3]['id']());
+
+},
+
+function test_isTrue(doh) {
+ //return (val && val != '0' && !(val+'').match(/^f$/i));
+ doh.assertFalse(null);
+ doh.assertFalse('0');
+ doh.assertFalse('f');
+ doh.assertTrue('false');
+ doh.assertTrue('true');
+ doh.assertTrue('t');
+ doh.assertTrue(1);
+ doh.assertTrue('T');
+ doh.assertTrue('F');
+ doh.assertFalse([]);
+},
+
+
+function test_mapList(doh) {
+ var obj_list = [{
+ id: '2',
+ name: "y"
+ }, {
+ id: '1',
+ name: "z"
+ }, {
+ id: '3',
+ name: "x"
+ }];
+ var obj_func_list = [{
+ id: function () {
+ return '2';
+ },
+ name: "y"
+ }, {
+ id: function () {
+ return '1';
+ },
+ name: "z"
+ }, {
+ id: function () {
+ return '3';
+ },
+ name: "x"
+ }];
+
+
+ var id_mapping = openils.Util.mapList(obj_list, 'id', false);
+ var id_func_mapping = openils.Util.mapList(obj_func_list, 'id', true);
+ console.log(id_mapping);
+ console.log(id_func_mapping);
+
+ doh.assertTrue(Object.keys(id_mapping).length == obj_list.length);
+ doh.assertTrue(Object.keys(id_func_mapping).length == obj_list.length);
+
+ /**doh.assertTrue(id_mapping['1'][name] == "z");
+ doh.assertTrue(id_mapping['2'][name] == "y");
+ doh.assertTrue(id_mapping['3'][name] == "x");
+
+
+ doh.assertTrue(id_func_mapping['1'][name] == "z");
+ doh.assertTrue(id_func_mapping['2'][name] == "y");
+ doh.assertTrue(id_func_mapping['3'][name] == "x");
+
+ **/
+},
+
+ function test_trimString(doh) {
+ doh.assertTrue(openils.Util.trimString(" Hello world ") == "Hello world");
+ doh.assertTrue(openils.Util.trimString("\t\tHello world ") == "Hello world");
+ doh.assertTrue(openils.Util.trimString("\f\n\r\t\vHello world") == "Hello world");
+ },
+
+ function test_intervalToSeconds(doh) {
+ doh.assertTrue(openils.Util.intervalToSeconds("3 days 6 hours") == 280800);
+ doh.assertTrue(openils.Util.intervalToSeconds("1 year 2 days") == 31708800);
+ },
+
+ function test_hide(doh) {
+ //doh.assertTrue(false);
+ //TODO fixme
+ //openils.Util.hide = function(node) {
+ },
+
+
+
+ function test_show(doh) {
+ /**openils.Util.show = function(node, displayType) {
+ if(typeof node == 'string')
+ node = dojo.byId(node);
+ displayType = displayType || 'block';
+ dojo.style(node, 'display', displayType);
+ dojo.style(node, 'visibility', 'visible');
+ };**/
+ //doh.assertTrue(false);
+ },
+
+
+ function test_toggle(doh) {
+ /**
+ openils.Util.toggle = function(node, displayType) {
+ if(typeof node == 'string')
+ node = dojo.byId(node);
+ if(dojo.style(node, 'display') == 'none')
+ openils.Util.show(node, displayType);
+ else
+ openils.Util.hide(node);
+ };**/
+ //doh.assertTrue(false);
+ },
+
+
+ function test_appendClear(doh) {
+ /**
+
+ openils.Util.appendClear = function(node, child) {
+ if(typeof node == 'string')
+ node = dojo.byId(node);
+ while(node.childNodes[0])
+ node.removeChild(node.childNodes[0]);
+ node.appendChild(child);
+ };**/
+ //doh.assertTrue(false);
+ },
+
+ function test_playAudioUrl(doh) {
+ /**
+ * Plays a sound file via URL. Only works with browsers
+ * that support HTML 5 <audio> element. E.g. Firefox 3.5
+ */
+ /**openils.Util.playAudioUrl = function(urlString) {
+ if(!urlString) return;
+ var audio = document.createElement('audio');
+ audio.setAttribute('src', urlString);
+ audio.setAttribute('autoplay', 'true');
+ document.body.appendChild(audio);
+ document.body.removeChild(audio);
+ }**/
+ //doh.assertTrue(false);
+ },
+
+ function test_objectProperties(doh) {
+ var object = {
+ dagny: "taggart",
+ john: "galt"
+ };
+
+ var props = openils.Util.objectProperties(object);
+
+ doh.assertTrue(props.length == 2);
+ },
+
+ function test_objectValues(doh) {
+ var object = {
+ dagny: "taggart",
+ john: "galt"
+ };
+
+ var vals = openils.Util.objectValues(object);
+
+ doh.assertTrue(vals.length == 2);
+
+ for (var i in vals)
+ doh.assertTrue(vals[i] == "taggart" || vals[i] == "galt");
+
+ },
+
+ function test_uniqueElements(doh) {
+ var object = {
+ dagny: "taggart",
+ james: "taggart"
+ };
+ var nodup = {
+ ford: "prefect",
+ marvin: "the paranoid"
+ };
+
+
+ doh.assertTrue(openils.Util.uniqueElements(object).length == 1);
+ doh.assertTrue(openils.Util.uniqueElements(nodup).length == 2);
+ },
+
+ function test_uniqueObjects(doh) {
+ var hc = {
+ make: function(){return "Honda";},
+ model: function(){return "Civic";}
+ };
+ var bc = {
+ make: function(){return "Buick";},
+ model: function(){return "Century";}
+ };
+ var gc = {
+ make: function(){return "Google";},
+ model: function(){return "Car";}
+ };
+ var hp = {
+ make: function(){return "Honda";},
+ model: function(){return "Pilot";}
+ };
+ var bj = {
+ make: function(){return "Bantam";},
+ model: function(){return "Jeep";}
+ };
+ var jj = {
+ make: function(){return "Jeep";},
+ model: function(){return "Jeep";}
+ };
+
+ var objectList = [hc, bc, gc, hp, bj, jj];
+
+ var unique_makes = openils.Util.uniqueObjects(objectList, "make");
+ var unique_models = openils.Util.uniqueObjects(objectList, "model");
+
+ doh.assertTrue(unique_makes.length == objectList.length - 1);
+ doh.assertTrue(unique_models.length == objectList.length - 1);
+
+ },
+
+ function test_hilightNode(doh) {
+ /**
+ * Highlight instances of each pattern in the given DOM node
+ * Inspired by the jquery plugin
+ * http://johannburkard.de/blog/programming/javascript/highlight-javascript-text-higlighting-jquery-plugin.html
+
+ openils.Util.hilightNode = function(node, patterns, args) {
+
+ args = args ||{};
+ var hclass = args.classname || 'oils-highlight';
+
+ function _hilightNode(node, pat) {
+
+ if(node.nodeType == 3) {
+
+ pat = pat.toUpperCase();
+ var text = node.data.toUpperCase();
+ var pos = -1;
+
+ // find each instance of pat in the current node
+ while( (pos = text.indexOf(pat, pos + 1)) >= 0 ) {
+
+ var wrapper = dojo.create('span', {className : hclass});
+ var midnode = node.splitText(pos);
+ midnode.splitText(pat.length);
+ wrapper.appendChild(midnode.cloneNode(true));
+ midnode.parentNode.replaceChild(wrapper, midnode);
+ }
+
+ } else if(node.nodeType == 1 && node.childNodes[0]) {
+
+ // not a text node? have you checked the children?
+ dojo.forEach(
+ node.childNodes,
+ function(child) { _hilightNode(child, pat); }
+ );
+ }
+ }
+
+ // descend the tree for each pattern, since nodes are changed during highlighting
+ dojo.forEach(patterns, function(pat) { _hilightNode(node, pat); });
+ };*/
+
+ //doh.assertTrue(false);
+ },
+
+ function test_printHTMLString(doh) {
+ var def = new doh.Deferred();
+
+ openils.Util.printHtmlString("<h1>Hello, world!</h1>", function () {
+ def.callback(true);
+ });
+
+ return def;
+ },
+
+ function test_alwaysFalse(doh) {
+ // summary:
+ // A simple test of the alwaysFalse function
+ // description:
+ // A simple test of the alwaysFalse function
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_isTrue(doh) {
+ // summary:
+ // A simple test of the isTrue function
+ // description:
+ // A simple test of the isTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.CopyLocation");
+
+//Import in the code being tested.
+dojo.require("openils.CopyLocation");
+
+
+doh.register("openils.tests.functions.CopyLocation", [
+
+ function test_loaded(doh) {
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+
+ doh.assertTrue(openils.CopyLocation.createStore != null);
+ doh.assertTrue(openils.CopyLocation.retrieve != null);
+ },
+
+ function test_assertFalse(doh) {
+ // summary:
+ // A simple test of the doh assertFalse function.
+ // description:
+ // A simple test of the doh assertFalse function.
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_assertTrue(doh) {
+ // summary:
+ // A simple test of the assertTrue function.
+ // description:
+ // A simple test of the assertTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.editors");
+
+//Import in the code being tested.
+dojo.require("openils.editors");
+
+
+doh.register("openils.tests.functions.editors", [
+
+ function test_loaded(doh) {
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+
+ doh.assertTrue(openils.editors.NumberSpinner != null);
+ doh.assertTrue(openils.editors.FundSelectEditor != null);
+ doh.assertTrue(openils.editors.ProviderSelectEditor != null);
+ doh.assertTrue(openils.editors.OrgUnitSelectEditor != null);
+ doh.assertTrue(openils.editors.CopyLocationSelectEditor != null);
+ },
+
+ function test_assertFalse(doh) {
+ // summary:
+ // A simple test of the doh assertFalse function.
+ // description:
+ // A simple test of the doh assertFalse function.
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_assertTrue(doh) {
+ // summary:
+ // A simple test of the assertTrue function.
+ // description:
+ // A simple test of the assertTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.functions.editors");
+
+//Import in the code being tested.
+dojo.require("openils.editors");
+
+
+doh.register("openils.tests.functions.editors", [
+
+ function test_loaded(doh) {
+ // summary:
+ // Simplest test, fail on not loading.
+ // description:
+ // only checks that the functions are there, not that they work.
+
+ doh.assertTrue(openils.CopyLocation.createStore != null);
+ doh.assertTrue(openils.CopyLocation.retrieve != null);
+ },
+
+ function test_assertFalse(doh) {
+ // summary:
+ // A simple test of the doh assertFalse function.
+ // description:
+ // A simple test of the doh assertFalse function.
+ doh.assertFalse(false);
+ doh.assertFalse(!true);
+ doh.assertFalse(null);
+ doh.assertFalse(0);
+ },
+
+ function test_assertTrue(doh) {
+ // summary:
+ // A simple test of the assertTrue function.
+ // description:
+ // A simple test of the assertTrue function with multiple permutations of
+ // calling it.
+ doh.assertTrue(true);
+ doh.assertTrue(!false);
+ doh.assertTrue({});
+ doh.assertTrue(!null);
+ doh.assertTrue(!0);
+ }
+]);
--- /dev/null
+dojo.provide("openils.tests.module");
+//This file loads in all the test definitions.
+
+try{
+ //Load in the functions tests.
+ dojo.require("openils.tests.functions.Util");
+ dojo.require("openils.tests.functions.CGI");
+ dojo.require("openils.tests.functions.Util");
+ dojo.require("openils.tests.functions.BibTemplate");
+ dojo.require("openils.tests.functions.editors");
+ dojo.require("openils.tests.functions.AutoSuggestStore");
+ dojo.require("openils.tests.functions.AuthorityControlSet");
+ dojo.require("openils.tests.functions.Event");
+ dojo.require("openils.tests.functions.CopyLocation");
+ dojo.require("openils.tests.functions.FlattenerStore");
+ dojo.require("openils.tests.functions.DojoPatch");
+
+ //Load in the widget tests.
+ //dojo.require("demo.doh.tests.widgets.DemoWidget");
+}catch(e){
+ doh.debug(e);
+}
--- /dev/null
+dojo.provide("openils.tests.module");");
+dojo.require("openils.tests.functions//This file loads in all the test definitions. ");
+dojo.require("openils.tests.functions");
+dojo.require("openils.tests.functionstry{");
+dojo.require("openils.tests.functions //Load in the functions tests.");
+dojo.require("openils.tests.functions dojo.require("openils.tests.functions.Util");");
+dojo.require("openils.tests.functions dojo.require("openils.");
+dojo.require("openils.tests.functions ");
+dojo.require("openils.tests.functionsCGI");
+dojo.require("openils.tests.functionsUtil");
+dojo.require("openils.tests.functionsBibTemplate");
+dojo.require("openils.tests.functionseditors");
+dojo.require("openils.tests.functionsAutoSuggestStore");
+dojo.require("openils.tests.functionsAuthorityControlSet");
+dojo.require("openils.tests.functionsEvent");
+dojo.require("openils.tests.functionsCopyLocation");
+dojo.require("openils.tests.functionsFlattenerStore");
+dojo.require("openils.tests.functionsDojoPatch");
+dojo.require("openils.tests.functions");
+dojo.require("openils.tests.functions //Load in the widget tests.");
+dojo.require("openils.tests.functions //dojo.require("demo.doh.tests.widgets.DemoWidget");");
+dojo.require("openils.tests.functions}catch(e){");
+dojo.require("openils.tests.functions doh.debug(e);");
+dojo.require("openils.tests.functions}
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>demo.doh Unit Test Runner</title>
+ <meta http-equiv="REFRESH"
+content="0;url=/js/util/doh/runner.html?testModule=dojo.openils.tests.module">
+ </head>
+ <body>
+ Redirecting to D.O.H runner.
+ </body>
+</html>
--- /dev/null
+dojo.provide("demo.doh.tests.module");
+//This file loads in all the test definitions.
+
+try{
+ //Load in the demoFunctions module test.
+ dojo.require("demo.doh.tests.functions.demoFunctions");
+ //Load in the widget tests.
+ dojo.require("demo.doh.tests.widgets.DemoWidget");
+}catch(e){
+ doh.debug(e);
+}
--- /dev/null
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+ <head>
+ <title>demo.doh Unit Test Runner</title>
+ <meta http-equiv="REFRESH"
+content="0;url=/js/util/doh/runner.html?testModule=demo.doh.tests.module">
+ </head>
+ <body>
+ Redirecting to D.O.H runner.
+ </body>
+</html>
-dojo.require('dijit.Dialog');
-dojo.require('dojo.cookie');
-dojo.require('fieldmapper.AutoIDL'); // make conditional. TT variable sets JS var to enable/disable?
-dojo.require('openils.User');
-dojo.require('openils.CGI');
-dojo.require('openils.Event');
-dojo.require('openils.Util');
-dojo.require('openils.XUL');
-
-var cgi = new openils.CGI();
-
-function oilsSetupUser() {
- var authtoken = cgi.param('ses') || dojo.cookie('ses');
- var workstation = cgi.param('ws') || dojo.cookie('ws');
- var user;
- var ses_user;
-
- openils.User.user = null;
- openils.User.authtoken = null;
- openils.User.workstation = null;
-
- if(openils.XUL.isXUL()) {
- stash = openils.XUL.getStash();
- authtoken = stash.session.key
- ses_user = stash.list.au[0];
+require([
+ "dijit/Dialog",
+ "dojo/cookie",
+ "fieldmapper/AutoIDL", // make conditional. TT variable sets JS var to enable/disable?
+ "openils/User",
+ "openils/CGI",
+ "openils/Event",
+ "openils/Util",
+ "openils/XUL"
+ ],
+function(dijit_Dialog,
+ dojo_cookie,
+ fieldmapper_AutoIDL,
+ openils_User,
+ openils_CGI,
+ openils_Event,
+ openils_Util,
+ openils_XUL){
+
+ var cgi = new openils_CGI();
+
+ function oilsSetupUser() {
+ var authtoken = cgi.param('ses') || dojo_cookie('ses');
+ var workstation = cgi.param('ws') || dojo_cookie('ws');
+ var user;
+ var ses_user;
+
+ openils_User.user = null;
+ openils_User.authtoken = null;
+ openils_User.workstation = null;
+
+ if(openils_XUL.isXUL()) {
+ stash = openils_XUL.getStash();
+ authtoken = stash.session.key
+ ses_user = stash.list.au[0];
+ }
+
+ if(authtoken) {
+ user = new openils_User();
+ delete user.sessionCache[authtoken];
+ user.authtoken = authtoken;
+ if(ses_user) {
+ user.user = ses_user;
+ user.sessionCache[authtoken] = ses_user;
+ }
+ user.user = user.getBySession();
+ }
+
+ if(!authtoken || openils_Event.parse(user.user)) {
+
+ authtoken = oilsLoginFromCookies();
+
+ if(!authtoken) {
+
+ dojo_cookie('ses', null, {expires:-1, path:'/'}); // remove the cookie
+
+ dojo.addOnLoad(function(){
+ if(openils_XUL.isXUL()) {
+ // let XUL handle the login dialog
+ dump('getNewSession in base.js\n');
+ openils_XUL.getNewSession( function() { location.href = location.href } );
+ } else {
+ // in web-only mode, use the dojo login dialog
+ oilsLoginDialog.show();
+ var func = function(){ oilsDoLogin(); };
+ openils_Util.registerEnterHandler(dojo.byId('oils-login-username'), func);
+ openils_Util.registerEnterHandler(dojo.byId('oils-login-password'), func);
+ dojo.byId('oils-login-workstation').innerHTML = workstation || '';
+ }
+ });
+ return null;
+ }
+ }
+
+ dojo_cookie('ses', authtoken, {path:'/'});
+ openils_User.authtoken = authtoken;
+ openils_User.workstation = workstation;
+ return authtoken;
}
+
+ // pulls username / password and optional workstation from cgi params or cookies
+ function oilsLoginFromCookies() {
+
+ var username = cgi.param('username') || dojo_cookie('username');
+ var password = cgi.param('password') || dojo_cookie('password');
+ var workstation = cgi.param('ws') || dojo_cookie('ws');
+
+ if(username && password) {
+
+ var user = new openils_User();
+ var args = {
+ username : username,
+ passwd : password,
+ type : 'staff'
+ };
+
+ if(workstation)
+ args.workstation = workstation;
+
+ if(user.login(args)) {
+ // fetches the login session and sets the global vars
+ user = new openils_User({authtoken : user.authtoken});
+ return (user && !openils_Event.parse(user.user)) ? user.authtoken : null;
+ }
+ }
+
+ return null;
+ }
+
+ function oilsDoLogin() {
+ openils_Util.hide('oils-login-failed');
+ var workstation = cgi.param('ws') || dojo_cookie('ws');
+ var user = new openils_User();
+ var args = {
+ username: dojo.byId('oils-login-username').value,
+ passwd: dojo.byId('oils-login-password').value,
+ type: 'staff', // hardcode for now
+ };
+ if(workstation)
+ args.workstation = workstation;
+
+ if(user.login(args)) {
+ dojo_cookie('ses', user.authtoken, {path : '/'});
+ location.href = location.href;
+ } else {
+ openils_Util.show('oils-login-failed');
+ }
+
+ return false;
+ }
+
+ oilsSetupUser();
+
+
- if(authtoken) {
- user = new openils.User();
- delete user.sessionCache[authtoken];
- user.authtoken = authtoken;
- if(ses_user) {
- user.user = ses_user;
- user.sessionCache[authtoken] = ses_user;
- }
- user.user = user.getBySession();
- }
-
- if(!authtoken || openils.Event.parse(user.user)) {
-
- authtoken = oilsLoginFromCookies();
-
- if(!authtoken) {
-
- dojo.cookie('ses', null, {expires:-1, path:'/'}); // remove the cookie
-
- dojo.addOnLoad(function(){
- if(openils.XUL.isXUL()) {
- // let XUL handle the login dialog
- dump('getNewSession in base.js\n');
- openils.XUL.getNewSession( function() { location.href = location.href } );
- } else {
- // in web-only mode, use the dojo login dialog
- oilsLoginDialog.show();
- var func = function(){ oilsDoLogin(); };
- openils.Util.registerEnterHandler(dojo.byId('oils-login-username'), func);
- openils.Util.registerEnterHandler(dojo.byId('oils-login-password'), func);
- dojo.byId('oils-login-workstation').innerHTML = workstation || '';
- }
- });
- return null;
- }
- }
-
- dojo.cookie('ses', authtoken, {path:'/'});
- openils.User.authtoken = authtoken;
- openils.User.workstation = workstation;
- return authtoken;
-}
-
-// pulls username / password and optional workstation from cgi params or cookies
-function oilsLoginFromCookies() {
-
- var username = cgi.param('username') || dojo.cookie('username');
- var password = cgi.param('password') || dojo.cookie('password');
- var workstation = cgi.param('ws') || dojo.cookie('ws');
-
- if(username && password) {
-
- var user = new openils.User();
- var args = {
- username : username,
- passwd : password,
- type : 'staff'
- };
-
- if(workstation)
- args.workstation = workstation;
-
- if(user.login(args)) {
- // fetches the login session and sets the global vars
- user = new openils.User({authtoken : user.authtoken});
- return (user && !openils.Event.parse(user.user)) ? user.authtoken : null;
- }
- }
-
- return null;
-}
-
-function oilsDoLogin() {
- openils.Util.hide('oils-login-failed');
- var workstation = cgi.param('ws') || dojo.cookie('ws');
- var user = new openils.User();
- var args = {
- username: dojo.byId('oils-login-username').value,
- passwd: dojo.byId('oils-login-password').value,
- type: 'staff', // hardcode for now
- };
- if(workstation)
- args.workstation = workstation;
-
- if(user.login(args)) {
- dojo.cookie('ses', user.authtoken, {path : '/'});
- location.href = location.href;
- } else {
- openils.Util.show('oils-login-failed');
- }
-
- return false;
-}
-
-oilsSetupUser();
-
+});
\ No newline at end of file
-dojo.require("dojox.encoding.base64");
+require([
+ "dojox/encoding/base64"
+ ],
+function(dojox_encoding_base64){
+
+ function base64Encode(o) {
+ return dojox_encoding_base64.encode(
+ js2JSON(o).split("").map(function(c) { return c.charCodeAt(0); })
+ );
+ }
+
+ function base64Decode(s) {
+ return JSON2js(
+ dojox_encoding_base64.decode(s).map(
+ function(b) { return String.fromCharCode(b); }
+ ).join("")
+ );
+ }
+
-function base64Encode(o) {
- return dojox.encoding.base64.encode(
- js2JSON(o).split("").map(function(c) { return c.charCodeAt(0); })
- );
-}
-
-function base64Decode(s) {
- return JSON2js(
- dojox.encoding.base64.decode(s).map(
- function(b) { return String.fromCharCode(b); }
- ).join("")
- );
-}
+});
\ No newline at end of file
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require('dijit.layout.SplitContainer');
-dojo.require('dijit.Dialog');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.form.Button');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dojo.date.locale');
-dojo.require('dojo.date.stamp');
-
-
-dojo.require('openils.User');
-dojo.require('openils.acq.Fund');
-dojo.require('openils.acq.Lineitem');
-dojo.require('openils.acq.Provider');
-dojo.require('openils.widget.FundSelector');
-dojo.require('openils.editors');
-dojo.require('openils.Event');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('fieldmapper.OrgUtils');
-
-/* put all the accessors, etc. into a local object for namespacing */
-var JUBGrid = {
- jubGrid : null,
- lineitems : [], // full list of lineitem objects to display
- getLi : function(id) {
- // given an ID, returns the lineitem object from the list
- for(var i in JUBGrid.lineitems) {
- var li = JUBGrid.lineitems[i];
- if(li.id() == id)
- return li;
- }
- },
-
- _getMARCAttr : function(rowIndex, attr) {
- var data = JUBGrid.jubGrid.getItem(rowIndex);
- if (!data) return '';
- return new openils.acq.Lineitem(
- {lineitem:JUBGrid.getLi(data.id)}).findAttr(attr, 'lineitem_marc_attr_definition')
- },
- getJUBTitle : function(rowIndex) {
- return JUBGrid._getMARCAttr(rowIndex, 'title');
- },
- getJUBAuthor : function(rowIndex) {
- return JUBGrid._getMARCAttr(rowIndex, 'author');
- },
- getJUBIsbn : function(rowIndex) {
- return JUBGrid._getMARCAttr(rowIndex, 'isbn');
- },
- getJUBActualPrice : function(rowIndex) {
- var data = JUBGrid.jubGrid.getItem(rowIndex);
- if (!data) return '';
- var price = new openils.acq.Lineitem(
- {lineitem:JUBGrid.getLi(data.id)}).getActualPrice();
- if(price) return price.price;
- return ''
- },
- getJUBEstimatedPrice : function(rowIndex) {
- var data = JUBGrid.jubGrid.getItem(rowIndex);
- if (!data) return '';
- var price = new openils.acq.Lineitem(
- {lineitem:JUBGrid.getLi(data.id)}).getEstimatedPrice();
- if(price) return price.price;
- return ''
- },
- getJUBPubdate : function(rowIndex) {
- return JUBGrid._getMARCAttr(rowIndex, 'pubdate');
- },
- getProvider : function(rowIndex) {
- data = JUBGrid.jubGrid.getItem(rowIndex);
- if(!data || !data.provider) return;
- return openils.acq.Provider.retrieve(data.provider).code();
- },
- getRecvTime : function(rowIndex) {
- var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
- if (!(data && data.recv_time)) return '';
- var date = dojo.date.stamp.fromISOString(data.recv_time);
- return dojo.date.locale.format(date, {formatLength:'medium'});
- },
- getCopyLocation : function(rowIndex) {
- var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
- if(!data || !data.location) return '';
- return openils.CopyLocation.retrieve(data.location).name();
- },
- getLIDFundName : function(rowIndex) {
- var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
- if (!data || !data.fund) return;
- try {
- return openils.acq.Fund.retrieve(data.fund).name();
- } catch (evt) {
- return data.fund;
- }
- },
- getLIDFundCode : function(rowIndex) {
- var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
- if (!data || !data.fund) return;
- try {
- return openils.acq.Fund.retrieve(data.fund).code();
- } catch (evt) {
- return data.fund;
- }
- },
- getLIDLibName : function(rowIndex) {
- var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
- if (!data || !data.owning_lib) return;
- return fieldmapper.aou.findOrgUnit(data.owning_lib).shortname();
- },
-
- gridDataChanged : function(newVal, rowIdx, cellIdx) {
- // cellIdx == -1 if you are editing a column that
- // is not represented in the data model. Khaaaaaaan!!!
- },
-
- populate : function(gridWidget, model, lineitems) {
- for (var i in lineitems) {
- JUBGrid.lineitems[lineitems[i].id()] = lineitems[i];
- }
- JUBGrid.jubGrid = gridWidget;
- //JUBGrid.jubGrid.setModel(model);
- if(JUBGrid.showDetails) {
- dojo.connect(gridWidget, "onRowClick",
- function(evt) {
- var jub = JubGrid.jubGrid.getItem(evt.rowIndex);
- var grid;
-
- JUBGrid.jubDetailGrid.lineitemID = jub.id;
-
- //if (jub.state == "approved") {
- if (false) { // need finer grained control here
- grid = JUBGrid.jubDetailGridLayoutReadOnly;
- } else {
- grid = JUBGrid.jubDetailGridLayout;
- }
- openils.acq.Lineitem.loadLIDGrid(
- JUBGrid.jubDetailGrid,
- JUBGrid.jubGrid.getItem(evt.rowIndex).id, grid);
- }
- );
- }
- // capture changes to lineitems
- dojo.connect(JUBGrid.jubGrid.store, "onSet", JUBGrid.onJUBSet);
- gridWidget.update();
- },
-
- approveJUB: function(evt) {
- var list = [];
- var selected = JUBGrid.jubGrid.selection.getSelected();
- for (var idx = 0; idx < selected.length; idx++) {
- var rowIdx = selected[idx];
- JUBGrid.approveSingleJUB(JUBGrid.jubGrid.getItem(rowIdx));
- }
- },
-
- approveSingleJUB: function(jub) {
- var li = new openils.acq.Lineitem({lineitem:JUBGrid.getLi(jub.id)});
- var approveStore = function(evt) {
- if (evt) {
- // something bad happened
- console.log("jubgrid.js: approveJUB: error:");
- console.dir(evt);
- alert("Error: "+evt.desc);
- } else {
- var approveACQLI = function(jub, rq) {
- JUBGrid.jubGrid.model.store.setValue(jub, "state", "approved");
- JUBGrid.jubGrid.model.refresh();
- JUBGrid.jubGrid.update();
- // Reload lineitem details, read-only
- //openils.acq.Lineitem.loadLIDGrid(JUBGrid.jubDetailGrid, li.id(), JUBGrid.jubDetailGridLayout);
- //JUBGrid.jubDetailGridLayoutReadOnly);
- };
- JUBGrid.jubGrid.model.store.fetch({query:{id:jub.id}, onItem: approveACQLI});
- }
- };
-
- li.approve(approveStore);
- },
-
-
- removeSelectedJUBs: function(evt) {
-
- function deleteList(list, idx, oncomplete) {
- if(idx >= list.length)
- return oncomplete();
- fieldmapper.standardRequest([
- 'open-ils.acq',
- 'open-ils.acq.lineitem.delete'],
- { async: true,
- params: [openils.User.authtoken, list[idx].id()],
- oncomplete: function(r) {
- var res = r.recv().content();
- if(openils.Event.parse(res))
- alert(openils.Event.parse(res));
- deleteList(list, ++idx, oncomplete);
- }
- }
- );
- }
-
- var lineitems = JUBGrid.lineitems;
- var deleteMe = [];
- var keepMe = [];
- var selected = JUBGrid.jubGrid.selection.getSelected();
-
- for(var id in lineitems) {
- var deleted = false;
- for(var i = 0; i < selected.length; i++) {
- var rowIdx = selected[i];
- var jubid = JUBGrid.jubGrid.getItem(rowIdx).id;
- if(jubid == id) {
- if (lineitems[id].state() == 'new') {
- deleteMe.push(lineitems[id]);
- deleted = true;
- } else {
- alert("Can not delete line item "+id+
- ": item is "+lineitems[id].state());
- }
- }
- }
- if(!deleted)
- keepMe[id] = lineitems[id];
- }
-
- JUBGrid.lineitems = keepMe;
- deleteList(deleteMe, 0, function(){
- JUBGrid.jubGrid.store = new dojo.data.ItemFileReadStore({data:jub.toStoreData(keepMe)});
- });
- },
-
- deleteLID: function(evt) {
- var list =[];
- var selected = JUBGrid.jubDetailGrid.selection.getSelected();
- for (var idx = 0; idx < selected.length; idx++) {
- var rowIdx = selected[idx];
- var lid = JUBGrid.jubDetailGrid.getItem(rowIdx);
- var deleteFromStore = function (evt) {
-
- if (evt) {
- // something bad happened
- alert("Error: "+evt.desc);
- } else {
- var deleteItem = function(item, rq) {
- JUBGrid.jubDetailGrid.store.deleteItem(item);
+require([
+ "dojo/data/ItemFileReadStore",
+ "dijit/layout/SplitContainer",
+ "dijit/Dialog",
+ "dijit/form/FilteringSelect",
+ "dijit/form/Button",
+ "dojox/grid/cells/dijit",
+ "dojo/data/ItemFileWriteStore",
+ "dojox/grid/DataGrid",
+ "dojo/date/locale",
+ "dojo/date/stamp",
+ "openils/User",
+ "openils/acq/Fund",
+ "openils/acq/Lineitem",
+ "openils/acq/Provider",
+ "openils/widget/FundSelector",
+ "openils/editors",
+ "openils/Event",
+ "openils/widget/OrgUnitFilteringSelect",
+ "fieldmapper/OrgUtils"
+ ],
+function(dojo_data_ItemFileReadStore,
+ dijit_layout_SplitContainer,
+ dijit_Dialog,
+ dijit_form_FilteringSelect,
+ dijit_form_Button,
+ dojox_grid_cells_dijit,
+ dojo_data_ItemFileWriteStore,
+ dojox_grid_DataGrid,
+ dojo_date_locale,
+ dojo_date_stamp,
+ openils_User,
+ openils_acq_Fund,
+ openils_acq_Lineitem,
+ openils_acq_Provider,
+ openils_widget_FundSelector,
+ openils_editors,
+ openils_Event,
+ openils_widget_OrgUnitFilteringSelect,
+ fieldmapper_OrgUtils){
+
+
+
+ /* put all the accessors, etc. into a local object for namespacing */
+ var JUBGrid = {
+ jubGrid : null,
+ lineitems : [], // full list of lineitem objects to display
+ getLi : function(id) {
+ // given an ID, returns the lineitem object from the list
+ for(var i in JUBGrid.lineitems) {
+ var li = JUBGrid.lineitems[i];
+ if(li.id() == id)
+ return li;
+ }
+ },
+
+ _getMARCAttr : function(rowIndex, attr) {
+ var data = JUBGrid.jubGrid.getItem(rowIndex);
+ if (!data) return '';
+ return new openils_acq_Lineitem(
+ {lineitem:JUBGrid.getLi(data.id)}).findAttr(attr, 'lineitem_marc_attr_definition')
+ },
+ getJUBTitle : function(rowIndex) {
+ return JUBGrid._getMARCAttr(rowIndex, 'title');
+ },
+ getJUBAuthor : function(rowIndex) {
+ return JUBGrid._getMARCAttr(rowIndex, 'author');
+ },
+ getJUBIsbn : function(rowIndex) {
+ return JUBGrid._getMARCAttr(rowIndex, 'isbn');
+ },
+ getJUBActualPrice : function(rowIndex) {
+ var data = JUBGrid.jubGrid.getItem(rowIndex);
+ if (!data) return '';
+ var price = new openils_acq_Lineitem(
+ {lineitem:JUBGrid.getLi(data.id)}).getActualPrice();
+ if(price) return price.price;
+ return ''
+ },
+ getJUBEstimatedPrice : function(rowIndex) {
+ var data = JUBGrid.jubGrid.getItem(rowIndex);
+ if (!data) return '';
+ var price = new openils_acq_Lineitem(
+ {lineitem:JUBGrid.getLi(data.id)}).getEstimatedPrice();
+ if(price) return price.price;
+ return ''
+ },
+ getJUBPubdate : function(rowIndex) {
+ return JUBGrid._getMARCAttr(rowIndex, 'pubdate');
+ },
+ getProvider : function(rowIndex) {
+ data = JUBGrid.jubGrid.getItem(rowIndex);
+ if(!data || !data.provider) return;
+ return openils_acq_Provider.retrieve(data.provider).code();
+ },
+ getRecvTime : function(rowIndex) {
+ var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
+ if (!(data && data.recv_time)) return '';
+ var date = dojo_date_stamp.fromISOString(data.recv_time);
+ return dojo_date_locale.format(date, {formatLength:'medium'});
+ },
+ getCopyLocation : function(rowIndex) {
+ var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
+ if(!data || !data.location) return '';
+ return openils.CopyLocation.retrieve(data.location).name();
+ },
+ getLIDFundName : function(rowIndex) {
+ var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
+ if (!data || !data.fund) return;
+ try {
+ return openils_acq_Fund.retrieve(data.fund).name();
+ } catch (evt) {
+ return data.fund;
+ }
+ },
+ getLIDFundCode : function(rowIndex) {
+ var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
+ if (!data || !data.fund) return;
+ try {
+ return openils_acq_Fund.retrieve(data.fund).code();
+ } catch (evt) {
+ return data.fund;
+ }
+ },
+ getLIDLibName : function(rowIndex) {
+ var data = JUBGrid.jubDetailGrid.getItem(rowIndex);
+ if (!data || !data.owning_lib) return;
+ return fieldmapper.aou.findOrgUnit(data.owning_lib).shortname();
+ },
+
+ gridDataChanged : function(newVal, rowIdx, cellIdx) {
+ // cellIdx == -1 if you are editing a column that
+ // is not represented in the data model. Khaaaaaaan!!!
+ },
+
+ populate : function(gridWidget, model, lineitems) {
+ for (var i in lineitems) {
+ JUBGrid.lineitems[lineitems[i].id()] = lineitems[i];
+ }
+ JUBGrid.jubGrid = gridWidget;
+ //JUBGrid.jubGrid.setModel(model);
+ if(JUBGrid.showDetails) {
+ dojo.connect(gridWidget, "onRowClick",
+ function(evt) {
+ var jub = JubGrid.jubGrid.getItem(evt.rowIndex);
+ var grid;
+
+ JUBGrid.jubDetailGrid.lineitemID = jub.id;
+
+ //if (jub.state == "approved") {
+ if (false) { // need finer grained control here
+ grid = JUBGrid.jubDetailGridLayoutReadOnly;
+ } else {
+ grid = JUBGrid.jubDetailGridLayout;
+ }
+ openils_acq_Lineitem.loadLIDGrid(
+ JUBGrid.jubDetailGrid,
+ JUBGrid.jubGrid.getItem(evt.rowIndex).id, grid);
+ }
+ );
+ }
+ // capture changes to lineitems
+ dojo.connect(JUBGrid.jubGrid.store, "onSet", JUBGrid.onJUBSet);
+ gridWidget.update();
+ },
+
+ approveJUB: function(evt) {
+ var list = [];
+ var selected = JUBGrid.jubGrid.selection.getSelected();
+ for (var idx = 0; idx < selected.length; idx++) {
+ var rowIdx = selected[idx];
+ JUBGrid.approveSingleJUB(JUBGrid.jubGrid.getItem(rowIdx));
+ }
+ },
+
+ approveSingleJUB: function(jub) {
+ var li = new openils_acq_Lineitem({lineitem:JUBGrid.getLi(jub.id)});
+ var approveStore = function(evt) {
+ if (evt) {
+ // something bad happened
+ console.log("jubgrid.js: approveJUB: error:");
+ console.dir(evt);
+ alert("Error: "+evt.desc);
+ } else {
+ var approveACQLI = function(jub, rq) {
+ JUBGrid.jubGrid.model.store.setValue(jub, "state", "approved");
+ JUBGrid.jubGrid.model.refresh();
+ JUBGrid.jubGrid.update();
+ // Reload lineitem details, read-only
+ //openils_acq_Lineitem.loadLIDGrid(JUBGrid.jubDetailGrid, li.id(), JUBGrid.jubDetailGridLayout);
+ //JUBGrid.jubDetailGridLayoutReadOnly);
+ };
+ JUBGrid.jubGrid.model.store.fetch({query:{id:jub.id}, onItem: approveACQLI});
+ }
+ };
+
+ li.approve(approveStore);
+ },
+
+
+ removeSelectedJUBs: function(evt) {
+
+ function deleteList(list, idx, oncomplete) {
+ if(idx >= list.length)
+ return oncomplete();
+ fieldmapper.standardRequest([
+ 'open-ils.acq',
+ 'open-ils.acq.lineitem.delete'],
+ { async: true,
+ params: [openils_User.authtoken, list[idx].id()],
+ oncomplete: function(r) {
+ var res = r.recv().content();
+ if(openils_Event.parse(res))
+ alert(openils_Event.parse(res));
+ deleteList(list, ++idx, oncomplete);
+ }
+ }
+ );
+ }
+
+ var lineitems = JUBGrid.lineitems;
+ var deleteMe = [];
+ var keepMe = [];
+ var selected = JUBGrid.jubGrid.selection.getSelected();
+
+ for(var id in lineitems) {
+ var deleted = false;
+ for(var i = 0; i < selected.length; i++) {
+ var rowIdx = selected[i];
+ var jubid = JUBGrid.jubGrid.getItem(rowIdx).id;
+ if(jubid == id) {
+ if (lineitems[id].state() == 'new') {
+ deleteMe.push(lineitems[id]);
+ deleted = true;
+ } else {
+ alert("Can not delete line item "+id+
+ ": item is "+lineitems[id].state());
+ }
+ }
+ }
+ if(!deleted)
+ keepMe[id] = lineitems[id];
+ }
+
+ JUBGrid.lineitems = keepMe;
+ deleteList(deleteMe, 0, function(){
+ JUBGrid.jubGrid.store = new dojo_data_ItemFileReadStore({data:jub.toStoreData(keepMe)});
+ });
+ },
+
+ deleteLID: function(evt) {
+ var list =[];
+ var selected = JUBGrid.jubDetailGrid.selection.getSelected();
+ for (var idx = 0; idx < selected.length; idx++) {
+ var rowIdx = selected[idx];
+ var lid = JUBGrid.jubDetailGrid.getItem(rowIdx);
+ var deleteFromStore = function (evt) {
+
+ if (evt) {
+ // something bad happened
+ alert("Error: "+evt.desc);
+ } else {
+ var deleteItem = function(item, rq) {
+ JUBGrid.jubDetailGrid.store.deleteItem(item);
+ };
+ var updateCount = function(item) {
+ var newval = JUBGrid.jubGrid.store.getValue(item, "item_count");
+ JUBGrid.jubGrid.store.setValue(item, "item_count", newval-1);
+ };
+
+ JUBGrid.jubDetailGrid.store.fetch({query:{id:lid.id},
+ onItem: deleteItem});
+ JUBGrid.jubGrid.store.fetch({query:{id:JUBGrid.jubDetailGrid.lineitemID},
+ onItem: updateCount});
+ }
};
- var updateCount = function(item) {
- var newval = JUBGrid.jubGrid.store.getValue(item, "item_count");
- JUBGrid.jubGrid.store.setValue(item, "item_count", newval-1);
- };
-
- JUBGrid.jubDetailGrid.store.fetch({query:{id:lid.id},
- onItem: deleteItem});
- JUBGrid.jubGrid.store.fetch({query:{id:JUBGrid.jubDetailGrid.lineitemID},
- onItem: updateCount});
+
+ openils_acq_Lineitem.deleteLID(lid.id, deleteFromStore);
}
- };
-
- openils.acq.Lineitem.deleteLID(lid.id, deleteFromStore);
- }
- },
-
- createLID: function(fields) {
- console.log(fields);
- fields['lineitem'] = JUBGrid.jubDetailGrid.lineitemID;
- console.log(fields);
- JUBGrid.jubDetailGrid.store.newItem(acqlid.toStoreData([lid]).items[0]);
- var addToStore = function (lid) {
- JUBGrid.jubDetailGrid.store.newItem(acqlid.toStoreData([lid]).items[0]);
- //JUBGrid.jubDetailGrid.refresh();
- //JUBGrid.jubGrid.update();
- //JUBGrid.jubGrid.refresh();
- }
- console.log("added to store");
- console.log(addToStore());
- openils.acq.Lineitem.createLID(fields, addToStore);
- },
-
- receiveLID: function(evt) {
- var list =[];
- var selected = JUBGrid.jubDetailGrid.selection.getSelected();
- for (var idx = 0; idx < selected.length; idx++) {
- var rowIdx = selected[idx];
- var lid = JUBGrid.jubDetailGrid.getItem(rowIdx);
- list.push(lid.id);
- }
- if(lid != null) { // is at least one selected?
- JUBGrid._receiveLIDList(list, 0,
- function() {
- delete openils.acq.Lineitem.ModelCache[lid.lineitem];
- openils.acq.Lineitem.loadLIDGrid(
- JUBGrid.jubDetailGrid, lid.lineitem, JUBGrid.jubDetailGridLayout);
- }
- );
- }
- },
-
- // loop through the list of LIDs and mark them as received
- _receiveLIDList: function(list, idx, callback) {
- if(idx >= list.length)
- return callback();
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem_detail.receive'],
- { asnync: true,
- params: [openils.User.authtoken, list[idx++]],
- oncomplete: function(r) {
- var res = r.recv().content();
- if(e = openils.Event.parse(res))
- return alert(e);
- JUBGrid._receiveLIDList(list, idx, callback);
- }
- }
- );
- },
-
-
- // called when a lineitem is edited
- onJUBSet: function (griditem, attr, oldVal,newVal) {
- console.log("onJUBSet called");
- var item;
-
- var updateDone = function(r) {
- var stat = r.recv().content();
- if(e = openils.Event.parse(stat))
- console.dir(e);
- };
-
- // after an attribute has been updated
- var attrUpdateDone = function(r, attr) {
- var res = r.recv().content();
- if(e = openils.Event.parse(res))
- return alert(e);
-
- var oldVal = new openils.acq.Lineitem(
- {lineitem:item}).findAttr(attr, 'lineitem_local_attr_definition');
-
- if(oldVal) {
- // if this attr already exists on the object, just update the value
- for(var i = 0; i < item.attributes().length; i++) {
- var attrobj = item.attributes()[i];
- if(attrobj.attr_type() == 'lineitem_local_attr_definition' && attrobj.attr_name() == attr) {
- attrobj.attr_value(newVal);
- }
- }
- } else {
- // if this is a new attribute, create a new object to match reality
- liad = new acqlia();
- liad.attr_type('lineitem_local_attr_definition');
- liad.attr_value(newVal);
- liad.attr_name(attr);
- liad.id(res);
- item.attributes().push(liad);
- }
- }
-
- if (oldVal == newVal) {
- return;
- }
-
- item = JUBGrid.lineitems[griditem.id];
- if (attr == "provider") {
- if(newVal == '')
- newVal = null;
- item.provider(newVal);
-
- } else if(attr == 'estimated_price' || attr == 'actual_price') {
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem_local_attr.set'],
- { async: true,
- params: [openils.User.authtoken, item.id(), attr, newVal],
- oncomplete: function(r) {attrUpdateDone(r, attr); }
- }
- );
- } else {
- //alert("Unexpected attr in Picklist.onSet: '"+attr+"'");
- return;
- }
-
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem.update"],
- {params: [openils.User.authtoken, item],
- oncomplete: updateDone
- }
- );
- },
-};
-
-
+ },
+
+ createLID: function(fields) {
+ console.log(fields);
+ fields['lineitem'] = JUBGrid.jubDetailGrid.lineitemID;
+ console.log(fields);
+ JUBGrid.jubDetailGrid.store.newItem(acqlid.toStoreData([lid]).items[0]);
+ var addToStore = function (lid) {
+ JUBGrid.jubDetailGrid.store.newItem(acqlid.toStoreData([lid]).items[0]);
+ //JUBGrid.jubDetailGrid.refresh();
+ //JUBGrid.jubGrid.update();
+ //JUBGrid.jubGrid.refresh();
+ }
+ console.log("added to store");
+ console.log(addToStore());
+ openils_acq_Lineitem.createLID(fields, addToStore);
+ },
+
+ receiveLID: function(evt) {
+ var list =[];
+ var selected = JUBGrid.jubDetailGrid.selection.getSelected();
+ for (var idx = 0; idx < selected.length; idx++) {
+ var rowIdx = selected[idx];
+ var lid = JUBGrid.jubDetailGrid.getItem(rowIdx);
+ list.push(lid.id);
+ }
+ if(lid != null) { // is at least one selected?
+ JUBGrid._receiveLIDList(list, 0,
+ function() {
+ delete openils_acq_Lineitem.ModelCache[lid.lineitem];
+ openils_acq_Lineitem.loadLIDGrid(
+ JUBGrid.jubDetailGrid, lid.lineitem, JUBGrid.jubDetailGridLayout);
+ }
+ );
+ }
+ },
+
+ // loop through the list of LIDs and mark them as received
+ _receiveLIDList: function(list, idx, callback) {
+ if(idx >= list.length)
+ return callback();
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem_detail.receive'],
+ { asnync: true,
+ params: [openils_User.authtoken, list[idx++]],
+ oncomplete: function(r) {
+ var res = r.recv().content();
+ if(e = openils_Event.parse(res))
+ return alert(e);
+ JUBGrid._receiveLIDList(list, idx, callback);
+ }
+ }
+ );
+ },
+
+
+ // called when a lineitem is edited
+ onJUBSet: function (griditem, attr, oldVal,newVal) {
+ console.log("onJUBSet called");
+ var item;
+
+ var updateDone = function(r) {
+ var stat = r.recv().content();
+ if(e = openils_Event.parse(stat))
+ console.dir(e);
+ };
+
+ // after an attribute has been updated
+ var attrUpdateDone = function(r, attr) {
+ var res = r.recv().content();
+ if(e = openils_Event.parse(res))
+ return alert(e);
+
+ var oldVal = new openils_acq_Lineitem(
+ {lineitem:item}).findAttr(attr, 'lineitem_local_attr_definition');
+
+ if(oldVal) {
+ // if this attr already exists on the object, just update the value
+ for(var i = 0; i < item.attributes().length; i++) {
+ var attrobj = item.attributes()[i];
+ if(attrobj.attr_type() == 'lineitem_local_attr_definition' && attrobj.attr_name() == attr) {
+ attrobj.attr_value(newVal);
+ }
+ }
+ } else {
+ // if this is a new attribute, create a new object to match reality
+ liad = new acqlia();
+ liad.attr_type('lineitem_local_attr_definition');
+ liad.attr_value(newVal);
+ liad.attr_name(attr);
+ liad.id(res);
+ item.attributes().push(liad);
+ }
+ }
+
+ if (oldVal == newVal) {
+ return;
+ }
+
+ item = JUBGrid.lineitems[griditem.id];
+ if (attr == "provider") {
+ if(newVal == '')
+ newVal = null;
+ item.provider(newVal);
+
+ } else if(attr == 'estimated_price' || attr == 'actual_price') {
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem_local_attr.set'],
+ { async: true,
+ params: [openils_User.authtoken, item.id(), attr, newVal],
+ oncomplete: function(r) {attrUpdateDone(r, attr); }
+ }
+ );
+ } else {
+ //alert("Unexpected attr in Picklist.onSet: '"+attr+"'");
+ return;
+ }
+
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem.update"],
+ {params: [openils_User.authtoken, item],
+ oncomplete: updateDone
+ }
+ );
+ },
+ };
+
+
+
+
+});
\ No newline at end of file
-dojo.require('dojo.date.locale');
-dojo.require('dojo.date.stamp');
-dojo.require('dijit.form.Button');
-dojo.require('dijit.form.TextBox');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.form.Textarea');
-dojo.require('dijit.Tooltip');
-dojo.require('dijit.ProgressBar');
-dojo.require('openils.acq.Lineitem');
-dojo.require('openils.acq.PO');
-dojo.require('openils.acq.Picklist');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require('openils.widget.ProgressDialog');
-dojo.require('openils.PermaCrud');
-dojo.require("openils.widget.PCrudAutocompleteBox");
-
-if (!localeStrings) { /* we can do this because javascript doesn't have block scope */
- dojo.requireLocalization('openils.acq', 'acq');
- var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
-}
-const XUL_OPAC_WRAPPER = 'chrome://open_ils_staff_client/content/cat/opac.xul';
-var li_exportable_attrs = ["issn", "isbn", "upc"];
-
-var fundLabelFormat = [
- '<span class="fund_${0}">${1} (${2})</span>', 'id', 'code', 'year'
-];
-var fundSearchFormat = ['${0} (${1})', 'code', 'year'];
-
-function nodeByName(name, context) {
- return dojo.query('[name='+name+']', context)[0];
-}
-
-// for caching linked users. e.g. lineitem_detail.receiver
-var userCache = {};
-
-var liDetailBatchFields = ['fund', 'owning_lib', 'location', 'collection_code', 'circ_modifier', 'cn_label'];
-var liDetailFields = liDetailBatchFields.concat(['barcode', 'note']);
-var fundStyles = {
- "stop": "color: #c00; font-weight: bold;",
- "warning": "color: #c93;"
-};
-
-function AcqLiTable() {
-
- var self = this;
- this.liCache = {};
- this.plCache = {};
- this.poCache = {};
- this.relCache = {};
- this.haveFundClass = {}
- this.fundBalanceState = {};
- this.realDfaCache = {};
- this.virtDfaCounts = {};
- this.virtDfaId = -1;
- this.dfeOffset = 0;
- this.claimEligibleLidByLi = {};
- this.claimEligibleLid = {};
- this.toggleState = false;
- this.tbody = dojo.byId('acq-lit-tbody');
- this.selectors = [];
- this.noteAcks = {};
- this.authtoken = openils.User.authtoken;
- this.pcrud = new openils.PermaCrud();
- this.rowTemplate = this.tbody.removeChild(dojo.byId('acq-lit-row'));
- this.copyTbody = dojo.byId('acq-lit-li-details-tbody');
- this.copyRow = this.copyTbody.removeChild(dojo.byId('acq-lit-li-details-row'));
- this.copyBatchRow = dojo.byId('acq-lit-li-details-batch-row');
- this.copyBatchWidgets = {};
- this.liNotesTbody = dojo.byId('acq-lit-notes-tbody');
- this.liNotesRow = this.liNotesTbody.removeChild(dojo.byId('acq-lit-notes-row'));
- this.realCopiesTbody = dojo.byId('acq-lit-real-copies-tbody');
- this.realCopiesRow = this.realCopiesTbody.removeChild(dojo.byId('acq-lit-real-copies-row'));
- this._copy_fields_for_acqdf = ['owning_lib', 'location'];
- this.skipInitialEligibilityCheck = false;
- this.claimDialog = new ClaimDialogManager(
- liClaimDialog, finalClaimDialog, this.claimEligibleLidByLi,
- function(li) { /* callback that fires when claims are made */
- self.fetchClaimInfo(li.id(), /* force update */ true);
- }
- );
- this.vlAgent = new VLAgent();
-
- dojo.byId("acq-lit-li-actions-selector").onchange = function() {
- self.applySelectedLiAction(this.options[this.selectedIndex].value);
- this.selectedIndex = 0;
- };
-
- acqLitCreatePoSubmit.onClick = function() {
- if (!self.createPoProviderSelector.attr("value") ||
- !self.createPoAgencySelector.attr("value")) {
- alert(localeStrings.CREATE_PO_INVALID);
- return false;
- } else if (self._confirmPoPrepaySituation()) {
- acqLitPoCreateDialog.hide();
- self._createPO(acqLitPoCreateDialog.getValues());
- } else {
- return false;
- }
- }
-
- acqLitSavePlButton.onClick = function() {
- acqLitSavePlDialog.hide();
- self._savePl(acqLitSavePlDialog.getValues());
- }
-
- acqLitCancelLiStateButton.onClick = function() {
- acqLitChangeLiStateDialog.hide();
- }
- acqLitSaveLiStateButton.onClick = function() {
- acqLitChangeLiStateDialog.hide();
- self._updateLiState(acqLitChangeLiStateDialog.getValues(), acqLitChangeLiStateDialog.attr('state'));
- }
-
-
- dojo.byId('acq-lit-select-toggle').onclick = function(){self.toggleSelect()};
- dojo.byId('acq-lit-info-back-button').onclick = function(){self.show('list')};
- dojo.byId('acq-lit-copies-back-button').onclick = function(){self.show('list')};
- dojo.byId('acq-lit-notes-back-button').onclick = function(){self.show('list')};
- dojo.byId('acq-lit-real-copies-back-button').onclick = function(){self.show('list')};
-
- this.reset = function(keep_selectors) {
- while(self.tbody.childNodes[0])
- self.tbody.removeChild(self.tbody.childNodes[0]);
- self.noteAcks = {};
- self.relCache = {};
-
- if (!keep_selectors)
- self.selectors = [];
- };
-
- this.setNext = function(handler) {
- var link = dojo.byId('acq-lit-next');
- if(handler) {
- dojo.style(link, 'visibility', 'visible');
- link.onclick = handler;
- } else {
- dojo.style(link, 'visibility', 'hidden');
- }
- };
-
- this.setPrev = function(handler) {
- var link = dojo.byId('acq-lit-prev');
- if(handler) {
- dojo.style(link, 'visibility', 'visible');
- link.onclick = handler;
- } else {
- dojo.style(link, 'visibility', 'hidden');
- }
- };
-
- this.show = function(div) {
- openils.Util.hide('acq-lit-table-div');
- openils.Util.hide('acq-lit-info-div');
- openils.Util.hide('acq-lit-li-details');
- openils.Util.hide('acq-lit-notes-div');
- openils.Util.hide('acq-lit-real-copies-div');
- openils.Util.hide('acq-lit-asset-creator');
- switch(div) {
- case 'list':
- openils.Util.show('acq-lit-table-div');
- break;
- case 'info':
- openils.Util.show('acq-lit-info-div');
- break;
- case 'copies':
- openils.Util.show('acq-lit-li-details');
- break;
- case 'real-copies':
- openils.Util.show('acq-lit-real-copies-div');
- break;
- case 'notes':
- openils.Util.show('acq-lit-notes-div');
- break;
- case 'asset-creator':
- openils.Util.show('acq-lit-asset-creator');
- break;
- default:
- if(div)
- openils.Util.show(div);
- }
- }
-
- this.hide = function() {
- this.show(null);
- }
-
- this.toggleSelect = function() {
- if(self.toggleState)
- dojo.forEach(self.selectors, function(i){i.checked = false});
- else
- dojo.forEach(self.selectors, function(i){i.checked = true});
- self.toggleState = !self.toggleState;
- };
-
-
- this.getAll = function(callback, id_only) {
- /* For some uses of the li table, we may not really know about "all"
- * the lineitems that the user thinks we know about. If we're a paged
- * picklist, for example, we only know about the lineitems we've
- * displayed, but not necessarily all the lineitems on the picklist.
- * So we reach out to pcrud to inform us.
- */
-
- var oncomplete = function(r) {
- var id_list = openils.Util.readResponse(r);
- if (id_only)
- callback(id_list);
- else
- self.fetchLineitemsById(id_list, callback);
- };
-
- if (this.isPL) {
- this.pcrud.search(
- "jub", {"picklist": this.isPL}, {
- "id_list": true, /* sic, even if id_only */
- "async": true,
- "oncomplete": oncomplete
- }
- );
- return;
- } else if (this.isPO) {
- this.pcrud.search(
- "jub", {"purchase_order": this.isPO}, {
- "id_list": true,
- "async": true,
- "oncomplete": oncomplete
- }
- );
- return;
- } else if (this.isUni && this.pager) {
- this.pager.getAllLineitemIDs(oncomplete);
- return;
- }
-
- /* If execution reaches this point, we don't need or can't perform
- * any special tricks to find out the "real" list of "all" lineitems
- * in this context, so we fall back to the old method.
- */
- callback(this.getSelected(true, null, id_only));
- };
-
- /** @param all If true, assume all are selected */
- this.getSelected = function(
- all,
- callback /* If you want a "good" idea of "all" lineitems, you must
- provide a callback that accepts an array parameter, rather than
- relying on the return value of this method itself. */,
- id_only
- ) {
- if (all && callback)
- return this.getAll(callback, id_only);
-
- var indices = {}; /* use to uniqify. needed in paging situations. */
- dojo.forEach(this.selectors,
- function(i) {
- if(i.checked || all)
- indices[i.parentNode.parentNode.getAttribute('li')] = true;
- }
- );
-
- var result = openils.Util.objectProperties(indices);
-
- if (!id_only)
- result = result.map(function(liId) { return self.liCache[liId]; });
-
- if (callback)
- callback(result);
- else
- return result;
- };
-
- this.setRowAttr = function(td, liWrapper, field, type) {
- var val = liWrapper.findAttr(field, type || 'lineitem_marc_attr_definition') || '';
- td.appendChild(document.createTextNode(val));
- };
-
- this.setClaimPolicyControl = function(li, row) {
- if (!self.claimPolicyPicker) {
- self.claimPolicyPicker = true; /* prevents a race condition */
- new openils.widget.AutoFieldWidget({
- "parentNode": "acq-lit-li-claim-policy",
- "fmClass": "acqclp",
- "selfReference": true,
- "dijitArgs": {"required": true}
- }).build(function(w) { self.claimPolicyPicker = w; });
- }
-
- if (!row) row = this._findLiRow(li);
-
- var actViewPolicy = nodeByName("action_view_claim_policy", row);
- if (li.claim_policy())
- actViewPolicy.innerHTML = localeStrings.CHANGE_CLAIM_POLICY;
-
- if (!actViewPolicy.onclick) {
- actViewPolicy.onclick = function() {
- if (li.claim_policy())
- self.claimPolicyPicker.attr("value", li.claim_policy());
- liClaimPolicyDialog.show();
- liClaimPolicySave.onClick = function() {
- self.changeClaimPolicy(
- [li], self.claimPolicyPicker.attr("value"),
- function() {
- self.setClaimPolicyControl(li, row);
- self.reconsiderClaimControl(li, row);
- liClaimPolicyDialog.hide();
- }
- );
- }
- };
- }
- };
-
- this.fetchClaimInfo = function(liId, force, callback, row) {
- this._fetchLineitem(
- liId, function(full) {
- self.liCache[full.id()] = full;
- self.checkClaimEligibility(full, callback, row);
- }, force
- );
- }
-
- /**
- * Inserts a single lineitem into the growing table of lineitems
- * @param {Object} li The lineitem object to insert
- */
- this.addLineitem = function(li, skip_final_placement) {
- this.liCache[li.id()] = li;
-
- // insert the row right away so that final order isn't
- // dependent on how long subsequent async request take
- // for a given line item
- var row = self.rowTemplate.cloneNode(true);
- if (!skip_final_placement) {
- self.tbody.appendChild(row);
- }
- self.selectors.push(dojo.query('[name=selectbox]', row)[0]);
-
- // sort the lineitem notes on edit_time
- if(!li.lineitem_notes()) li.lineitem_notes([]);
-
- var liWrapper = new openils.acq.Lineitem({lineitem:li});
- row.setAttribute('li', li.id());
- var tds = dojo.query('[attr]', row);
- dojo.forEach(tds, function(td) {self.setRowAttr(td, liWrapper, td.getAttribute('attr'), td.getAttribute('attr_type'));});
- dojo.query('[name=source_label]', row)[0].appendChild(document.createTextNode(li.source_label()));
-
- var identifier =
- liWrapper.findAttr("isbn", "lineitem_marc_attr_definition") ||
- liWrapper.findAttr("upc", "lineitem_marc_attr_definition");
-
- // XXX media prefix for added content
- if (identifier) {
- nodeByName("jacket", row).setAttribute(
- "src", "/opac/extras/ac/jacket/small/" + identifier
- );
- }
-
- nodeByName("liid", row).innerHTML += li.id();
-
- if(li.eg_bib_id()) {
- openils.Util.show(nodeByName('catalog', row), 'inline');
- nodeByName("catalog_link", row).onclick = this.generateMakeRecTab(li.eg_bib_id());
- } else {
- openils.Util.show(nodeByName('link_to_catalog', row), 'inline');
- nodeByName("link_to_catalog_link", row).onclick = function() { self.drawBibFinder(li) };
- }
-
- if (li.queued_record()) {
- this.pcrud.retrieve('vqbr', li.queued_record(),
- { async : true,
- oncomplete : function(r) {
- var qrec = openils.Util.readResponse(r);
- openils.Util.show(nodeByName('queue', row), 'inline');
- var link = nodeByName("queue_link", row);
- link.onclick = function() {
- // open a new tab to the vandelay queue for this record
- openils.XUL.newTabEasy(
- oilsBasePath + '/vandelay/vandelay?qtype=bib&qid=' + qrec.queue()
- );
- }
- }
- }
- );
- }
-
- nodeByName("worksheet_link", row).href =
- oilsBasePath + "/acq/lineitem/worksheet/" + li.id();
-
- nodeByName("show_requests_link", row).href =
- oilsBasePath + "/acq/picklist/user_request?lineitem=" + li.id();
-
- dojo.query('[attr=title]', row)[0].onclick = function() {self.drawInfo(li.id())};
- dojo.query('[name=copieslink]', row)[0].onclick = function() {self.drawCopies(li.id())};
- dojo.query('[name=noteslink]', row)[0].onclick = function() {self.drawLiNotes(li)};
-
- if (!this.skipInitialEligibilityCheck)
- this.fetchClaimInfo(
- li.id(),
- false,
- function(full) { self.setClaimPolicyControl(full, row) },
- row
- );
-
- this.updateLiNotesCount(li, row);
-
- // show which PO this lineitem is a member of
- if(li.purchase_order() && !this.isPO) {
- var po =
- this.poCache[li.purchase_order()] =
- this.poCache[li.purchase_order()] ||
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.retrieve'],
- {params: [
- this.authtoken, li.purchase_order(), {
- "flesh_price_summary": true,
- "flesh_provider" : true,
- "flesh_lineitem_count": true
- }
- ]});
- if(po && !this.isMeta) {
- openils.Util.show(nodeByName('po', row), 'inline');
- var link = nodeByName('po_link', row);
- link.setAttribute('href', oilsBasePath + '/acq/po/view/' + li.purchase_order());
- link.innerHTML += po.name();
-
- openils.Util.show(nodeByName('pro', row), 'inline');
- link = nodeByName('pro_link', row);
- link.setAttribute('href', oilsBasePath + '/conify/global/acq/provider/' + po.provider().id())
- link.innerHTML += po.provider().code();
- }
- }
-
- // show which picklist this lineitem is a member of
- if(li.picklist() && (this.isPO || this.isMeta || this.isUni)) {
- var pl =
- this.plCache[li.picklist()] =
- this.plCache[li.picklist()] ||
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.picklist.retrieve.authoritative'],
- {params: [this.authtoken, li.picklist()]});
- if (pl) {
- if (pl.name() == "") {
- openils.Util.show(nodeByName("bib_origin", row), "inline");
-
- } else {
-
- openils.Util.show(nodeByName('pl', row), 'inline');
- var link = nodeByName('pl_link', row);
- link.setAttribute('href', oilsBasePath + '/acq/picklist/view/' + li.picklist());
- link.innerHTML += pl.name();
- }
- }
- }
-
- var countNode = nodeByName('count', row);
- var count = li.item_count() || 0;
- if (typeof(this._copy_count_cb) == "function") {
- this._copy_count_cb(li.id(), count);
- }
- countNode.innerHTML = count;
- countNode.id = 'acq-lit-copy-count-label-' + li.id();
-
- // lineitem price
- var priceInput = dojo.query('[name=price]', row)[0];
- priceInput.value = li.estimated_unit_price() || '';
- priceInput.onchange = function() { self.updateLiPrice(priceInput, li) };
-
- // show either "mark received" or "unreceive" as appropriate
- this.updateLiState(li, row);
-
- if (skip_final_placement) {
- return row;
- }
- };
-
- this._liCountClaims = function(li) {
- var total = 0;
- for (var i = 0; i < li.lineitem_details().length; i++)
- total += li.lineitem_details()[i].claims().length;
- return total;
- };
-
- this._findLiRow = function(li) {
- return dojo.query('tr[li="' + li.id() + '"]', "acq-lit-tbody")[0];
- };
-
- this.reconsiderClaimControl = function(li, row) {
- if (!row) row = this._findLiRow(li);
- var option = nodeByName("action_manage_claims", row);
- var eligible = this.claimEligibleLidByLi[li.id()].length;
- var count = this._liCountClaims(li);
-
- option.disabled = !(count || eligible);
- option.innerHTML =
- dojo.string.substitute(localeStrings.NUM_CLAIMS_EXISTING, [count]);
- option.onclick = function() { self.claimDialog.show(li); };
- };
-
- this.clearEligibility = function(li) {
- this.claimEligibleLidByLi[li.id()] = [];
-
- if (li.lineitem_details()) {
- li.lineitem_details().forEach(
- function(lid) { delete self.claimEligibleLid[lid.id()]; }
- );
- }
-
- if (this.copyCache) {
- var to_del = [];
- for (var k in this.copyCache) {
- if (this.copyCache[k].lineitem() == li.id())
- to_del.push(k);
- }
- to_del.forEach(
- function(k) { delete self.claimEligibleLid[k]; }
- );
- }
- };
-
- this.checkClaimEligibility = function(li, callback, row) {
- /* Assume always eligible, i.e. from this interface we don't care about
- * claim eligibility any more. this is where the user would force a
- * claime. */
- this.clearEligibility(li);
- this.claimEligibleLidByLi[li.id()] = li.lineitem_details().map(
- function(lid) { return lid.id(); }
- );
- li.lineitem_details().forEach(
- function(lid) { self.claimEligibleLid[lid.id()] = true; }
- );
- this.reconsiderClaimControl(li, row);
- if (callback) callback(li);
- /*
- this.clearEligibility(li);
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.claim.eligible.lineitem_detail"], {
- "params": [openils.User.authtoken, {"lineitem": li.id()}],
- "async": true,
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- self.claimEligibleLidByLi[li.id()].push(
- r.lineitem_detail()
- );
- self.claimEligibleLid[r.lineitem_detail()] = true;
- }
- },
- "oncomplete": function() {
- self.reconsiderClaimControl(li, row);
- if (typeof(callback) == "function")
- callback();
- }
- }
- );
- */
- };
-
- this.updateLiNotesCount = function(li, row) {
- if (!row) row = this._findLiRow(li);
-
- var has_notes = (li.lineitem_notes().filter(
- function(o) { return Boolean (o.alert_text()); }
- ).length > 0);
-
- /* U+2691 is the code point for a filled-in flag character */
- nodeByName("notes_alert_flag", row).innerHTML =
- has_notes ? "⚑" : "";
- nodeByName("noteslink", row).style.fontStyle =
- has_notes ? "italic" : "normal";
- nodeByName("notes_count", row).innerHTML = li.lineitem_notes().length;
- };
-
- /* XXX NOT related to _updateLiState(). rethink */
- this.updateLiState = function(li, row) {
- if (!row) row = this._findLiRow(li);
-
- var actReceive = nodeByName("action_mark_recv", row);
- var actUnRecv = nodeByName("action_mark_unrecv", row);
- var actUpdateBarcodes = nodeByName("action_update_barcodes", row);
- var actHoldingsMaint = nodeByName("action_holdings_maint", row);
-
- var actNewInvoice = nodeByName('action_new_invoice', row);
- var actLinkInvoice = nodeByName('action_link_invoice', row);
- var actViewInvoice = nodeByName('action_view_invoice', row);
-
- nodeByName('action_view_history', row).onclick =
- function() { location.href = oilsBasePath + '/acq/lineitem/history/' + li.id(); };
-
- var state_cell = nodeByName("li_state", row);
-
- if (li.state() == "cancelled") {
- if (typeof li.cancel_reason() == "object") {
- var holds_state = dojo.create(
- "span", {
- "style": "border-bottom: 1px dashed #000;",
- "innerHTML": li.state()
- }, state_cell, "only"
- );
- new dijit.Tooltip(
- {
- "label": "<em>" + li.cancel_reason().label() +
- "</em><br />" + li.cancel_reason().description(),
- "connectId": [holds_state]
- }, dojo.create("span", null, state_cell, "last")
- );
- } else {
- state_cell.innerHTML = li.state(); // TODO i18n state labels
- }
- } else {
- state_cell.innerHTML = li.state(); // TODO i18n state labels
- }
-
-
- /* handle row coloring for based on LI state */
- openils.Util.removeCSSClass(row, /^oils-acq-li-state-/);
- openils.Util.addCSSClass(row, "oils-acq-li-state-" + li.state());
-
- /* handle links that appear/disappear based on whether LI is received */
- if (this.isPO) {
- var self = this;
-
- actNewInvoice.onclick = function() {
- location.href = oilsBasePath + '/acq/invoice/view?create=1&attach_li=' + li.id();
- nodeByName("action_none", row).selected = true;
- };
- actLinkInvoice.onclick = function() {
- if (!self.invoiceLinkDialogManager) {
- self.invoiceLinkDialogManager =
- new InvoiceLinkDialogManager("li");
- }
- self.invoiceLinkDialogManager.target = li;
- acqLitLinkInvoiceDialog.show();
- nodeByName("action_none", row).selected = true;
- };
- actViewInvoice.onclick = function() {
- location.href = oilsBasePath +
- "/acq/search/unified?so=" +
- base64Encode({"jub":[{"id": li.id()}]}) +
- "&rt=invoice";
- nodeByName("action_none", row).selected = true;
- };
-
- actNewInvoice.disabled = false;
- actLinkInvoice.disabled = false;
- actViewInvoice.disabled = false;
-
- switch(li.state()) {
- case "on-order":
- actReceive.disabled = false;
- actReceive.onclick = function() {
- if (self.checkLiAlerts(li.id()))
- self.issueReceive(li);
- nodeByName("action_none", row).selected = true;
- };
- return;
-
- case "received":
- actUnRecv.disabled = false;
- actUnRecv.onclick = function() {
- if (confirm(localeStrings.UNRECEIVE_LI))
- self.issueReceive(li, /* rollback */ true);
- nodeByName("action_none", row).selected = true;
- };
- // TODO we should allow editing before receipt, in which case the
- // test should be "if 1 or more real (acp) copies exist
- actUpdateBarcodes.disabled = false;
- actUpdateBarcodes.onclick = function() {
- self.showRealCopyEditUI(li);
- nodeByName("action_none", row).selected = true;
- }
- actHoldingsMaint.disabled = false;
- actHoldingsMaint.onclick = self.generateMakeRecTab( li.eg_bib_id(), 'copy_browser', row );
-
- return;
- }
- }
- };
-
-
- this._setAlertStore = function() {
- acqLitAlertAlertText.store = new dojo.data.ItemFileReadStore(
- {
- "data": acqliat.toStoreData(
- this.pcrud.search(
- "acqliat", {"id": {"!=": null}}
- )
- )
- }
- );
- acqLitAlertAlertText.setValue(); /* make the store "live" */
- acqLitAlertAlertText._store_ready = true;
- };
-
- /**
- * Draws and shows the lineitem notes pane
- */
- this.drawLiNotes = function(li) {
- var self = this;
-
- if (!acqLitAlertAlertText._store_ready)
- this._setAlertStore();
-
- li.lineitem_notes(
- li.lineitem_notes().sort(
- function(a, b) {
- if(a.edit_time() < b.edit_time()) return 1;
- return -1;
- }
- )
- );
-
- while(this.liNotesTbody.childNodes[0])
- this.liNotesTbody.removeChild(this.liNotesTbody.childNodes[0]);
- this.show('notes');
-
- acqLitCreateNoteSubmit.onClick = function() {
- var value = acqLitCreateNoteText.attr('value');
- if(!value) return;
- var note = new fieldmapper.acqlin();
- note.isnew(true);
- note.vendor_public(
- Boolean(acqLitCreateNoteVendorPublic.attr('checked'))
- );
- note.value(value);
- note.lineitem(li.id());
-
- self.updateLiNotes(li, note);
- acqLitCreateNoteVendorPublic.attr("checked", false);
- acqLitCreateNoteText.attr("value", "");
- }
-
- acqLitCreateAlertSubmit.onClick = function() {
- if (!acqLitAlertAlertText.item) {
- alert(localeStrings.ALERT_UNSELECTED);
- return;
- }
-
- var alert_text = new fieldmapper.acqliat().fromStoreItem(
- acqLitAlertAlertText.item
- );
- var value = acqLitAlertNoteValue.attr("value") || "";
-
- var note = new fieldmapper.acqlin();
- note.isnew(true);
- note.lineitem(li.id());
- note.value(value);
- note.alert_text(alert_text);
-
- self.updateLiNotes(li, note);
- }
-
- dojo.forEach(li.lineitem_notes(), function(note) { self.addLiNote(li, note) });
- }
-
- /**
- * Draws a single lineitem note in the notes pane
- */
- this.addLiNote = function(li, note) {
- if(note.isdeleted()) return;
- var self = this;
- var row = self.liNotesRow.cloneNode(true);
- nodeByName("value", row).innerHTML = note.value();
- var alert_node = nodeByName("alert_code", row);
- if (note.alert_text()) {
- alert_node.innerHTML = note.alert_text().code();
- if (note.alert_text().description()) {
- new dijit.Tooltip(
- {
- "connectId": [alert_node],
- "label": note.alert_text().description()
- }, dojo.create("span", null, alert_node, "after")
- );
- }
- }
-
- if (openils.Util.isTrue(note.vendor_public()))
- nodeByName("vendor_public", row).innerHTML =
- localeStrings.VENDOR_PUBLIC;
-
- nodeByName("delete", row).onclick = function() {
- note.isdeleted(true);
- self.liNotesTbody.removeChild(row);
- self.updateLiNotes(li);
- };
-
- if(note.edit_time()) {
- nodeByName("edit_time", row).innerHTML =
- dojo.date.locale.format(
- dojo.date.stamp.fromISOString(note.edit_time()),
- {formatLength:'short'});
- }
-
- self.liNotesTbody.appendChild(row);
- }
-
- /**
- * Updates any new/changed/deleted notes on the server
- */
- this.updateLiNotes = function(li, newNote) {
-
- var notes;
- if(newNote) {
- notes = [newNote];
- } else {
- notes = li.lineitem_notes().filter(
- function(note) {
- if(note.ischanged() || note.isnew() || note.isdeleted())
- return note;
- }
- );
- }
-
- if(notes.length == 0) return;
- progressDialog.show();
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem_note.cud.batch'],
- { async : true,
- params : [this.authtoken, notes],
- onresponse : function(r) {
- var resp = openils.Util.readResponse(r);
-
- if(resp.complete) {
-
- if(!newNote) {
- // remove the old changed notes
- var list = [];
- dojo.forEach(li.lineitem_notes(),
- function(note) {
- if(!(note.ischanged() || note.isnew() || note.isdeleted()))
- list.push(note);
- }
- );
- li.lineitem_notes(list);
- }
-
- progressDialog.hide();
- self.updateLiNotesCount(li);
- self.drawLiNotes(li);
- return;
- }
-
- progressDialog.update(resp);
- var newnote = resp.note;
-
- if(!newnote.isdeleted()) {
- newnote.isnew(false);
- newnote.ischanged(false);
- li.lineitem_notes().push(newnote);
- }
- },
- }
- );
- }
-
- this.updateLiPrice = function(input, li) {
- var self = this;
- var price = input.value;
- if(Number(price) == Number(li.estimated_unit_price())) return;
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.price.set'],
- { async : false, // redundant w/ timeout
- timeout : 10,
- params : [this.authtoken, li.id(), price],
- oncomplete : function(r) {
- openils.Util.readResponse(r);
- li.estimated_unit_price(price); // update local copy
-
- /*
- * If this is a PO and every visible lineitem has a price,
- * check again to see if this PO can be activated. Note that
- * every visible lineitem having a price does not guarantee it can
- * be activated, which is why we still make the call. Having a price
- * set for every visiable lineitem is just the lowest barrier to entry.
- */
- if (self.isPO) {
- var priceNodes = dojo.query('[name=price]', dojo.byId('acq-lit-tbody'));
- var allSet = true;
- dojo.forEach(priceNodes, function(node) { if (node.value == '') allSet = false});
- if (allSet) checkCouldActivatePo();
- }
- }
- }
- );
- }
-
- this.removeLineitem = function(liId) {
- this.tbody.removeChild(dojo.query('[li='+liId+']', this.tbody)[0]);
- delete this.liCache[liId];
- //selected.push(self.liCache[i.parentNode.parentNode.getAttribute('li')]);
- }
-
- this.drawInfo = function(liId) {
- if (!this._isRelatedViewer) {
- var d = dojo.byId("acq-lit-info-related");
- if (!this.relCache[liId]) {
- fieldmapper.standardRequest(
- [
- "open-ils.acq",
- "open-ils.acq.lineitems_for_bib.by_lineitem_id.count"
- ], {
- "async": true,
- "params": [openils.User.authtoken, liId],
- "onresponse": function(r) {
- self.relCache[liId] = openils.Util.readResponse(r);
- nodeByName("related_number", d).innerHTML =
- self.relCache[liId];
- openils.Util[
- self.relCache[liId] >1 ? "show" : "hide"
- ](d);
- }
- }
- );
- } else {
- nodeByName("related_number", d).innerHTML = this.relCache[liId];
- openils.Util[this.relCache[liId] > 1 ? "show" : "hide"](d);
- }
- }
-
- this.show('info');
- openils.acq.Lineitem.fetchAttrDefs(
- function() {
- self._fetchLineitem(liId, function(li){self._drawInfo(li);});
- }
- );
- };
-
- /* For a given list of lineitem ids, build a list of full lineitems
- * re-using the fetching logic that is otherwise typical to use in this
- * module.
- *
- * If we've already got a lineitem in the cache, just use that.
- *
- * Once we've built a list of lineitems, call callback(thatlist).
- */
- this.fetchLineitemsById = function(id_list, callback) {
- var total = id_list.length;
- var result_list = [];
-
- var inner = function(li) {
- result_list.push(li)
- if (--total <= 0)
- callback(result_list);
- };
-
- id_list.forEach(function(id) { self._fetchLineitem(id, inner); });
- };
-
- this._fetchLineitem = function(liId, handler, force) {
-
- var li = this.liCache[liId];
- if(li && li.marc() && li.lineitem_details() && !force)
- return handler(li);
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.retrieve.authoritative'],
- { async: true,
-
- params: [self.authtoken, liId, {
- flesh_attrs: true,
- flesh_cancel_reason: true,
- flesh_li_details: true,
- flesh_notes: true,
- flesh_fund_debit: true }],
-
- oncomplete: function(r) {
- var li = openils.Util.readResponse(r);
- self.liCache[liId] = li;
- handler(li)
- }
- }
- );
- };
-
- this._drawInfo = function(li) {
-
- acqLitEditOrderMarc.onClick = function() { self.editOrderMarc(li); }
-
- if(li.eg_bib_id()) {
- openils.Util.hide('acq-lit-marc-order-record-label');
- openils.Util.hide(acqLitEditOrderMarc.domNode);
- openils.Util.show('acq-lit-marc-real-record-label');
- } else {
- openils.Util.show('acq-lit-marc-order-record-label');
- openils.Util.show(acqLitEditOrderMarc.domNode);
- openils.Util.hide('acq-lit-marc-real-record-label');
- }
-
- this.drawMarcHTML(li);
- this.infoTbody = dojo.byId('acq-lit-info-tbody');
-
- if(!this.infoRow)
- this.infoRow = this.infoTbody.removeChild(dojo.byId('acq-lit-info-row'));
- while(this.infoTbody.childNodes[0])
- this.infoTbody.removeChild(this.infoTbody.childNodes[0]);
-
- for(var i = 0; i < li.attributes().length; i++) {
- var attr = li.attributes()[i];
- var row = this.infoRow.cloneNode(true);
-
- var type = attr.attr_type().replace(/lineitem_(.*)_attr_definition/, '$1');
- var name = openils.acq.Lineitem.attrDefs[type].filter(
- function(a) {
- return (a.code() == attr.attr_name());
- }
- ).pop().description();
-
- dojo.query('[name=label]', row)[0].appendChild(document.createTextNode(name));
- dojo.query('[name=value]', row)[0].appendChild(document.createTextNode(attr.attr_value()));
- this.infoTbody.appendChild(row);
- }
-
- if (!this._isRelatedViewer) {
- nodeByName("rel_link", dojo.byId("acq-lit-info-related")).href =
- oilsBasePath + "/acq/lineitem/related/" + li.id();
- }
-
- };
-
- this.generateMakeRecTab = function(bib_id,default_view, row) {
- return function() {
- xulG.new_tab(
- XUL_OPAC_WRAPPER,
- {tab_name: localeStrings.XUL_RECORD_DETAIL_PAGE, browser:false},
- {
- no_xulG : false,
- show_nav_buttons : true,
- show_print_button : true,
- opac_url : xulG.url_prefix(xulG.urls.opac_rdetail + bib_id),
- default_view : default_view
- }
- );
-
- if(row) nodeByName("action_none", row).selected = true;
- }
- };
-
- this.drawMarcHTML = function(li) {
- var params = [null, true, li.marc()];
- if(li.eg_bib_id())
- params = [li.eg_bib_id(), true];
-
- fieldmapper.standardRequest(
- ['open-ils.search', 'open-ils.search.biblio.record.html'],
- { async: true,
- params: params,
- oncomplete: function(r) {
- dojo.byId('acq-lit-marc-div').innerHTML =
- openils.Util.readResponse(r);
- }
- }
- );
- }
-
- this.drawCopies = function(liId, force_fetch) {
- if (typeof force_fetch == "undefined")
- force_fetch = false;
-
- openils.acq.Lineitem.fetchAndRender(liId, {},
- function(li, html) {
- dojo.byId('acq-lit-copies-li-summary').innerHTML = html;
- }
- );
-
- this.show('copies');
- var self = this;
- this.copyCache = {};
- this.copyWidgetCache = {};
- this.oldCopyWidgetCache = {};
- this.virtDfaCounts = {};
- this.realDfaCache = {};
- this.dfeOffset = 0;
-
- acqLitSaveCopies.onClick = function() { self.saveCopyChanges(liId) };
- acqLitBatchUpdateCopies.onClick = function() { self.batchCopyUpdate() };
- acqLitCopyCountInput.attr('value', '0');
-
- while(this.copyTbody.childNodes[0])
- this.copyTbody.removeChild(this.copyTbody.childNodes[0]);
-
- this._drawBatchCopyWidgets();
-
- this._drawDistribApplied(liId);
-
- this._fetchDistribFormulas(
- function() {
- openils.acq.Lineitem.fetchAttrDefs(
- function() {
- self._fetchLineitem(liId, function(li){self._drawCopies(li);}, force_fetch);
- }
- );
- }
- );
- };
-
- this._saveDistribAppliedTemplates = function() {
- if (!this._appliedDistribTemplate) {
- this._appliedDistribTemplate =
- dojo.byId("acq-lit-distrib-applied-tbody").
- removeChild(dojo.byId("acq-lit-distrib-applied-row"));
- dojo.attr(this._appliedDistribTemplate, "id");
- }
- };
-
- this._drawDistribApplied = function(liId) {
- /* Build this table while hidden to prevent rendering artifacts */
- openils.Util.hide("acq-lit-distrib-applied-tbody");
-
- this._saveDistribAppliedTemplates();
-
- /* Remove any rows in the table from previous populations */
- dojo.query("tr[formula]", "acq-lit-distrib-applied-tbody").
- forEach(dojo.destroy);
-
- /* Unregister all dijits previously created (for some reason this isn't
- * covered by the above destroy calls). */
- dijit.registry.forEach(
- function(w) { if (/^dfa-/.test(w.id)) w.destroyRecursive(); }
- );
-
- /* Populate the table with our liId */
- var total = 0;
- fieldmapper.standardRequest(
- ["open-ils.acq",
- "open-ils.acq.distribution_formula_application.ranged.retrieve"],
- {
- "async": true,
- "params": [self.authtoken, liId],
- "onresponse": function(r) {
- var dfa = openils.Util.readResponse(r);
- if (dfa) {
- total++;
- self.realDfaCache[dfa.id()] = dfa;
- self._drawDistribAppliedUnit(dfa);
- }
- },
- "oncomplete": function() {
- /* Reveal built table */
- if (total) {
- openils.Util.show(
- "acq-lit-distrib-applied-tbody", "table-row-group"
- );
- }
- }
- }
- );
- };
-
- this._drawDistribAppliedUnit = function(dfa) {
- var new_row = false;
- var row = dojo.query(
- 'tr[formula="' + dfa.formula().id() + '"]',
- "acq-lit-distrib-applied-tbody"
- )[0];
-
- if (!row) {
- new_row = true;
- row = dojo.clone(this._appliedDistribTemplate);
- dojo.attr(row, "formula", dfa.formula().id());
- dojo.query("th", row)[0].innerHTML = dfa.formula().name();
- }
-
- var td = dojo.query("td", row)[0];
-
- dojo.create("span", {"id": "dfa-button-" + dfa.id()}, td, "last");
- dojo.create("span", {"id": "dfa-tip-" + dfa.id()}, td, "last");
-
- if (new_row)
- dojo.place(row, "acq-lit-distrib-applied-tbody", "last");
-
- new dijit.form.Button(
- {
- "onClick": function() {
- if (confirm(localeStrings.EXPLAIN_DFA_MGMT))
- self.deleteDfa(dfa);
- },
- "label": "X",
- /* XXX I /cannot/ make the following work in as a CSS class
- * for some reason. So frustrating... */
- "style": function(id) {
- return (id > 0 ?
- "font-weight: bold; color: #c00;" :
- "color: #666;");
- }(dfa.id()) + "margin: 0 6px;display: inline;"
- }, "dfa-button-" + dfa.id()
- );
- new dijit.Tooltip(
- {
- "connectId": ["dfa-button-" + dfa.id()],
- "label": dojo.string.substitute(
- localeStrings.DFA_TIP, dfa.id() > 0 ? [
- openils.User.formalName(dfa.creator()),
- dojo.date.locale.format(
- dojo.date.stamp.fromISOString(dfa.create_time()),
- {"formatLength":"short"}
- )
- ] : [localeStrings.ITS_YOU, localeStrings.JUST_NOW]
- )
- }, "dfa-tip-" + dfa.id()
- );
- }
-
- this.deleteDfa = function(dfa) {
- if (dfa.id() > 0) { /* real */
- this.pcrud.eliminate(
- dfa, {
- "async": true,
- "oncomplete": function() {
- self._removeDistribApplied(dfa.id());
- delete self.realDfaCache[dfa.id()];
- }
- }
- );
- } else { /* virtual */
- if (--(this.virtDfaCounts[dfa.formula().id()]) < 0)
- this.virtDfaCounts[dfa.formula().id()] = 0;
- /* hasn't been saved yet, so no need to do anything server side */
- this._removeDistribApplied(dfa.id());
- }
-
- };
-
- this._removeDistribApplied = function(dfaId) {
- var re = new RegExp("^dfa-\\w+-" + String(dfaId));
- dijit.registry.forEach(
- function(w) { if (re.test(w.id)) w.destroyRecursive(); }
- );
- this._removeDistribAppliedEmptyRows();
- };
-
- this._removeAllDistribAppliedVirtual = function() {
- /* Unregister dijits */
- dijit.registry.forEach(
- function(w) { if (/^dfa-\w+--/.test(w.id)) w.destroyRecursive(); }
- );
- this._removeDistribAppliedEmptyRows();
- };
-
- this._removeDistribAppliedEmptyRows = function() {
- /* Remove any rows with no DFA at all */
- dojo.query("tr[formula] td", "acq-lit-distrib-applied-tbody").forEach(
- function(o) {
- if (o.childNodes.length < 1) dojo.destroy(o.parentNode);
- }
- );
- };
-
- /**
- * Insert a new row into the distribution formula selection form
- */
- this._addDistribFormulaRow = function() {
- var self = this;
-
- if (!self.distribForms) {
- // no formulas, hide the form
- openils.Util.hide('acq-lit-distrib-formula-table');
- return;
- }
-
- if(!this.distribFormulaTemplate)
- this.distribFormulaTemplate =
- dojo.byId('acq-lit-distrib-formula-tbody').removeChild(dojo.byId('acq-lit-distrib-form-row'));
-
- var row = this.distribFormulaTemplate.cloneNode(true);
- dojo.place(row, "acq-lit-distrib-formula-tbody", "only");
-
- this.dfSelector = new dijit.form.FilteringSelect(
- {"labelAttr": "dynLabel", "labelType": "html"},
- nodeByName("selector", row)
- );
- this._updateFormulaStore();
- this.dfSelector.fetchProperties =
- {"sort": [{"attribute": "use_count", "descending": true}]};
-
- var apply = new dijit.form.Button(
- {"label": localeStrings.APPLY},
- nodeByName('set_button', row)
- );
-
- var reset = new dijit.form.Button(
- {"label": localeStrings.RESET_FORMULAE, "disabled": true},
- nodeByName("reset_button", row)
- );
-
- dojo.connect(apply, 'onClick',
- function() {
- var form_id = self.dfSelector.attr("value");
- if(!form_id) return;
- self._applyDistribFormula(form_id);
- reset.attr("disabled", false);
- }
- );
-
- dojo.connect(reset, 'onClick',
- function() {
- self.restoreCopyFieldsBeforeDF();
- self.virtDfaCounts = {};
- self.virtDfaId = -1;
- self.dfeOffset = 0;
- self._updateFormulaStore();
- self._removeAllDistribAppliedVirtual();
- reset.attr("disabled", "true");
- }
- );
-
- };
-
- /**
- * Applies a distrib formula to the current set of copies
- */
- this._applyDistribFormula = function(formula) {
- if(!formula) return;
-
- formula = this.distribForms.filter(
- function(form) { return form.id() == formula; }
- )[0];
-
- var copyRows = dojo.query('tr', self.copyTbody);
-
- if (this.dfeOffset >= copyRows.length) {
- alert(localeStrings.OUT_OF_COPIES);
- return;
- }
-
- var entries_applied = 0;
- for(
- var rowIndex = this.dfeOffset;
- rowIndex < copyRows.length;
- rowIndex++
- ) {
-
- var row = copyRows[rowIndex];
- var copy_id = row.getAttribute('copy_id');
- var copyWidgets = this.copyWidgetCache[copy_id];
- var entryIndex = this.dfeOffset;
- var entry = null;
-
- // find the correct entry for the current row
- dojo.forEach(formula.entries(),
- function(e) {
- if(!entry) {
- entryIndex += e.item_count();
- if(entryIndex > rowIndex)
- entry = e;
- }
- }
- );
-
- if(entry) {
-
- //console.log("rowIndex = " + rowIndex + ", entry = " + entry.id() + ", entryIndex=" +
- // entryIndex + ", owning_lib = " + entry.owning_lib() + ", location = " + entry.location());
-
- entries_applied++;
- this.saveCopyFieldsBeforeDF(copy_id);
- this._copy_fields_for_acqdf.forEach(
- function(field) {
- if(entry[field]()) {
- copyWidgets[field].attr('value', (entry[field]()));
- }
- }
- );
- }
- }
-
- if (entries_applied) {
- this.virtDfaCounts[formula.id()] =
- ++(this.virtDfaCounts[formula.id()]) || 1;
- this._updateFormulaStore();
- this._drawDistribAppliedUnit(
- function(df) {
- var dfa = new acqdfa();
- dfa.formula(df); dfa.id(self.virtDfaId--); return dfa;
- }(formula)
- );
- this.dfeOffset += entries_applied;
- };
- };
-
- /**
- * This function updates the DF store for the dropdown so that use_counts
- * can reflect DF applications from this session before they're saved
- * server-side.
- */
- this._updateFormulaStore = function() {
- this.dfSelector.store = new dojo.data.ItemFileReadStore(
- {
- "data": self._labelFormulasWithCounts(
- acqdf.toStoreData(self.distribForms)
- )
- }
- );
- };
-
- this.saveCopyFieldsBeforeDF = function(copy_id) {
- var self = this;
- if (!this.oldCopyWidgetCache[copy_id]) {
- var copyWidgets = this.copyWidgetCache[copy_id];
-
- this.oldCopyWidgetCache[copy_id] = {};
- this._copy_fields_for_acqdf.forEach(
- function(f) {
- self.oldCopyWidgetCache[copy_id][f] =
- copyWidgets[f].attr("value");
- }
- );
- }
- };
-
- this.restoreCopyFieldsBeforeDF = function() {
- var self = this;
- for (var copy_id in this.oldCopyWidgetCache) {
- this._copy_fields_for_acqdf.forEach(
- function(f) {
- self.copyWidgetCache[copy_id][f].attr(
- "value", self.oldCopyWidgetCache[copy_id][f]
- );
- }
- );
- }
- };
-
- this._labelFormulasWithCounts = function(store_data) {
- for (var key in store_data.items) {
- var obj = store_data.items[key];
- obj.use_count = Number(obj.use_count); /* needed for sorting */
-
- if (this.virtDfaCounts[obj.id])
- obj.use_count = obj.use_count + Number(this.virtDfaCounts[obj.id]);
-
- obj.dynLabel = "<span class='acq-lit-distrib-form-use-count'>[" +
- obj.use_count + "]</span> " + obj.name;
- }
- return store_data;
- };
-
- /**
- * This method formerly would not refetch the DF formulas if they'd been
- * loaded already, but now it always re-fetches, since use_count changes.
- */
- /** TODO: port distrib-formula selector to autofieldwidget+pcrud/dojo store */
- this._fetchDistribFormulas = function(onload) {
- fieldmapper.standardRequest(
- ["open-ils.acq",
- "open-ils.acq.distribution_formula.ranged.retrieve.atomic"],
- {
- "async": true,
- "params": [openils.User.authtoken, 0, 500],
- "oncomplete": function(r) {
- self.distribForms = openils.Util.readResponse(r);
- if(!self.distribForms || self.distribForms.length == 0) {
- self.distribForms = [];
- }
- self._addDistribFormulaRow();
- onload();
- }
- }
- );
- }
-
- this._drawBatchCopyWidgets = function() {
- var row = this.copyBatchRow;
- dojo.forEach(liDetailBatchFields,
- function(field) {
- if(self.copyBatchRowDrawn) {
- self.copyBatchWidgets[field].attr('value', null);
- } else {
- var widget = new openils.widget.AutoFieldWidget({
- fmField : field,
- fmClass : 'acqlid',
- labelFormat : (field == 'fund') ? fundLabelFormat : null,
- searchFormat : (field == 'fund') ? fundSearchFormat : null,
- searchFilter : (field == 'fund') ? {"active": "t"} : null,
- parentNode : dojo.query('[name='+field+']', row)[0],
- orgLimitPerms : ['CREATE_PICKLIST'],
- dijitArgs : {
- "required": false,
- "labelType": (field == "fund") ? "html" : null
- },
- noCache: (field == "fund"),
- forceSync : true
- });
- widget.build(
- function(w, ww) {
- if (field == "fund" && w.store)
- self._ensureCSSFundClasses(w.store);
- self.copyBatchWidgets[field] = w;
- }
- );
- if (field == "fund") {
- dojo.connect(
- widget.widget, "onChange", function(val) {
- self._updateFundSelectorStyle(widget, val);
- }
- );
- }
- }
- }
- );
- this.copyBatchRowDrawn = true;
- };
-
- this.batchCopyUpdate = function() {
- var self = this;
- for(var k in this.copyWidgetCache) {
- var cache = this.copyWidgetCache[k];
- dojo.forEach(liDetailBatchFields, function(f) {
- var newval = self.copyBatchWidgets[f].attr('value');
- if(newval) cache[f].attr('value', newval);
- });
- }
- };
-
- this._drawCopies = function(li) {
- var self = this;
-
- // this button sets the total number of copies for a given lineitem
- acqLitAddCopyCount.onClick = function() {
- var count = acqLitCopyCountInput.attr('value');
-
- // add new rows
- while(self.copyCount() < count)
- self.addCopy(li);
-
- // delete rows if necessary
- var diff = self.copyCount() - count;
- if(diff > 0) {
- var rows = dojo.query('tr', self.copyTbody).reverse().slice(0, diff);
- if(confirm(dojo.string.substitute(localeStrings.DELETE_LI_COPIES_CONFIRM, [diff]))) {
- dojo.forEach(rows, function(row) {self.deleteCopy(row); });
- } else {
- acqLitCopyCountInput.attr('value', self.copyCount()+'');
- }
- }
- }
-
-
- if(li.lineitem_details().length > 0) {
- dojo.forEach(li.lineitem_details(),
- function(copy) {
- self.addCopy(li, copy);
- }
- );
- } else {
- self.addCopy(li);
- }
- };
-
- this.copyCount = function() {
- var count = 0;
- for(var id in this.copyCache) {
- if(!this.copyCache[id].isdeleted())
- count++;
- }
- return count;
- }
-
- this.virtCopyId = -1;
- this.addCopy = function(li, copy) {
- var row = this.copyRow.cloneNode(true);
- this.copyTbody.appendChild(row);
- var self = this;
-
- if(!copy) {
- copy = new fieldmapper.acqlid();
- copy.isnew(true);
- copy.id(this.virtCopyId--);
- copy.lineitem(li.id());
- }
-
- this.copyCache[copy.id()] = copy;
- row.setAttribute('copy_id', copy.id());
- self.copyWidgetCache[copy.id()] = {};
-
- acqLitCopyCountInput.attr('value', self.copyCount()+'');
-
- var rcvr = copy.receiver();
- if (rcvr) {
- if (!userCache[rcvr]) {
- if(rcvr == openils.User.user.id()) {
- userCache[rcvr] = openils.User.user;
- } else {
- userCache[rcvr] = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.retrieve'],
- {params: [openils.User.authtoken, rcvr]}
- );
- }
- }
- dojo.query('[name=receiver]', row)[0].innerHTML = userCache[rcvr].usrname();
- }
-
- dojo.forEach(liDetailFields,
- function(field) {
- var searchFilter;
- if (field == "fund") {
- searchFilter = (copy.fund() ?
- {"-or": {"active": "t", "id": copy.fund()}} :
- {"active" : "t"});
- } else {
- searchFilter = null;
- }
-
- var readOnly = false;
-
- // TODO: Add support for changing the owning_lib after real copies have been made.
- // owning_lib is order data as much as its item data
- if(copy.eg_copy_id() && ['owning_lib', 'location', 'circ_modifier', 'cn_label', 'barcode'].indexOf(field) >= 0) {
- readOnly = true;
- }
-
- // TODO: add support for changing the fund after debits have been created
- // Note: invoicing allows the change
- if(copy.fund_debit() && field == 'fund') {
- readOnly = true;
- }
-
-
- var widget = new openils.widget.AutoFieldWidget({
- fmObject : copy,
- fmField : field,
- labelFormat : (field == 'fund') ? fundLabelFormat : null,
- searchFormat : (field == 'fund') ? fundSearchFormat : null,
- dijitArgs: {"labelType": (field == 'fund') ? "html" : null},
- searchFilter : searchFilter,
- noCache: (field == "fund"),
- fmClass : 'acqlid',
- parentNode : dojo.query('[name='+field+']', row)[0],
- orgLimitPerms : ['CREATE_PICKLIST', 'CREATE_PURCHASE_ORDER'],
- readOnly : readOnly,
- orgDefaultsToWs : true
- });
-
- widget.build(
- // make sure we capture the value from any async widgets
- function(w, ww) {
-
- if (field == "fund" && w.store)
- self._ensureCSSFundClasses(w.store);
-
- if(!readOnly)
- copy[field](ww.getFormattedValue())
-
- self.copyWidgetCache[copy.id()][field] = w;
-
- dojo.connect(w, 'onChange',
- function(val) {
- if (field == "fund")
- self._updateFundSelectorStyle(widget, val);
-
- if (!readOnly && (copy.isnew() || val != copy[field]())) {
- // prevent setting ischanged() automatically on widget load for existing copies
- copy[field](widget.getFormattedValue())
- copy.ischanged(true);
- }
- }
- );
- }
- );
- }
- );
-
- this.updateLidState(copy, row);
- };
-
- this._ensureCSSFundClass = function(id) {
- if (!this.fundStyleSheet) {
- dojo.create(
- "style", {"type": "text/css"},
- document.getElementsByTagName("head")[0], "last"
- );
- this.fundStyleSheet = document.styleSheets[
- document.styleSheets.length - 1
- ];
- }
-
- var cn = "fund_" + id;
- if (!this.haveFundClass[cn]) {
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.fund.check_balance_percentages"],
- {
- "params": [openils.User.authtoken, id],
- "async": true,
- "oncomplete": function(r) {
- r = openils.Util.readResponse(r);
- self.fundBalanceState[id] = r;
- var style = "";
- if (r[0] /* stop */)
- style = fundStyles.stop;
- else if (r[1] /* warning */)
- style = fundStyles.warning;
- self.fundStyleSheet.insertRule(
- "." + cn + " { " + style + " }",
- self.fundStyleSheet.cssRules.length
- );
- self.haveFundClass[cn] = true;
- }
- }
- );
- }
- };
-
- this._ensureCSSFundClasses = function(store) {
- store.fetch({
- "query": {"id": "*"},
- "onItem": function(o) { self._ensureCSSFundClass(o.id[0]); }
- });
- };
-
- this._updateFundSelectorStyle = function(widget, fund_id) {
- openils.Util.removeCSSClass(widget.widget.domNode, /fund_\d+/);
- openils.Util.addCSSClass(widget.widget.domNode, "fund_" + fund_id);
- };
-
- this.updateLidState = function(copy, row) {
- if (typeof(row) == "undefined") {
- row = dojo.query(
- 'tr[copy_id="' + copy.id() + '"]', this.copyTbody
- )[0];
- }
-
- var self = this;
- var recv_link = nodeByName("receive", row);
- var unrecv_link = nodeByName("unreceive", row);
- var del_link = nodeByName("delete", row);
- var cxl_link = nodeByName("cancel", row);
- var claim_link = nodeByName("claim", row);
- var cxl_reason_link = nodeByName("cancel_reason", row);
-
- if (copy.cancel_reason()) {
- openils.Util.hide(del_link.parentNode);
- openils.Util.hide(recv_link);
- openils.Util.hide(unrecv_link);
- openils.Util.hide(cxl_link);
- openils.Util.hide(claim_link);
-
- /* XXX the following may leak memory in a long lived table: dijits may not get destroyed... not positive. revisit. */
- var holds_reason = dojo.create(
- "span", {
- "style": "border-bottom: 1px dashed #000;",
- "innerHTML": "Cancelled" /* XXX [sic] and i18n */
- }, cxl_reason_link, "only"
- );
- new dijit.Tooltip(
- {
- "label": "<em>" + copy.cancel_reason().label() +
- "</em><br />" + copy.cancel_reason().description(),
- "connectId": [holds_reason]
- }, dojo.create("span", null, cxl_reason_link, "last")
- );
- openils.Util.show(cxl_reason_link, "inline");
- } else if (this.isPO) {
- /* Only using this in one place so far, but may want it for better
- * decisions on when to display certain controls. */
- var li_state = this.liCache[copy.lineitem()].state();
-
- openils.Util.hide(del_link.parentNode);
- openils.Util.hide(cxl_reason_link);
-
- /* Avoid showing (un)receive links, cancel links, for virt copies */
- if (copy.id() > 0) {
- if (copy.recv_time()) {
- openils.Util.hide(cxl_link);
- openils.Util.hide(recv_link);
- openils.Util.hide(claim_link);
-
- openils.Util.show(unrecv_link, "inline");
- unrecv_link.onclick = function() {
- if (confirm(localeStrings.UNRECEIVE_LID))
- self.issueReceive(copy, /* rollback */ true);
- };
- } else {
- openils.Util.hide(unrecv_link);
-
- if (this.claimEligibleLid[copy.id()]) {
- openils.Util.show(claim_link, "inline");
- claim_link.onclick = function() {
- self.claimDialog.show(
- self.liCache[copy.lineitem()], copy.id()
- );
- };
- } else {
- openils.Util.hide(claim_link);
- }
-
- openils.Util[li_state == "on-order" ? "show" : "hide"](
- recv_link, "inline"
- );
- openils.Util.show(cxl_link, "inline");
- recv_link.onclick = function() {
- if (self.checkLiAlerts(copy.lineitem()))
- self.issueReceive(copy);
- };
- cxl_link.onclick = function() {
- self.cancelLid(copy.id());
- };
- }
- } else {
- openils.Util.hide(cxl_link);
- openils.Util.hide(unrecv_link);
- openils.Util.hide(recv_link);
- openils.Util.hide(claim_link);
- }
- } else {
- openils.Util.hide(unrecv_link);
- openils.Util.hide(recv_link);
- openils.Util.hide(cxl_reason_link);
- openils.Util.hide(claim_link);
-
- del_link.onclick = function() { self.deleteCopy(row) };
- openils.Util.show(del_link.parentNode);
- }
- }
-
- this.cancelLid = function(lid_id) {
- lidCancelDialog._lid_id = lid_id;
- openils.Util.show(lidCancelDialog.domNode.parentNode);
- lidCancelDialog.show();
- if (!lidCancelDialog._prepared) {
- var widget = new openils.widget.AutoFieldWidget({
- "fmField": "cancel_reason",
- "fmClass": "acqlid",
- "parentNode": dojo.byId("acq-lit-lid-cancel-reason"),
- "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
- "forceSync": true
- });
- widget.build(
- function(w, ww) {
- acqLidCancelButton.onClick = function() {
- if (w.attr("value")) {
- if (confirm(localeStrings.LID_CANCEL_CONFIRM)) {
- self._cancelLid(
- lidCancelDialog._lid_id,
- w.attr("value")
- );
- }
- lidCancelDialog.hide();
- }
- };
- lidCancelDialog._prepared = true;
- }
- );
- }
- };
-
- this._cancelLid = function(lid_id, reason) {
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem_detail.cancel"], {
- "params": [openils.User.authtoken, lid_id, reason],
- "async": true,
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- if (r.lid) {
- for (var id in r.lid) {
- /* actually this should only iterate once */
- self.copyCache[id].cancel_reason(
- r.lid[id].cancel_reason
- );
- self.updateLidState(self.copyCache[id]);
- }
- }
- }
- }
- }
- );
- };
-
- this._confirmAlert = function(li, lin) {
- return confirm(
- dojo.string.substitute(
- localeStrings.CONFIRM_LI_ALERT, [
- (new openils.acq.Lineitem({"lineitem": li})).findAttr(
- "title", "lineitem_marc_attr_definition"
- ),
- lin.alert_text().code(),
- lin.alert_text().description() || "",
- lin.value()
- ]
- )
- );
- };
-
- this.checkLiAlerts = function(li_id) {
- var li = this.liCache[li_id];
-
- var alert_notes = li.lineitem_notes().filter(
- function(o) { return Boolean(o.alert_text()); }
- );
-
- /* this is _intentionally_ not done in a call to forEach() ... */
- for (var i = 0; i < alert_notes.length; i++) {
- if (this.noteAcks[alert_notes[i].id()])
- continue;
- else if (!this._confirmAlert(li, alert_notes[i]))
- return false;
- else
- this.noteAcks[alert_notes[i].id()] = true;
- }
-
- return true;
- };
-
- this.deleteCopy = function(row) {
- var copy = this.copyCache[row.getAttribute('copy_id')];
- copy.isdeleted(true);
- if(copy.isnew())
- delete this.copyCache[copy.id()];
- this.copyTbody.removeChild(row);
- }
-
- this._virtDfaCountsAsList = function() {
- var L = [];
- for (var key in this.virtDfaCounts) {
- for (var i = 0; i < this.virtDfaCounts[key]; i++)
- L.push(key);
- }
- return L;
- }
-
- this.confirmBreachedCopyFunds = function(copies) {
- var stop = 0, warning = 0;
- copies.forEach(
- function(o) {
- if (o.fund()) {
- var state = self.fundBalanceState[o.fund()];
- if (state[0] /* stop */)
- stop++;
- else if (state[1] /* warning */)
- warning++;
- }
- }
- );
-
- if (stop) {
- return confirm(localeStrings.CONFIRM_FUNDS_AT_STOP);
- } else if (warning) {
- return confirm(localeStrings.CONFIRM_FUNDS_AT_WARNING);
- }
- return true;
- };
-
- this.saveCopyChanges = function(liId) {
- var self = this;
- var copies = [];
-
-
- var total = 0;
- for(var id in this.copyCache) {
- var c = this.copyCache[id];
- if(!c.isdeleted()) total++;
- if(c.isnew() || c.ischanged() || c.isdeleted()) {
- if(c.id() < 0) c.id(null);
- copies.push(c);
- }
- }
-
-
- dojo.byId('acq-lit-copy-count-label-' + liId).innerHTML = total;
-
-
- if (copies.length > 0) {
- if (!this.confirmBreachedCopyFunds(copies))
- return;
-
- if (typeof(this._copy_count_cb) == "function")
- this._copy_count_cb(liId, total);
-
- openils.Util.show("acq-lit-update-copies-progress");
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem_detail.cud.batch'],
- { async: true,
- params: [openils.User.authtoken, copies],
- onresponse: function(r) {
- var res = openils.Util.readResponse(r);
- litUpdateCopiesProgress.update(res);
- },
- oncomplete: function() {
- self.drawCopies(liId, true /* force_fetch */);
- openils.Util.hide("acq-lit-update-copies-progress");
- }
- }
- );
- }
-
- var dfa_list = this._virtDfaCountsAsList();
- if (dfa_list.length > 0) {
- fieldmapper.standardRequest(
- ["open-ils.acq",
- "open-ils.acq.distribution_formula.record_application"],
- {
- "async": true,
- "params": [openils.User.authtoken, dfa_list, liId],
- "onresponse": function(r) {
- var res = openils.Util.readResponse(r);
- if (res && res.length < dfa_list.length)
- alert(localeStrings.DFA_NOT_ALL);
- }
- }
- );
- this.virtDfaCounts = {};
- }
- }
-
- this._updateCreatePoPrepayCheckbox = function(prepay) {
- var prepay = openils.Util.isTrue(prepay);
- this._prepayRequiredByVendor = prepay;
- dijit.byId("acq-lit-po-prepay").attr("checked", prepay);
- };
-
- this._confirmPoPrepaySituation = function() {
- var want_prepay = dijit.byId("acq-lit-po-prepay").attr("checked");
- if (want_prepay != this._prepayRequiredByVendor) {
- return confirm(
- want_prepay ?
- localeStrings.VENDOR_SAYS_PREPAY_NOT_NEEDED :
- localeStrings.VENDOR_SAYS_PREPAY_NEEDED
- );
- } else {
- return true;
- }
- };
-
- this.applySelectedLiAction = function(action) {
- var self = this;
- switch(action) {
-
- case 'delete_selected':
- this._deleteLiList(self.getSelected());
- break;
-
- case 'create_order':
- this._loadPOSelect();
- acqLitPoCreateDialog.show();
- break;
-
- case 'save_picklist':
- acqLitSavePlDialog.show();
- break;
-
- case 'selector_ready':
- case 'order_ready':
- acqLitChangeLiStateDialog.attr('state', action.replace('_', '-'));
- acqLitChangeLiStateDialog.show();
- break;
-
- case 'print_po':
- this.printPO();
- break;
-
- case 'po_history':
- location.href = oilsBasePath + '/acq/po/history/' + this.isPO;
- break;
-
- case 'receive_po':
- this.receivePO();
- break;
-
- case 'rollback_receive_po':
- this.rollbackPoReceive();
- break;
-
- case 'create_assets':
- this.showAssetCreator();
- break;
-
- case 'export_attr_list':
- this.chooseExportAttr();
- break;
-
- case 'batch_apply_funds':
- this.applyBatchLiFunds();
- break;
-
- case 'add_brief_record':
- if(this.isPO)
- location.href = oilsBasePath + '/acq/picklist/brief_record?po=' + this.isPO;
- else
- location.href = oilsBasePath + '/acq/picklist/brief_record?pl=' + this.isPL;
-
- break;
-
- case "cancel_lineitems":
- this.maybeCancelLineitems();
- break;
-
- case "change_claim_policy":
- var li_list = this.getSelected();
- this.claimPolicyPicker.attr("value", null);
- liClaimPolicyDialog.show();
- liClaimPolicySave.onClick = function() {
- self.changeClaimPolicy(
- li_list,
- self.claimPolicyPicker.attr("value"),
- function() {
- li_list.forEach(
- function(li) {
- self.setClaimPolicyControl(li);
- self.reconsiderClaimControl(li);
- }
- );
- liClaimPolicyDialog.hide();
- }
- )
- };
- break;
- }
- };
-
- this.changeClaimPolicy = function(li_list, value, callback) {
- li_list.forEach(
- function(li) { li.claim_policy(value); }
- );
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem.update"], {
- "params": [openils.User.authtoken, li_list],
- "async": true,
- "oncomplete": function(r) {
- r = openils.Util.readResponse(r);
- if (callback) callback(r);
- }
- }
- );
- };
-
- this.showAssetCreator = function(onAssetsCreated) {
- if(!this.isPO) return;
- var self = this;
-
- // first, let's see if this PO has any LI's that need to be merged/imported
- self.pcrud.search('jub', {purchase_order : this.isPO, eg_bib_id : null}, {
- id_list : true,
- oncomplete : function(r) {
- var resp = openils.Util.readResponse(r);
- if (resp && resp.length) {
- // PO has some non-linked jubs.
-
- self.show('asset-creator');
- if(!self.vlAgent.loaded)
- self.vlAgent.init();
-
- dojo.connect(assetCreatorButton, 'onClick',
- function() { self.createAssets(onAssetsCreated) });
-
- } else {
-
- // all jubs linked, move on to asset creation
- self.createAssets(onAssetsCreated, true);
- }
- }
- });
- }
-
- this.createAssets = function(onAssetsCreated, noVl) {
- this.show('acq-lit-progress-numbers');
- var self = this;
- var vlArgs = (noVl) ? {} : {vandelay : this.vlAgent.values()};
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.assets.create'],
- { async: true,
- params: [this.authtoken, this.isPO, vlArgs],
- onresponse: function(r) {
- var resp = openils.Util.readResponse(r);
- self._updateProgressNumbers(resp, !Boolean(onAssetsCreated), onAssetsCreated);
- }
- }
- );
- }
-
- this.maybeCancelLineitems = function() {
- openils.Util.show("acq-lit-cancel-reason", "inline");
- if (!acqLitCancelLineitemsButton._prepared) {
- var widget = new openils.widget.AutoFieldWidget({
- "fmField": "cancel_reason",
- "fmClass": "jub",
- "parentNode": dojo.byId("acq-lit-cancel-reason-selector"),
- "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
- "forceSync": true
- });
- widget.build(
- function(w, ww) {
- acqLitCancelLineitemsButton.onClick = function() {
- if (w.attr("value")) {
- if (confirm(localeStrings.LI_CANCEL_CONFIRM)) {
- self._cancelLineitems(w.attr("value"));
- }
- openils.Util.hide("acq-lit-cancel-reason");
- }
- };
- acqLitCancelLineitemsButton._prepared = true;
- }
- );
- }
- };
-
- this._cancelLineitems = function(reason) {
- var id_list = this.getSelected().map(function(o) { return o.id(); });
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem.cancel.batch"], {
- "params": [openils.User.authtoken, id_list, reason],
- "async": true,
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- if (r.li) {
- for (var id in r.li) {
- self.liCache[id].state(r.li[id].state);
- self.liCache[id].cancel_reason(
- r.li[id].cancel_reason
- );
- self.updateLiState(self.liCache[id]);
- }
- }
- if (r.lid && self.copyCache) {
- for (var id in r.lid) {
- if (self.copyCache[id]) {
- self.copyCache[id].cancel_reason(
- r.lid[id].cancel_reason
- );
- self.updateLidState(self.copyCache[id]);
- }
- }
- }
- }
- }
- }
- );
- };
-
- this.chooseExportAttr = function() {
- if (!acqLitExportAttrSelector._li_setup) {
- var self = this;
- acqLitExportAttrSelector.store = new dojo.data.ItemFileReadStore(
- {
- "data": acqlimad.toStoreData(
- this.pcrud.search(
- "acqlimad", {"code": li_exportable_attrs}
- )
- )
- }
- );
- acqLitExportAttrSelector.setValue();
- acqLitExportAttrButton.onClick = function(){self.exportAttrList();};
- acqLitExportAttrSelector._li_setup = true;
- }
- openils.Util.show("acq-lit-export-attr-holder", "inline");
- };
-
- this.exportAttrList = function() {
- var attr_def = acqLitExportAttrSelector.item;
- var li_list = this.getSelected();
- var value_list = li_list.map(
- function(li) {
- return (new openils.acq.Lineitem({"lineitem": li})).findAttr(
- attr_def.code, "lineitem_marc_attr_definition"
- );
- }
- ).filter(function(attr) { return Boolean(attr); });
-
- if (value_list.length > 0) {
- if (value_list.length < li_list.length) {
- if (!confirm(
- dojo.string.substitute(
- localeStrings.EXPORT_SHORT_LIST, [attr_def.description]
- )
- )) {
- return;
- }
- }
- try {
- openils.XUL.contentToFileSaveDialog(
- value_list.join("\n"),
- localeStrings.EXPORT_SAVE_DIALOG_TITLE
- );
- } catch (E) {
- alert(E);
- }
- } else {
- alert(dojo.string.substitute(
- localeStrings.EXPORT_EMPTY_LIST, [attr_def.description]
- ));
- }
-
- openils.Util.hide("acq-lit-export-attr-holder");
- };
-
- this.printPO = function() {
- if(!this.isPO) return;
- progressDialog.show(true);
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.format'],
- { async: true,
- params: [this.authtoken, this.isPO, 'html'],
- oncomplete: function(r) {
- progressDialog.hide();
- var evt = openils.Util.readResponse(r);
- if(evt && evt.template_output()) {
- openils.Util.printHtmlString(evt.template_output().data());
- }
- }
- }
- );
- }
-
-
- this.receivePO = function() {
- if (!this.isPO) return;
-
- for (var id in this.liCache) {
- /* assumption: liCache reflects exactly the
- * set of LIs that belong to our PO */
- if (this.liCache[id].state() != "received" &&
- !this.checkLiAlerts(id)) return;
- }
-
- this.show('acq-lit-progress-numbers');
- var self = this;
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.receive'],
- { async: true,
- params: [this.authtoken, this.isPO],
- onresponse : function(r) {
- var resp = openils.Util.readResponse(r);
- self._updateProgressNumbers(resp, true);
- },
- }
- );
- }
-
- this.issueReceive = function(obj, rollback) {
- /* (For now) there shall be no marking LI or LIDs (un)received
- * except from the actual "view PO" interface. */
- if (!this.isPO) return;
-
- var part =
- {"jub": "lineitem", "acqlid": "lineitem_detail"}[obj.classname];
- var method =
- "open-ils.acq." + part + ".receive" + (rollback ? ".rollback" : "");
-
- progressDialog.show(true);
- fieldmapper.standardRequest(
- ["open-ils.acq", method], {
- "async": true,
- "params": [this.authtoken, obj.id()],
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- self.fetchClaimInfo(
- part == "lineitem" ? obj.id() : obj.lineitem(),
- /* force */ true,
- function() { self.handleReceive(r); }
- );
- progressDialog.hide();
- }
- }
- }
- );
- };
-
- /**
- * Handles the responses from receive and rollback ML calls.
- */
- this.handleReceive = function(resp) {
- if (resp) {
- if (resp.li) {
- for (var li_id in resp.li) {
- for (var key in resp.li[li_id])
- self.liCache[li_id][key](resp.li[li_id][key]);
- self.updateLiState(self.liCache[li_id]);
- }
- }
- if (resp.po) {
- if (typeof(self.poUpdateCallback) == "function")
- self.poUpdateCallback(resp.po);
- }
- if (resp.lid) {
- for (var lid_id in resp.lid) {
- for (var key in resp.lid[lid_id])
- self.copyCache[lid_id][key](resp.lid[lid_id][key]);
- self.updateLidState(self.copyCache[lid_id]);
- }
- }
- }
- };
-
- this.rollbackPoReceive = function() {
- if(!this.isPO) return;
- if(!confirm(localeStrings.ROLLBACK_PO_RECEIVE_CONFIRM)) return;
- this.show('acq-lit-progress-numbers');
- var self = this;
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.receive.rollback'],
- { async: true,
- params: [this.authtoken, this.isPO],
- onresponse : function(r) {
- var resp = openils.Util.readResponse(r);
- self._updateProgressNumbers(resp, true);
- },
- }
- );
- }
-
- this._updateProgressNumbers = function(resp, reloadOnComplete, onComplete) {
- this.vlAgent.handleResponse(resp,
- function(resp, res) {
- if(reloadOnComplete)
- location.href = location.href;
- if (onComplete)
- onComplete(resp, res);
- }
- );
- }
-
-
- this._createPO = function(fields) {
- var wantall = (fields.create_from == "all");
-
- /* If we're a picklist or purchase order already and the user wants
- * all lineitems, we might have pages' worth of lineitems haven't all
- * been loaded yet, so getSelected() won't find them. The server,
- * however, should know about all our lineitems, so let's ask the
- * server for a complete list.
- */
-
- if (wantall) {
- this.getSelected(
- true, function(list) {
- self._createPOFromLineitems(fields, list);
- }, /* id_list */ true
- );
- } else {
- this._createPOFromLineitems(fields, this.getSelected(false, null, true /* id_list */));
- }
- };
-
- this._createPOFromLineitems = function(fields, selected) {
- if (selected.length == 0) return;
- var self = this;
-
- var po = new fieldmapper.acqpo();
- po.provider(this.createPoProviderSelector.attr("value"));
- po.ordering_agency(this.createPoAgencySelector.attr("value"));
- po.prepayment_required(fields.prepayment_required[0] ? true : false);
-
- // if we're creating assets, delay the asset creation
- // until after the PO is created. This will allow us to
- // use showAssetCreator() directly.
-
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.purchase_order.create"],
- { async: true,
- params: [
- openils.User.authtoken,
- po, {lineitems : selected}
- ],
- onresponse : function(r) {
- var resp = openils.Util.readResponse(r);
- if (resp.complete) {
- // self.isPO is needed for showAssetCreator();
- self.isPO = resp.purchase_order.id();
- var redir = oilsBasePath + "/acq/po/view/" + self.isPO;
- if (fields.create_assets[0]) {
- self.showAssetCreator(
- function() {location.href = redir}
- );
- } else {
- location.href = redir;
- }
- }
- }
- }
- );
- };
-
-
- this.batchFundWidget = null;
-
- this.applyBatchLiFunds = function() {
-
- var liIds = this.getSelected().map(function(li) { return li.id(); });
- if(liIds.length == 0) return; // warn?
-
- var self = this;
- batchFundUpdateDialog.show();
-
- if(!this.batchFundWidget) {
- this.batchFundWidget = new openils.widget.AutoFieldWidget({
- fmClass : 'acqf',
- selfReference : true,
- labelFormat : fundLabelFormat,
- searchFormat : fundSearchFormat,
- searchFilter : {"active": "t"},
- parentNode : dojo.byId('acq-lit-batch-fund-selector'),
- orgLimitPerms : ['CREATE_PICKLIST', 'CREATE_PURCHASE_ORDER'],
- dijitArgs : { "required": true, "labelType": "html" },
- forceSync : true
- });
- this.batchFundWidget.build();
- }
-
- dojo.connect(batchFundUpdateCancel, 'onClick', function() { batchFundUpdateDialog.hide(); });
- dojo.connect(batchFundUpdateSubmit, 'onClick',
- function() {
-
- // TODO: call .dry_run first to test thresholds
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.fund.update.batch'],
- {
- params : [
- openils.User.authtoken,
- liIds,
- self.batchFundWidget.widget.attr('value')
- ],
- oncomplete : function(r) {
- var resp = openils.Util.readResponse(r);
- if(resp) {
- location.href = location.href;
- }
- }
- }
- )
- }
- );
- }
-
- this._deleteLiList = function(list, idx) {
- if(idx == null) idx = 0;
- if(idx >= list.length) return;
-
- var li = list[idx];
- var liId = li.id();
-
- if (this.isPO && (li.state() == "on-order" || li.state() == "received")) {
- /* It makes little sense to delete a lineitem from a PO that has
- * already been marked 'on-order'. Especially if EDI is in use,
- * such a purchase order will probably have already been shipped
- * off to a vendor, and mucking with it at this point could leave
- * your data in a bad state that doesn't jive with reality.
- *
- * I could see making this restriction even firmer.
- *
- * I could also see adjusting the li state comparisons, extending
- * the comparison to the PO's state, and/or providing functions
- * that house the logic for comparing states in a single location.
- *
- * Yes, this will be really annoying if you have selected a lot
- * of lineitems to cancel that have been ordered. You'll get a
- * confirm dialog for each one.
- */
-
- if (!confirm(localeStrings.DEL_LI_FROM_PO)) {
- self._deleteLiList(list, ++idx); /* move on to next in list */
- return;
- }
- }
-
- fieldmapper.standardRequest(
- ['open-ils.acq',
- this.isPO ? 'open-ils.acq.purchase_order.lineitem.delete' : 'open-ils.acq.picklist.lineitem.delete'],
- { async: true,
- params: [openils.User.authtoken, liId],
- oncomplete: function(r) {
- self.removeLineitem(liId);
- self._deleteLiList(list, ++idx);
- }
- }
- );
- }
-
- this.editOrderMarc = function(li) {
-
- /* To run in Firefox directly, must set signed.applets.codebase_principal_support
- to true in about:config */
-
- if(!openils.XUL.enableXPConnect()) return;
-
- if(openils.XUL.isXUL()) {
- win = window.open('/xul/' + openils.XUL.buildId() + '/server/cat/marcedit.xul');
- } else {
- win = window.open('/xul/server/cat/marcedit.xul');
- }
- var self = this;
- win.xulG = {
- record : {marc : li.marc(), "rtype": "bre"},
- save : {
- label: 'Save Record', // XXX I18N
- func: function(xmlString) {
- li.marc(xmlString);
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.update'],
- { async: true,
- params: [openils.User.authtoken, li],
- oncomplete: function(r) {
- openils.Util.readResponse(r);
- win.close();
- self.drawInfo(li.id())
- }
- }
- );
- },
- },
- 'lock_tab' : typeof xulG != 'undefined' ? (typeof xulG['lock_tab'] != 'undefined' ? xulG.lock_tab : undefined) : undefined,
- 'unlock_tab' : typeof xulG != 'undefined' ? (typeof xulG['unlock_tab'] != 'undefined' ? xulG.unlock_tab : undefined) : undefined
- };
- }
-
- this._savePl = function(values) {
- this.getSelected(
- (values.which == 'all'),
- function(list) { self._savePlFromLineitems(values, list); }
- );
- };
-
- this._savePlFromLineitems = function(values, selected) {
- openils.Util.show("acq-lit-generic-progress");
-
- if(values.new_name) {
- openils.acq.Picklist.create(
- {name: values.new_name},
- function(id) {
- self._updateLiList(
- id, selected, 0,
- function() {
- location.href =
- oilsBasePath + "/acq/picklist/view/" + id;
- }
- );
- }
- );
- } else if(values.existing_pl) {
- // update lineitems to use an existing picklist
- self._updateLiList(
- values.existing_pl, selected, 0,
- function(){
- location.href =
- oilsBasePath + "/acq/picklist/view/" +
- values.existing_pl;
- }
- );
- }
- };
-
- this._updateLiState = function(values, state) {
- progressDialog.show(true);
- this.getSelected(
- (values.which == 'all'),
- function(list) {
- self._updateLiStateFromLineitems(values, state, list);
- }
- );
- };
-
- this._updateLiStateFromLineitems = function(values, state, selected) {
- if(!selected.length) return;
- dojo.forEach(selected, function(li) {li.state(state);});
- self._updateLiList(null, selected, 0,
- // TODO consider inline updates for efficiency
- function() { location.href = location.href }
- );
- };
-
- this._updateLiList = function(pl, list, idx, oncomplete) {
- if(idx >= list.length) return oncomplete();
- var li = list[idx];
- if(pl != null) li.picklist(pl);
- litGenericProgress.update({maximum: list.length, progress: idx});
- new openils.acq.Lineitem({lineitem:li}).update(
- function(r) {
- self._updateLiList(pl, list, ++idx, oncomplete);
- }
- );
- }
-
- this._loadPOSelect = function() {
- if (!this.createPoProviderSelector) {
- var widget = new openils.widget.AutoFieldWidget({
- "fmField": "provider",
- "fmClass": "acqpo",
- "searchFilter": {"active": "t"},
- "parentNode": dojo.byId("acq-lit-po-provider"),
- "dijitArgs": {
- "onChange": function() {
- if (this.item) {
- self._updateCreatePoPrepayCheckbox(
- this.item.prepayment_required()
- );
- }
- }
- }
- });
- widget.build(function(w) { self.createPoProviderSelector = w; });
- }
-
- if (!this.createPoAgencySelector) {
- var widget = new openils.widget.AutoFieldWidget({
- "fmField": "ordering_agency",
- "fmClass": "acqpo",
- "parentNode": dojo.byId("acq-lit-po-agency"),
- "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
- });
- widget.build(function(w) { self.createPoAgencySelector = w; });
- }
- };
-
- this.showRealCopyEditUI = function(li) {
- copyList = [];
- var self = this;
- this.volCache = {};
-
- this._fetchLineitem(li.id(),
- function(fullLi) {
- li = self.liCache[li.id()] = fullLi;
-
- self.pcrud.search(
- 'acp', {
- id : li.lineitem_details().map(
- function(item) { return item.eg_copy_id() }
- )
- }, {
- async : true,
- oncomplete : function(r) {
- try {
- var r_list = openils.Util.readResponse( r );
- for (var i = 0; i < r_list.length; i++) {
- var copy = r_list[i];
- var volId = copy.call_number();
- var volume = self.volCache[volId];
- if(!volume) {
- volume = self.volCache[volId] = self.pcrud.retrieve('acn', volId);
- }
- copy.call_number(volume);
- copyList.push(copy);
- }
- if (xulG) {
- xulG.volume_item_creator( { 'existing_copies' : copyList } );
- }
- } catch(E) {
- alert('error in oncomplete: ' + E);
- }
- }
- }
- );
- }
- );
- },
-
- this.drawBibFinder = function(li) {
-
- var query = '';
- var liWrapper = new openils.acq.Lineitem({lineitem:li});
-
- dojo.forEach(
- ['isbn', 'upc', 'issn', 'title', 'author'],
- function(field) {
- var val = liWrapper.findAttr(field, 'lineitem_marc_attr_definition');
- if(val) {
- if(field == 'title' || field == 'author') {
- query += field +':' + val + ' ';
- } else {
- query += 'identifier|' + field + ':' + val + ' ';
- }
- }
- }
- );
-
- win = window.open(
- oilsBasePath + '/acq/lineitem/findbib?query=' + escape(query),
- '', 'resizable,scrollbars=1');
-
- win.window.recordFound = function(bibId) {
- win.close();
-
- var attrs = li.attributes();
- li.attributes(null);
- li.eg_bib_id(bibId);
-
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem.update"],
- {
- "params": [openils.User.authtoken, li],
- "async": true,
- "oncomplete": function(r) {
- if(openils.Util.readResponse(r)) {
- location.href = location.href;
- }
- }
- }
- );
- }
- }
-}
-
+require([
+ "dojo/date/locale",
+ "dojo/date/stamp",
+ "dijit/form/Button",
+ "dijit/form/TextBox",
+ "dijit/form/FilteringSelect",
+ "dijit/form/Textarea",
+ "dijit/Tooltip",
+ "dijit/ProgressBar",
+ "openils/acq/Lineitem",
+ "openils/acq/PO",
+ "openils/acq/Picklist",
+ "openils/widget/AutoFieldWidget",
+ "dojo/data/ItemFileReadStore",
+ "openils/widget/ProgressDialog",
+ "openils/PermaCrud",
+ "openils/widget/PCrudAutocompleteBox"
+ ],
+function(dojo_date_locale,
+ dojo_date_stamp,
+ dijit_form_Button,
+ dijit_form_TextBox,
+ dijit_form_FilteringSelect,
+ dijit_form_Textarea,
+ dijit_Tooltip,
+ dijit_ProgressBar,
+ openils_acq_Lineitem,
+ openils_acq_PO,
+ openils_acq_Picklist,
+ openils_widget_AutoFieldWidget,
+ dojo_data_ItemFileReadStore,
+ openils_widget_ProgressDialog,
+ openils_PermaCrud,
+ openils_widget_PCrudAutocompleteBox){
+
+ if (!localeStrings) { /* we can do this because javascript doesn't have block scope */
+ dojo.requireLocalization('openils.acq', 'acq');
+ var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
+ }
+ const XUL_OPAC_WRAPPER = 'chrome://open_ils_staff_client/content/cat/opac.xul';
+ var li_exportable_attrs = ["issn", "isbn", "upc"];
+
+ var fundLabelFormat = [
+ '<span class="fund_${0}">${1} (${2})</span>', 'id', 'code', 'year'
+ ];
+ var fundSearchFormat = ['${0} (${1})', 'code', 'year'];
+
+ function nodeByName(name, context) {
+ return dojo.query('[name='+name+']', context)[0];
+ }
+
+ // for caching linked users. e.g. lineitem_detail.receiver
+ var userCache = {};
+
+ var liDetailBatchFields = ['fund', 'owning_lib', 'location', 'collection_code', 'circ_modifier', 'cn_label'];
+ var liDetailFields = liDetailBatchFields.concat(['barcode', 'note']);
+ var fundStyles = {
+ "stop": "color: #c00; font-weight: bold;",
+ "warning": "color: #c93;"
+ };
+
+ function AcqLiTable() {
+
+ var self = this;
+ this.liCache = {};
+ this.plCache = {};
+ this.poCache = {};
+ this.relCache = {};
+ this.haveFundClass = {}
+ this.fundBalanceState = {};
+ this.realDfaCache = {};
+ this.virtDfaCounts = {};
+ this.virtDfaId = -1;
+ this.dfeOffset = 0;
+ this.claimEligibleLidByLi = {};
+ this.claimEligibleLid = {};
+ this.toggleState = false;
+ this.tbody = dojo.byId('acq-lit-tbody');
+ this.selectors = [];
+ this.noteAcks = {};
+ this.authtoken = openils.User.authtoken;
+ this.pcrud = new openils_PermaCrud();
+ this.rowTemplate = this.tbody.removeChild(dojo.byId('acq-lit-row'));
+ this.copyTbody = dojo.byId('acq-lit-li-details-tbody');
+ this.copyRow = this.copyTbody.removeChild(dojo.byId('acq-lit-li-details-row'));
+ this.copyBatchRow = dojo.byId('acq-lit-li-details-batch-row');
+ this.copyBatchWidgets = {};
+ this.liNotesTbody = dojo.byId('acq-lit-notes-tbody');
+ this.liNotesRow = this.liNotesTbody.removeChild(dojo.byId('acq-lit-notes-row'));
+ this.realCopiesTbody = dojo.byId('acq-lit-real-copies-tbody');
+ this.realCopiesRow = this.realCopiesTbody.removeChild(dojo.byId('acq-lit-real-copies-row'));
+ this._copy_fields_for_acqdf = ['owning_lib', 'location'];
+ this.skipInitialEligibilityCheck = false;
+ this.claimDialog = new ClaimDialogManager(
+ liClaimDialog, finalClaimDialog, this.claimEligibleLidByLi,
+ function(li) { /* callback that fires when claims are made */
+ self.fetchClaimInfo(li.id(), /* force update */ true);
+ }
+ );
+ this.vlAgent = new VLAgent();
+
+ dojo.byId("acq-lit-li-actions-selector").onchange = function() {
+ self.applySelectedLiAction(this.options[this.selectedIndex].value);
+ this.selectedIndex = 0;
+ };
+
+ acqLitCreatePoSubmit.onClick = function() {
+ if (!self.createPoProviderSelector.attr("value") ||
+ !self.createPoAgencySelector.attr("value")) {
+ alert(localeStrings.CREATE_PO_INVALID);
+ return false;
+ } else if (self._confirmPoPrepaySituation()) {
+ acqLitPoCreateDialog.hide();
+ self._createPO(acqLitPoCreateDialog.getValues());
+ } else {
+ return false;
+ }
+ }
+
+ acqLitSavePlButton.onClick = function() {
+ acqLitSavePlDialog.hide();
+ self._savePl(acqLitSavePlDialog.getValues());
+ }
+
+ acqLitCancelLiStateButton.onClick = function() {
+ acqLitChangeLiStateDialog.hide();
+ }
+ acqLitSaveLiStateButton.onClick = function() {
+ acqLitChangeLiStateDialog.hide();
+ self._updateLiState(acqLitChangeLiStateDialog.getValues(), acqLitChangeLiStateDialog.attr('state'));
+ }
+
+
+ dojo.byId('acq-lit-select-toggle').onclick = function(){self.toggleSelect()};
+ dojo.byId('acq-lit-info-back-button').onclick = function(){self.show('list')};
+ dojo.byId('acq-lit-copies-back-button').onclick = function(){self.show('list')};
+ dojo.byId('acq-lit-notes-back-button').onclick = function(){self.show('list')};
+ dojo.byId('acq-lit-real-copies-back-button').onclick = function(){self.show('list')};
+
+ this.reset = function(keep_selectors) {
+ while(self.tbody.childNodes[0])
+ self.tbody.removeChild(self.tbody.childNodes[0]);
+ self.noteAcks = {};
+ self.relCache = {};
+
+ if (!keep_selectors)
+ self.selectors = [];
+ };
+
+ this.setNext = function(handler) {
+ var link = dojo.byId('acq-lit-next');
+ if(handler) {
+ dojo.style(link, 'visibility', 'visible');
+ link.onclick = handler;
+ } else {
+ dojo.style(link, 'visibility', 'hidden');
+ }
+ };
+
+ this.setPrev = function(handler) {
+ var link = dojo.byId('acq-lit-prev');
+ if(handler) {
+ dojo.style(link, 'visibility', 'visible');
+ link.onclick = handler;
+ } else {
+ dojo.style(link, 'visibility', 'hidden');
+ }
+ };
+
+ this.show = function(div) {
+ openils.Util.hide('acq-lit-table-div');
+ openils.Util.hide('acq-lit-info-div');
+ openils.Util.hide('acq-lit-li-details');
+ openils.Util.hide('acq-lit-notes-div');
+ openils.Util.hide('acq-lit-real-copies-div');
+ openils.Util.hide('acq-lit-asset-creator');
+ switch(div) {
+ case 'list':
+ openils.Util.show('acq-lit-table-div');
+ break;
+ case 'info':
+ openils.Util.show('acq-lit-info-div');
+ break;
+ case 'copies':
+ openils.Util.show('acq-lit-li-details');
+ break;
+ case 'real-copies':
+ openils.Util.show('acq-lit-real-copies-div');
+ break;
+ case 'notes':
+ openils.Util.show('acq-lit-notes-div');
+ break;
+ case 'asset-creator':
+ openils.Util.show('acq-lit-asset-creator');
+ break;
+ default:
+ if(div)
+ openils.Util.show(div);
+ }
+ }
+
+ this.hide = function() {
+ this.show(null);
+ }
+
+ this.toggleSelect = function() {
+ if(self.toggleState)
+ dojo.forEach(self.selectors, function(i){i.checked = false});
+ else
+ dojo.forEach(self.selectors, function(i){i.checked = true});
+ self.toggleState = !self.toggleState;
+ };
+
+
+ this.getAll = function(callback, id_only) {
+ /* For some uses of the li table, we may not really know about "all"
+ * the lineitems that the user thinks we know about. If we're a paged
+ * picklist, for example, we only know about the lineitems we've
+ * displayed, but not necessarily all the lineitems on the picklist.
+ * So we reach out to pcrud to inform us.
+ */
+
+ var oncomplete = function(r) {
+ var id_list = openils.Util.readResponse(r);
+ if (id_only)
+ callback(id_list);
+ else
+ self.fetchLineitemsById(id_list, callback);
+ };
+
+ if (this.isPL) {
+ this.pcrud.search(
+ "jub", {"picklist": this.isPL}, {
+ "id_list": true, /* sic, even if id_only */
+ "async": true,
+ "oncomplete": oncomplete
+ }
+ );
+ return;
+ } else if (this.isPO) {
+ this.pcrud.search(
+ "jub", {"purchase_order": this.isPO}, {
+ "id_list": true,
+ "async": true,
+ "oncomplete": oncomplete
+ }
+ );
+ return;
+ } else if (this.isUni && this.pager) {
+ this.pager.getAllLineitemIDs(oncomplete);
+ return;
+ }
+
+ /* If execution reaches this point, we don't need or can't perform
+ * any special tricks to find out the "real" list of "all" lineitems
+ * in this context, so we fall back to the old method.
+ */
+ callback(this.getSelected(true, null, id_only));
+ };
+
+ /** @param all If true, assume all are selected */
+ this.getSelected = function(
+ all,
+ callback /* If you want a "good" idea of "all" lineitems, you must
+ provide a callback that accepts an array parameter, rather than
+ relying on the return value of this method itself. */,
+ id_only
+ ) {
+ if (all && callback)
+ return this.getAll(callback, id_only);
+
+ var indices = {}; /* use to uniqify. needed in paging situations. */
+ dojo.forEach(this.selectors,
+ function(i) {
+ if(i.checked || all)
+ indices[i.parentNode.parentNode.getAttribute('li')] = true;
+ }
+ );
+
+ var result = openils.Util.objectProperties(indices);
+
+ if (!id_only)
+ result = result.map(function(liId) { return self.liCache[liId]; });
+
+ if (callback)
+ callback(result);
+ else
+ return result;
+ };
+
+ this.setRowAttr = function(td, liWrapper, field, type) {
+ var val = liWrapper.findAttr(field, type || 'lineitem_marc_attr_definition') || '';
+ td.appendChild(document.createTextNode(val));
+ };
+
+ this.setClaimPolicyControl = function(li, row) {
+ if (!self.claimPolicyPicker) {
+ self.claimPolicyPicker = true; /* prevents a race condition */
+ new openils_widget_AutoFieldWidget({
+ "parentNode": "acq-lit-li-claim-policy",
+ "fmClass": "acqclp",
+ "selfReference": true,
+ "dijitArgs": {"required": true}
+ }).build(function(w) { self.claimPolicyPicker = w; });
+ }
+
+ if (!row) row = this._findLiRow(li);
+
+ var actViewPolicy = nodeByName("action_view_claim_policy", row);
+ if (li.claim_policy())
+ actViewPolicy.innerHTML = localeStrings.CHANGE_CLAIM_POLICY;
+
+ if (!actViewPolicy.onclick) {
+ actViewPolicy.onclick = function() {
+ if (li.claim_policy())
+ self.claimPolicyPicker.attr("value", li.claim_policy());
+ liClaimPolicyDialog.show();
+ liClaimPolicySave.onClick = function() {
+ self.changeClaimPolicy(
+ [li], self.claimPolicyPicker.attr("value"),
+ function() {
+ self.setClaimPolicyControl(li, row);
+ self.reconsiderClaimControl(li, row);
+ liClaimPolicyDialog.hide();
+ }
+ );
+ }
+ };
+ }
+ };
+
+ this.fetchClaimInfo = function(liId, force, callback, row) {
+ this._fetchLineitem(
+ liId, function(full) {
+ self.liCache[full.id()] = full;
+ self.checkClaimEligibility(full, callback, row);
+ }, force
+ );
+ }
+
+ /**
+ * Inserts a single lineitem into the growing table of lineitems
+ * @param {Object} li The lineitem object to insert
+ */
+ this.addLineitem = function(li, skip_final_placement) {
+ this.liCache[li.id()] = li;
+
+ // insert the row right away so that final order isn't
+ // dependent on how long subsequent async request take
+ // for a given line item
+ var row = self.rowTemplate.cloneNode(true);
+ if (!skip_final_placement) {
+ self.tbody.appendChild(row);
+ }
+ self.selectors.push(dojo.query('[name=selectbox]', row)[0]);
+
+ // sort the lineitem notes on edit_time
+ if(!li.lineitem_notes()) li.lineitem_notes([]);
+
+ var liWrapper = new openils_acq_Lineitem({lineitem:li});
+ row.setAttribute('li', li.id());
+ var tds = dojo.query('[attr]', row);
+ dojo.forEach(tds, function(td) {self.setRowAttr(td, liWrapper, td.getAttribute('attr'), td.getAttribute('attr_type'));});
+ dojo.query('[name=source_label]', row)[0].appendChild(document.createTextNode(li.source_label()));
+
+ var identifier =
+ liWrapper.findAttr("isbn", "lineitem_marc_attr_definition") ||
+ liWrapper.findAttr("upc", "lineitem_marc_attr_definition");
+
+ // XXX media prefix for added content
+ if (identifier) {
+ nodeByName("jacket", row).setAttribute(
+ "src", "/opac/extras/ac/jacket/small/" + identifier
+ );
+ }
+
+ nodeByName("liid", row).innerHTML += li.id();
+
+ if(li.eg_bib_id()) {
+ openils.Util.show(nodeByName('catalog', row), 'inline');
+ nodeByName("catalog_link", row).onclick = this.generateMakeRecTab(li.eg_bib_id());
+ } else {
+ openils.Util.show(nodeByName('link_to_catalog', row), 'inline');
+ nodeByName("link_to_catalog_link", row).onclick = function() { self.drawBibFinder(li) };
+ }
+
+ if (li.queued_record()) {
+ this.pcrud.retrieve('vqbr', li.queued_record(),
+ { async : true,
+ oncomplete : function(r) {
+ var qrec = openils.Util.readResponse(r);
+ openils.Util.show(nodeByName('queue', row), 'inline');
+ var link = nodeByName("queue_link", row);
+ link.onclick = function() {
+ // open a new tab to the vandelay queue for this record
+ openils.XUL.newTabEasy(
+ oilsBasePath + '/vandelay/vandelay?qtype=bib&qid=' + qrec.queue()
+ );
+ }
+ }
+ }
+ );
+ }
+
+ nodeByName("worksheet_link", row).href =
+ oilsBasePath + "/acq/lineitem/worksheet/" + li.id();
+
+ nodeByName("show_requests_link", row).href =
+ oilsBasePath + "/acq/picklist/user_request?lineitem=" + li.id();
+
+ dojo.query('[attr=title]', row)[0].onclick = function() {self.drawInfo(li.id())};
+ dojo.query('[name=copieslink]', row)[0].onclick = function() {self.drawCopies(li.id())};
+ dojo.query('[name=noteslink]', row)[0].onclick = function() {self.drawLiNotes(li)};
+
+ if (!this.skipInitialEligibilityCheck)
+ this.fetchClaimInfo(
+ li.id(),
+ false,
+ function(full) { self.setClaimPolicyControl(full, row) },
+ row
+ );
+
+ this.updateLiNotesCount(li, row);
+
+ // show which PO this lineitem is a member of
+ if(li.purchase_order() && !this.isPO) {
+ var po =
+ this.poCache[li.purchase_order()] =
+ this.poCache[li.purchase_order()] ||
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.retrieve'],
+ {params: [
+ this.authtoken, li.purchase_order(), {
+ "flesh_price_summary": true,
+ "flesh_provider" : true,
+ "flesh_lineitem_count": true
+ }
+ ]});
+ if(po && !this.isMeta) {
+ openils.Util.show(nodeByName('po', row), 'inline');
+ var link = nodeByName('po_link', row);
+ link.setAttribute('href', oilsBasePath + '/acq/po/view/' + li.purchase_order());
+ link.innerHTML += po.name();
+
+ openils.Util.show(nodeByName('pro', row), 'inline');
+ link = nodeByName('pro_link', row);
+ link.setAttribute('href', oilsBasePath + '/conify/global/acq/provider/' + po.provider().id())
+ link.innerHTML += po.provider().code();
+ }
+ }
+
+ // show which picklist this lineitem is a member of
+ if(li.picklist() && (this.isPO || this.isMeta || this.isUni)) {
+ var pl =
+ this.plCache[li.picklist()] =
+ this.plCache[li.picklist()] ||
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.picklist.retrieve.authoritative'],
+ {params: [this.authtoken, li.picklist()]});
+ if (pl) {
+ if (pl.name() == "") {
+ openils.Util.show(nodeByName("bib_origin", row), "inline");
+
+ } else {
+
+ openils.Util.show(nodeByName('pl', row), 'inline');
+ var link = nodeByName('pl_link', row);
+ link.setAttribute('href', oilsBasePath + '/acq/picklist/view/' + li.picklist());
+ link.innerHTML += pl.name();
+ }
+ }
+ }
+
+ var countNode = nodeByName('count', row);
+ var count = li.item_count() || 0;
+ if (typeof(this._copy_count_cb) == "function") {
+ this._copy_count_cb(li.id(), count);
+ }
+ countNode.innerHTML = count;
+ countNode.id = 'acq-lit-copy-count-label-' + li.id();
+
+ // lineitem price
+ var priceInput = dojo.query('[name=price]', row)[0];
+ priceInput.value = li.estimated_unit_price() || '';
+ priceInput.onchange = function() { self.updateLiPrice(priceInput, li) };
+
+ // show either "mark received" or "unreceive" as appropriate
+ this.updateLiState(li, row);
+
+ if (skip_final_placement) {
+ return row;
+ }
+ };
+
+ this._liCountClaims = function(li) {
+ var total = 0;
+ for (var i = 0; i < li.lineitem_details().length; i++)
+ total += li.lineitem_details()[i].claims().length;
+ return total;
+ };
+
+ this._findLiRow = function(li) {
+ return dojo.query('tr[li="' + li.id() + '"]', "acq-lit-tbody")[0];
+ };
+
+ this.reconsiderClaimControl = function(li, row) {
+ if (!row) row = this._findLiRow(li);
+ var option = nodeByName("action_manage_claims", row);
+ var eligible = this.claimEligibleLidByLi[li.id()].length;
+ var count = this._liCountClaims(li);
+
+ option.disabled = !(count || eligible);
+ option.innerHTML =
+ dojo.string.substitute(localeStrings.NUM_CLAIMS_EXISTING, [count]);
+ option.onclick = function() { self.claimDialog.show(li); };
+ };
+
+ this.clearEligibility = function(li) {
+ this.claimEligibleLidByLi[li.id()] = [];
+
+ if (li.lineitem_details()) {
+ li.lineitem_details().forEach(
+ function(lid) { delete self.claimEligibleLid[lid.id()]; }
+ );
+ }
+
+ if (this.copyCache) {
+ var to_del = [];
+ for (var k in this.copyCache) {
+ if (this.copyCache[k].lineitem() == li.id())
+ to_del.push(k);
+ }
+ to_del.forEach(
+ function(k) { delete self.claimEligibleLid[k]; }
+ );
+ }
+ };
+
+ this.checkClaimEligibility = function(li, callback, row) {
+ /* Assume always eligible, i.e. from this interface we don't care about
+ * claim eligibility any more. this is where the user would force a
+ * claime. */
+ this.clearEligibility(li);
+ this.claimEligibleLidByLi[li.id()] = li.lineitem_details().map(
+ function(lid) { return lid.id(); }
+ );
+ li.lineitem_details().forEach(
+ function(lid) { self.claimEligibleLid[lid.id()] = true; }
+ );
+ this.reconsiderClaimControl(li, row);
+ if (callback) callback(li);
+ /*
+ this.clearEligibility(li);
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.claim.eligible.lineitem_detail"], {
+ "params": [openils.User.authtoken, {"lineitem": li.id()}],
+ "async": true,
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ self.claimEligibleLidByLi[li.id()].push(
+ r.lineitem_detail()
+ );
+ self.claimEligibleLid[r.lineitem_detail()] = true;
+ }
+ },
+ "oncomplete": function() {
+ self.reconsiderClaimControl(li, row);
+ if (typeof(callback) == "function")
+ callback();
+ }
+ }
+ );
+ */
+ };
+
+ this.updateLiNotesCount = function(li, row) {
+ if (!row) row = this._findLiRow(li);
+
+ var has_notes = (li.lineitem_notes().filter(
+ function(o) { return Boolean (o.alert_text()); }
+ ).length > 0);
+
+ /* U+2691 is the code point for a filled-in flag character */
+ nodeByName("notes_alert_flag", row).innerHTML =
+ has_notes ? "⚑" : "";
+ nodeByName("noteslink", row).style.fontStyle =
+ has_notes ? "italic" : "normal";
+ nodeByName("notes_count", row).innerHTML = li.lineitem_notes().length;
+ };
+
+ /* XXX NOT related to _updateLiState(). rethink */
+ this.updateLiState = function(li, row) {
+ if (!row) row = this._findLiRow(li);
+
+ var actReceive = nodeByName("action_mark_recv", row);
+ var actUnRecv = nodeByName("action_mark_unrecv", row);
+ var actUpdateBarcodes = nodeByName("action_update_barcodes", row);
+ var actHoldingsMaint = nodeByName("action_holdings_maint", row);
+
+ var actNewInvoice = nodeByName('action_new_invoice', row);
+ var actLinkInvoice = nodeByName('action_link_invoice', row);
+ var actViewInvoice = nodeByName('action_view_invoice', row);
+
+ nodeByName('action_view_history', row).onclick =
+ function() { location.href = oilsBasePath + '/acq/lineitem/history/' + li.id(); };
+
+ var state_cell = nodeByName("li_state", row);
+
+ if (li.state() == "cancelled") {
+ if (typeof li.cancel_reason() == "object") {
+ var holds_state = dojo.create(
+ "span", {
+ "style": "border-bottom: 1px dashed #000;",
+ "innerHTML": li.state()
+ }, state_cell, "only"
+ );
+ new dijit_Tooltip(
+ {
+ "label": "<em>" + li.cancel_reason().label() +
+ "</em><br />" + li.cancel_reason().description(),
+ "connectId": [holds_state]
+ }, dojo.create("span", null, state_cell, "last")
+ );
+ } else {
+ state_cell.innerHTML = li.state(); // TODO i18n state labels
+ }
+ } else {
+ state_cell.innerHTML = li.state(); // TODO i18n state labels
+ }
+
+
+ /* handle row coloring for based on LI state */
+ openils.Util.removeCSSClass(row, /^oils-acq-li-state-/);
+ openils.Util.addCSSClass(row, "oils-acq-li-state-" + li.state());
+
+ /* handle links that appear/disappear based on whether LI is received */
+ if (this.isPO) {
+ var self = this;
+
+ actNewInvoice.onclick = function() {
+ location.href = oilsBasePath + '/acq/invoice/view?create=1&attach_li=' + li.id();
+ nodeByName("action_none", row).selected = true;
+ };
+ actLinkInvoice.onclick = function() {
+ if (!self.invoiceLinkDialogManager) {
+ self.invoiceLinkDialogManager =
+ new InvoiceLinkDialogManager("li");
+ }
+ self.invoiceLinkDialogManager.target = li;
+ acqLitLinkInvoiceDialog.show();
+ nodeByName("action_none", row).selected = true;
+ };
+ actViewInvoice.onclick = function() {
+ location.href = oilsBasePath +
+ "/acq/search/unified?so=" +
+ base64Encode({"jub":[{"id": li.id()}]}) +
+ "&rt=invoice";
+ nodeByName("action_none", row).selected = true;
+ };
+
+ actNewInvoice.disabled = false;
+ actLinkInvoice.disabled = false;
+ actViewInvoice.disabled = false;
+
+ switch(li.state()) {
+ case "on-order":
+ actReceive.disabled = false;
+ actReceive.onclick = function() {
+ if (self.checkLiAlerts(li.id()))
+ self.issueReceive(li);
+ nodeByName("action_none", row).selected = true;
+ };
+ return;
+
+ case "received":
+ actUnRecv.disabled = false;
+ actUnRecv.onclick = function() {
+ if (confirm(localeStrings.UNRECEIVE_LI))
+ self.issueReceive(li, /* rollback */ true);
+ nodeByName("action_none", row).selected = true;
+ };
+ // TODO we should allow editing before receipt, in which case the
+ // test should be "if 1 or more real (acp) copies exist
+ actUpdateBarcodes.disabled = false;
+ actUpdateBarcodes.onclick = function() {
+ self.showRealCopyEditUI(li);
+ nodeByName("action_none", row).selected = true;
+ }
+ actHoldingsMaint.disabled = false;
+ actHoldingsMaint.onclick = self.generateMakeRecTab( li.eg_bib_id(), 'copy_browser', row );
+
+ return;
+ }
+ }
+ };
+
+
+ this._setAlertStore = function() {
+ acqLitAlertAlertText.store = new dojo_data_ItemFileReadStore(
+ {
+ "data": acqliat.toStoreData(
+ this.pcrud.search(
+ "acqliat", {"id": {"!=": null}}
+ )
+ )
+ }
+ );
+ acqLitAlertAlertText.setValue(); /* make the store "live" */
+ acqLitAlertAlertText._store_ready = true;
+ };
+
+ /**
+ * Draws and shows the lineitem notes pane
+ */
+ this.drawLiNotes = function(li) {
+ var self = this;
+
+ if (!acqLitAlertAlertText._store_ready)
+ this._setAlertStore();
+
+ li.lineitem_notes(
+ li.lineitem_notes().sort(
+ function(a, b) {
+ if(a.edit_time() < b.edit_time()) return 1;
+ return -1;
+ }
+ )
+ );
+
+ while(this.liNotesTbody.childNodes[0])
+ this.liNotesTbody.removeChild(this.liNotesTbody.childNodes[0]);
+ this.show('notes');
+
+ acqLitCreateNoteSubmit.onClick = function() {
+ var value = acqLitCreateNoteText.attr('value');
+ if(!value) return;
+ var note = new fieldmapper.acqlin();
+ note.isnew(true);
+ note.vendor_public(
+ Boolean(acqLitCreateNoteVendorPublic.attr('checked'))
+ );
+ note.value(value);
+ note.lineitem(li.id());
+
+ self.updateLiNotes(li, note);
+ acqLitCreateNoteVendorPublic.attr("checked", false);
+ acqLitCreateNoteText.attr("value", "");
+ }
+
+ acqLitCreateAlertSubmit.onClick = function() {
+ if (!acqLitAlertAlertText.item) {
+ alert(localeStrings.ALERT_UNSELECTED);
+ return;
+ }
+
+ var alert_text = new fieldmapper.acqliat().fromStoreItem(
+ acqLitAlertAlertText.item
+ );
+ var value = acqLitAlertNoteValue.attr("value") || "";
+
+ var note = new fieldmapper.acqlin();
+ note.isnew(true);
+ note.lineitem(li.id());
+ note.value(value);
+ note.alert_text(alert_text);
+
+ self.updateLiNotes(li, note);
+ }
+
+ dojo.forEach(li.lineitem_notes(), function(note) { self.addLiNote(li, note) });
+ }
+
+ /**
+ * Draws a single lineitem note in the notes pane
+ */
+ this.addLiNote = function(li, note) {
+ if(note.isdeleted()) return;
+ var self = this;
+ var row = self.liNotesRow.cloneNode(true);
+ nodeByName("value", row).innerHTML = note.value();
+ var alert_node = nodeByName("alert_code", row);
+ if (note.alert_text()) {
+ alert_node.innerHTML = note.alert_text().code();
+ if (note.alert_text().description()) {
+ new dijit_Tooltip(
+ {
+ "connectId": [alert_node],
+ "label": note.alert_text().description()
+ }, dojo.create("span", null, alert_node, "after")
+ );
+ }
+ }
+
+ if (openils.Util.isTrue(note.vendor_public()))
+ nodeByName("vendor_public", row).innerHTML =
+ localeStrings.VENDOR_PUBLIC;
+
+ nodeByName("delete", row).onclick = function() {
+ note.isdeleted(true);
+ self.liNotesTbody.removeChild(row);
+ self.updateLiNotes(li);
+ };
+
+ if(note.edit_time()) {
+ nodeByName("edit_time", row).innerHTML =
+ dojo_date_locale.format(
+ dojo_date_stamp.fromISOString(note.edit_time()),
+ {formatLength:'short'});
+ }
+
+ self.liNotesTbody.appendChild(row);
+ }
+
+ /**
+ * Updates any new/changed/deleted notes on the server
+ */
+ this.updateLiNotes = function(li, newNote) {
+
+ var notes;
+ if(newNote) {
+ notes = [newNote];
+ } else {
+ notes = li.lineitem_notes().filter(
+ function(note) {
+ if(note.ischanged() || note.isnew() || note.isdeleted())
+ return note;
+ }
+ );
+ }
+
+ if(notes.length == 0) return;
+ progressDialog.show();
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem_note.cud.batch'],
+ { async : true,
+ params : [this.authtoken, notes],
+ onresponse : function(r) {
+ var resp = openils.Util.readResponse(r);
+
+ if(resp.complete) {
+
+ if(!newNote) {
+ // remove the old changed notes
+ var list = [];
+ dojo.forEach(li.lineitem_notes(),
+ function(note) {
+ if(!(note.ischanged() || note.isnew() || note.isdeleted()))
+ list.push(note);
+ }
+ );
+ li.lineitem_notes(list);
+ }
+
+ progressDialog.hide();
+ self.updateLiNotesCount(li);
+ self.drawLiNotes(li);
+ return;
+ }
+
+ progressDialog.update(resp);
+ var newnote = resp.note;
+
+ if(!newnote.isdeleted()) {
+ newnote.isnew(false);
+ newnote.ischanged(false);
+ li.lineitem_notes().push(newnote);
+ }
+ },
+ }
+ );
+ }
+
+ this.updateLiPrice = function(input, li) {
+ var self = this;
+ var price = input.value;
+ if(Number(price) == Number(li.estimated_unit_price())) return;
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem.price.set'],
+ { async : false, // redundant w/ timeout
+ timeout : 10,
+ params : [this.authtoken, li.id(), price],
+ oncomplete : function(r) {
+ openils.Util.readResponse(r);
+ li.estimated_unit_price(price); // update local copy
+
+ /*
+ * If this is a PO and every visible lineitem has a price,
+ * check again to see if this PO can be activated. Note that
+ * every visible lineitem having a price does not guarantee it can
+ * be activated, which is why we still make the call. Having a price
+ * set for every visiable lineitem is just the lowest barrier to entry.
+ */
+ if (self.isPO) {
+ var priceNodes = dojo.query('[name=price]', dojo.byId('acq-lit-tbody'));
+ var allSet = true;
+ dojo.forEach(priceNodes, function(node) { if (node.value == '') allSet = false});
+ if (allSet) checkCouldActivatePo();
+ }
+ }
+ }
+ );
+ }
+
+ this.removeLineitem = function(liId) {
+ this.tbody.removeChild(dojo.query('[li='+liId+']', this.tbody)[0]);
+ delete this.liCache[liId];
+ //selected.push(self.liCache[i.parentNode.parentNode.getAttribute('li')]);
+ }
+
+ this.drawInfo = function(liId) {
+ if (!this._isRelatedViewer) {
+ var d = dojo.byId("acq-lit-info-related");
+ if (!this.relCache[liId]) {
+ fieldmapper.standardRequest(
+ [
+ "open-ils.acq",
+ "open-ils.acq.lineitems_for_bib.by_lineitem_id.count"
+ ], {
+ "async": true,
+ "params": [openils.User.authtoken, liId],
+ "onresponse": function(r) {
+ self.relCache[liId] = openils.Util.readResponse(r);
+ nodeByName("related_number", d).innerHTML =
+ self.relCache[liId];
+ openils.Util[
+ self.relCache[liId] >1 ? "show" : "hide"
+ ](d);
+ }
+ }
+ );
+ } else {
+ nodeByName("related_number", d).innerHTML = this.relCache[liId];
+ openils.Util[this.relCache[liId] > 1 ? "show" : "hide"](d);
+ }
+ }
+
+ this.show('info');
+ openils_acq_Lineitem.fetchAttrDefs(
+ function() {
+ self._fetchLineitem(liId, function(li){self._drawInfo(li);});
+ }
+ );
+ };
+
+ /* For a given list of lineitem ids, build a list of full lineitems
+ * re-using the fetching logic that is otherwise typical to use in this
+ * module.
+ *
+ * If we've already got a lineitem in the cache, just use that.
+ *
+ * Once we've built a list of lineitems, call callback(thatlist).
+ */
+ this.fetchLineitemsById = function(id_list, callback) {
+ var total = id_list.length;
+ var result_list = [];
+
+ var inner = function(li) {
+ result_list.push(li)
+ if (--total <= 0)
+ callback(result_list);
+ };
+
+ id_list.forEach(function(id) { self._fetchLineitem(id, inner); });
+ };
+
+ this._fetchLineitem = function(liId, handler, force) {
+
+ var li = this.liCache[liId];
+ if(li && li.marc() && li.lineitem_details() && !force)
+ return handler(li);
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem.retrieve.authoritative'],
+ { async: true,
+
+ params: [self.authtoken, liId, {
+ flesh_attrs: true,
+ flesh_cancel_reason: true,
+ flesh_li_details: true,
+ flesh_notes: true,
+ flesh_fund_debit: true }],
+
+ oncomplete: function(r) {
+ var li = openils.Util.readResponse(r);
+ self.liCache[liId] = li;
+ handler(li)
+ }
+ }
+ );
+ };
+
+ this._drawInfo = function(li) {
+
+ acqLitEditOrderMarc.onClick = function() { self.editOrderMarc(li); }
+
+ if(li.eg_bib_id()) {
+ openils.Util.hide('acq-lit-marc-order-record-label');
+ openils.Util.hide(acqLitEditOrderMarc.domNode);
+ openils.Util.show('acq-lit-marc-real-record-label');
+ } else {
+ openils.Util.show('acq-lit-marc-order-record-label');
+ openils.Util.show(acqLitEditOrderMarc.domNode);
+ openils.Util.hide('acq-lit-marc-real-record-label');
+ }
+
+ this.drawMarcHTML(li);
+ this.infoTbody = dojo.byId('acq-lit-info-tbody');
+
+ if(!this.infoRow)
+ this.infoRow = this.infoTbody.removeChild(dojo.byId('acq-lit-info-row'));
+ while(this.infoTbody.childNodes[0])
+ this.infoTbody.removeChild(this.infoTbody.childNodes[0]);
+
+ for(var i = 0; i < li.attributes().length; i++) {
+ var attr = li.attributes()[i];
+ var row = this.infoRow.cloneNode(true);
+
+ var type = attr.attr_type().replace(/lineitem_(.*)_attr_definition/, '$1');
+ var name = openils_acq_Lineitem.attrDefs[type].filter(
+ function(a) {
+ return (a.code() == attr.attr_name());
+ }
+ ).pop().description();
+
+ dojo.query('[name=label]', row)[0].appendChild(document.createTextNode(name));
+ dojo.query('[name=value]', row)[0].appendChild(document.createTextNode(attr.attr_value()));
+ this.infoTbody.appendChild(row);
+ }
+
+ if (!this._isRelatedViewer) {
+ nodeByName("rel_link", dojo.byId("acq-lit-info-related")).href =
+ oilsBasePath + "/acq/lineitem/related/" + li.id();
+ }
+
+ };
+
+ this.generateMakeRecTab = function(bib_id,default_view, row) {
+ return function() {
+ xulG.new_tab(
+ XUL_OPAC_WRAPPER,
+ {tab_name: localeStrings.XUL_RECORD_DETAIL_PAGE, browser:false},
+ {
+ no_xulG : false,
+ show_nav_buttons : true,
+ show_print_button : true,
+ opac_url : xulG.url_prefix(xulG.urls.opac_rdetail + bib_id),
+ default_view : default_view
+ }
+ );
+
+ if(row) nodeByName("action_none", row).selected = true;
+ }
+ };
+
+ this.drawMarcHTML = function(li) {
+ var params = [null, true, li.marc()];
+ if(li.eg_bib_id())
+ params = [li.eg_bib_id(), true];
+
+ fieldmapper.standardRequest(
+ ['open-ils.search', 'open-ils.search.biblio.record.html'],
+ { async: true,
+ params: params,
+ oncomplete: function(r) {
+ dojo.byId('acq-lit-marc-div').innerHTML =
+ openils.Util.readResponse(r);
+ }
+ }
+ );
+ }
+
+ this.drawCopies = function(liId, force_fetch) {
+ if (typeof force_fetch == "undefined")
+ force_fetch = false;
+
+ openils_acq_Lineitem.fetchAndRender(liId, {},
+ function(li, html) {
+ dojo.byId('acq-lit-copies-li-summary').innerHTML = html;
+ }
+ );
+
+ this.show('copies');
+ var self = this;
+ this.copyCache = {};
+ this.copyWidgetCache = {};
+ this.oldCopyWidgetCache = {};
+ this.virtDfaCounts = {};
+ this.realDfaCache = {};
+ this.dfeOffset = 0;
+
+ acqLitSaveCopies.onClick = function() { self.saveCopyChanges(liId) };
+ acqLitBatchUpdateCopies.onClick = function() { self.batchCopyUpdate() };
+ acqLitCopyCountInput.attr('value', '0');
+
+ while(this.copyTbody.childNodes[0])
+ this.copyTbody.removeChild(this.copyTbody.childNodes[0]);
+
+ this._drawBatchCopyWidgets();
+
+ this._drawDistribApplied(liId);
+
+ this._fetchDistribFormulas(
+ function() {
+ openils_acq_Lineitem.fetchAttrDefs(
+ function() {
+ self._fetchLineitem(liId, function(li){self._drawCopies(li);}, force_fetch);
+ }
+ );
+ }
+ );
+ };
+
+ this._saveDistribAppliedTemplates = function() {
+ if (!this._appliedDistribTemplate) {
+ this._appliedDistribTemplate =
+ dojo.byId("acq-lit-distrib-applied-tbody").
+ removeChild(dojo.byId("acq-lit-distrib-applied-row"));
+ dojo.attr(this._appliedDistribTemplate, "id");
+ }
+ };
+
+ this._drawDistribApplied = function(liId) {
+ /* Build this table while hidden to prevent rendering artifacts */
+ openils.Util.hide("acq-lit-distrib-applied-tbody");
+
+ this._saveDistribAppliedTemplates();
+
+ /* Remove any rows in the table from previous populations */
+ dojo.query("tr[formula]", "acq-lit-distrib-applied-tbody").
+ forEach(dojo.destroy);
+
+ /* Unregister all dijits previously created (for some reason this isn't
+ * covered by the above destroy calls). */
+ dijit.registry.forEach(
+ function(w) { if (/^dfa-/.test(w.id)) w.destroyRecursive(); }
+ );
+
+ /* Populate the table with our liId */
+ var total = 0;
+ fieldmapper.standardRequest(
+ ["open-ils.acq",
+ "open-ils.acq.distribution_formula_application.ranged.retrieve"],
+ {
+ "async": true,
+ "params": [self.authtoken, liId],
+ "onresponse": function(r) {
+ var dfa = openils.Util.readResponse(r);
+ if (dfa) {
+ total++;
+ self.realDfaCache[dfa.id()] = dfa;
+ self._drawDistribAppliedUnit(dfa);
+ }
+ },
+ "oncomplete": function() {
+ /* Reveal built table */
+ if (total) {
+ openils.Util.show(
+ "acq-lit-distrib-applied-tbody", "table-row-group"
+ );
+ }
+ }
+ }
+ );
+ };
+
+ this._drawDistribAppliedUnit = function(dfa) {
+ var new_row = false;
+ var row = dojo.query(
+ 'tr[formula="' + dfa.formula().id() + '"]',
+ "acq-lit-distrib-applied-tbody"
+ )[0];
+
+ if (!row) {
+ new_row = true;
+ row = dojo.clone(this._appliedDistribTemplate);
+ dojo.attr(row, "formula", dfa.formula().id());
+ dojo.query("th", row)[0].innerHTML = dfa.formula().name();
+ }
+
+ var td = dojo.query("td", row)[0];
+
+ dojo.create("span", {"id": "dfa-button-" + dfa.id()}, td, "last");
+ dojo.create("span", {"id": "dfa-tip-" + dfa.id()}, td, "last");
+
+ if (new_row)
+ dojo.place(row, "acq-lit-distrib-applied-tbody", "last");
+
+ new dijit_form_Button(
+ {
+ "onClick": function() {
+ if (confirm(localeStrings.EXPLAIN_DFA_MGMT))
+ self.deleteDfa(dfa);
+ },
+ "label": "X",
+ /* XXX I /cannot/ make the following work in as a CSS class
+ * for some reason. So frustrating... */
+ "style": function(id) {
+ return (id > 0 ?
+ "font-weight: bold; color: #c00;" :
+ "color: #666;");
+ }(dfa.id()) + "margin: 0 6px;display: inline;"
+ }, "dfa-button-" + dfa.id()
+ );
+ new dijit_Tooltip(
+ {
+ "connectId": ["dfa-button-" + dfa.id()],
+ "label": dojo.string.substitute(
+ localeStrings.DFA_TIP, dfa.id() > 0 ? [
+ openils.User.formalName(dfa.creator()),
+ dojo_date_locale.format(
+ dojo_date_stamp.fromISOString(dfa.create_time()),
+ {"formatLength":"short"}
+ )
+ ] : [localeStrings.ITS_YOU, localeStrings.JUST_NOW]
+ )
+ }, "dfa-tip-" + dfa.id()
+ );
+ }
+
+ this.deleteDfa = function(dfa) {
+ if (dfa.id() > 0) { /* real */
+ this.pcrud.eliminate(
+ dfa, {
+ "async": true,
+ "oncomplete": function() {
+ self._removeDistribApplied(dfa.id());
+ delete self.realDfaCache[dfa.id()];
+ }
+ }
+ );
+ } else { /* virtual */
+ if (--(this.virtDfaCounts[dfa.formula().id()]) < 0)
+ this.virtDfaCounts[dfa.formula().id()] = 0;
+ /* hasn't been saved yet, so no need to do anything server side */
+ this._removeDistribApplied(dfa.id());
+ }
+
+ };
+
+ this._removeDistribApplied = function(dfaId) {
+ var re = new RegExp("^dfa-\\w+-" + String(dfaId));
+ dijit.registry.forEach(
+ function(w) { if (re.test(w.id)) w.destroyRecursive(); }
+ );
+ this._removeDistribAppliedEmptyRows();
+ };
+
+ this._removeAllDistribAppliedVirtual = function() {
+ /* Unregister dijits */
+ dijit.registry.forEach(
+ function(w) { if (/^dfa-\w+--/.test(w.id)) w.destroyRecursive(); }
+ );
+ this._removeDistribAppliedEmptyRows();
+ };
+
+ this._removeDistribAppliedEmptyRows = function() {
+ /* Remove any rows with no DFA at all */
+ dojo.query("tr[formula] td", "acq-lit-distrib-applied-tbody").forEach(
+ function(o) {
+ if (o.childNodes.length < 1) dojo.destroy(o.parentNode);
+ }
+ );
+ };
+
+ /**
+ * Insert a new row into the distribution formula selection form
+ */
+ this._addDistribFormulaRow = function() {
+ var self = this;
+
+ if (!self.distribForms) {
+ // no formulas, hide the form
+ openils.Util.hide('acq-lit-distrib-formula-table');
+ return;
+ }
+
+ if(!this.distribFormulaTemplate)
+ this.distribFormulaTemplate =
+ dojo.byId('acq-lit-distrib-formula-tbody').removeChild(dojo.byId('acq-lit-distrib-form-row'));
+
+ var row = this.distribFormulaTemplate.cloneNode(true);
+ dojo.place(row, "acq-lit-distrib-formula-tbody", "only");
+
+ this.dfSelector = new dijit_form_FilteringSelect(
+ {"labelAttr": "dynLabel", "labelType": "html"},
+ nodeByName("selector", row)
+ );
+ this._updateFormulaStore();
+ this.dfSelector.fetchProperties =
+ {"sort": [{"attribute": "use_count", "descending": true}]};
+
+ var apply = new dijit_form_Button(
+ {"label": localeStrings.APPLY},
+ nodeByName('set_button', row)
+ );
+
+ var reset = new dijit_form_Button(
+ {"label": localeStrings.RESET_FORMULAE, "disabled": true},
+ nodeByName("reset_button", row)
+ );
+
+ dojo.connect(apply, 'onClick',
+ function() {
+ var form_id = self.dfSelector.attr("value");
+ if(!form_id) return;
+ self._applyDistribFormula(form_id);
+ reset.attr("disabled", false);
+ }
+ );
+
+ dojo.connect(reset, 'onClick',
+ function() {
+ self.restoreCopyFieldsBeforeDF();
+ self.virtDfaCounts = {};
+ self.virtDfaId = -1;
+ self.dfeOffset = 0;
+ self._updateFormulaStore();
+ self._removeAllDistribAppliedVirtual();
+ reset.attr("disabled", "true");
+ }
+ );
+
+ };
+
+ /**
+ * Applies a distrib formula to the current set of copies
+ */
+ this._applyDistribFormula = function(formula) {
+ if(!formula) return;
+
+ formula = this.distribForms.filter(
+ function(form) { return form.id() == formula; }
+ )[0];
+
+ var copyRows = dojo.query('tr', self.copyTbody);
+
+ if (this.dfeOffset >= copyRows.length) {
+ alert(localeStrings.OUT_OF_COPIES);
+ return;
+ }
+
+ var entries_applied = 0;
+ for(
+ var rowIndex = this.dfeOffset;
+ rowIndex < copyRows.length;
+ rowIndex++
+ ) {
+
+ var row = copyRows[rowIndex];
+ var copy_id = row.getAttribute('copy_id');
+ var copyWidgets = this.copyWidgetCache[copy_id];
+ var entryIndex = this.dfeOffset;
+ var entry = null;
+
+ // find the correct entry for the current row
+ dojo.forEach(formula.entries(),
+ function(e) {
+ if(!entry) {
+ entryIndex += e.item_count();
+ if(entryIndex > rowIndex)
+ entry = e;
+ }
+ }
+ );
+
+ if(entry) {
+
+ //console.log("rowIndex = " + rowIndex + ", entry = " + entry.id() + ", entryIndex=" +
+ // entryIndex + ", owning_lib = " + entry.owning_lib() + ", location = " + entry.location());
+
+ entries_applied++;
+ this.saveCopyFieldsBeforeDF(copy_id);
+ this._copy_fields_for_acqdf.forEach(
+ function(field) {
+ if(entry[field]()) {
+ copyWidgets[field].attr('value', (entry[field]()));
+ }
+ }
+ );
+ }
+ }
+
+ if (entries_applied) {
+ this.virtDfaCounts[formula.id()] =
+ ++(this.virtDfaCounts[formula.id()]) || 1;
+ this._updateFormulaStore();
+ this._drawDistribAppliedUnit(
+ function(df) {
+ var dfa = new acqdfa();
+ dfa.formula(df); dfa.id(self.virtDfaId--); return dfa;
+ }(formula)
+ );
+ this.dfeOffset += entries_applied;
+ };
+ };
+
+ /**
+ * This function updates the DF store for the dropdown so that use_counts
+ * can reflect DF applications from this session before they're saved
+ * server-side.
+ */
+ this._updateFormulaStore = function() {
+ this.dfSelector.store = new dojo_data_ItemFileReadStore(
+ {
+ "data": self._labelFormulasWithCounts(
+ acqdf.toStoreData(self.distribForms)
+ )
+ }
+ );
+ };
+
+ this.saveCopyFieldsBeforeDF = function(copy_id) {
+ var self = this;
+ if (!this.oldCopyWidgetCache[copy_id]) {
+ var copyWidgets = this.copyWidgetCache[copy_id];
+
+ this.oldCopyWidgetCache[copy_id] = {};
+ this._copy_fields_for_acqdf.forEach(
+ function(f) {
+ self.oldCopyWidgetCache[copy_id][f] =
+ copyWidgets[f].attr("value");
+ }
+ );
+ }
+ };
+
+ this.restoreCopyFieldsBeforeDF = function() {
+ var self = this;
+ for (var copy_id in this.oldCopyWidgetCache) {
+ this._copy_fields_for_acqdf.forEach(
+ function(f) {
+ self.copyWidgetCache[copy_id][f].attr(
+ "value", self.oldCopyWidgetCache[copy_id][f]
+ );
+ }
+ );
+ }
+ };
+
+ this._labelFormulasWithCounts = function(store_data) {
+ for (var key in store_data.items) {
+ var obj = store_data.items[key];
+ obj.use_count = Number(obj.use_count); /* needed for sorting */
+
+ if (this.virtDfaCounts[obj.id])
+ obj.use_count = obj.use_count + Number(this.virtDfaCounts[obj.id]);
+
+ obj.dynLabel = "<span class='acq-lit-distrib-form-use-count'>[" +
+ obj.use_count + "]</span> " + obj.name;
+ }
+ return store_data;
+ };
+
+ /**
+ * This method formerly would not refetch the DF formulas if they'd been
+ * loaded already, but now it always re-fetches, since use_count changes.
+ */
+ /** TODO: port distrib-formula selector to autofieldwidget+pcrud/dojo store */
+ this._fetchDistribFormulas = function(onload) {
+ fieldmapper.standardRequest(
+ ["open-ils.acq",
+ "open-ils.acq.distribution_formula.ranged.retrieve.atomic"],
+ {
+ "async": true,
+ "params": [openils.User.authtoken, 0, 500],
+ "oncomplete": function(r) {
+ self.distribForms = openils.Util.readResponse(r);
+ if(!self.distribForms || self.distribForms.length == 0) {
+ self.distribForms = [];
+ }
+ self._addDistribFormulaRow();
+ onload();
+ }
+ }
+ );
+ }
+
+ this._drawBatchCopyWidgets = function() {
+ var row = this.copyBatchRow;
+ dojo.forEach(liDetailBatchFields,
+ function(field) {
+ if(self.copyBatchRowDrawn) {
+ self.copyBatchWidgets[field].attr('value', null);
+ } else {
+ var widget = new openils_widget_AutoFieldWidget({
+ fmField : field,
+ fmClass : 'acqlid',
+ labelFormat : (field == 'fund') ? fundLabelFormat : null,
+ searchFormat : (field == 'fund') ? fundSearchFormat : null,
+ searchFilter : (field == 'fund') ? {"active": "t"} : null,
+ parentNode : dojo.query('[name='+field+']', row)[0],
+ orgLimitPerms : ['CREATE_PICKLIST'],
+ dijitArgs : {
+ "required": false,
+ "labelType": (field == "fund") ? "html" : null
+ },
+ noCache: (field == "fund"),
+ forceSync : true
+ });
+ widget.build(
+ function(w, ww) {
+ if (field == "fund" && w.store)
+ self._ensureCSSFundClasses(w.store);
+ self.copyBatchWidgets[field] = w;
+ }
+ );
+ if (field == "fund") {
+ dojo.connect(
+ widget.widget, "onChange", function(val) {
+ self._updateFundSelectorStyle(widget, val);
+ }
+ );
+ }
+ }
+ }
+ );
+ this.copyBatchRowDrawn = true;
+ };
+
+ this.batchCopyUpdate = function() {
+ var self = this;
+ for(var k in this.copyWidgetCache) {
+ var cache = this.copyWidgetCache[k];
+ dojo.forEach(liDetailBatchFields, function(f) {
+ var newval = self.copyBatchWidgets[f].attr('value');
+ if(newval) cache[f].attr('value', newval);
+ });
+ }
+ };
+
+ this._drawCopies = function(li) {
+ var self = this;
+
+ // this button sets the total number of copies for a given lineitem
+ acqLitAddCopyCount.onClick = function() {
+ var count = acqLitCopyCountInput.attr('value');
+
+ // add new rows
+ while(self.copyCount() < count)
+ self.addCopy(li);
+
+ // delete rows if necessary
+ var diff = self.copyCount() - count;
+ if(diff > 0) {
+ var rows = dojo.query('tr', self.copyTbody).reverse().slice(0, diff);
+ if(confirm(dojo.string.substitute(localeStrings.DELETE_LI_COPIES_CONFIRM, [diff]))) {
+ dojo.forEach(rows, function(row) {self.deleteCopy(row); });
+ } else {
+ acqLitCopyCountInput.attr('value', self.copyCount()+'');
+ }
+ }
+ }
+
+
+ if(li.lineitem_details().length > 0) {
+ dojo.forEach(li.lineitem_details(),
+ function(copy) {
+ self.addCopy(li, copy);
+ }
+ );
+ } else {
+ self.addCopy(li);
+ }
+ };
+
+ this.copyCount = function() {
+ var count = 0;
+ for(var id in this.copyCache) {
+ if(!this.copyCache[id].isdeleted())
+ count++;
+ }
+ return count;
+ }
+
+ this.virtCopyId = -1;
+ this.addCopy = function(li, copy) {
+ var row = this.copyRow.cloneNode(true);
+ this.copyTbody.appendChild(row);
+ var self = this;
+
+ if(!copy) {
+ copy = new fieldmapper.acqlid();
+ copy.isnew(true);
+ copy.id(this.virtCopyId--);
+ copy.lineitem(li.id());
+ }
+
+ this.copyCache[copy.id()] = copy;
+ row.setAttribute('copy_id', copy.id());
+ self.copyWidgetCache[copy.id()] = {};
+
+ acqLitCopyCountInput.attr('value', self.copyCount()+'');
+
+ var rcvr = copy.receiver();
+ if (rcvr) {
+ if (!userCache[rcvr]) {
+ if(rcvr == openils.User.user.id()) {
+ userCache[rcvr] = openils.User.user;
+ } else {
+ userCache[rcvr] = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.retrieve'],
+ {params: [openils.User.authtoken, rcvr]}
+ );
+ }
+ }
+ dojo.query('[name=receiver]', row)[0].innerHTML = userCache[rcvr].usrname();
+ }
+
+ dojo.forEach(liDetailFields,
+ function(field) {
+ var searchFilter;
+ if (field == "fund") {
+ searchFilter = (copy.fund() ?
+ {"-or": {"active": "t", "id": copy.fund()}} :
+ {"active" : "t"});
+ } else {
+ searchFilter = null;
+ }
+
+ var readOnly = false;
+
+ // TODO: Add support for changing the owning_lib after real copies have been made.
+ // owning_lib is order data as much as its item data
+ if(copy.eg_copy_id() && ['owning_lib', 'location', 'circ_modifier', 'cn_label', 'barcode'].indexOf(field) >= 0) {
+ readOnly = true;
+ }
+
+ // TODO: add support for changing the fund after debits have been created
+ // Note: invoicing allows the change
+ if(copy.fund_debit() && field == 'fund') {
+ readOnly = true;
+ }
+
+
+ var widget = new openils_widget_AutoFieldWidget({
+ fmObject : copy,
+ fmField : field,
+ labelFormat : (field == 'fund') ? fundLabelFormat : null,
+ searchFormat : (field == 'fund') ? fundSearchFormat : null,
+ dijitArgs: {"labelType": (field == 'fund') ? "html" : null},
+ searchFilter : searchFilter,
+ noCache: (field == "fund"),
+ fmClass : 'acqlid',
+ parentNode : dojo.query('[name='+field+']', row)[0],
+ orgLimitPerms : ['CREATE_PICKLIST', 'CREATE_PURCHASE_ORDER'],
+ readOnly : readOnly,
+ orgDefaultsToWs : true
+ });
+
+ widget.build(
+ // make sure we capture the value from any async widgets
+ function(w, ww) {
+
+ if (field == "fund" && w.store)
+ self._ensureCSSFundClasses(w.store);
+
+ if(!readOnly)
+ copy[field](ww.getFormattedValue())
+
+ self.copyWidgetCache[copy.id()][field] = w;
+
+ dojo.connect(w, 'onChange',
+ function(val) {
+ if (field == "fund")
+ self._updateFundSelectorStyle(widget, val);
+
+ if (!readOnly && (copy.isnew() || val != copy[field]())) {
+ // prevent setting ischanged() automatically on widget load for existing copies
+ copy[field](widget.getFormattedValue())
+ copy.ischanged(true);
+ }
+ }
+ );
+ }
+ );
+ }
+ );
+
+ this.updateLidState(copy, row);
+ };
+
+ this._ensureCSSFundClass = function(id) {
+ if (!this.fundStyleSheet) {
+ dojo.create(
+ "style", {"type": "text/css"},
+ document.getElementsByTagName("head")[0], "last"
+ );
+ this.fundStyleSheet = document.styleSheets[
+ document.styleSheets.length - 1
+ ];
+ }
+
+ var cn = "fund_" + id;
+ if (!this.haveFundClass[cn]) {
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.fund.check_balance_percentages"],
+ {
+ "params": [openils.User.authtoken, id],
+ "async": true,
+ "oncomplete": function(r) {
+ r = openils.Util.readResponse(r);
+ self.fundBalanceState[id] = r;
+ var style = "";
+ if (r[0] /* stop */)
+ style = fundStyles.stop;
+ else if (r[1] /* warning */)
+ style = fundStyles.warning;
+ self.fundStyleSheet.insertRule(
+ "." + cn + " { " + style + " }",
+ self.fundStyleSheet.cssRules.length
+ );
+ self.haveFundClass[cn] = true;
+ }
+ }
+ );
+ }
+ };
+
+ this._ensureCSSFundClasses = function(store) {
+ store.fetch({
+ "query": {"id": "*"},
+ "onItem": function(o) { self._ensureCSSFundClass(o.id[0]); }
+ });
+ };
+
+ this._updateFundSelectorStyle = function(widget, fund_id) {
+ openils.Util.removeCSSClass(widget.widget.domNode, /fund_\d+/);
+ openils.Util.addCSSClass(widget.widget.domNode, "fund_" + fund_id);
+ };
+
+ this.updateLidState = function(copy, row) {
+ if (typeof(row) == "undefined") {
+ row = dojo.query(
+ 'tr[copy_id="' + copy.id() + '"]', this.copyTbody
+ )[0];
+ }
+
+ var self = this;
+ var recv_link = nodeByName("receive", row);
+ var unrecv_link = nodeByName("unreceive", row);
+ var del_link = nodeByName("delete", row);
+ var cxl_link = nodeByName("cancel", row);
+ var claim_link = nodeByName("claim", row);
+ var cxl_reason_link = nodeByName("cancel_reason", row);
+
+ if (copy.cancel_reason()) {
+ openils.Util.hide(del_link.parentNode);
+ openils.Util.hide(recv_link);
+ openils.Util.hide(unrecv_link);
+ openils.Util.hide(cxl_link);
+ openils.Util.hide(claim_link);
+
+ /* XXX the following may leak memory in a long lived table: dijits may not get destroyed... not positive. revisit. */
+ var holds_reason = dojo.create(
+ "span", {
+ "style": "border-bottom: 1px dashed #000;",
+ "innerHTML": "Cancelled" /* XXX [sic] and i18n */
+ }, cxl_reason_link, "only"
+ );
+ new dijit_Tooltip(
+ {
+ "label": "<em>" + copy.cancel_reason().label() +
+ "</em><br />" + copy.cancel_reason().description(),
+ "connectId": [holds_reason]
+ }, dojo.create("span", null, cxl_reason_link, "last")
+ );
+ openils.Util.show(cxl_reason_link, "inline");
+ } else if (this.isPO) {
+ /* Only using this in one place so far, but may want it for better
+ * decisions on when to display certain controls. */
+ var li_state = this.liCache[copy.lineitem()].state();
+
+ openils.Util.hide(del_link.parentNode);
+ openils.Util.hide(cxl_reason_link);
+
+ /* Avoid showing (un)receive links, cancel links, for virt copies */
+ if (copy.id() > 0) {
+ if (copy.recv_time()) {
+ openils.Util.hide(cxl_link);
+ openils.Util.hide(recv_link);
+ openils.Util.hide(claim_link);
+
+ openils.Util.show(unrecv_link, "inline");
+ unrecv_link.onclick = function() {
+ if (confirm(localeStrings.UNRECEIVE_LID))
+ self.issueReceive(copy, /* rollback */ true);
+ };
+ } else {
+ openils.Util.hide(unrecv_link);
+
+ if (this.claimEligibleLid[copy.id()]) {
+ openils.Util.show(claim_link, "inline");
+ claim_link.onclick = function() {
+ self.claimDialog.show(
+ self.liCache[copy.lineitem()], copy.id()
+ );
+ };
+ } else {
+ openils.Util.hide(claim_link);
+ }
+
+ openils.Util[li_state == "on-order" ? "show" : "hide"](
+ recv_link, "inline"
+ );
+ openils.Util.show(cxl_link, "inline");
+ recv_link.onclick = function() {
+ if (self.checkLiAlerts(copy.lineitem()))
+ self.issueReceive(copy);
+ };
+ cxl_link.onclick = function() {
+ self.cancelLid(copy.id());
+ };
+ }
+ } else {
+ openils.Util.hide(cxl_link);
+ openils.Util.hide(unrecv_link);
+ openils.Util.hide(recv_link);
+ openils.Util.hide(claim_link);
+ }
+ } else {
+ openils.Util.hide(unrecv_link);
+ openils.Util.hide(recv_link);
+ openils.Util.hide(cxl_reason_link);
+ openils.Util.hide(claim_link);
+
+ del_link.onclick = function() { self.deleteCopy(row) };
+ openils.Util.show(del_link.parentNode);
+ }
+ }
+
+ this.cancelLid = function(lid_id) {
+ lidCancelDialog._lid_id = lid_id;
+ openils.Util.show(lidCancelDialog.domNode.parentNode);
+ lidCancelDialog.show();
+ if (!lidCancelDialog._prepared) {
+ var widget = new openils_widget_AutoFieldWidget({
+ "fmField": "cancel_reason",
+ "fmClass": "acqlid",
+ "parentNode": dojo.byId("acq-lit-lid-cancel-reason"),
+ "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
+ "forceSync": true
+ });
+ widget.build(
+ function(w, ww) {
+ acqLidCancelButton.onClick = function() {
+ if (w.attr("value")) {
+ if (confirm(localeStrings.LID_CANCEL_CONFIRM)) {
+ self._cancelLid(
+ lidCancelDialog._lid_id,
+ w.attr("value")
+ );
+ }
+ lidCancelDialog.hide();
+ }
+ };
+ lidCancelDialog._prepared = true;
+ }
+ );
+ }
+ };
+
+ this._cancelLid = function(lid_id, reason) {
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem_detail.cancel"], {
+ "params": [openils.User.authtoken, lid_id, reason],
+ "async": true,
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ if (r.lid) {
+ for (var id in r.lid) {
+ /* actually this should only iterate once */
+ self.copyCache[id].cancel_reason(
+ r.lid[id].cancel_reason
+ );
+ self.updateLidState(self.copyCache[id]);
+ }
+ }
+ }
+ }
+ }
+ );
+ };
+
+ this._confirmAlert = function(li, lin) {
+ return confirm(
+ dojo.string.substitute(
+ localeStrings.CONFIRM_LI_ALERT, [
+ (new openils_acq_Lineitem({"lineitem": li})).findAttr(
+ "title", "lineitem_marc_attr_definition"
+ ),
+ lin.alert_text().code(),
+ lin.alert_text().description() || "",
+ lin.value()
+ ]
+ )
+ );
+ };
+
+ this.checkLiAlerts = function(li_id) {
+ var li = this.liCache[li_id];
+
+ var alert_notes = li.lineitem_notes().filter(
+ function(o) { return Boolean(o.alert_text()); }
+ );
+
+ /* this is _intentionally_ not done in a call to forEach() ... */
+ for (var i = 0; i < alert_notes.length; i++) {
+ if (this.noteAcks[alert_notes[i].id()])
+ continue;
+ else if (!this._confirmAlert(li, alert_notes[i]))
+ return false;
+ else
+ this.noteAcks[alert_notes[i].id()] = true;
+ }
+
+ return true;
+ };
+
+ this.deleteCopy = function(row) {
+ var copy = this.copyCache[row.getAttribute('copy_id')];
+ copy.isdeleted(true);
+ if(copy.isnew())
+ delete this.copyCache[copy.id()];
+ this.copyTbody.removeChild(row);
+ }
+
+ this._virtDfaCountsAsList = function() {
+ var L = [];
+ for (var key in this.virtDfaCounts) {
+ for (var i = 0; i < this.virtDfaCounts[key]; i++)
+ L.push(key);
+ }
+ return L;
+ }
+
+ this.confirmBreachedCopyFunds = function(copies) {
+ var stop = 0, warning = 0;
+ copies.forEach(
+ function(o) {
+ if (o.fund()) {
+ var state = self.fundBalanceState[o.fund()];
+ if (state[0] /* stop */)
+ stop++;
+ else if (state[1] /* warning */)
+ warning++;
+ }
+ }
+ );
+
+ if (stop) {
+ return confirm(localeStrings.CONFIRM_FUNDS_AT_STOP);
+ } else if (warning) {
+ return confirm(localeStrings.CONFIRM_FUNDS_AT_WARNING);
+ }
+ return true;
+ };
+
+ this.saveCopyChanges = function(liId) {
+ var self = this;
+ var copies = [];
+
+
+ var total = 0;
+ for(var id in this.copyCache) {
+ var c = this.copyCache[id];
+ if(!c.isdeleted()) total++;
+ if(c.isnew() || c.ischanged() || c.isdeleted()) {
+ if(c.id() < 0) c.id(null);
+ copies.push(c);
+ }
+ }
+
+
+ dojo.byId('acq-lit-copy-count-label-' + liId).innerHTML = total;
+
+
+ if (copies.length > 0) {
+ if (!this.confirmBreachedCopyFunds(copies))
+ return;
+
+ if (typeof(this._copy_count_cb) == "function")
+ this._copy_count_cb(liId, total);
+
+ openils.Util.show("acq-lit-update-copies-progress");
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem_detail.cud.batch'],
+ { async: true,
+ params: [openils.User.authtoken, copies],
+ onresponse: function(r) {
+ var res = openils.Util.readResponse(r);
+ litUpdateCopiesProgress.update(res);
+ },
+ oncomplete: function() {
+ self.drawCopies(liId, true /* force_fetch */);
+ openils.Util.hide("acq-lit-update-copies-progress");
+ }
+ }
+ );
+ }
+
+ var dfa_list = this._virtDfaCountsAsList();
+ if (dfa_list.length > 0) {
+ fieldmapper.standardRequest(
+ ["open-ils.acq",
+ "open-ils.acq.distribution_formula.record_application"],
+ {
+ "async": true,
+ "params": [openils.User.authtoken, dfa_list, liId],
+ "onresponse": function(r) {
+ var res = openils.Util.readResponse(r);
+ if (res && res.length < dfa_list.length)
+ alert(localeStrings.DFA_NOT_ALL);
+ }
+ }
+ );
+ this.virtDfaCounts = {};
+ }
+ }
+
+ this._updateCreatePoPrepayCheckbox = function(prepay) {
+ var prepay = openils.Util.isTrue(prepay);
+ this._prepayRequiredByVendor = prepay;
+ dijit.byId("acq-lit-po-prepay").attr("checked", prepay);
+ };
+
+ this._confirmPoPrepaySituation = function() {
+ var want_prepay = dijit.byId("acq-lit-po-prepay").attr("checked");
+ if (want_prepay != this._prepayRequiredByVendor) {
+ return confirm(
+ want_prepay ?
+ localeStrings.VENDOR_SAYS_PREPAY_NOT_NEEDED :
+ localeStrings.VENDOR_SAYS_PREPAY_NEEDED
+ );
+ } else {
+ return true;
+ }
+ };
+
+ this.applySelectedLiAction = function(action) {
+ var self = this;
+ switch(action) {
+
+ case 'delete_selected':
+ this._deleteLiList(self.getSelected());
+ break;
+
+ case 'create_order':
+ this._loadPOSelect();
+ acqLitPoCreateDialog.show();
+ break;
+
+ case 'save_picklist':
+ acqLitSavePlDialog.show();
+ break;
+
+ case 'selector_ready':
+ case 'order_ready':
+ acqLitChangeLiStateDialog.attr('state', action.replace('_', '-'));
+ acqLitChangeLiStateDialog.show();
+ break;
+
+ case 'print_po':
+ this.printPO();
+ break;
+
+ case 'po_history':
+ location.href = oilsBasePath + '/acq/po/history/' + this.isPO;
+ break;
+
+ case 'receive_po':
+ this.receivePO();
+ break;
+
+ case 'rollback_receive_po':
+ this.rollbackPoReceive();
+ break;
+
+ case 'create_assets':
+ this.showAssetCreator();
+ break;
+
+ case 'export_attr_list':
+ this.chooseExportAttr();
+ break;
+
+ case 'batch_apply_funds':
+ this.applyBatchLiFunds();
+ break;
+
+ case 'add_brief_record':
+ if(this.isPO)
+ location.href = oilsBasePath + '/acq/picklist/brief_record?po=' + this.isPO;
+ else
+ location.href = oilsBasePath + '/acq/picklist/brief_record?pl=' + this.isPL;
+
+ break;
+
+ case "cancel_lineitems":
+ this.maybeCancelLineitems();
+ break;
+
+ case "change_claim_policy":
+ var li_list = this.getSelected();
+ this.claimPolicyPicker.attr("value", null);
+ liClaimPolicyDialog.show();
+ liClaimPolicySave.onClick = function() {
+ self.changeClaimPolicy(
+ li_list,
+ self.claimPolicyPicker.attr("value"),
+ function() {
+ li_list.forEach(
+ function(li) {
+ self.setClaimPolicyControl(li);
+ self.reconsiderClaimControl(li);
+ }
+ );
+ liClaimPolicyDialog.hide();
+ }
+ )
+ };
+ break;
+ }
+ };
+
+ this.changeClaimPolicy = function(li_list, value, callback) {
+ li_list.forEach(
+ function(li) { li.claim_policy(value); }
+ );
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem.update"], {
+ "params": [openils.User.authtoken, li_list],
+ "async": true,
+ "oncomplete": function(r) {
+ r = openils.Util.readResponse(r);
+ if (callback) callback(r);
+ }
+ }
+ );
+ };
+
+ this.showAssetCreator = function(onAssetsCreated) {
+ if(!this.isPO) return;
+ var self = this;
+
+ // first, let's see if this PO has any LI's that need to be merged/imported
+ self.pcrud.search('jub', {purchase_order : this.isPO, eg_bib_id : null}, {
+ id_list : true,
+ oncomplete : function(r) {
+ var resp = openils.Util.readResponse(r);
+ if (resp && resp.length) {
+ // PO has some non-linked jubs.
+
+ self.show('asset-creator');
+ if(!self.vlAgent.loaded)
+ self.vlAgent.init();
+
+ dojo.connect(assetCreatorButton, 'onClick',
+ function() { self.createAssets(onAssetsCreated) });
+
+ } else {
+
+ // all jubs linked, move on to asset creation
+ self.createAssets(onAssetsCreated, true);
+ }
+ }
+ });
+ }
+
+ this.createAssets = function(onAssetsCreated, noVl) {
+ this.show('acq-lit-progress-numbers');
+ var self = this;
+ var vlArgs = (noVl) ? {} : {vandelay : this.vlAgent.values()};
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.assets.create'],
+ { async: true,
+ params: [this.authtoken, this.isPO, vlArgs],
+ onresponse: function(r) {
+ var resp = openils.Util.readResponse(r);
+ self._updateProgressNumbers(resp, !Boolean(onAssetsCreated), onAssetsCreated);
+ }
+ }
+ );
+ }
+
+ this.maybeCancelLineitems = function() {
+ openils.Util.show("acq-lit-cancel-reason", "inline");
+ if (!acqLitCancelLineitemsButton._prepared) {
+ var widget = new openils_widget_AutoFieldWidget({
+ "fmField": "cancel_reason",
+ "fmClass": "jub",
+ "parentNode": dojo.byId("acq-lit-cancel-reason-selector"),
+ "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
+ "forceSync": true
+ });
+ widget.build(
+ function(w, ww) {
+ acqLitCancelLineitemsButton.onClick = function() {
+ if (w.attr("value")) {
+ if (confirm(localeStrings.LI_CANCEL_CONFIRM)) {
+ self._cancelLineitems(w.attr("value"));
+ }
+ openils.Util.hide("acq-lit-cancel-reason");
+ }
+ };
+ acqLitCancelLineitemsButton._prepared = true;
+ }
+ );
+ }
+ };
+
+ this._cancelLineitems = function(reason) {
+ var id_list = this.getSelected().map(function(o) { return o.id(); });
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem.cancel.batch"], {
+ "params": [openils.User.authtoken, id_list, reason],
+ "async": true,
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ if (r.li) {
+ for (var id in r.li) {
+ self.liCache[id].state(r.li[id].state);
+ self.liCache[id].cancel_reason(
+ r.li[id].cancel_reason
+ );
+ self.updateLiState(self.liCache[id]);
+ }
+ }
+ if (r.lid && self.copyCache) {
+ for (var id in r.lid) {
+ if (self.copyCache[id]) {
+ self.copyCache[id].cancel_reason(
+ r.lid[id].cancel_reason
+ );
+ self.updateLidState(self.copyCache[id]);
+ }
+ }
+ }
+ }
+ }
+ }
+ );
+ };
+
+ this.chooseExportAttr = function() {
+ if (!acqLitExportAttrSelector._li_setup) {
+ var self = this;
+ acqLitExportAttrSelector.store = new dojo_data_ItemFileReadStore(
+ {
+ "data": acqlimad.toStoreData(
+ this.pcrud.search(
+ "acqlimad", {"code": li_exportable_attrs}
+ )
+ )
+ }
+ );
+ acqLitExportAttrSelector.setValue();
+ acqLitExportAttrButton.onClick = function(){self.exportAttrList();};
+ acqLitExportAttrSelector._li_setup = true;
+ }
+ openils.Util.show("acq-lit-export-attr-holder", "inline");
+ };
+
+ this.exportAttrList = function() {
+ var attr_def = acqLitExportAttrSelector.item;
+ var li_list = this.getSelected();
+ var value_list = li_list.map(
+ function(li) {
+ return (new openils_acq_Lineitem({"lineitem": li})).findAttr(
+ attr_def.code, "lineitem_marc_attr_definition"
+ );
+ }
+ ).filter(function(attr) { return Boolean(attr); });
+
+ if (value_list.length > 0) {
+ if (value_list.length < li_list.length) {
+ if (!confirm(
+ dojo.string.substitute(
+ localeStrings.EXPORT_SHORT_LIST, [attr_def.description]
+ )
+ )) {
+ return;
+ }
+ }
+ try {
+ openils.XUL.contentToFileSaveDialog(
+ value_list.join("\n"),
+ localeStrings.EXPORT_SAVE_DIALOG_TITLE
+ );
+ } catch (E) {
+ alert(E);
+ }
+ } else {
+ alert(dojo.string.substitute(
+ localeStrings.EXPORT_EMPTY_LIST, [attr_def.description]
+ ));
+ }
+
+ openils.Util.hide("acq-lit-export-attr-holder");
+ };
+
+ this.printPO = function() {
+ if(!this.isPO) return;
+ progressDialog.show(true);
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.format'],
+ { async: true,
+ params: [this.authtoken, this.isPO, 'html'],
+ oncomplete: function(r) {
+ progressDialog.hide();
+ var evt = openils.Util.readResponse(r);
+ if(evt && evt.template_output()) {
+ openils.Util.printHtmlString(evt.template_output().data());
+ }
+ }
+ }
+ );
+ }
+
+
+ this.receivePO = function() {
+ if (!this.isPO) return;
+
+ for (var id in this.liCache) {
+ /* assumption: liCache reflects exactly the
+ * set of LIs that belong to our PO */
+ if (this.liCache[id].state() != "received" &&
+ !this.checkLiAlerts(id)) return;
+ }
+
+ this.show('acq-lit-progress-numbers');
+ var self = this;
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.receive'],
+ { async: true,
+ params: [this.authtoken, this.isPO],
+ onresponse : function(r) {
+ var resp = openils.Util.readResponse(r);
+ self._updateProgressNumbers(resp, true);
+ },
+ }
+ );
+ }
+
+ this.issueReceive = function(obj, rollback) {
+ /* (For now) there shall be no marking LI or LIDs (un)received
+ * except from the actual "view PO" interface. */
+ if (!this.isPO) return;
+
+ var part =
+ {"jub": "lineitem", "acqlid": "lineitem_detail"}[obj.classname];
+ var method =
+ "open-ils.acq." + part + ".receive" + (rollback ? ".rollback" : "");
+
+ progressDialog.show(true);
+ fieldmapper.standardRequest(
+ ["open-ils.acq", method], {
+ "async": true,
+ "params": [this.authtoken, obj.id()],
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ self.fetchClaimInfo(
+ part == "lineitem" ? obj.id() : obj.lineitem(),
+ /* force */ true,
+ function() { self.handleReceive(r); }
+ );
+ progressDialog.hide();
+ }
+ }
+ }
+ );
+ };
+
+ /**
+ * Handles the responses from receive and rollback ML calls.
+ */
+ this.handleReceive = function(resp) {
+ if (resp) {
+ if (resp.li) {
+ for (var li_id in resp.li) {
+ for (var key in resp.li[li_id])
+ self.liCache[li_id][key](resp.li[li_id][key]);
+ self.updateLiState(self.liCache[li_id]);
+ }
+ }
+ if (resp.po) {
+ if (typeof(self.poUpdateCallback) == "function")
+ self.poUpdateCallback(resp.po);
+ }
+ if (resp.lid) {
+ for (var lid_id in resp.lid) {
+ for (var key in resp.lid[lid_id])
+ self.copyCache[lid_id][key](resp.lid[lid_id][key]);
+ self.updateLidState(self.copyCache[lid_id]);
+ }
+ }
+ }
+ };
+
+ this.rollbackPoReceive = function() {
+ if(!this.isPO) return;
+ if(!confirm(localeStrings.ROLLBACK_PO_RECEIVE_CONFIRM)) return;
+ this.show('acq-lit-progress-numbers');
+ var self = this;
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.receive.rollback'],
+ { async: true,
+ params: [this.authtoken, this.isPO],
+ onresponse : function(r) {
+ var resp = openils.Util.readResponse(r);
+ self._updateProgressNumbers(resp, true);
+ },
+ }
+ );
+ }
+
+ this._updateProgressNumbers = function(resp, reloadOnComplete, onComplete) {
+ this.vlAgent.handleResponse(resp,
+ function(resp, res) {
+ if(reloadOnComplete)
+ location.href = location.href;
+ if (onComplete)
+ onComplete(resp, res);
+ }
+ );
+ }
+
+
+ this._createPO = function(fields) {
+ var wantall = (fields.create_from == "all");
+
+ /* If we're a picklist or purchase order already and the user wants
+ * all lineitems, we might have pages' worth of lineitems haven't all
+ * been loaded yet, so getSelected() won't find them. The server,
+ * however, should know about all our lineitems, so let's ask the
+ * server for a complete list.
+ */
+
+ if (wantall) {
+ this.getSelected(
+ true, function(list) {
+ self._createPOFromLineitems(fields, list);
+ }, /* id_list */ true
+ );
+ } else {
+ this._createPOFromLineitems(fields, this.getSelected(false, null, true /* id_list */));
+ }
+ };
+
+ this._createPOFromLineitems = function(fields, selected) {
+ if (selected.length == 0) return;
+ var self = this;
+
+ var po = new fieldmapper.acqpo();
+ po.provider(this.createPoProviderSelector.attr("value"));
+ po.ordering_agency(this.createPoAgencySelector.attr("value"));
+ po.prepayment_required(fields.prepayment_required[0] ? true : false);
+
+ // if we're creating assets, delay the asset creation
+ // until after the PO is created. This will allow us to
+ // use showAssetCreator() directly.
+
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.purchase_order.create"],
+ { async: true,
+ params: [
+ openils.User.authtoken,
+ po, {lineitems : selected}
+ ],
+ onresponse : function(r) {
+ var resp = openils.Util.readResponse(r);
+ if (resp.complete) {
+ // self.isPO is needed for showAssetCreator();
+ self.isPO = resp.purchase_order.id();
+ var redir = oilsBasePath + "/acq/po/view/" + self.isPO;
+ if (fields.create_assets[0]) {
+ self.showAssetCreator(
+ function() {location.href = redir}
+ );
+ } else {
+ location.href = redir;
+ }
+ }
+ }
+ }
+ );
+ };
+
+
+ this.batchFundWidget = null;
+
+ this.applyBatchLiFunds = function() {
+
+ var liIds = this.getSelected().map(function(li) { return li.id(); });
+ if(liIds.length == 0) return; // warn?
+
+ var self = this;
+ batchFundUpdateDialog.show();
+
+ if(!this.batchFundWidget) {
+ this.batchFundWidget = new openils_widget_AutoFieldWidget({
+ fmClass : 'acqf',
+ selfReference : true,
+ labelFormat : fundLabelFormat,
+ searchFormat : fundSearchFormat,
+ searchFilter : {"active": "t"},
+ parentNode : dojo.byId('acq-lit-batch-fund-selector'),
+ orgLimitPerms : ['CREATE_PICKLIST', 'CREATE_PURCHASE_ORDER'],
+ dijitArgs : { "required": true, "labelType": "html" },
+ forceSync : true
+ });
+ this.batchFundWidget.build();
+ }
+
+ dojo.connect(batchFundUpdateCancel, 'onClick', function() { batchFundUpdateDialog.hide(); });
+ dojo.connect(batchFundUpdateSubmit, 'onClick',
+ function() {
+
+ // TODO: call .dry_run first to test thresholds
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem.fund.update.batch'],
+ {
+ params : [
+ openils.User.authtoken,
+ liIds,
+ self.batchFundWidget.widget.attr('value')
+ ],
+ oncomplete : function(r) {
+ var resp = openils.Util.readResponse(r);
+ if(resp) {
+ location.href = location.href;
+ }
+ }
+ }
+ )
+ }
+ );
+ }
+
+ this._deleteLiList = function(list, idx) {
+ if(idx == null) idx = 0;
+ if(idx >= list.length) return;
+
+ var li = list[idx];
+ var liId = li.id();
+
+ if (this.isPO && (li.state() == "on-order" || li.state() == "received")) {
+ /* It makes little sense to delete a lineitem from a PO that has
+ * already been marked 'on-order'. Especially if EDI is in use,
+ * such a purchase order will probably have already been shipped
+ * off to a vendor, and mucking with it at this point could leave
+ * your data in a bad state that doesn't jive with reality.
+ *
+ * I could see making this restriction even firmer.
+ *
+ * I could also see adjusting the li state comparisons, extending
+ * the comparison to the PO's state, and/or providing functions
+ * that house the logic for comparing states in a single location.
+ *
+ * Yes, this will be really annoying if you have selected a lot
+ * of lineitems to cancel that have been ordered. You'll get a
+ * confirm dialog for each one.
+ */
+
+ if (!confirm(localeStrings.DEL_LI_FROM_PO)) {
+ self._deleteLiList(list, ++idx); /* move on to next in list */
+ return;
+ }
+ }
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq',
+ this.isPO ? 'open-ils.acq.purchase_order.lineitem.delete' : 'open-ils.acq.picklist.lineitem.delete'],
+ { async: true,
+ params: [openils.User.authtoken, liId],
+ oncomplete: function(r) {
+ self.removeLineitem(liId);
+ self._deleteLiList(list, ++idx);
+ }
+ }
+ );
+ }
+
+ this.editOrderMarc = function(li) {
+
+ /* To run in Firefox directly, must set signed.applets.codebase_principal_support
+ to true in about:config */
+
+ if(!openils.XUL.enableXPConnect()) return;
+
+ if(openils.XUL.isXUL()) {
+ win = window.open('/xul/' + openils.XUL.buildId() + '/server/cat/marcedit.xul');
+ } else {
+ win = window.open('/xul/server/cat/marcedit.xul');
+ }
+ var self = this;
+ win.xulG = {
+ record : {marc : li.marc(), "rtype": "bre"},
+ save : {
+ label: 'Save Record', // XXX I18N
+ func: function(xmlString) {
+ li.marc(xmlString);
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem.update'],
+ { async: true,
+ params: [openils.User.authtoken, li],
+ oncomplete: function(r) {
+ openils.Util.readResponse(r);
+ win.close();
+ self.drawInfo(li.id())
+ }
+ }
+ );
+ },
+ },
+ 'lock_tab' : typeof xulG != 'undefined' ? (typeof xulG['lock_tab'] != 'undefined' ? xulG.lock_tab : undefined) : undefined,
+ 'unlock_tab' : typeof xulG != 'undefined' ? (typeof xulG['unlock_tab'] != 'undefined' ? xulG.unlock_tab : undefined) : undefined
+ };
+ }
+
+ this._savePl = function(values) {
+ this.getSelected(
+ (values.which == 'all'),
+ function(list) { self._savePlFromLineitems(values, list); }
+ );
+ };
+
+ this._savePlFromLineitems = function(values, selected) {
+ openils.Util.show("acq-lit-generic-progress");
+
+ if(values.new_name) {
+ openils_acq_Picklist.create(
+ {name: values.new_name},
+ function(id) {
+ self._updateLiList(
+ id, selected, 0,
+ function() {
+ location.href =
+ oilsBasePath + "/acq/picklist/view/" + id;
+ }
+ );
+ }
+ );
+ } else if(values.existing_pl) {
+ // update lineitems to use an existing picklist
+ self._updateLiList(
+ values.existing_pl, selected, 0,
+ function(){
+ location.href =
+ oilsBasePath + "/acq/picklist/view/" +
+ values.existing_pl;
+ }
+ );
+ }
+ };
+
+ this._updateLiState = function(values, state) {
+ progressDialog.show(true);
+ this.getSelected(
+ (values.which == 'all'),
+ function(list) {
+ self._updateLiStateFromLineitems(values, state, list);
+ }
+ );
+ };
+
+ this._updateLiStateFromLineitems = function(values, state, selected) {
+ if(!selected.length) return;
+ dojo.forEach(selected, function(li) {li.state(state);});
+ self._updateLiList(null, selected, 0,
+ // TODO consider inline updates for efficiency
+ function() { location.href = location.href }
+ );
+ };
+
+ this._updateLiList = function(pl, list, idx, oncomplete) {
+ if(idx >= list.length) return oncomplete();
+ var li = list[idx];
+ if(pl != null) li.picklist(pl);
+ litGenericProgress.update({maximum: list.length, progress: idx});
+ new openils_acq_Lineitem({lineitem:li}).update(
+ function(r) {
+ self._updateLiList(pl, list, ++idx, oncomplete);
+ }
+ );
+ }
+
+ this._loadPOSelect = function() {
+ if (!this.createPoProviderSelector) {
+ var widget = new openils_widget_AutoFieldWidget({
+ "fmField": "provider",
+ "fmClass": "acqpo",
+ "searchFilter": {"active": "t"},
+ "parentNode": dojo.byId("acq-lit-po-provider"),
+ "dijitArgs": {
+ "onChange": function() {
+ if (this.item) {
+ self._updateCreatePoPrepayCheckbox(
+ this.item.prepayment_required()
+ );
+ }
+ }
+ }
+ });
+ widget.build(function(w) { self.createPoProviderSelector = w; });
+ }
+
+ if (!this.createPoAgencySelector) {
+ var widget = new openils_widget_AutoFieldWidget({
+ "fmField": "ordering_agency",
+ "fmClass": "acqpo",
+ "parentNode": dojo.byId("acq-lit-po-agency"),
+ "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
+ });
+ widget.build(function(w) { self.createPoAgencySelector = w; });
+ }
+ };
+
+ this.showRealCopyEditUI = function(li) {
+ copyList = [];
+ var self = this;
+ this.volCache = {};
+
+ this._fetchLineitem(li.id(),
+ function(fullLi) {
+ li = self.liCache[li.id()] = fullLi;
+
+ self.pcrud.search(
+ 'acp', {
+ id : li.lineitem_details().map(
+ function(item) { return item.eg_copy_id() }
+ )
+ }, {
+ async : true,
+ oncomplete : function(r) {
+ try {
+ var r_list = openils.Util.readResponse( r );
+ for (var i = 0; i < r_list.length; i++) {
+ var copy = r_list[i];
+ var volId = copy.call_number();
+ var volume = self.volCache[volId];
+ if(!volume) {
+ volume = self.volCache[volId] = self.pcrud.retrieve('acn', volId);
+ }
+ copy.call_number(volume);
+ copyList.push(copy);
+ }
+ if (xulG) {
+ xulG.volume_item_creator( { 'existing_copies' : copyList } );
+ }
+ } catch(E) {
+ alert('error in oncomplete: ' + E);
+ }
+ }
+ }
+ );
+ }
+ );
+ },
+
+ this.drawBibFinder = function(li) {
+
+ var query = '';
+ var liWrapper = new openils_acq_Lineitem({lineitem:li});
+
+ dojo.forEach(
+ ['isbn', 'upc', 'issn', 'title', 'author'],
+ function(field) {
+ var val = liWrapper.findAttr(field, 'lineitem_marc_attr_definition');
+ if(val) {
+ if(field == 'title' || field == 'author') {
+ query += field +':' + val + ' ';
+ } else {
+ query += 'identifier|' + field + ':' + val + ' ';
+ }
+ }
+ }
+ );
+
+ win = window.open(
+ oilsBasePath + '/acq/lineitem/findbib?query=' + escape(query),
+ '', 'resizable,scrollbars=1');
+
+ win.window.recordFound = function(bibId) {
+ win.close();
+
+ var attrs = li.attributes();
+ li.attributes(null);
+ li.eg_bib_id(bibId);
+
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem.update"],
+ {
+ "params": [openils.User.authtoken, li],
+ "async": true,
+ "oncomplete": function(r) {
+ if(openils.Util.readResponse(r)) {
+ location.href = location.href;
+ }
+ }
+ }
+ );
+ }
+ }
+ }
+
+
+
+});
\ No newline at end of file
-dojo.require("openils.PermaCrud");
-dojo.require("dojo.data.ItemFileReadStore");
+require([
+ "openils/PermaCrud",
+ "dojo/data/ItemFileReadStore"
+ ],
+function(openils_PermaCrud,
+ dojo_data_ItemFileReadStore){
+
+ if (typeof(localeStrings) == "undefined") {
+ dojo.requireLocalization("openils.acq", "acq");
+ var localeStrings = dojo.i18n.getLocalization("openils.acq", "acq");
+ }
+
+ function TagManager(displayNode) {
+ var self = this;
+ this.tagCache = {};
+ this.displayNode = displayNode;
+
+ this.pcrud = new openils_PermaCrud();
+
+ // selected (by checkbox) id's from an autogrid of objects:
+ // return grid.getSelectedItems().map(function(o) { return o.id[0]; });
+
+ this.displayFund = function(fund) {
+ if (!fund) {
+ this.displayNode.innerHTML = localeStrings.FUND_NOT_YET_LOADED;
+ return;
+ }
+
+ dojo.empty(this.displayNode);
+ fund.tags().forEach(
+ function(o) {
+ dojo.place(self.renderTagMapping(o), self.displayNode, "last");
+ }
+ );
+ };
+
+ this.renderTagMapping = function(mapping) {
+ var span = dojo.create(
+ "span", {
+ "id": "oils-acq-fund-tag-mapping-" + mapping.id(),
+ "className": "oils-acq-fund-tag",
+ "innerHTML": mapping.tag().name()
+ }
+ );
+ dojo.create(
+ "a", {
+ "href": "javascript:void(0);",
+ "innerHTML": "X",
+ "onclick": function() { self.deleteMapping(mapping); },
+ },
+ span, "last"
+ );
+ return span;
+ };
+
+ this.deleteMapping = function(mapping) {
+ if (confirm(localeStrings.CONFIRM_DELETE_MAPPING)) {
+ this.pcrud.eliminate(
+ mapping, {
+ "oncomplete": function(r) {
+ dojo.destroy(
+ "oils-acq-fund-tag-mapping-" + mapping.id()
+ );
+ fund.tags(
+ fund.tags().filter(
+ function(o) { return o.id() != mapping.id(); }
+ )
+ );
+ },
+ "onerror": function() {
+ /* XXX does onerror not actually work? */
+ alert(localeStrings.COULD_NOT_DELETE_MAPPING);
+ }
+ }
+ );
+ }
+ };
+
+ this.addMapping = function(fund, tag) {
+ var mapping = new acqftm();
+ mapping.fund(fund.id());
+ mapping.tag(tag.id());
+
+ this.pcrud.create(
+ mapping, {
+ "onerror": function(r) {
+ /* XXX does onerror not actually work? */
+ alert(localeStrings.COULD_NOT_CREATE_MAPPING);
+ },
+ "oncomplete": function(r, list) {
+ mapping = list[0]; /* get the new mapping's ID this way */
+ mapping.tag(tag); /* re-"flesh" */
+ fund.tags().push(mapping); /* save local reference */
+ dojo.place(
+ self.renderTagMapping(mapping),
+ self.displayNode, "last"
+ );
+ }
+ }
+ );
+ };
+
+ this.prepareTagSelector = function(selector) {
+ this.pcrud.search(
+ "acqft", {
+ "owner": fieldmapper.aou.orgNodeTrail(
+ fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()),
+ true /* asId */
+ )
+ }, {
+ "async": true,
+ "oncomplete": function(r) {
+ if ((r = openils.Util.readResponse(r))) {
+ selector.store = new dojo_data_ItemFileReadStore(
+ {"data": acqft.toStoreData(r)}
+ );
+ selector.startup();
+ }
+ }
+ }
+ );
+ };
+ }
+
-if (typeof(localeStrings) == "undefined") {
- dojo.requireLocalization("openils.acq", "acq");
- var localeStrings = dojo.i18n.getLocalization("openils.acq", "acq");
-}
-
-function TagManager(displayNode) {
- var self = this;
- this.tagCache = {};
- this.displayNode = displayNode;
-
- this.pcrud = new openils.PermaCrud();
-
-// selected (by checkbox) id's from an autogrid of objects:
-// return grid.getSelectedItems().map(function(o) { return o.id[0]; });
-
- this.displayFund = function(fund) {
- if (!fund) {
- this.displayNode.innerHTML = localeStrings.FUND_NOT_YET_LOADED;
- return;
- }
-
- dojo.empty(this.displayNode);
- fund.tags().forEach(
- function(o) {
- dojo.place(self.renderTagMapping(o), self.displayNode, "last");
- }
- );
- };
-
- this.renderTagMapping = function(mapping) {
- var span = dojo.create(
- "span", {
- "id": "oils-acq-fund-tag-mapping-" + mapping.id(),
- "className": "oils-acq-fund-tag",
- "innerHTML": mapping.tag().name()
- }
- );
- dojo.create(
- "a", {
- "href": "javascript:void(0);",
- "innerHTML": "X",
- "onclick": function() { self.deleteMapping(mapping); },
- },
- span, "last"
- );
- return span;
- };
-
- this.deleteMapping = function(mapping) {
- if (confirm(localeStrings.CONFIRM_DELETE_MAPPING)) {
- this.pcrud.eliminate(
- mapping, {
- "oncomplete": function(r) {
- dojo.destroy(
- "oils-acq-fund-tag-mapping-" + mapping.id()
- );
- fund.tags(
- fund.tags().filter(
- function(o) { return o.id() != mapping.id(); }
- )
- );
- },
- "onerror": function() {
- /* XXX does onerror not actually work? */
- alert(localeStrings.COULD_NOT_DELETE_MAPPING);
- }
- }
- );
- }
- };
-
- this.addMapping = function(fund, tag) {
- var mapping = new acqftm();
- mapping.fund(fund.id());
- mapping.tag(tag.id());
-
- this.pcrud.create(
- mapping, {
- "onerror": function(r) {
- /* XXX does onerror not actually work? */
- alert(localeStrings.COULD_NOT_CREATE_MAPPING);
- },
- "oncomplete": function(r, list) {
- mapping = list[0]; /* get the new mapping's ID this way */
- mapping.tag(tag); /* re-"flesh" */
- fund.tags().push(mapping); /* save local reference */
- dojo.place(
- self.renderTagMapping(mapping),
- self.displayNode, "last"
- );
- }
- }
- );
- };
-
- this.prepareTagSelector = function(selector) {
- this.pcrud.search(
- "acqft", {
- "owner": fieldmapper.aou.orgNodeTrail(
- fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()),
- true /* asId */
- )
- }, {
- "async": true,
- "oncomplete": function(r) {
- if ((r = openils.Util.readResponse(r))) {
- selector.store = new dojo.data.ItemFileReadStore(
- {"data": acqft.toStoreData(r)}
- );
- selector.startup();
- }
- }
- }
- );
- };
-}
+});
\ No newline at end of file
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.PermaCrud');
-
-function VLAgent(args) {
- args = args || {};
- for (var key in args) {
- this[key] = args[key];
- }
-
- this.widgets = [
- {key : 'import_no_match'},
- {key : 'auto_overlay_exact'},
- {key : 'auto_overlay_1match'},
- {key : 'auto_overlay_best_match'},
- {key : 'match_quality_ratio'},
- {key : 'queue_name'},
- {key : 'match_set', cls : 'vms'},
- {key : 'bib_source', cls : 'cbs'},
- {key : 'merge_profile', cls : 'vmp'},
- {key : 'fall_through_merge_profile', cls : 'vmp'},
- {key : 'existing_queue', cls : 'vbq'}
- ];
-
- this.loaded = false;
-
- this.init = function() {
- var self = this;
-
- dojo.forEach(this.widgets,
- function(widg) {
- if (widg.cls) { // selectors
-
- new openils.widget.AutoFieldWidget({
- fmClass : widg.cls,
- selfReference : true,
- orgLimitPerms : [self.limitPerm || 'CREATE_PURCHASE_ORDER'],
- parentNode : dojo.byId('acq_vl:' + widg.key),
- searchFilter : (widg.cls == 'vbq') ? {queue_type : 'acq'} : null,
- useWriteStore : (widg.cls == 'vbq')
- }).build(function(dijit) {
- widg.dijit = dijit;
- self.attachOnChange(widg);
- });
-
- } else { // bools
- widg.dijit = dijit.byId('acq_vl:' + widg.key);
- self.attachOnChange(widg);
- }
- }
- );
-
- // loaded != all widgets are done rendering,
- // only that init() has been called.
- this.loaded = true;
- }
-
- this.attachOnChange = function(widg) {
- var self = this;
- var qInputChange;
-
- var qSelChange = function(val) {
- // user selected a queue from the selector; clear the text input
- // and set the item import profile already defined for the queue
-
- var qInput = self.getDijit('queue_name');
- var matchSetSelector = self.getDijit('match_set');
- var qSelector = self.getDijit('existing_queue');
-
- if(val) {
- qSelector.store.fetch({
- query : {id : val+''},
- onComplete : function(items) {
- matchSetSelector.attr('value', items[0].match_set[0] || '');
- matchSetSelector.attr('disabled', true);
- }
- });
- } else {
- matchSetSelector.attr('value', '');
- matchSetSelector.attr('disabled', false);
- }
-
- // detach and reattach to avoid onchange firing while when we clear
- dojo.disconnect(qInput._onchange);
- qInput.attr('value', '');
- qInput._onchange = dojo.connect(qInput, 'onChange', qInputChange);
- }
-
- qInputChange = function(val) {
-
- var qSelector = self.getDijit('existing_queue');
- var matchSetSelector = self.getDijit('match_set');
- var foundMatch = false;
-
- if (val) {
-
- // if the user entered the name of an existing queue, update the
- // queue selector to match the value (and clear the text input
- // via qselector onchange)
- qSelector.store.fetch({
- query:{name:val},
- onComplete:function(items) {
- if(items.length == 0) return;
- var item = items[0];
- qSelector.attr('value', item.id);
- foundMatch = true;
- }
- });
- }
-
- if (!foundMatch) {
- self.getDijit('match_set').attr('disabled', false);
- dojo.disconnect(qSelector._onchange);
- qSelector.attr('value', '');
- qSelector._onchange = dojo.connect(qSelector, 'onChange', qSelChange);
- }
- }
-
- if (widg.key == 'existing_queue') {
- var qSelector = self.getDijit('existing_queue');
- qSelector._onchange = dojo.connect(qSelector, 'onChange', qSelChange);
- } else if(widg.key == 'queue_name') {
- var qInput = self.getDijit('queue_name');
- qInput._onchange = dojo.connect(qInput, 'onChange', qInputChange);
- }
- }
-
- this.getDijit = function(key) {
- return this.widgets.filter(function(w) {return (w.key == key)})[0].dijit;
- }
-
- this.values = function() {
- var values = {};
- dojo.forEach(this.widgets,
- function(widg) {
- values[widg.key] = widg.dijit.attr('value');
- }
- );
- return values;
- }
-
- this.handleResponse = function(resp, oncomplete) {
- if(!resp) return;
- var res = {}
-
- console.log('vandelay import returned : ' + js2JSON(resp));
-
- // update the display counts
- dojo.byId('acq_vl:li-processed').innerHTML = resp.li;
- dojo.byId('acq_vl:vqbr-processed').innerHTML = resp.vqbr;
- dojo.byId('acq_vl:bibs-processed').innerHTML = resp.bibs;
- dojo.byId('acq_vl:lid-processed').innerHTML = resp.lid;
- dojo.byId('acq_vl:debits-processed').innerHTML = resp.debits_accrued;
- dojo.byId('acq_vl:copies-processed').innerHTML = resp.copies;
-
- if (resp.complete) {
-
- if(resp.picklist) {
- res.picklist_url = oilsBasePath + '/acq/picklist/view/' + resp.picklist.id();
- }
-
- if(resp.purchase_order) {
- res.po_url = oilsBasePath + '/acq/po/view/' + resp.purchase_order.id();
- }
-
- if (resp.queue) {
- var newQid = resp.queue.id();
- res.queue_url = oilsBasePath + '/vandelay/vandelay?qtype=bib&qid=' + newQid;
-
- var qInput = this.getDijit('queue_name');
-
- if (newQName = qInput.attr('value')) {
- // user created a new queue. Fetch the new queue object,
- // replace the ReadStore with a WriteStore and insert.
- qInput.attr('value', '');
- var qSelector = this.getDijit('existing_queue');
- var newQ = new openils.PermaCrud().retrieve('vbq', newQid);
- qSelector.store.newItem(newQ.toStoreItem());
- qSelector.attr('value', newQid);
- }
- }
-
- if (oncomplete)
- oncomplete(resp, res);
-
- return res;
- }
-
- return false; // not yet complete
- }
-}
+require([
+ "openils/widget/AutoFieldWidget",
+ "openils/PermaCrud"
+ ],
+function(openils_widget_AutoFieldWidget,
+ openils_PermaCrud){
+
+ function VLAgent(args) {
+ args = args || {};
+ for (var key in args) {
+ this[key] = args[key];
+ }
+
+ this.widgets = [
+ {key : 'import_no_match'},
+ {key : 'auto_overlay_exact'},
+ {key : 'auto_overlay_1match'},
+ {key : 'auto_overlay_best_match'},
+ {key : 'match_quality_ratio'},
+ {key : 'queue_name'},
+ {key : 'match_set', cls : 'vms'},
+ {key : 'bib_source', cls : 'cbs'},
+ {key : 'merge_profile', cls : 'vmp'},
+ {key : 'fall_through_merge_profile', cls : 'vmp'},
+ {key : 'existing_queue', cls : 'vbq'}
+ ];
+
+ this.loaded = false;
+
+ this.init = function() {
+ var self = this;
+
+ dojo.forEach(this.widgets,
+ function(widg) {
+ if (widg.cls) { // selectors
+
+ new openils_widget_AutoFieldWidget({
+ fmClass : widg.cls,
+ selfReference : true,
+ orgLimitPerms : [self.limitPerm || 'CREATE_PURCHASE_ORDER'],
+ parentNode : dojo.byId('acq_vl:' + widg.key),
+ searchFilter : (widg.cls == 'vbq') ? {queue_type : 'acq'} : null,
+ useWriteStore : (widg.cls == 'vbq')
+ }).build(function(dijit) {
+ widg.dijit = dijit;
+ self.attachOnChange(widg);
+ });
+
+ } else { // bools
+ widg.dijit = dijit.byId('acq_vl:' + widg.key);
+ self.attachOnChange(widg);
+ }
+ }
+ );
+
+ // loaded != all widgets are done rendering,
+ // only that init() has been called.
+ this.loaded = true;
+ }
+
+ this.attachOnChange = function(widg) {
+ var self = this;
+ var qInputChange;
+
+ var qSelChange = function(val) {
+ // user selected a queue from the selector; clear the text input
+ // and set the item import profile already defined for the queue
+
+ var qInput = self.getDijit('queue_name');
+ var matchSetSelector = self.getDijit('match_set');
+ var qSelector = self.getDijit('existing_queue');
+
+ if(val) {
+ qSelector.store.fetch({
+ query : {id : val+''},
+ onComplete : function(items) {
+ matchSetSelector.attr('value', items[0].match_set[0] || '');
+ matchSetSelector.attr('disabled', true);
+ }
+ });
+ } else {
+ matchSetSelector.attr('value', '');
+ matchSetSelector.attr('disabled', false);
+ }
+
+ // detach and reattach to avoid onchange firing while when we clear
+ dojo.disconnect(qInput._onchange);
+ qInput.attr('value', '');
+ qInput._onchange = dojo.connect(qInput, 'onChange', qInputChange);
+ }
+
+ qInputChange = function(val) {
+
+ var qSelector = self.getDijit('existing_queue');
+ var matchSetSelector = self.getDijit('match_set');
+ var foundMatch = false;
+
+ if (val) {
+
+ // if the user entered the name of an existing queue, update the
+ // queue selector to match the value (and clear the text input
+ // via qselector onchange)
+ qSelector.store.fetch({
+ query:{name:val},
+ onComplete:function(items) {
+ if(items.length == 0) return;
+ var item = items[0];
+ qSelector.attr('value', item.id);
+ foundMatch = true;
+ }
+ });
+ }
+
+ if (!foundMatch) {
+ self.getDijit('match_set').attr('disabled', false);
+ dojo.disconnect(qSelector._onchange);
+ qSelector.attr('value', '');
+ qSelector._onchange = dojo.connect(qSelector, 'onChange', qSelChange);
+ }
+ }
+
+ if (widg.key == 'existing_queue') {
+ var qSelector = self.getDijit('existing_queue');
+ qSelector._onchange = dojo.connect(qSelector, 'onChange', qSelChange);
+ } else if(widg.key == 'queue_name') {
+ var qInput = self.getDijit('queue_name');
+ qInput._onchange = dojo.connect(qInput, 'onChange', qInputChange);
+ }
+ }
+
+ this.getDijit = function(key) {
+ return this.widgets.filter(function(w) {return (w.key == key)})[0].dijit;
+ }
+
+ this.values = function() {
+ var values = {};
+ dojo.forEach(this.widgets,
+ function(widg) {
+ values[widg.key] = widg.dijit.attr('value');
+ }
+ );
+ return values;
+ }
+
+ this.handleResponse = function(resp, oncomplete) {
+ if(!resp) return;
+ var res = {}
+
+ console.log('vandelay import returned : ' + js2JSON(resp));
+
+ // update the display counts
+ dojo.byId('acq_vl:li-processed').innerHTML = resp.li;
+ dojo.byId('acq_vl:vqbr-processed').innerHTML = resp.vqbr;
+ dojo.byId('acq_vl:bibs-processed').innerHTML = resp.bibs;
+ dojo.byId('acq_vl:lid-processed').innerHTML = resp.lid;
+ dojo.byId('acq_vl:debits-processed').innerHTML = resp.debits_accrued;
+ dojo.byId('acq_vl:copies-processed').innerHTML = resp.copies;
+
+ if (resp.complete) {
+
+ if(resp.picklist) {
+ res.picklist_url = oilsBasePath + '/acq/picklist/view/' + resp.picklist.id();
+ }
+
+ if(resp.purchase_order) {
+ res.po_url = oilsBasePath + '/acq/po/view/' + resp.purchase_order.id();
+ }
+
+ if (resp.queue) {
+ var newQid = resp.queue.id();
+ res.queue_url = oilsBasePath + '/vandelay/vandelay?qtype=bib&qid=' + newQid;
+
+ var qInput = this.getDijit('queue_name');
+
+ if (newQName = qInput.attr('value')) {
+ // user created a new queue. Fetch the new queue object,
+ // replace the ReadStore with a WriteStore and insert.
+ qInput.attr('value', '');
+ var qSelector = this.getDijit('existing_queue');
+ var newQ = new openils_PermaCrud().retrieve('vbq', newQid);
+ qSelector.store.newItem(newQ.toStoreItem());
+ qSelector.attr('value', newQid);
+ }
+ }
+
+ if (oncomplete)
+ oncomplete(resp, res);
+
+ return res;
+ }
+
+ return false; // not yet complete
+ }
+ }
+
+
+});
\ No newline at end of file
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.TextBox");
-dojo.require("openils.acq.Lineitem");
-dojo.require("openils.widget.OrgUnitFilteringSelect");
-dojo.require("openils.widget.ProgressDialog");
-dojo.require("openils.widget.AutoFieldWidget");
-
-var eligibleLiTable;
-
-function nodeByName(n, c) { return dojo.query("[name='" + n + "']", c)[0]; }
-
-function EligibleLiTable(filter) {
- var self = this;
-
- this.filter = filter;
- this.liCache = {};
- this.numClaimableLids = {};
-
- this.claimNote = dijit.byId("acq-eligible-claim-note");
- this.table = dojo.byId("acq-eligible-li-table");
- this.tBody = dojo.query("tbody", this.table)[0];
- this.tHead = dojo.query("thead", this.table)[0];
- [this.rowTemplate, this.emptyTemplate] =
- dojo.query("tr", this.tBody).map(
- function(o) { return self.tBody.removeChild(o); }
- );
-
- nodeByName("selector_all", this.tHead).onclick = function() {
- var value = this.checked;
- dojo.query("[name='selector']", self.tBody).forEach(
- function(o) { o.checked = value; }
- );
- };
-
- new openils.widget.AutoFieldWidget({
- "fmClass": "acqclt",
- "selfReference": true,
- "dijitArgs": {"required": true},
- "parentNode": dojo.byId("acq-eligible-claim-type")
- }).build(function(w) { self.claimType = w; });
-
- new openils.User().buildPermOrgSelector(
- "VIEW_PURCHASE_ORDER", orderingAgency, null,
- function() {
- orderingAgency.attr("value", self.filter.ordering_agency);
- dojo.connect(
- orderingAgency, "onChange",
- function() {
- self.filter.ordering_agency = this.attr("value");
- self.load();
- }
- );
- self.load();
- }
- );
-
- dojo.byId("acq-eligible-claim-submit").onclick = function() {
- finalClaimDialog.hide();
- self.claim(self.getSelected());
- };
-
- dojo.query("button[name='claim_submit']").forEach(
- function(button) {
- button.onclick = function() {
- if (self.getSelected().length)
- finalClaimDialog.show();
- else
- alert(localeStrings.NO_LI_TO_CLAIM);
- };
- }
- );
-
- this.showEmpty = function() {
- dojo.place(dojo.clone(this.emptyTemplate), this.tBody, "only");
- openils.Util.hide("acq-eligible-claim-controls");
- };
-
- this.load = function() {
- progressDialog.show(true);
-
- var count = 0;
- this.reset();
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.claim.eligible.lineitem_detail.atomic"], {
- "params": [openils.User.authtoken, this.filter],
- "async": true,
- "oncomplete": function(r) {
- progressDialog.hide();
- var rset = openils.Util.readResponse(r);
- if (rset.length < 1) self.showEmpty();
- else {
- var byLi = {};
- rset.forEach(
- function(r) {
- byLi[r.lineitem()] =
- (byLi[r.lineitem()] || 0) + 1;
- }
- );
- for (var key in byLi)
- self.addIfMissing(key, byLi[key]);
- }
- }
- }
- );
- };
-
- this.reset = function() {
- this.liCache = {};
- this.numClaimableLids = {};
- dojo.empty(this.tBody);
- };
-
- this._updateLidLink = function(liId) {
- this.numClaimableLids[liId] = (this.numClaimableLids[liId] || 0) + 1;
- if (this.numClaimableLids[liId] == 2) {
- nodeByName("lid_link", "eligible-li-" + liId).onclick =
- function() {
- location.href = oilsBasePath + "/acq/po/view/" +
- self.liCache[liId].purchase_order().id() + "/" +
- liId;
- };
- openils.Util.show(
- nodeByName("lid_link_holder", "eligible-li-" + liId)
- );
- }
- };
-
- /* Despite being called with an argument that's a lineitem ID, this method
- * is actually called once per lineitem _detail_. */
- this.addIfMissing = function(liId, number_of_appearances) {
- var row = dojo.clone(this.rowTemplate);
-
- var checkbox = nodeByName("selector", row);
- var desc = nodeByName("description", row);
-
- openils.acq.Lineitem.fetchAndRender(
- liId, null, function(li, contents) {
- self.liCache[liId] = li;
-
- desc.innerHTML = contents;
- dojo.attr(row, "id", "eligible-li-" + liId);
- dojo.attr(checkbox, "value", liId);
- dojo.place(row, self.tBody, "last");
-
- for (var i = 0; i < number_of_appearances; i++)
- self._updateLidLink(liId);
- }
- );
- };
-
- /* Despite being called with an argument that's a lineitem ID, this method
- * is actually called once per lineitem _detail_. */
- this.removeIfPresent = function(liId) {
- if (this.liCache[liId]) {
- delete this.liCache[liId];
- delete this.numClaimableLids[liId];
- this.tBody.removeChild(dojo.byId("eligible-li-" + liId));
- }
- };
-
- this.getSelected = function() {
- return dojo.query("[name='selector']", this.tBody).
- filter(function(o) { return o.checked; }).
- map(function(o) { return o.value; });
- };
-
- this.resetVoucher = function() { this.voucherWin = null; };
-
- this.addToVoucher = function(contents) {
- if (!this.voucherWin)
- this.voucherWin = openClaimVoucherWindow();
- dojo.byId("main", this.voucherWin.document).innerHTML +=
- (contents + "<hr />");
- };
-
- this.finishVoucher = function() {
- var print_btn = dojo.byId("print", this.voucherWin.document);
- print_btn.disabled = false;
- print_btn.innerHTML = localeStrings.PRINT;
- };
-
- this.claim = function(lineitems) {
- progressDialog.show(true);
- self.resetVoucher();
-
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.claim.lineitem"], {
- "params": [
- openils.User.authtoken, lineitems, null,
- this.claimType.attr("value"), this.claimNote.attr("value")
- ],
- "async": true,
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r))
- self.addToVoucher(r.template_output().data());
- else
- progressDialog.hide();
- },
- "oncomplete": function() {
- lineitems.forEach(
- function(liId) { self.removeIfPresent(liId); }
- );
- if (!nodeByName("selector", self.tBody)) // emptiness test
- self.showEmpty();
-
- self.finishVoucher();
- progressDialog.hide();
- }
- }
- );
- };
-}
-
-function init() {
- var finished_filter = {};
- if (filter && filter.indexOf(":") != -1) {
- filter.split(",").forEach(
- function(chunk) {
- var kvlist = chunk.split(":");
- finished_filter[kvlist[0]] = kvlist[1];
- }
- );
- }
- filter = finished_filter;
-
- if (!filter.ordering_agency)
- filter.ordering_agency = openils.User.user.ws_ou();
-
- eligibleLiTable = new EligibleLiTable(filter);
-}
-
-openils.Util.addOnLoad(init);
+require([
+ "dijit/form/Button",
+ "dijit/form/TextBox",
+ "openils/acq/Lineitem",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/widget/ProgressDialog",
+ "openils/widget/AutoFieldWidget"
+ ],
+function(dijit_form_Button,
+ dijit_form_TextBox,
+ openils_acq_Lineitem,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_widget_ProgressDialog,
+ openils_widget_AutoFieldWidget){
+
+ var eligibleLiTable;
+
+ function nodeByName(n, c) { return dojo.query("[name='" + n + "']", c)[0]; }
+
+ function EligibleLiTable(filter) {
+ var self = this;
+
+ this.filter = filter;
+ this.liCache = {};
+ this.numClaimableLids = {};
+
+ this.claimNote = dijit.byId("acq-eligible-claim-note");
+ this.table = dojo.byId("acq-eligible-li-table");
+ this.tBody = dojo.query("tbody", this.table)[0];
+ this.tHead = dojo.query("thead", this.table)[0];
+ [this.rowTemplate, this.emptyTemplate] =
+ dojo.query("tr", this.tBody).map(
+ function(o) { return self.tBody.removeChild(o); }
+ );
+
+ nodeByName("selector_all", this.tHead).onclick = function() {
+ var value = this.checked;
+ dojo.query("[name='selector']", self.tBody).forEach(
+ function(o) { o.checked = value; }
+ );
+ };
+
+ new openils_widget_AutoFieldWidget({
+ "fmClass": "acqclt",
+ "selfReference": true,
+ "dijitArgs": {"required": true},
+ "parentNode": dojo.byId("acq-eligible-claim-type")
+ }).build(function(w) { self.claimType = w; });
+
+ new openils.User().buildPermOrgSelector(
+ "VIEW_PURCHASE_ORDER", orderingAgency, null,
+ function() {
+ orderingAgency.attr("value", self.filter.ordering_agency);
+ dojo.connect(
+ orderingAgency, "onChange",
+ function() {
+ self.filter.ordering_agency = this.attr("value");
+ self.load();
+ }
+ );
+ self.load();
+ }
+ );
+
+ dojo.byId("acq-eligible-claim-submit").onclick = function() {
+ finalClaimDialog.hide();
+ self.claim(self.getSelected());
+ };
+
+ dojo.query("button[name='claim_submit']").forEach(
+ function(button) {
+ button.onclick = function() {
+ if (self.getSelected().length)
+ finalClaimDialog.show();
+ else
+ alert(localeStrings.NO_LI_TO_CLAIM);
+ };
+ }
+ );
+
+ this.showEmpty = function() {
+ dojo.place(dojo.clone(this.emptyTemplate), this.tBody, "only");
+ openils.Util.hide("acq-eligible-claim-controls");
+ };
+
+ this.load = function() {
+ progressDialog.show(true);
+
+ var count = 0;
+ this.reset();
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.claim.eligible.lineitem_detail.atomic"], {
+ "params": [openils.User.authtoken, this.filter],
+ "async": true,
+ "oncomplete": function(r) {
+ progressDialog.hide();
+ var rset = openils.Util.readResponse(r);
+ if (rset.length < 1) self.showEmpty();
+ else {
+ var byLi = {};
+ rset.forEach(
+ function(r) {
+ byLi[r.lineitem()] =
+ (byLi[r.lineitem()] || 0) + 1;
+ }
+ );
+ for (var key in byLi)
+ self.addIfMissing(key, byLi[key]);
+ }
+ }
+ }
+ );
+ };
+
+ this.reset = function() {
+ this.liCache = {};
+ this.numClaimableLids = {};
+ dojo.empty(this.tBody);
+ };
+
+ this._updateLidLink = function(liId) {
+ this.numClaimableLids[liId] = (this.numClaimableLids[liId] || 0) + 1;
+ if (this.numClaimableLids[liId] == 2) {
+ nodeByName("lid_link", "eligible-li-" + liId).onclick =
+ function() {
+ location.href = oilsBasePath + "/acq/po/view/" +
+ self.liCache[liId].purchase_order().id() + "/" +
+ liId;
+ };
+ openils.Util.show(
+ nodeByName("lid_link_holder", "eligible-li-" + liId)
+ );
+ }
+ };
+
+ /* Despite being called with an argument that's a lineitem ID, this method
+ * is actually called once per lineitem _detail_. */
+ this.addIfMissing = function(liId, number_of_appearances) {
+ var row = dojo.clone(this.rowTemplate);
+
+ var checkbox = nodeByName("selector", row);
+ var desc = nodeByName("description", row);
+
+ openils_acq_Lineitem.fetchAndRender(
+ liId, null, function(li, contents) {
+ self.liCache[liId] = li;
+
+ desc.innerHTML = contents;
+ dojo.attr(row, "id", "eligible-li-" + liId);
+ dojo.attr(checkbox, "value", liId);
+ dojo.place(row, self.tBody, "last");
+
+ for (var i = 0; i < number_of_appearances; i++)
+ self._updateLidLink(liId);
+ }
+ );
+ };
+
+ /* Despite being called with an argument that's a lineitem ID, this method
+ * is actually called once per lineitem _detail_. */
+ this.removeIfPresent = function(liId) {
+ if (this.liCache[liId]) {
+ delete this.liCache[liId];
+ delete this.numClaimableLids[liId];
+ this.tBody.removeChild(dojo.byId("eligible-li-" + liId));
+ }
+ };
+
+ this.getSelected = function() {
+ return dojo.query("[name='selector']", this.tBody).
+ filter(function(o) { return o.checked; }).
+ map(function(o) { return o.value; });
+ };
+
+ this.resetVoucher = function() { this.voucherWin = null; };
+
+ this.addToVoucher = function(contents) {
+ if (!this.voucherWin)
+ this.voucherWin = openClaimVoucherWindow();
+ dojo.byId("main", this.voucherWin.document).innerHTML +=
+ (contents + "<hr />");
+ };
+
+ this.finishVoucher = function() {
+ var print_btn = dojo.byId("print", this.voucherWin.document);
+ print_btn.disabled = false;
+ print_btn.innerHTML = localeStrings.PRINT;
+ };
+
+ this.claim = function(lineitems) {
+ progressDialog.show(true);
+ self.resetVoucher();
+
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.claim.lineitem"], {
+ "params": [
+ openils.User.authtoken, lineitems, null,
+ this.claimType.attr("value"), this.claimNote.attr("value")
+ ],
+ "async": true,
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r))
+ self.addToVoucher(r.template_output().data());
+ else
+ progressDialog.hide();
+ },
+ "oncomplete": function() {
+ lineitems.forEach(
+ function(liId) { self.removeIfPresent(liId); }
+ );
+ if (!nodeByName("selector", self.tBody)) // emptiness test
+ self.showEmpty();
+
+ self.finishVoucher();
+ progressDialog.hide();
+ }
+ }
+ );
+ };
+ }
+
+ function init() {
+ var finished_filter = {};
+ if (filter && filter.indexOf(":") != -1) {
+ filter.split(",").forEach(
+ function(chunk) {
+ var kvlist = chunk.split(":");
+ finished_filter[kvlist[0]] = kvlist[1];
+ }
+ );
+ }
+ filter = finished_filter;
+
+ if (!filter.ordering_agency)
+ filter.ordering_agency = openils.User.user.ws_ou();
+
+ eligibleLiTable = new EligibleLiTable(filter);
+ }
+
+ openils.Util.addOnLoad(init);
+
+
+});
\ No newline at end of file
-dojo.require("dijit.Dialog");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require('openils.acq.FundingSource');
-dojo.require('openils.acq.CurrencyType');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('dijit.form.Button');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dojox.grid.DataGrid');
-dojo.require('openils.Event');
-dojo.require('openils.Util');
-dojo.require('openils.widget.AutoGrid');
-
-function getOrgInfo(rowIndex, item) {
- if(!item) return '';
- var owner = this.grid.store.getValue(item, 'owner');
- return fieldmapper.aou.findOrgUnit(owner).shortname();
-
-}
-
-function getBalanceInfo(rowIndex, item) {
- if(!item) return '';
- var id = this.grid.store.getValue( item, 'id');
- var fs = openils.acq.FundingSource.cache[id];
- if(fs && fs.summary())
- return fs.summary().balance;
- return 0;
-}
-
-function loadFSGrid() {
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.funding_source.org.retrieve'], {
- async: true,
- params: [openils.User.authtoken, null, {flesh_summary:1}],
- onresponse: function(r) { /* request object*/
- if(fs = openils.Util.readResponse(r)) {
- openils.acq.FundingSource.cache[fs.id()] = fs;
- fsGrid.store.newItem(acqfs.toStoreItem(fs));
- }
- },
- oncomplete: function() {
- fsGrid.hideLoadProgressIndicator();
- }
- }
- );
-}
-
-openils.Util.addOnLoad(loadFSGrid);
+require([
+ "dijit/Dialog",
+ "dijit/form/FilteringSelect",
+ "openils/acq/FundingSource",
+ "openils/acq/CurrencyType",
+ "openils/widget/OrgUnitFilteringSelect",
+ "dijit/form/Button",
+ "dojo/data/ItemFileWriteStore",
+ "dojox/grid/DataGrid",
+ "openils/Event",
+ "openils/Util",
+ "openils/widget/AutoGrid"
+ ],
+function(dijit_Dialog,
+ dijit_form_FilteringSelect,
+ openils_acq_FundingSource,
+ openils_acq_CurrencyType,
+ openils_widget_OrgUnitFilteringSelect,
+ dijit_form_Button,
+ dojo_data_ItemFileWriteStore,
+ dojox_grid_DataGrid,
+ openils_Event,
+ openils_Util,
+ openils_widget_AutoGrid){
+
+ function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var owner = this.grid.store.getValue(item, 'owner');
+ return fieldmapper.aou.findOrgUnit(owner).shortname();
+
+ }
+
+ function getBalanceInfo(rowIndex, item) {
+ if(!item) return '';
+ var id = this.grid.store.getValue( item, 'id');
+ var fs = openils_acq_FundingSource.cache[id];
+ if(fs && fs.summary())
+ return fs.summary().balance;
+ return 0;
+ }
+
+ function loadFSGrid() {
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.funding_source.org.retrieve'], {
+ async: true,
+ params: [openils.User.authtoken, null, {flesh_summary:1}],
+ onresponse: function(r) { /* request object*/
+ if(fs = openils_Util.readResponse(r)) {
+ openils_acq_FundingSource.cache[fs.id()] = fs;
+ fsGrid.store.newItem(acqfs.toStoreItem(fs));
+ }
+ },
+ oncomplete: function() {
+ fsGrid.hideLoadProgressIndicator();
+ }
+ }
+ );
+ }
+
+ openils_Util.addOnLoad(loadFSGrid);
+
+
+});
\ No newline at end of file
-dojo.require("dijit.Dialog");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require('dijit.form.Button');
-dojo.require('dijit.TooltipDialog');
-dojo.require('dijit.form.DropDownButton');
-dojo.require('dijit.form.CheckBox');
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('openils.acq.CurrencyType');
-dojo.require('openils.Event');
-dojo.require('openils.Util');
-dojo.require('openils.User');
-dojo.require('openils.CGI');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.widget.ProgressDialog');
-dojo.require('fieldmapper.OrgUtils');
-dojo.requireLocalization('openils.acq', 'acq');
-var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
-
-var contextOrg;
-var rolloverResponses;
-var rolloverMode = false;
-var fundFleshFields = [
- 'spent_balance',
- 'combined_balance',
- 'spent_total',
- 'encumbrance_total',
- 'debit_total',
- 'allocation_total'
-];
-
-var adminPermOrgs = [];
-var cachedFunds = [];
-
-function initPage() {
- contextOrg = openils.User.user.ws_ou();
-
- var connect = function() {
- dojo.connect(contextOrgSelector, 'onChange',
- function() {
- contextOrg = this.attr('value');
- dojo.byId('oils-acq-rollover-ctxt-org').innerHTML =
- fieldmapper.aou.findOrgUnit(contextOrg).shortname();
- rolloverMode = false;
- gridDataLoader();
- }
- );
- };
-
- dojo.connect(refreshButton, 'onClick',
- function() { rolloverMode = false; gridDataLoader(); });
-
- new openils.User().buildPermOrgSelector(
- ['ADMIN_ACQ_FUND', 'VIEW_FUND'],
- contextOrgSelector, contextOrg, connect);
-
- dojo.byId('oils-acq-rollover-ctxt-org').innerHTML =
- fieldmapper.aou.findOrgUnit(contextOrg).shortname();
-
- loadYearSelector();
- lfGrid.onItemReceived = function(item) {cachedFunds.push(item)};
-
- new openils.User().getPermOrgList(
- 'ADMIN_ACQ_FUND',
- function(list) {
- adminPermOrgs = list;
- loadFundGrid(
- new openils.CGI().param('year')
- || new Date().getFullYear().toString());
- },
- true, true
- );
-}
-
-function gridDataLoader() {
- lfGrid.resetStore();
- if(rolloverMode) {
- var offset = lfGrid.displayOffset;
- for(var i = offset; i < (offset + lfGrid.displayLimit - 1); i++) {
- var fund = rolloverResponses[i];
- if(!fund) break;
- lfGrid.store.newItem(fieldmapper.acqf.toStoreItem(fund));
- }
- } else {
- loadFundGrid();
- }
-}
-
-function getBalanceInfo(rowIdx, item) {
- if (!item) return '';
- var fundId = this.grid.store.getValue(item, 'id');
- var fund = cachedFunds.filter(function(f) { return f.id() == fundId })[0];
- var cb = fund.combined_balance();
- return cb ? cb.amount() : '0';
-}
-
-function loadFundGrid(year) {
- openils.Util.hide('acq-fund-list-rollover-summary');
- year = year || fundFilterYearSelect.attr('value');
- cachedFunds = [];
-
- lfGrid.loadAll(
- {
- flesh : 1,
- flesh_fields : {acqf : fundFleshFields},
-
- // by default, sort funds I can edit to the front
- order_by : [
- { 'class' : 'acqf',
- field : 'org',
- compare : {'in' : adminPermOrgs},
- direction : 'desc'
- },
- { 'class' : 'acqf',
- field : 'name'
- }
- ]
- }, {
- year : year,
- org : fieldmapper.aou.descendantNodeList(contextOrg, true)
- }
- );
-}
-
-function loadYearSelector() {
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.fund.org.years.retrieve'],
- { async : true,
- params : [openils.User.authtoken, {}, {limit_perm : 'VIEW_FUND'}],
- oncomplete : function(r) {
-
- var yearList = openils.Util.readResponse(r);
- if(!yearList) return;
- yearList = yearList.map(function(year){return {year:year+''};}); // dojo wants strings
-
- var yearStore = {identifier:'year', name:'year', items:yearList};
- yearStore.items = yearStore.items.sort().reverse();
- fundFilterYearSelect.store = new dojo.data.ItemFileWriteStore({data:yearStore});
-
- // default to this year
- fundFilterYearSelect.setValue(new Date().getFullYear().toString());
-
- dojo.connect(
- fundFilterYearSelect,
- 'onChange',
- function() {
- rolloverMode = false;
- gridDataLoader();
- }
- );
- }
- }
- );
-}
-
-function performRollover(args) {
-
- rolloverMode = true;
- progressDialog.show(true, "Processing...");
- rolloverResponses = [];
-
- var method = 'open-ils.acq.fiscal_rollover';
-
- if(args.rollover[0] == 'on') {
- method += '.combined';
- } else {
- method += '.propagate';
- }
-
- var dryRun = args.dry_run[0] == 'on';
- if(dryRun) method += '.dry_run';
-
- var count = 0;
- var amount_rolled = 0;
- var year = fundFilterYearSelect.attr('value'); // TODO alternate selector?
-
- fieldmapper.standardRequest(
- ['open-ils.acq', method],
- {
- async : true,
-
- params : [
- openils.User.authtoken,
- year,
- contextOrg,
- (args.child_orgs[0] == 'on')
- ],
-
- onresponse : function(r) {
- var resp = openils.Util.readResponse(r);
- rolloverResponses.push(resp.fund);
- count += 1;
- amount_rolled += Number(resp.rollover_amount);
- },
-
- oncomplete : function() {
-
- var nextYear = Number(year) + 1;
- rolloverResponses = rolloverResponses.sort(
- function(a, b) {
- if(a.code() > b.code())
- return 1;
- return -1;
- }
- )
-
- dojo.byId('acq-fund-list-rollover-summary-header').innerHTML =
- dojo.string.substitute(
- localeStrings.FUND_LIST_ROLLOVER_SUMMARY,
- [nextYear]
- );
-
- dojo.byId('acq-fund-list-rollover-summary-funds').innerHTML =
- dojo.string.substitute(
- localeStrings.FUND_LIST_ROLLOVER_SUMMARY_FUNDS,
- [nextYear, count]
- );
-
- dojo.byId('acq-fund-list-rollover-summary-rollover-amount').innerHTML =
- dojo.string.substitute(
- localeStrings.FUND_LIST_ROLLOVER_SUMMARY_ROLLOVER_AMOUNT,
- [nextYear, amount_rolled]
- );
-
- if(!dryRun) {
- openils.Util.hide('acq-fund-list-rollover-summary-dry-run');
-
- // add the new year to the year selector if it's not already there
- fundFilterYearSelect.store.fetch({
- query : {year : nextYear},
- onComplete:
- function(list) {
- if(list && list.length > 0) return;
- fundFilterYearSelect.store.newItem({year : nextYear});
- }
- });
- }
-
- openils.Util.show('acq-fund-list-rollover-summary');
- progressDialog.hide();
- gridDataLoader();
- }
- }
- );
-}
-
-openils.Util.addOnLoad(initPage);
+require([
+ "dijit/Dialog",
+ "dijit/form/FilteringSelect",
+ "dijit/form/Button",
+ "dijit/TooltipDialog",
+ "dijit/form/DropDownButton",
+ "dijit/form/CheckBox",
+ "dojox/grid/DataGrid",
+ "dojo/data/ItemFileWriteStore",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/acq/CurrencyType",
+ "openils/Event",
+ "openils/Util",
+ "openils/User",
+ "openils/CGI",
+ "openils/PermaCrud",
+ "openils/widget/AutoGrid",
+ "openils/widget/ProgressDialog",
+ "fieldmapper/OrgUtils"
+ ],
+function(dijit_Dialog,
+ dijit_form_FilteringSelect,
+ dijit_form_Button,
+ dijit_TooltipDialog,
+ dijit_form_DropDownButton,
+ dijit_form_CheckBox,
+ dojox_grid_DataGrid,
+ dojo_data_ItemFileWriteStore,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_acq_CurrencyType,
+ openils_Event,
+ openils_Util,
+ openils_User,
+ openils_CGI,
+ openils_PermaCrud,
+ openils_widget_AutoGrid,
+ openils_widget_ProgressDialog,
+ fieldmapper_OrgUtils){
+ dojo.requireLocalization('openils.acq', 'acq');
+ var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
+
+ var contextOrg;
+ var rolloverResponses;
+ var rolloverMode = false;
+ var fundFleshFields = [
+ 'spent_balance',
+ 'combined_balance',
+ 'spent_total',
+ 'encumbrance_total',
+ 'debit_total',
+ 'allocation_total'
+ ];
+
+ var adminPermOrgs = [];
+ var cachedFunds = [];
+
+ function initPage() {
+ contextOrg = openils_User.user.ws_ou();
+
+ var connect = function() {
+ dojo.connect(contextOrgSelector, 'onChange',
+ function() {
+ contextOrg = this.attr('value');
+ dojo.byId('oils-acq-rollover-ctxt-org').innerHTML =
+ fieldmapper.aou.findOrgUnit(contextOrg).shortname();
+ rolloverMode = false;
+ gridDataLoader();
+ }
+ );
+ };
+
+ dojo.connect(refreshButton, 'onClick',
+ function() { rolloverMode = false; gridDataLoader(); });
+
+ new openils_User().buildPermOrgSelector(
+ ['ADMIN_ACQ_FUND', 'VIEW_FUND'],
+ contextOrgSelector, contextOrg, connect);
+
+ dojo.byId('oils-acq-rollover-ctxt-org').innerHTML =
+ fieldmapper.aou.findOrgUnit(contextOrg).shortname();
+
+ loadYearSelector();
+ lfGrid.onItemReceived = function(item) {cachedFunds.push(item)};
+
+ new openils_User().getPermOrgList(
+ 'ADMIN_ACQ_FUND',
+ function(list) {
+ adminPermOrgs = list;
+ loadFundGrid(
+ new openils_CGI().param('year')
+ || new Date().getFullYear().toString());
+ },
+ true, true
+ );
+ }
+
+ function gridDataLoader() {
+ lfGrid.resetStore();
+ if(rolloverMode) {
+ var offset = lfGrid.displayOffset;
+ for(var i = offset; i < (offset + lfGrid.displayLimit - 1); i++) {
+ var fund = rolloverResponses[i];
+ if(!fund) break;
+ lfGrid.store.newItem(fieldmapper.acqf.toStoreItem(fund));
+ }
+ } else {
+ loadFundGrid();
+ }
+ }
+
+ function getBalanceInfo(rowIdx, item) {
+ if (!item) return '';
+ var fundId = this.grid.store.getValue(item, 'id');
+ var fund = cachedFunds.filter(function(f) { return f.id() == fundId })[0];
+ var cb = fund.combined_balance();
+ return cb ? cb.amount() : '0';
+ }
+
+ function loadFundGrid(year) {
+ openils_Util.hide('acq-fund-list-rollover-summary');
+ year = year || fundFilterYearSelect.attr('value');
+ cachedFunds = [];
+
+ lfGrid.loadAll(
+ {
+ flesh : 1,
+ flesh_fields : {acqf : fundFleshFields},
+
+ // by default, sort funds I can edit to the front
+ order_by : [
+ { 'class' : 'acqf',
+ field : 'org',
+ compare : {'in' : adminPermOrgs},
+ direction : 'desc'
+ },
+ { 'class' : 'acqf',
+ field : 'name'
+ }
+ ]
+ }, {
+ year : year,
+ org : fieldmapper.aou.descendantNodeList(contextOrg, true)
+ }
+ );
+ }
+
+ function loadYearSelector() {
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.fund.org.years.retrieve'],
+ { async : true,
+ params : [openils_User.authtoken, {}, {limit_perm : 'VIEW_FUND'}],
+ oncomplete : function(r) {
+
+ var yearList = openils_Util.readResponse(r);
+ if(!yearList) return;
+ yearList = yearList.map(function(year){return {year:year+''};}); // dojo wants strings
+
+ var yearStore = {identifier:'year', name:'year', items:yearList};
+ yearStore.items = yearStore.items.sort().reverse();
+ fundFilterYearSelect.store = new dojo_data_ItemFileWriteStore({data:yearStore});
+
+ // default to this year
+ fundFilterYearSelect.setValue(new Date().getFullYear().toString());
+
+ dojo.connect(
+ fundFilterYearSelect,
+ 'onChange',
+ function() {
+ rolloverMode = false;
+ gridDataLoader();
+ }
+ );
+ }
+ }
+ );
+ }
+
+ function performRollover(args) {
+
+ rolloverMode = true;
+ progressDialog.show(true, "Processing...");
+ rolloverResponses = [];
+
+ var method = 'open-ils.acq.fiscal_rollover';
+
+ if(args.rollover[0] == 'on') {
+ method += '.combined';
+ } else {
+ method += '.propagate';
+ }
+
+ var dryRun = args.dry_run[0] == 'on';
+ if(dryRun) method += '.dry_run';
+
+ var count = 0;
+ var amount_rolled = 0;
+ var year = fundFilterYearSelect.attr('value'); // TODO alternate selector?
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', method],
+ {
+ async : true,
+
+ params : [
+ openils_User.authtoken,
+ year,
+ contextOrg,
+ (args.child_orgs[0] == 'on')
+ ],
+
+ onresponse : function(r) {
+ var resp = openils_Util.readResponse(r);
+ rolloverResponses.push(resp.fund);
+ count += 1;
+ amount_rolled += Number(resp.rollover_amount);
+ },
+
+ oncomplete : function() {
+
+ var nextYear = Number(year) + 1;
+ rolloverResponses = rolloverResponses.sort(
+ function(a, b) {
+ if(a.code() > b.code())
+ return 1;
+ return -1;
+ }
+ )
+
+ dojo.byId('acq-fund-list-rollover-summary-header').innerHTML =
+ dojo.string.substitute(
+ localeStrings.FUND_LIST_ROLLOVER_SUMMARY,
+ [nextYear]
+ );
+
+ dojo.byId('acq-fund-list-rollover-summary-funds').innerHTML =
+ dojo.string.substitute(
+ localeStrings.FUND_LIST_ROLLOVER_SUMMARY_FUNDS,
+ [nextYear, count]
+ );
+
+ dojo.byId('acq-fund-list-rollover-summary-rollover-amount').innerHTML =
+ dojo.string.substitute(
+ localeStrings.FUND_LIST_ROLLOVER_SUMMARY_ROLLOVER_AMOUNT,
+ [nextYear, amount_rolled]
+ );
+
+ if(!dryRun) {
+ openils_Util.hide('acq-fund-list-rollover-summary-dry-run');
+
+ // add the new year to the year selector if it's not already there
+ fundFilterYearSelect.store.fetch({
+ query : {year : nextYear},
+ onComplete:
+ function(list) {
+ if(list && list.length > 0) return;
+ fundFilterYearSelect.store.newItem({year : nextYear});
+ }
+ });
+ }
+
+ openils_Util.show('acq-fund-list-rollover-summary');
+ progressDialog.hide();
+ gridDataLoader();
+ }
+ }
+ );
+ }
+
+ openils_Util.addOnLoad(initPage);
+
+
+});
\ No newline at end of file
-dojo.require("dijit.Dialog");
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.layout.TabContainer');
-dojo.require('dijit.layout.ContentPane');
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dijit.form.CurrencyTextBox');
-dojo.require("dijit.form.CheckBox");
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require("fieldmapper.OrgUtils");
-dojo.require('openils.acq.Fund');
-dojo.require('openils.acq.FundingSource');
-dojo.require('openils.Event');
-dojo.require('openils.User');
-dojo.require('openils.Util');
-dojo.require("openils.widget.AutoFieldWidget");
-dojo.require("openils.widget.AutoGrid");
-
-var fund = null;
-var tagManager;
-var xferManager;
-
-function getSummaryInfo(rowIndex, item) {
- if(!item) return'';
- return new String(fund.summary()[this.field]);
-}
-
-function createAllocation(fields) {
- fields.fund = fundID;
- if(isNaN(fields.amount)) fields.amount = null;
- openils.acq.Fund.createAllocation(fields,
- function(r){location.href = location.href;});
-}
-function getOrgInfo(rowIndex, item) {
- if(!item) return '';
- var owner = this.grid.store.getValue(item, 'org');
- return fieldmapper.aou.findOrgUnit(owner).shortname();
-
-}
-
-
-function getFundingSource(rowIndex, item) {
- if(item) {
- var fsId = this.grid.store.getValue(item, 'funding_source');
- return openils.acq.FundingSource.retrieve(fsId);
- }
-}
-
-function formatFundingSource(fs) {
- if(fs) {
- return '<a href="' + oilsBasePath + '/acq/funding_source/view/'+fs.id()+'">'+fs.code()+'</a>';
- }
-}
-
-function getXferDest(rowIndex, item) {
- if(!item) return '';
- var xfer_destination = this.grid.store.getValue(item, 'xfer_destination');
- if(!(item && xfer_destination)) return '';
- return xfer_destination;
-}
-
-function loadFundGrid() {
- var store = new dojo.data.ItemFileReadStore({data:acqf.toStoreData([fund])});
- fundGrid.setStore(store);
- fundGrid.render();
-}
-
-function loadAllocationGrid() {
- if(fundAllocationGrid.isLoaded) return;
- /* XXX If we want to show allocating user with a username instead of just
- * ID#, the following pcrud search will have to be replaced with an API
- * call. */
- fundAllocationGrid.loadAll({order_by : {acqfa : 'create_time DESC'}}, {fund : fundID});
- fundAllocationGrid.isLoaded = true;
-}
-
-function loadDebitGrid() {
- if(fundDebitGrid.isLoaded) return;
- fundDebitGrid.loadAll({order_by : {acqfdeb : 'create_time DESC'}}, {fund : fundID});
- fundDebitGrid.isLoaded = true;
-}
-
-function fetchFund() {
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.fund.retrieve'],
- { async: true,
- params: [
- openils.User.authtoken, fundID,
- {flesh_summary:1, flesh_tags:1}
- ],
- oncomplete: function(r) {
- fund = r.recv().content();
- loadFundGrid(fund);
- }
- }
- );
-}
-
-function TransferManager() {
- var self = this;
-
- this._init = function() {
- new openils.widget.AutoFieldWidget({
- "fmField": "fund",
- /* We're not really using LIDs here, we just need some class
- * that has a fund field to take advantage of AutoFieldWidget's
- * magic. */
- "fmClass": "acqlid",
- "labelFormat": ["${0} (${1})", "code", "year"],
- "searchFormat": ["${0} (${1})", "code", "year"],
- "searchFilter": {"active": "t"}, /* consider making it possible
- to select inactive? */
- "parentNode": dojo.byId("oils-acq-fund-xfer-d-selector"),
- "orgLimitPerms": ["ADMIN_ACQ_FUND"], /* XXX is there a more
- appropriate permission
- for this? */
- "dijitArgs": {
- "onChange": function() {
- openils.Util[
- this.item.currency_type == fund.currency_type() ?
- "hide" : "show"
- ]("oils-acq-fund-xfer-dest-amount", "table-row");
- }
- },
- "forceSync": true
- }).build(function(w, ww) { self.fundSelector = w; });
-
- dijit.byId("oils-acq-fund-xfer-same-o-d").onChange = function() {
- dijit.byId("oils-acq-fund-xfer-d-amount").attr(
- "disabled", this.attr("checked")
- );
- }
- };
-
- this._init();
-
- this.clearFundSelector = function() {
- if (this.fundSelector.attr("value"))
- this.fundSelector.attr("value", "");
- };
-
- this.setFundName = function(fund) {
- dojo.byId("oils-acq-fund-xfer-name-fund").innerHTML =
- fund.code() + " (" + fund.year() + ") / " + fund.name();
- };
-
- this.submit = function() {
- var values = xferDialog.getValues();
- var dfund = this.fundSelector.item;
- var dfund_id = typeof(dfund.id) == "object" ? dfund.id[0] : dfund.id;
-
- if (dfund_id == fund.id()) {
- alert(localeStrings.FUND_XFER_SAME_SOURCE_AND_DEST);
- return false;
- }
- if (confirm(localeStrings.FUND_XFER_CONFIRM)) {
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.funds.transfer_money"], {
- "params": [
- openils.User.authtoken,
- fund.id(),
- values.o_amount,
- dfund_id,
- (dfund.currency_type != fund.currency_type() &&
- values.same_o_d.length) ? null : values.d_amount,
- values.note
- ],
- "async": true,
- "oncomplete": function(r) {
- if (openils.Util.readResponse(r) == 1) {
- location.href = location.href;
- }
- }
- }
- );
- }
- };
-}
-
-function load() {
- tagManager = new TagManager(dojo.byId("oils-acq-tag-manager-display"));
- tagManager.prepareTagSelector(tagSelector);
-
- xferManager = new TransferManager();
-
- fetchFund();
-}
-
-openils.Util.addOnLoad(load);
+require([
+ "dijit/Dialog",
+ "dijit/form/FilteringSelect",
+ "dijit/layout/TabContainer",
+ "dijit/layout/ContentPane",
+ "dojox/grid/DataGrid",
+ "dijit/form/CurrencyTextBox",
+ "dijit/form/CheckBox",
+ "dojo/data/ItemFileReadStore",
+ "fieldmapper/OrgUtils",
+ "openils/acq/Fund",
+ "openils/acq/FundingSource",
+ "openils/Event",
+ "openils/User",
+ "openils/Util",
+ "openils/widget/AutoFieldWidget",
+ "openils/widget/AutoGrid"
+ ],
+function(dijit_Dialog,
+ dijit_form_FilteringSelect,
+ dijit_layout_TabContainer,
+ dijit_layout_ContentPane,
+ dojox_grid_DataGrid,
+ dijit_form_CurrencyTextBox,
+ dijit_form_CheckBox,
+ dojo_data_ItemFileReadStore,
+ fieldmapper_OrgUtils,
+ openils_acq_Fund,
+ openils_acq_FundingSource,
+ openils_Event,
+ openils_User,
+ openils_Util,
+ openils_widget_AutoFieldWidget,
+ openils_widget_AutoGrid){
+
+ var fund = null;
+ var tagManager;
+ var xferManager;
+
+ function getSummaryInfo(rowIndex, item) {
+ if(!item) return'';
+ return new String(fund.summary()[this.field]);
+ }
+
+ function createAllocation(fields) {
+ fields.fund = fundID;
+ if(isNaN(fields.amount)) fields.amount = null;
+ openils_acq_Fund.createAllocation(fields,
+ function(r){location.href = location.href;});
+ }
+ function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var owner = this.grid.store.getValue(item, 'org');
+ return fieldmapper.aou.findOrgUnit(owner).shortname();
+
+ }
+
+
+ function getFundingSource(rowIndex, item) {
+ if(item) {
+ var fsId = this.grid.store.getValue(item, 'funding_source');
+ return openils_acq_FundingSource.retrieve(fsId);
+ }
+ }
+
+ function formatFundingSource(fs) {
+ if(fs) {
+ return '<a href="' + oilsBasePath + '/acq/funding_source/view/'+fs.id()+'">'+fs.code()+'</a>';
+ }
+ }
+
+ function getXferDest(rowIndex, item) {
+ if(!item) return '';
+ var xfer_destination = this.grid.store.getValue(item, 'xfer_destination');
+ if(!(item && xfer_destination)) return '';
+ return xfer_destination;
+ }
+
+ function loadFundGrid() {
+ var store = new dojo_data_ItemFileReadStore({data:acqf.toStoreData([fund])});
+ fundGrid.setStore(store);
+ fundGrid.render();
+ }
+
+ function loadAllocationGrid() {
+ if(fundAllocationGrid.isLoaded) return;
+ /* XXX If we want to show allocating user with a username instead of just
+ * ID#, the following pcrud search will have to be replaced with an API
+ * call. */
+ fundAllocationGrid.loadAll({order_by : {acqfa : 'create_time DESC'}}, {fund : fundID});
+ fundAllocationGrid.isLoaded = true;
+ }
+
+ function loadDebitGrid() {
+ if(fundDebitGrid.isLoaded) return;
+ fundDebitGrid.loadAll({order_by : {acqfdeb : 'create_time DESC'}}, {fund : fundID});
+ fundDebitGrid.isLoaded = true;
+ }
+
+ function fetchFund() {
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.fund.retrieve'],
+ { async: true,
+ params: [
+ openils_User.authtoken, fundID,
+ {flesh_summary:1, flesh_tags:1}
+ ],
+ oncomplete: function(r) {
+ fund = r.recv().content();
+ loadFundGrid(fund);
+ }
+ }
+ );
+ }
+
+ function TransferManager() {
+ var self = this;
+
+ this._init = function() {
+ new openils_widget_AutoFieldWidget({
+ "fmField": "fund",
+ /* We're not really using LIDs here, we just need some class
+ * that has a fund field to take advantage of AutoFieldWidget's
+ * magic. */
+ "fmClass": "acqlid",
+ "labelFormat": ["${0} (${1})", "code", "year"],
+ "searchFormat": ["${0} (${1})", "code", "year"],
+ "searchFilter": {"active": "t"}, /* consider making it possible
+ to select inactive? */
+ "parentNode": dojo.byId("oils-acq-fund-xfer-d-selector"),
+ "orgLimitPerms": ["ADMIN_ACQ_FUND"], /* XXX is there a more
+ appropriate permission
+ for this? */
+ "dijitArgs": {
+ "onChange": function() {
+ openils_Util[
+ this.item.currency_type == fund.currency_type() ?
+ "hide" : "show"
+ ]("oils-acq-fund-xfer-dest-amount", "table-row");
+ }
+ },
+ "forceSync": true
+ }).build(function(w, ww) { self.fundSelector = w; });
+
+ dijit.byId("oils-acq-fund-xfer-same-o-d").onChange = function() {
+ dijit.byId("oils-acq-fund-xfer-d-amount").attr(
+ "disabled", this.attr("checked")
+ );
+ }
+ };
+
+ this._init();
+
+ this.clearFundSelector = function() {
+ if (this.fundSelector.attr("value"))
+ this.fundSelector.attr("value", "");
+ };
+
+ this.setFundName = function(fund) {
+ dojo.byId("oils-acq-fund-xfer-name-fund").innerHTML =
+ fund.code() + " (" + fund.year() + ") / " + fund.name();
+ };
+
+ this.submit = function() {
+ var values = xferDialog.getValues();
+ var dfund = this.fundSelector.item;
+ var dfund_id = typeof(dfund.id) == "object" ? dfund.id[0] : dfund.id;
+
+ if (dfund_id == fund.id()) {
+ alert(localeStrings.FUND_XFER_SAME_SOURCE_AND_DEST);
+ return false;
+ }
+ if (confirm(localeStrings.FUND_XFER_CONFIRM)) {
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.funds.transfer_money"], {
+ "params": [
+ openils_User.authtoken,
+ fund.id(),
+ values.o_amount,
+ dfund_id,
+ (dfund.currency_type != fund.currency_type() &&
+ values.same_o_d.length) ? null : values.d_amount,
+ values.note
+ ],
+ "async": true,
+ "oncomplete": function(r) {
+ if (openils_Util.readResponse(r) == 1) {
+ location.href = location.href;
+ }
+ }
+ }
+ );
+ }
+ };
+ }
+
+ function load() {
+ tagManager = new TagManager(dojo.byId("oils-acq-tag-manager-display"));
+ tagManager.prepareTagSelector(tagSelector);
+
+ xferManager = new TransferManager();
+
+ fetchFund();
+ }
+
+ openils_Util.addOnLoad(load);
+
+
+});
\ No newline at end of file
-dojo.require("dijit.Dialog");
-dojo.require('dijit.layout.TabContainer');
-dojo.require('dijit.layout.ContentPane');
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("dijit.form.Textarea");
-dojo.require("dijit.form.CurrencyTextBox");
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require("fieldmapper.OrgUtils");
-dojo.require('openils.acq.FundingSource');
-dojo.require('openils.acq.Fund');
-dojo.require('openils.Event');
-dojo.require('openils.Util');
-dojo.require('openils.widget.AutoGrid');
-
-var ses = new OpenSRF.ClientSession('open-ils.acq');
-var fundingSource = null;
-
-function resetPage(also_load_grid) {
- fundingSource = null;
- fsCreditGrid.isLoaded = false;
- fsAllocationGrid.isLoaded = false;
- loadFS(also_load_grid);
-}
-
-function getFund(rowIndex, item) {
- return '';
- //return '<a href="[% ctx.base_path %]/acq/fund/view/'+fund.id()+'">'+fund.code()+'</a>';
-}
-
-
-/** creates a new funding_source_credit from the dialog ----- */
-function applyFSCredit(fields) {
- fields.funding_source = fundingSourceID;
- openils.acq.FundingSource.createCredit(
- fields, function() { resetPage(loadCreditGrid); }
- );
-}
-
-function applyFSAllocation(fields) {
- fields.funding_source = fundingSourceID;
- if(isNaN(fields.amount)) fields.amount = null;
- openils.acq.Fund.createAllocation(
- fields, function() { resetPage(loadAllocationGrid); }
- );
-}
-
-/** fetch the fleshed funding source ----- */
-function loadFS(also_load_grid) {
- var req = ses.request(
- 'open-ils.acq.funding_source.retrieve',
- openils.User.authtoken, fundingSourceID,
- {flesh_summary:1, flesh_credits:1,flesh_allocations:1}
- );
-
- req.oncomplete = function(r) {
- var msg = req.recv();
- fundingSource = msg.content();
- var evt = openils.Event.parse(fundingSource);
- if(evt) {
- alert(evt);
- return;
- }
- loadFSGrid();
- if (typeof(also_load_grid) == "function")
- also_load_grid(true /* reset_first */);
- }
- req.send();
-}
-
-/** Some grid rendering accessor functions ----- */
-function getOrgInfo(rowIndex, item) {
- if(!item) return '';
- var owner = this.grid.store.getValue(item, 'owner');
- return fieldmapper.aou.findOrgUnit(owner).shortname();
-
-}
-
-function getSummaryInfo(rowIndex) {
- return new String(fundingSource.summary()[this.field]);
-}
-
-function getFund(rowIndex, item) {
- if(item) {
- var fId = this.grid.store.getValue(item, 'fund');
- return openils.acq.Fund.retrieve(fId);
- }
-}
-
-function formatFund(fund) {
- if(fund) {
- return '<a href="' + oilsBasePath + '/acq/fund/view/'+fund.id()+'">'+fund.code()+'</a>';
- }
-}
-
-/** builds the summary grid ----- */
-function loadFSGrid() {
- if(!fundingSource) return;
- var store = new dojo.data.ItemFileReadStore({data:acqfs.toStoreData([fundingSource])});
- fundingSourceGrid.setStore(store);
- fundingSourceGrid.render();
-}
-
-
-/** builds the credits grid ----- */
-function loadCreditGrid(reset_first) {
- if (fsCreditGrid.isLoaded) return;
- if (reset_first) fsCreditGrid.resetStore();
- fsCreditGrid.loadAll(
- {"order_by": {"acqfscred": "effective_date DESC"}},
- {"funding_source": fundingSource.id()}
- );
- fsCreditGrid.isLoaded = true;
-}
-
-function loadAllocationGrid(reset_first) {
- if (fsAllocationGrid.isLoaded) return;
- if (reset_first) fsCreditGrid.resetStore();
- fsAllocationGrid.loadAll(
- {"order_by": {"acqfa": "create_time DESC"}},
- {"funding_source": fundingSource.id()}
- );
- fsAllocationGrid.isLoaded = true;
-}
-
-openils.Util.addOnLoad(loadFS);
+require([
+ "dijit/Dialog",
+ "dijit/layout/TabContainer",
+ "dijit/layout/ContentPane",
+ "dijit/form/FilteringSelect",
+ "dijit/form/Textarea",
+ "dijit/form/CurrencyTextBox",
+ "dojox/grid/DataGrid",
+ "dojo/data/ItemFileReadStore",
+ "fieldmapper/OrgUtils",
+ "openils/acq/FundingSource",
+ "openils/acq/Fund",
+ "openils/Event",
+ "openils/Util",
+ "openils/widget/AutoGrid"
+ ],
+function(dijit_Dialog,
+ dijit_layout_TabContainer,
+ dijit_layout_ContentPane,
+ dijit_form_FilteringSelect,
+ dijit_form_Textarea,
+ dijit_form_CurrencyTextBox,
+ dojox_grid_DataGrid,
+ dojo_data_ItemFileReadStore,
+ fieldmapper_OrgUtils,
+ openils_acq_FundingSource,
+ openils_acq_Fund,
+ openils_Event,
+ openils_Util,
+ openils_widget_AutoGrid){
+
+ var ses = new OpenSRF.ClientSession('open-ils.acq');
+ var fundingSource = null;
+
+ function resetPage(also_load_grid) {
+ fundingSource = null;
+ fsCreditGrid.isLoaded = false;
+ fsAllocationGrid.isLoaded = false;
+ loadFS(also_load_grid);
+ }
+
+ function getFund(rowIndex, item) {
+ return '';
+ //return '<a href="[% ctx.base_path %]/acq/fund/view/'+fund.id()+'">'+fund.code()+'</a>';
+ }
+
+
+ /** creates a new funding_source_credit from the dialog ----- */
+ function applyFSCredit(fields) {
+ fields.funding_source = fundingSourceID;
+ openils_acq_FundingSource.createCredit(
+ fields, function() { resetPage(loadCreditGrid); }
+ );
+ }
+
+ function applyFSAllocation(fields) {
+ fields.funding_source = fundingSourceID;
+ if(isNaN(fields.amount)) fields.amount = null;
+ openils_acq_Fund.createAllocation(
+ fields, function() { resetPage(loadAllocationGrid); }
+ );
+ }
+
+ /** fetch the fleshed funding source ----- */
+ function loadFS(also_load_grid) {
+ var req = ses.request(
+ 'open-ils.acq.funding_source.retrieve',
+ openils.User.authtoken, fundingSourceID,
+ {flesh_summary:1, flesh_credits:1,flesh_allocations:1}
+ );
+
+ req.oncomplete = function(r) {
+ var msg = req.recv();
+ fundingSource = msg.content();
+ var evt = openils_Event.parse(fundingSource);
+ if(evt) {
+ alert(evt);
+ return;
+ }
+ loadFSGrid();
+ if (typeof(also_load_grid) == "function")
+ also_load_grid(true /* reset_first */);
+ }
+ req.send();
+ }
+
+ /** Some grid rendering accessor functions ----- */
+ function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var owner = this.grid.store.getValue(item, 'owner');
+ return fieldmapper.aou.findOrgUnit(owner).shortname();
+
+ }
+
+ function getSummaryInfo(rowIndex) {
+ return new String(fundingSource.summary()[this.field]);
+ }
+
+ function getFund(rowIndex, item) {
+ if(item) {
+ var fId = this.grid.store.getValue(item, 'fund');
+ return openils_acq_Fund.retrieve(fId);
+ }
+ }
+
+ function formatFund(fund) {
+ if(fund) {
+ return '<a href="' + oilsBasePath + '/acq/fund/view/'+fund.id()+'">'+fund.code()+'</a>';
+ }
+ }
+
+ /** builds the summary grid ----- */
+ function loadFSGrid() {
+ if(!fundingSource) return;
+ var store = new dojo_data_ItemFileReadStore({data:acqfs.toStoreData([fundingSource])});
+ fundingSourceGrid.setStore(store);
+ fundingSourceGrid.render();
+ }
+
+
+ /** builds the credits grid ----- */
+ function loadCreditGrid(reset_first) {
+ if (fsCreditGrid.isLoaded) return;
+ if (reset_first) fsCreditGrid.resetStore();
+ fsCreditGrid.loadAll(
+ {"order_by": {"acqfscred": "effective_date DESC"}},
+ {"funding_source": fundingSource.id()}
+ );
+ fsCreditGrid.isLoaded = true;
+ }
+
+ function loadAllocationGrid(reset_first) {
+ if (fsAllocationGrid.isLoaded) return;
+ if (reset_first) fsCreditGrid.resetStore();
+ fsAllocationGrid.loadAll(
+ {"order_by": {"acqfa": "create_time DESC"}},
+ {"funding_source": fundingSource.id()}
+ );
+ fsAllocationGrid.isLoaded = true;
+ }
+
+ openils_Util.addOnLoad(loadFS);
+
+
+});
\ No newline at end of file
-dojo.require("dijit.Dialog");
-dojo.require('dijit.layout.TabContainer');
-dojo.require('dijit.layout.ContentPane');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require("fieldmapper.OrgUtils");
-dojo.require('openils.acq.Provider');
-dojo.require('openils.Event');
-dojo.require('openils.User');
-dojo.require('openils.Util');
-
-var provider = null;
-var marcRegex = /^\/\/\*\[@tag="(\d+)"]\/\*\[@code="(\w)"]$/;
-
-function getOrgInfo(rowIndex, item) {
- if(!item) return '';
- var owner = this.grid.store.getValue(item, 'owner');
- return fieldmapper.aou.findOrgUnit(owner).shortname();
-
-}
-
-function getTag(rowIdx, item) {
- if(!item) return '';
- var xpath = this.grid.store.getValue(item, 'xpath');
- return xpath.replace(marcRegex, '$1');
-}
-
-function getSubfield(rowIdx, item) {
- if(!item) return '';
- var xpath = this.grid.store.getValue(item, 'xpath');
- return xpath.replace(marcRegex, '$2');
-}
-
-function loadProviderGrid() {
- var store = new dojo.data.ItemFileReadStore({data:acqpro.toStoreData([provider])});
-
- providerGrid.setStore(store);
- providerGrid.render();
-}
-
-function loadPADGrid() {
- openils.acq.Provider.retrieveLineitemProviderAttrDefs(providerId,
- function(attrs) {
- var store = new dojo.data.ItemFileReadStore({data:acqlipad.toStoreData(attrs)});
- var model = new dojox.grid.data.DojoData(
- null, store, {rowsPerPage: 20, clientSort: true, query:{id:'*'}});
- padGrid.setModel(model);
- padGrid.update();
- }
- );
-}
-
-
-function fetchProvider() {
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.provider.retrieve'],
- { async: true,
- params: [ openils.User.authtoken, providerId ],
- oncomplete: function(r) {
- provider = r.recv().content();
- loadProviderGrid(provider);
- }
- }
- );
-}
-
-function createOrderRecordField(fields) {
- fields.provider = providerId;
- if(!fields.xpath)
- fields.xpath = '//*[@tag="'+fields.tag+'"]/*[@code="'+fields.subfield+'"]';
- delete fields.tag;
- delete fields.subfield;
- openils.acq.Provider.createLineitemProviderAttrDef(fields,
- function(id) {
- loadPADGrid();
- }
- );
-}
-
-function setORDesc() {
- var code = dijit.byId('oils-acq-provider-or-code');
- var desc = dijit.byId('oils-acq-provider-or-desc');
- desc.setValue(code.getDisplayedValue());
-}
-
-function deleteORDataFields() {
- var list = []
- var selected = padGrid.selection.getSelected();
- for(var idx = 0; idx < selected.length; idx++)
- list.push(padGrid.model.getRow(selected[idx]).id);
- openils.acq.Provider.lineitemProviderAttrDefDeleteList(
- list, function(){loadPADGrid();});
-}
-
-
-openils.Util.addOnLoad(fetchProvider);
-
-
+require([
+ "dijit/Dialog",
+ "dijit/layout/TabContainer",
+ "dijit/layout/ContentPane",
+ "dijit/form/FilteringSelect",
+ "dojox/grid/DataGrid",
+ "dojo/data/ItemFileReadStore",
+ "fieldmapper/OrgUtils",
+ "openils/acq/Provider",
+ "openils/Event",
+ "openils/User",
+ "openils/Util"
+ ],
+function(dijit_Dialog,
+ dijit_layout_TabContainer,
+ dijit_layout_ContentPane,
+ dijit_form_FilteringSelect,
+ dojox_grid_DataGrid,
+ dojo_data_ItemFileReadStore,
+ fieldmapper_OrgUtils,
+ openils_acq_Provider,
+ openils_Event,
+ openils_User,
+ openils_Util){
+
+ var provider = null;
+ var marcRegex = /^\/\/\*\[@tag="(\d+)"]\/\*\[@code="(\w)"]$/;
+
+ function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var owner = this.grid.store.getValue(item, 'owner');
+ return fieldmapper.aou.findOrgUnit(owner).shortname();
+
+ }
+
+ function getTag(rowIdx, item) {
+ if(!item) return '';
+ var xpath = this.grid.store.getValue(item, 'xpath');
+ return xpath.replace(marcRegex, '$1');
+ }
+
+ function getSubfield(rowIdx, item) {
+ if(!item) return '';
+ var xpath = this.grid.store.getValue(item, 'xpath');
+ return xpath.replace(marcRegex, '$2');
+ }
+
+ function loadProviderGrid() {
+ var store = new dojo_data_ItemFileReadStore({data:acqpro.toStoreData([provider])});
+
+ providerGrid.setStore(store);
+ providerGrid.render();
+ }
+
+ function loadPADGrid() {
+ openils_acq_Provider.retrieveLineitemProviderAttrDefs(providerId,
+ function(attrs) {
+ var store = new dojo_data_ItemFileReadStore({data:acqlipad.toStoreData(attrs)});
+ var model = new dojox.grid.data.DojoData(
+ null, store, {rowsPerPage: 20, clientSort: true, query:{id:'*'}});
+ padGrid.setModel(model);
+ padGrid.update();
+ }
+ );
+ }
+
+
+ function fetchProvider() {
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.provider.retrieve'],
+ { async: true,
+ params: [ openils_User.authtoken, providerId ],
+ oncomplete: function(r) {
+ provider = r.recv().content();
+ loadProviderGrid(provider);
+ }
+ }
+ );
+ }
+
+ function createOrderRecordField(fields) {
+ fields.provider = providerId;
+ if(!fields.xpath)
+ fields.xpath = '//*[@tag="'+fields.tag+'"]/*[@code="'+fields.subfield+'"]';
+ delete fields.tag;
+ delete fields.subfield;
+ openils_acq_Provider.createLineitemProviderAttrDef(fields,
+ function(id) {
+ loadPADGrid();
+ }
+ );
+ }
+
+ function setORDesc() {
+ var code = dijit.byId('oils-acq-provider-or-code');
+ var desc = dijit.byId('oils-acq-provider-or-desc');
+ desc.setValue(code.getDisplayedValue());
+ }
+
+ function deleteORDataFields() {
+ var list = []
+ var selected = padGrid.selection.getSelected();
+ for(var idx = 0; idx < selected.length; idx++)
+ list.push(padGrid.model.getRow(selected[idx]).id);
+ openils_acq_Provider.lineitemProviderAttrDefDeleteList(
+ list, function(){loadPADGrid();});
+ }
+
+
+ openils_Util.addOnLoad(fetchProvider);
+
+
+
+
+});
\ No newline at end of file
-dojo.require('dojo.date.stamp');
-dojo.require('openils.User');
-dojo.require('openils.widget.EditPane');
-
-function drawInvoicePane(parentNode, inv, args) {
- args = args || {};
-
- var override = {};
- if(!inv) {
- override = {
- recv_date : {widgetValue : dojo.date.stamp.toISOString(new Date())},
- receiver : {widgetValue : openils.User.user.ws_ou()},
- recv_method : {widgetValue : 'PPR'}
- };
- }
-
- dojo.mixin(override, {
- provider : { dijitArgs : { store_options : { base_filter : { active :"t" } } } },
- shipper : { dijitArgs : { store_options : { base_filter : { active :"t" } } } }
- });
-
- for(var field in args) {
- override[field] = {widgetValue : args[field]};
- }
-
- var pane = new openils.widget.EditPane({
- fmObject : inv,
- paneStackCount : 2,
- fmClass : 'acqinv',
- mode : (inv) ? 'edit' : 'create',
- hideActionButtons : true,
- overrideWidgetArgs : override,
- readOnly : (inv) && openils.Util.isTrue(inv.complete()),
- requiredFields : [
- 'inv_ident',
- 'recv_date',
- 'provider',
- 'shipper'
- ],
- fieldOrder : [
- 'inv_ident',
- 'recv_date',
- 'recv_method',
- 'inv_type',
- 'provider',
- 'shipper'
- ],
- suppressFields : ['id', 'complete']
- });
-
- pane.startup();
- parentNode.appendChild(pane.domNode);
- return pane;
-}
+require([
+ "dojo/date/stamp",
+ "openils/User",
+ "openils/widget/EditPane"
+ ],
+function(dojo_date_stamp,
+ openils_User,
+ openils_widget_EditPane){
+
+ function drawInvoicePane(parentNode, inv, args) {
+ args = args || {};
+
+ var override = {};
+ if(!inv) {
+ override = {
+ recv_date : {widgetValue : dojo_date_stamp.toISOString(new Date())},
+ receiver : {widgetValue : openils_User.user.ws_ou()},
+ recv_method : {widgetValue : 'PPR'}
+ };
+ }
+
+ dojo.mixin(override, {
+ provider : { dijitArgs : { store_options : { base_filter : { active :"t" } } } },
+ shipper : { dijitArgs : { store_options : { base_filter : { active :"t" } } } }
+ });
+
+ for(var field in args) {
+ override[field] = {widgetValue : args[field]};
+ }
+
+ var pane = new openils_widget_EditPane({
+ fmObject : inv,
+ paneStackCount : 2,
+ fmClass : 'acqinv',
+ mode : (inv) ? 'edit' : 'create',
+ hideActionButtons : true,
+ overrideWidgetArgs : override,
+ readOnly : (inv) && openils.Util.isTrue(inv.complete()),
+ requiredFields : [
+ 'inv_ident',
+ 'recv_date',
+ 'provider',
+ 'shipper'
+ ],
+ fieldOrder : [
+ 'inv_ident',
+ 'recv_date',
+ 'recv_method',
+ 'inv_type',
+ 'provider',
+ 'shipper'
+ ],
+ suppressFields : ['id', 'complete']
+ });
+
+ pane.startup();
+ parentNode.appendChild(pane.domNode);
+ return pane;
+ }
+
+
+});
\ No newline at end of file
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.NumberSpinner");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.acq.Lineitem");
-dojo.require("openils.widget.AutoFieldWidget");
-dojo.require("openils.widget.ProgressDialog");
-dojo.requireLocalization("openils.acq", "acq");
-
-var copy_table;
-var localeStrings = dojo.i18n.getLocalization("openils.acq", "acq");
-
-function ReceivableCopyTable() {
- var self = this;
-
- this._init = function() {
- this.columns = ["owning_lib", "location", "collection_code",
- "circ_modifier", "fund", "cn_label", "barcode"];
-
- this.tbody = dojo.byId("rows-here");
- this.pcrud = new openils.PermaCrud();
-
- this.mode = "number"; /* can be "number" or "list" */
- this.some_receiving_done = false;
-
- this._init_select_all();
- };
-
- this._init_select_all = function() {
- dojo.byId("select_all").onchange = function() {
- var checked = this.checked;
- dojo.query("input[type='checkbox']", self.tbody).forEach(
- function(cb) { cb.checked = checked; }
- );
- };
- };
-
- this._set_invoice_header = function() {
- dojo.byId("inv-header").innerHTML = dojo.string.substitute(
- localeStrings.INVOICE_NUMBER, [this.invoice.inv_ident()]
- );
- };
-
- this._configure_for_mode = function() {
- if (this.mode == "list") {
- openils.Util.show("list-mode-headings", "table-header-group");
- openils.Util.hide("set-list-mode");
- openils.Util.show("set-number-mode");
- dojo.byId("set-number-mode-link").onclick = function() {
- self.reset("number");
- self.load();
- };
- } else { /* number */
- openils.Util.hide("list-mode-headings");
- openils.Util.show("set-list-mode");
- openils.Util.hide("set-number-mode");
- dojo.byId("set-list-mode-link").onclick = function() {
- self.reset("list");
- self.load();
- };
- }
- };
-
- this._get_receivable_details = function(li) {
- return li.lineitem_details().filter(
- function(lid) { return (!lid.recv_time() && !lid.cancel_reason()); }
- );
- };
-
- this._create_receiver = function(lid, tr, precheck) {
- var args = {
- "type": "checkbox",
- "name": "receive",
- "value": lid.id()
- };
-
- if (precheck) args.checked = "checked";
-
- dojo.create("input", args, dojo.create("td", null, tr));
- };
-
- this._get_selected_list_mode = function() {
- return dojo.query("input[type=checkbox]", this.tbody).filter(
- function(cb) { return cb.checked; }
- ).map(
- function(cb) { return cb.value; }
- );
- };
-
- this._get_selected_number_mode = function() {
- var list = [];
- for (var li_id in this.spinners) {
- var spinner = this.spinners[li_id];
- var li = spinner._li;
-
- var number = spinner.attr("value");
- list = list.concat(
- this._get_receivable_details(li).slice(0, number)
- );
- }
- return list.map(function(lid) { return lid.id(); });
- };
-
- /* The first time this interface is loaded, use the phys_item_count field
- * (the "# paid" column on an invoice) to determing how man items to
- * preselect. Otherwise use 0.
- */
- this._number_to_preselect = function(ie, li) {
- return (this.some_receiving_done) ? 0 :
- Number(ie.phys_item_count() || 0);
-
-// var n = Number(ie.phys_item_count() || 0) -
-// li.lineitem_details().filter(
-// function(lid) {
-// return lid.recv_time() || lid.cancel_reason()
-// }
-// ).length;
-//
-// return n > 0 ? n : 0;
- };
-
- this._render_copy_count_info = function() {
- dojo.byId("inv-copy-count-info").innerHTML =
- dojo.string.substitute(
- localeStrings.INVOICE_COPY_COUNT_INFO,
- [this.copy_number_received, this.copy_number_total]
- );
- };
-
- this._increment_copy_count_info = function(li) {
- var all_uncanceled = li.lineitem_details().filter(
- function(lid) { return !lid.cancel_reason(); }
- );
- this.copy_number_total += all_uncanceled.length;
- this.copy_number_received += all_uncanceled.filter(
- function(lid) { return Boolean(lid.recv_time()); }
- ).length;
- };
-
- this._add_lineitem_number_mode = function(details, li, preselect_count) {
- var tr = dojo.create("tr", null, this.tbody);
- var td = dojo.create("td", {
- "colspan": 1 + this.columns.length,
- "className": "spinner-cell"
- }, tr);
-
- var span_id = "number-mode-li-" + li.id();
-
- td.innerHTML = localeStrings.COPIES_TO_RECEIVE;
- dojo.create("span", {"id": span_id}, td);
-
- var max = details.length;
- var value = (preselect_count <= max ? preselect_count : max);
-
- this.spinners[li.id()] = new dijit.form.NumberSpinner({
- "constraints": {"min": 0, "max": max},
- "value": value
- }, span_id);
- this.spinners[li.id()]._li = li;
- };
-
- this._add_lineitem_list_mode = function(details, li, preselect_count) {
- details.forEach(
- function(lid) {
- dump("preselect_count "+ preselect_count+"\n");
- self.add_lineitem_detail(
- lid, li, Boolean(preselect_count-- > 0)
- );
- }
- );
- };
-
- this.add_lineitem_detail = function(lid, li, precheck) {
- var tr = dojo.create(
- "tr", {"className": "copy-row"}, this.tbody
- );
-
- /* Make receive checkbox cell. */
- this._create_receiver(lid, tr, precheck);
-
- /* Make cells for all the other columns. Using a read-only
- * AutoFieldWidget to show the value of each field on a lineitem
- * detail is much easier than worrying about fleshing enough
- * information to do the same ourselves. */
- this.columns.forEach(
- function(column) {
- var td = dojo.create("td", null, tr);
- new openils.widget.AutoFieldWidget({
- "parentNode": dojo.create("div", null, td),
- "fmField": column,
- "fmObject": lid,
- "readOnly": true,
- "dijitArgs": {"labelType": (column=='fund') ? "html" : null}
- }).build();
- }
- );
- };
-
- /* /maybe/ add a lineitem to the table, if it has any lineitem details
- * that are still receivable, and preselect lineitem details up to the
- * number specified in ie.phys_item_count() */
- this.add_lineitem = function(ie, li, displayHTML) {
- /* This call only affects the blurb about received vs. total copies
- * on the invoice near the top of the display. */
- this._increment_copy_count_info(li);
-
- var receivable_details = this._get_receivable_details(li);
- if (!receivable_details.length) return;
-
- /* show lineitem overall description */
- /* add rows for copies (lineitem details) */
- dojo.create(
- "td", {
- "colspan": 1 + this.columns.length,
- "innerHTML": displayHTML
- }, dojo.create("tr", null, this.tbody)
- );
-
- /* build look-up table */
- receivable_details.forEach(
- function(lid) { self.li_by_lid[lid.id()] = li; }
- );
-
- /* Render something for receiving the lineitem details, depending
- * on mode. */
- this["_add_lineitem_" + this.mode + "_mode"](
- receivable_details, li, this._number_to_preselect(ie, li)
- );
- };
-
- this.reset = function(mode) {
- if (mode)
- this.mode = mode;
-
- this.user_has_acked = [];
- this.li_by_lid = {};
- this.copy_number_received = 0;
- this.copy_number_total = 0;
-
- if (this.spinners) {
- for (var key in this.spinners)
- this.spinners[key].destroy();
- }
-
- this.spinners = {};
-
- this._configure_for_mode();
-
- dojo.empty(this.tbody);
- };
-
- /* It's important to remember that an invoice doesn't actually have
- * lineitems, but rather is made up of invoice entries and invoice items.
- * Invoice entries usually link to lineitems, though (invoice items
- * usually link to po_items).
- */
- this.load = function(inv_id) {
- if (inv_id)
- this.inv_id = inv_id;
-
- this.reset();
- progress_dialog.show(true);
-
- if (!this.invoice) {
- this.invoice = this.pcrud.retrieve("acqinv", this.inv_id);
- this._set_invoice_header();
- }
-
- this.pcrud.search("acqie", {"invoice": this.inv_id}).forEach(
- function(entry) {
- if (entry.lineitem()) {
- openils.acq.Lineitem.fetchAndRender(
- entry.lineitem(),
- {"flesh_li_details": true, "flesh_notes": true},
- function(li, str) { self.add_lineitem(entry, li, str); }
- );
- }
- }
- );
-
- this._render_copy_count_info();
-
- if (openils.Util.objectProperties(this.li_by_lid).length) {
- openils.Util.show("non-empty");
- openils.Util.hide("empty");
- } else {
- openils.Util.hide("non-empty");
- openils.Util.show("empty");
- }
- progress_dialog.hide();
- };
-
- /* returns an array of lineitem_detail IDs */
- this.get_selected = function() {
- return this["_get_selected_" + this.mode + "_mode"]();
- };
-
- this.receive_lineitem_detail = function(id_list, index) {
- if (index >= id_list.length) {
- progress_dialog.hide();
- this.load();
-
- return;
- }
-
- var lid_id = id_list[index];
- var li = this.li_by_lid[lid_id];
-
- if (!this.check_lineitem_alerts(li)) {
- self.receive_lineitem_detail(id_list, ++index);
- return;
- }
-
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem_detail.receive"], {
- "async": false,
- "params": [openils.User.authtoken, lid_id],
- "oncomplete": function(r) {
- if (r = openils.Util.readResponse(r)) {
- self.some_receiving_done = true;
- /* receive the next lid in our list */
- self.receive_lineitem_detail(id_list, ++index);
- }
- }
- }
- );
- };
-
- this.receive_selected = function() {
- var lid_ids = this.get_selected();
-
- progress_dialog.show(true);
-
- this.receive_lineitem_detail(lid_ids, 0);
- };
-
- /* 1st of 2 functions all but copied from li_table.js. Refactor this and
- * that to share code from a 3rd place.
- */
- this.check_lineitem_alerts = function(lineitem) {
- var alert_notes = lineitem.lineitem_notes().filter(
- function(o) { return Boolean(o.alert_text()); }
- );
-
- for (var i = 0; i < alert_notes.length; i++) {
- if (this.user_has_acked[alert_notes[i].id()])
- continue;
- else if (!this.confirm_alert(li, alert_notes[i]))
- return false;
- else
- this.user_has_acked[alert_notes[i].id()] = true;
- }
-
- return true;
- };
-
- /* 2nd of 2 functions all but copied from li_table.js. Refactor this and
- * that to share code from a 3rd place.
- */
- this.confirm_alert = function(lineitem, note) {
- return confirm(
- dojo.string.substitute(
- localeStrings.CONFIRM_LI_ALERT, [
- (new openils.acq.Lineitem({"lineitem": lineitem})).findAttr(
- "title", "lineitem_marc_attr_definition"
- ),
- note.alert_text().code(),
- note.alert_text().description() || "",
- note.value()
- ]
- )
- );
- };
-
- this.back_to_invoice = function() {
- location.href = oilsBasePath + "/acq/invoice/view/" + this.inv_id;
- };
-
- this._init.apply(this, arguments);
-}
-
-function my_init() {
- copy_table = new ReceivableCopyTable();
- copy_table.load(inv_id);
-}
-
-openils.Util.addOnLoad(my_init);
+require([
+ "dijit/form/Button",
+ "dijit/form/NumberSpinner",
+ "openils/PermaCrud",
+ "openils/acq/Lineitem",
+ "openils/widget/AutoFieldWidget",
+ "openils/widget/ProgressDialog"
+ ],
+function(dijit_form_Button,
+ dijit_form_NumberSpinner,
+ openils_PermaCrud,
+ openils_acq_Lineitem,
+ openils_widget_AutoFieldWidget,
+ openils_widget_ProgressDialog){
+ dojo.requireLocalization("openils.acq", "acq");
+
+ var copy_table;
+ var localeStrings = dojo.i18n.getLocalization("openils.acq", "acq");
+
+ function ReceivableCopyTable() {
+ var self = this;
+
+ this._init = function() {
+ this.columns = ["owning_lib", "location", "collection_code",
+ "circ_modifier", "fund", "cn_label", "barcode"];
+
+ this.tbody = dojo.byId("rows-here");
+ this.pcrud = new openils_PermaCrud();
+
+ this.mode = "number"; /* can be "number" or "list" */
+ this.some_receiving_done = false;
+
+ this._init_select_all();
+ };
+
+ this._init_select_all = function() {
+ dojo.byId("select_all").onchange = function() {
+ var checked = this.checked;
+ dojo.query("input[type='checkbox']", self.tbody).forEach(
+ function(cb) { cb.checked = checked; }
+ );
+ };
+ };
+
+ this._set_invoice_header = function() {
+ dojo.byId("inv-header").innerHTML = dojo.string.substitute(
+ localeStrings.INVOICE_NUMBER, [this.invoice.inv_ident()]
+ );
+ };
+
+ this._configure_for_mode = function() {
+ if (this.mode == "list") {
+ openils.Util.show("list-mode-headings", "table-header-group");
+ openils.Util.hide("set-list-mode");
+ openils.Util.show("set-number-mode");
+ dojo.byId("set-number-mode-link").onclick = function() {
+ self.reset("number");
+ self.load();
+ };
+ } else { /* number */
+ openils.Util.hide("list-mode-headings");
+ openils.Util.show("set-list-mode");
+ openils.Util.hide("set-number-mode");
+ dojo.byId("set-list-mode-link").onclick = function() {
+ self.reset("list");
+ self.load();
+ };
+ }
+ };
+
+ this._get_receivable_details = function(li) {
+ return li.lineitem_details().filter(
+ function(lid) { return (!lid.recv_time() && !lid.cancel_reason()); }
+ );
+ };
+
+ this._create_receiver = function(lid, tr, precheck) {
+ var args = {
+ "type": "checkbox",
+ "name": "receive",
+ "value": lid.id()
+ };
+
+ if (precheck) args.checked = "checked";
+
+ dojo.create("input", args, dojo.create("td", null, tr));
+ };
+
+ this._get_selected_list_mode = function() {
+ return dojo.query("input[type=checkbox]", this.tbody).filter(
+ function(cb) { return cb.checked; }
+ ).map(
+ function(cb) { return cb.value; }
+ );
+ };
+
+ this._get_selected_number_mode = function() {
+ var list = [];
+ for (var li_id in this.spinners) {
+ var spinner = this.spinners[li_id];
+ var li = spinner._li;
+
+ var number = spinner.attr("value");
+ list = list.concat(
+ this._get_receivable_details(li).slice(0, number)
+ );
+ }
+ return list.map(function(lid) { return lid.id(); });
+ };
+
+ /* The first time this interface is loaded, use the phys_item_count field
+ * (the "# paid" column on an invoice) to determing how man items to
+ * preselect. Otherwise use 0.
+ */
+ this._number_to_preselect = function(ie, li) {
+ return (this.some_receiving_done) ? 0 :
+ Number(ie.phys_item_count() || 0);
+
+ // var n = Number(ie.phys_item_count() || 0) -
+ // li.lineitem_details().filter(
+ // function(lid) {
+ // return lid.recv_time() || lid.cancel_reason()
+ // }
+ // ).length;
+ //
+ // return n > 0 ? n : 0;
+ };
+
+ this._render_copy_count_info = function() {
+ dojo.byId("inv-copy-count-info").innerHTML =
+ dojo.string.substitute(
+ localeStrings.INVOICE_COPY_COUNT_INFO,
+ [this.copy_number_received, this.copy_number_total]
+ );
+ };
+
+ this._increment_copy_count_info = function(li) {
+ var all_uncanceled = li.lineitem_details().filter(
+ function(lid) { return !lid.cancel_reason(); }
+ );
+ this.copy_number_total += all_uncanceled.length;
+ this.copy_number_received += all_uncanceled.filter(
+ function(lid) { return Boolean(lid.recv_time()); }
+ ).length;
+ };
+
+ this._add_lineitem_number_mode = function(details, li, preselect_count) {
+ var tr = dojo.create("tr", null, this.tbody);
+ var td = dojo.create("td", {
+ "colspan": 1 + this.columns.length,
+ "className": "spinner-cell"
+ }, tr);
+
+ var span_id = "number-mode-li-" + li.id();
+
+ td.innerHTML = localeStrings.COPIES_TO_RECEIVE;
+ dojo.create("span", {"id": span_id}, td);
+
+ var max = details.length;
+ var value = (preselect_count <= max ? preselect_count : max);
+
+ this.spinners[li.id()] = new dijit_form_NumberSpinner({
+ "constraints": {"min": 0, "max": max},
+ "value": value
+ }, span_id);
+ this.spinners[li.id()]._li = li;
+ };
+
+ this._add_lineitem_list_mode = function(details, li, preselect_count) {
+ details.forEach(
+ function(lid) {
+ dump("preselect_count "+ preselect_count+"\n");
+ self.add_lineitem_detail(
+ lid, li, Boolean(preselect_count-- > 0)
+ );
+ }
+ );
+ };
+
+ this.add_lineitem_detail = function(lid, li, precheck) {
+ var tr = dojo.create(
+ "tr", {"className": "copy-row"}, this.tbody
+ );
+
+ /* Make receive checkbox cell. */
+ this._create_receiver(lid, tr, precheck);
+
+ /* Make cells for all the other columns. Using a read-only
+ * AutoFieldWidget to show the value of each field on a lineitem
+ * detail is much easier than worrying about fleshing enough
+ * information to do the same ourselves. */
+ this.columns.forEach(
+ function(column) {
+ var td = dojo.create("td", null, tr);
+ new openils_widget_AutoFieldWidget({
+ "parentNode": dojo.create("div", null, td),
+ "fmField": column,
+ "fmObject": lid,
+ "readOnly": true,
+ "dijitArgs": {"labelType": (column=='fund') ? "html" : null}
+ }).build();
+ }
+ );
+ };
+
+ /* /maybe/ add a lineitem to the table, if it has any lineitem details
+ * that are still receivable, and preselect lineitem details up to the
+ * number specified in ie.phys_item_count() */
+ this.add_lineitem = function(ie, li, displayHTML) {
+ /* This call only affects the blurb about received vs. total copies
+ * on the invoice near the top of the display. */
+ this._increment_copy_count_info(li);
+
+ var receivable_details = this._get_receivable_details(li);
+ if (!receivable_details.length) return;
+
+ /* show lineitem overall description */
+ /* add rows for copies (lineitem details) */
+ dojo.create(
+ "td", {
+ "colspan": 1 + this.columns.length,
+ "innerHTML": displayHTML
+ }, dojo.create("tr", null, this.tbody)
+ );
+
+ /* build look-up table */
+ receivable_details.forEach(
+ function(lid) { self.li_by_lid[lid.id()] = li; }
+ );
+
+ /* Render something for receiving the lineitem details, depending
+ * on mode. */
+ this["_add_lineitem_" + this.mode + "_mode"](
+ receivable_details, li, this._number_to_preselect(ie, li)
+ );
+ };
+
+ this.reset = function(mode) {
+ if (mode)
+ this.mode = mode;
+
+ this.user_has_acked = [];
+ this.li_by_lid = {};
+ this.copy_number_received = 0;
+ this.copy_number_total = 0;
+
+ if (this.spinners) {
+ for (var key in this.spinners)
+ this.spinners[key].destroy();
+ }
+
+ this.spinners = {};
+
+ this._configure_for_mode();
+
+ dojo.empty(this.tbody);
+ };
+
+ /* It's important to remember that an invoice doesn't actually have
+ * lineitems, but rather is made up of invoice entries and invoice items.
+ * Invoice entries usually link to lineitems, though (invoice items
+ * usually link to po_items).
+ */
+ this.load = function(inv_id) {
+ if (inv_id)
+ this.inv_id = inv_id;
+
+ this.reset();
+ progress_dialog.show(true);
+
+ if (!this.invoice) {
+ this.invoice = this.pcrud.retrieve("acqinv", this.inv_id);
+ this._set_invoice_header();
+ }
+
+ this.pcrud.search("acqie", {"invoice": this.inv_id}).forEach(
+ function(entry) {
+ if (entry.lineitem()) {
+ openils_acq_Lineitem.fetchAndRender(
+ entry.lineitem(),
+ {"flesh_li_details": true, "flesh_notes": true},
+ function(li, str) { self.add_lineitem(entry, li, str); }
+ );
+ }
+ }
+ );
+
+ this._render_copy_count_info();
+
+ if (openils.Util.objectProperties(this.li_by_lid).length) {
+ openils.Util.show("non-empty");
+ openils.Util.hide("empty");
+ } else {
+ openils.Util.hide("non-empty");
+ openils.Util.show("empty");
+ }
+ progress_dialog.hide();
+ };
+
+ /* returns an array of lineitem_detail IDs */
+ this.get_selected = function() {
+ return this["_get_selected_" + this.mode + "_mode"]();
+ };
+
+ this.receive_lineitem_detail = function(id_list, index) {
+ if (index >= id_list.length) {
+ progress_dialog.hide();
+ this.load();
+
+ return;
+ }
+
+ var lid_id = id_list[index];
+ var li = this.li_by_lid[lid_id];
+
+ if (!this.check_lineitem_alerts(li)) {
+ self.receive_lineitem_detail(id_list, ++index);
+ return;
+ }
+
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem_detail.receive"], {
+ "async": false,
+ "params": [openils.User.authtoken, lid_id],
+ "oncomplete": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ self.some_receiving_done = true;
+ /* receive the next lid in our list */
+ self.receive_lineitem_detail(id_list, ++index);
+ }
+ }
+ }
+ );
+ };
+
+ this.receive_selected = function() {
+ var lid_ids = this.get_selected();
+
+ progress_dialog.show(true);
+
+ this.receive_lineitem_detail(lid_ids, 0);
+ };
+
+ /* 1st of 2 functions all but copied from li_table.js. Refactor this and
+ * that to share code from a 3rd place.
+ */
+ this.check_lineitem_alerts = function(lineitem) {
+ var alert_notes = lineitem.lineitem_notes().filter(
+ function(o) { return Boolean(o.alert_text()); }
+ );
+
+ for (var i = 0; i < alert_notes.length; i++) {
+ if (this.user_has_acked[alert_notes[i].id()])
+ continue;
+ else if (!this.confirm_alert(li, alert_notes[i]))
+ return false;
+ else
+ this.user_has_acked[alert_notes[i].id()] = true;
+ }
+
+ return true;
+ };
+
+ /* 2nd of 2 functions all but copied from li_table.js. Refactor this and
+ * that to share code from a 3rd place.
+ */
+ this.confirm_alert = function(lineitem, note) {
+ return confirm(
+ dojo.string.substitute(
+ localeStrings.CONFIRM_LI_ALERT, [
+ (new openils_acq_Lineitem({"lineitem": lineitem})).findAttr(
+ "title", "lineitem_marc_attr_definition"
+ ),
+ note.alert_text().code(),
+ note.alert_text().description() || "",
+ note.value()
+ ]
+ )
+ );
+ };
+
+ this.back_to_invoice = function() {
+ location.href = oilsBasePath + "/acq/invoice/view/" + this.inv_id;
+ };
+
+ this._init.apply(this, arguments);
+ }
+
+ function my_init() {
+ copy_table = new ReceivableCopyTable();
+ copy_table.load(inv_id);
+ }
+
+ openils.Util.addOnLoad(my_init);
+
+
+});
\ No newline at end of file
-dojo.require('dojo.date.locale');
-dojo.require('dojo.date.stamp');
-dojo.require('dijit.form.CheckBox');
-dojo.require('dijit.form.CurrencyTextBox');
-dojo.require('dijit.form.NumberTextBox');
-dojo.require('openils.User');
-dojo.require('openils.Util');
-dojo.require('openils.CGI');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.EditPane');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.widget.ProgressDialog');
-dojo.require('openils.acq.Lineitem');
-
-dojo.requireLocalization('openils.acq', 'acq');
-var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
-
-var fundLabelFormat = ['${0} (${1})', 'code', 'year'];
-var fundSearchFormat = ['${0} (${1})', 'code', 'year'];
-
-var cgi = new openils.CGI();
-var pcrud = new openils.PermaCrud();
-var attachLi;
-var attachPo;
-var invoice;
-var itemTbody;
-var itemTemplate;
-var entryTemplate;
-var totalInvoicedBox;
-var totalPaidBox;
-var balanceOwedBox;
-var invoicePane;
-var itemTypes;
-var virtualId = -1;
-var extraCopies = {};
-var extraCopiesFund;
-var widgetRegistry = {acqie : {}, acqii : {}};
-
-function nodeByName(name, context) {
- return dojo.query('[name='+name+']', context)[0];
-}
-
-function init() {
-
- attachLi = cgi.param('attach_li');
- attachPo = cgi.param('attach_po');
-
- itemTypes = pcrud.retrieveAll('aiit');
-
- if(cgi.param('create')) {
- renderInvoice();
-
- } else {
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.invoice.retrieve.authoritative'],
- {
- params : [openils.User.authtoken, invoiceId],
- oncomplete : function(r) {
- invoice = openils.Util.readResponse(r);
- renderInvoice();
- }
- }
- );
- }
-
- extraCopiesFund = new openils.widget.AutoFieldWidget({
- fmField : 'fund',
- fmClass : 'acqlid',
- searchFilter : {active : 't'},
- labelFormat : fundLabelFormat,
- searchFormat : fundSearchFormat,
- dijitArgs : {required : true},
- parentNode : dojo.byId('acq-invoice-extra-copies-fund')
- });
- extraCopiesFund.build();
-}
-
-function renderInvoice() {
-
- // in create mode, let the LI or PO render the invoice with seed data
- if( !(cgi.param('create') && (attachPo || attachLi)) ) {
- invoicePane = drawInvoicePane(dojo.byId('acq-view-invoice-div'), invoice);
- }
-
- dojo.byId('acq-invoice-new-item').onclick = function() {
- var item = new fieldmapper.acqii();
- item.id(virtualId--);
- item.isnew(true);
- addInvoiceItem(item);
- }
-
- updateTotalCost();
-
- if(invoice && openils.Util.isTrue(invoice.complete())) {
-
- dojo.forEach( // hide widgets that should not be visible for a completed invoice
- dojo.query('.hide-complete'),
- function(node) { openils.Util.hide(node); }
- );
-
- new openils.User().getPermOrgList(
- 'ACQ_INVOICE_REOPEN',
- function (orgs) {
- if(orgs.indexOf(invoice.receiver()) >= 0)
- openils.Util.show('acq-invoice-reopen-button-wrapper', 'inline');
- },
- true,
- true
- );
- }
-
- if(invoice) {
- dojo.forEach(
- invoice.items(),
- function(item) {
- addInvoiceItem(item);
- }
- );
-
- dojo.forEach(
- invoice.entries(),
- function(entry) {
- addInvoiceEntry(entry);
- }
- );
- }
-
- if(attachLi) doAttachLi();
- if(attachPo) doAttachPo();
-}
-
-function doAttachLi() {
-
- //var invoiceArgs = {provider : lineitem.provider(), shipper : lineitem.provider()};
- if(cgi.param('create')) {
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.retrieve.authoritative'],
- {
- params : [openils.User.authtoken, attachLi, {clear_marc:1}],
- oncomplete : function(r) {
- var li = openils.Util.readResponse(r);
- invoicePane = drawInvoicePane(
- dojo.byId('acq-view-invoice-div'), null,
- {provider : li.provider(), shipper : li.provider()}
- );
- }
- }
- );
- }
-
- var entry = new fieldmapper.acqie();
- entry.id(virtualId--);
- entry.isnew(true);
- entry.lineitem(attachLi);
- addInvoiceEntry(entry);
-}
-
-function doAttachPo() {
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.retrieve'],
- { async: true,
- params: [
- openils.User.authtoken, attachPo,
- {flesh_lineitem_ids : true, flesh_po_items : true}
- ],
- oncomplete: function(r) {
- var po = openils.Util.readResponse(r);
-
- if(cgi.param('create')) {
- // render the invoice using some seed data from the PO
- var invoiceArgs = {provider : po.provider(), shipper : po.provider()};
- invoicePane = drawInvoicePane(dojo.byId('acq-view-invoice-div'), null, invoiceArgs);
- }
-
- dojo.forEach(po.lineitems(),
- function(lineitem) {
- var entry = new fieldmapper.acqie();
- entry.id(virtualId--);
- entry.isnew(true);
- entry.lineitem(lineitem);
- entry.purchase_order(po);
- addInvoiceEntry(entry);
- }
- );
-
- dojo.forEach(po.po_items(),
- function(poItem) {
- var item = new fieldmapper.acqii();
- item.id(virtualId--);
- item.isnew(true);
- item.fund(poItem.fund());
- item.title(poItem.title());
- item.author(poItem.author());
- item.note(poItem.note());
- item.inv_item_type(poItem.inv_item_type());
- item.purchase_order(po);
- item.po_item(poItem);
- addInvoiceItem(item);
- }
- );
- }
- }
- );
-}
-
-function updateTotalCost() {
-
- var totalCost = 0;
- for(var id in widgetRegistry.acqii)
- if(!widgetRegistry.acqii[id]._object.isdeleted())
- totalCost += Number(widgetRegistry.acqii[id].cost_billed.getFormattedValue());
- for(var id in widgetRegistry.acqie)
- if(!widgetRegistry.acqie[id]._object.isdeleted())
- totalCost += Number(widgetRegistry.acqie[id].cost_billed.getFormattedValue());
- totalInvoicedBox.attr('value', totalCost);
-
- totalPaid = 0;
- for(var id in widgetRegistry.acqii)
- if(!widgetRegistry.acqii[id]._object.isdeleted())
- totalPaid += Number(widgetRegistry.acqii[id].amount_paid.getFormattedValue());
- for(var id in widgetRegistry.acqie)
- if(!widgetRegistry.acqie[id]._object.isdeleted())
- totalPaid += Number(widgetRegistry.acqie[id].amount_paid.getFormattedValue());
- totalPaidBox.attr('value', totalPaid);
-
- var buttonsDisabled = false;
-
- if(totalPaid > totalCost || totalPaid < 0) {
- openils.Util.addCSSClass(totalPaidBox.domNode, 'acq-invoice-invalid-amount');
- invoiceSaveButton.attr('disabled', true);
- invoiceProrateButton.attr('disabled', true);
- buttonsDisabled = true;
- } else {
- openils.Util.removeCSSClass(totalPaidBox.domNode, 'acq-invoice-invalid-amount');
- invoiceSaveButton.attr('disabled', false);
- invoiceProrateButton.attr('disabled', false);
- }
-
- if(totalCost < 0) {
- openils.Util.addCSSClass(totalInvoicedBox.domNode, 'acq-invoice-invalid-amount');
- invoiceSaveButton.attr('disabled', true);
- invoiceProrateButton.attr('disabled', true);
- } else {
- openils.Util.removeCSSClass(totalInvoicedBox.domNode, 'acq-invoice-invalid-amount');
- if(!buttonsDisabled) {
- invoiceSaveButton.attr('disabled', false);
- invoiceProrateButton.attr('disabled', false);
- }
- }
-
- if(totalPaid == totalCost) { // XXX: too rigid?
- invoiceCloseButton.attr('disabled', false);
- } else {
- invoiceCloseButton.attr('disabled', true);
- }
-
- balanceOwedBox.attr('value', (totalCost - totalPaid));
-}
-
-
-function registerWidget(obj, field, widget, callback) {
- var blob = widgetRegistry[obj.classname];
- if(!blob[obj.id()])
- blob[obj.id()] = {_object : obj};
- blob[obj.id()][field] = widget;
- widget.build(
- function(w, ww) {
- dojo.connect(w, 'onChange',
- function(newVal) {
- obj.ischanged(true);
- updateTotalCost();
- }
- );
- if(callback) callback(w, ww);
- }
- );
- return widget;
-}
-
-function addInvoiceItem(item) {
- itemTbody = dojo.byId('acq-invoice-item-tbody');
- if(itemTemplate == null) {
- itemTemplate = itemTbody.removeChild(dojo.byId('acq-invoice-item-template'));
- }
-
- var row = itemTemplate.cloneNode(true);
- var itemType = itemTypes.filter(function(t) { return (t.code() == item.inv_item_type()) })[0];
-
- dojo.forEach(
- ['title', 'author', 'cost_billed', 'amount_paid'],
- function(field) {
-
- var args;
- if(field == 'title' || field == 'author') {
- //args = {style : 'width:10em'};
- } else if(field == 'cost_billed' || field == 'amount_paid') {
- args = {required : true, style : 'width: 8em'};
- }
- registerWidget(
- item,
- field,
- new openils.widget.AutoFieldWidget({
- fmClass : 'acqii',
- fmObject : item,
- fmField : field,
- readOnly : invoice && openils.Util.isTrue(invoice.complete()),
- dijitArgs : args,
- parentNode : nodeByName(field, row)
- })
- )
- }
- );
-
-
- /* ----------- fund -------------- */
- var fundArgs = {
- fmClass : 'acqii',
- fmObject : item,
- fmField : 'fund',
- labelFormat : fundLabelFormat,
- searchFormat : fundSearchFormat,
- readOnly : invoice && openils.Util.isTrue(invoice.complete()),
- dijitArgs : {required : true},
- parentNode : nodeByName('fund', row)
- }
-
- if(item.fund_debit()) {
- fundArgs.searchFilter = {'-or' : [{active : 't'}, {id : item.fund()}]};
- } else {
- fundArgs.searchFilter = {active : 't'}
- if(itemType && openils.Util.isTrue(itemType.prorate()))
- fundArgs.dijitArgs = {disabled : true};
- }
-
- var fundWidget = new openils.widget.AutoFieldWidget(fundArgs);
- registerWidget(item, 'fund', fundWidget);
-
- /* ---------- inv_item_type ------------- */
-
- if(item.po_item()) {
-
- // read-only item view for items that were the result of a po-item
- var po = item.purchase_order();
- var po_item = item.po_item();
- var node = nodeByName('inv_item_type', row);
- var itemType = itemTypes.filter(function(t) { return (t.code() == item.inv_item_type()) })[0];
- orderDate = (!po.order_date()) ? '' :
- dojo.date.locale.format(dojo.date.stamp.fromISOString(po.order_date()), {selector:'date'});
-
- node.innerHTML = dojo.string.substitute(
- localeStrings.INVOICE_ITEM_PO_DETAILS,
- [
- itemType.name(),
- oilsBasePath,
- po.id(),
- po.name(),
- orderDate,
- po_item.estimated_cost()
- ]
- );
-
- } else {
-
- registerWidget(
- item,
- 'inv_item_type',
- new openils.widget.AutoFieldWidget({
- fmObject : item,
- fmField : 'inv_item_type',
- parentNode : nodeByName('inv_item_type', row),
- readOnly : invoice && openils.Util.isTrue(invoice.complete()),
- dijitArgs : {required : true}
- }),
- function(w, ww) {
- // When the inv_item_type is set to prorate=true, don't allow the user the edit the fund
- // since this charge will be prorated against (potentially) multiple funds
- dojo.connect(w, 'onChange',
- function() {
- if(!item.fund_debit()) {
- var itemType = itemTypes.filter(function(t) { return (t.code() == w.attr('value')) })[0];
- if(!itemType) return;
- if(openils.Util.isTrue(itemType.prorate())) {
- fundWidget.widget.attr('disabled', true);
- fundWidget.widget.attr('value', '');
- } else {
- fundWidget.widget.attr('disabled', false);
- }
- }
- }
- );
- }
- );
- }
-
- nodeByName('delete', row).onclick = function() {
- var cost = widgetRegistry.acqii[item.id()].cost_billed.getFormattedValue();
- var msg = dojo.string.substitute(
- localeStrings.INVOICE_CONFIRM_ITEM_DELETE, [
- cost || 0,
- widgetRegistry.acqii[item.id()].inv_item_type.getFormattedValue() || ''
- ]
- );
- if(!confirm(msg)) return;
- itemTbody.removeChild(row);
- item.isdeleted(true);
- if(item.isnew())
- delete widgetRegistry.acqii[item.id()];
- updateTotalCost();
- }
-
- itemTbody.appendChild(row);
- updateTotalCost();
-}
-
-function updateReceiveLink(li) {
- if (!invoiceId)
- return; /* can't do this with unsaved invoices */
-
- var link = dojo.byId("acq-view-invoice-receive-link");
- if (link.onclick) return; /* only need to do this once */
-
- /* don't do this if there's nothing receivable on the lineitem */
- if (li.order_summary().recv_count() + li.order_summary().cancel_count() >=
- li.order_summary().item_count())
- return;
-
- openils.Util.show("acq-view-invoice-receive");
- link.onclick = function() { location.href = oilsBasePath + '/acq/invoice/receive/' + invoiceId; };
-}
-
-function addInvoiceEntry(entry) {
-
- openils.Util.removeCSSClass(dojo.byId('acq-invoice-entry-header'), 'hidden');
- openils.Util.removeCSSClass(dojo.byId('acq-invoice-entry-thead'), 'hidden');
- openils.Util.removeCSSClass(dojo.byId('acq-invoice-entry-tbody'), 'hidden');
-
- entryTbody = dojo.byId('acq-invoice-entry-tbody');
- if(entryTemplate == null) {
- entryTemplate = entryTbody.removeChild(dojo.byId('acq-invoice-entry-template'));
- }
-
- if(dojo.query('[lineitem=' + entry.lineitem() +']', entryTbody)[0])
- // Is it ever valid to have multiple entries for 1 lineitem in a single invoice?
- return;
-
- var row = entryTemplate.cloneNode(true);
- row.setAttribute('lineitem', entry.lineitem());
-
- openils.acq.Lineitem.fetchAndRender(
- entry.lineitem(), {},
- function(li, html) {
- entry.lineitem(li);
- entry.purchase_order(li.purchase_order());
- nodeByName('title_details', row).innerHTML = html;
-
- updateReceiveLink(li);
-
- dojo.forEach(
- ['inv_item_count', 'phys_item_count', 'cost_billed', 'amount_paid'],
- function(field) {
- var dijitArgs = {required : true, constraints : {min: 0}, style : 'width:6em'};
- if(!field.match(/count/)) dijitArgs.style = 'width:9em';
- if(entry.isnew() && field == 'phys_item_count') {
- // by default, attempt to pay for all non-canceled and as-of-yet-un-invoiced items
- var count = Number(li.order_summary().item_count() || 0) -
- Number(li.order_summary().cancel_count() || 0) -
- Number(li.order_summary().invoice_count() || 0);
- if(count < 0) count = 0;
- dijitArgs.value = count;
- }
- registerWidget(
- entry,
- field,
- new openils.widget.AutoFieldWidget({
- fmObject : entry,
- fmClass : 'acqie',
- fmField : field,
- dijitArgs : dijitArgs,
- readOnly : invoice && openils.Util.isTrue(invoice.complete()),
- parentNode : nodeByName(field, row)
- }),
- function(w) {
- if(field == 'phys_item_count') {
- dojo.connect(w, 'onChange',
- function() {
- // staff entered a higher number in the receive field than was originally ordered
- // taking into account already invoiced items
- var extra = Number(this.attr('value')) -
- (Number(entry.lineitem().item_count()) - Number(entry.lineitem().order_summary().invoice_count()));
- if(extra > 0) {
- storeExtraCopies(entry, extra);
- }
- }
- )
- }
- }
- );
- }
- );
- }
- );
-
- nodeByName('detach', row).onclick = function() {
- var cost = widgetRegistry.acqie[entry.id()].cost_billed.getFormattedValue();
- var idents = [];
- dojo.forEach(['isbn', 'upc', 'issn'],
- function(ident) {
- var val = liMarcAttr(entry.lineitem(), ident);
- if(val) idents.push(val);
- }
- );
-
- var msg = dojo.string.substitute(
- localeStrings.INVOICE_CONFIRM_ENTRY_DETACH, [
- cost || 0,
- liMarcAttr(entry.lineitem(), 'title'),
- liMarcAttr(entry.lineitem(), 'author'),
- idents.join(',')
- ]
- );
- if(!confirm(msg)) return;
- entryTbody.removeChild(row);
- entry.isdeleted(true);
- if(entry.isnew())
- delete widgetRegistry.acqie[entry.id()];
- updateTotalCost();
- }
-
- entryTbody.appendChild(row);
- updateTotalCost();
-}
-
-function liMarcAttr(lineitem, name) {
- var attr = lineitem.attributes().filter(
- function(attr) {
- if(
- attr.attr_type() == 'lineitem_marc_attr_definition' &&
- attr.attr_name() == name)
- return attr
- }
- )[0];
- return (attr) ? attr.attr_value() : '';
-}
-
-function saveChanges(doProrate, doClose, doReopen) {
- createExtraCopies(
- function() {
- saveChangesPartTwo(doProrate, doClose, doReopen);
- }
- );
-}
-
-function saveChangesPartTwo(doProrate, doClose, doReopen) {
-
- progressDialog.show(true);
-
- if(doReopen) {
- invoice.complete('f');
-
- } else {
-
-
- var updateItems = [];
- for(var id in widgetRegistry.acqii) {
- var reg = widgetRegistry.acqii[id];
- var item = reg._object;
- if(item.ischanged() || item.isnew() || item.isdeleted()) {
- updateItems.push(item);
- if(item.isnew()) item.id(null);
- for(var field in reg) {
- if(field != '_object')
- item[field]( reg[field].getFormattedValue() );
- }
-
- // unflesh
- if(item.purchase_order() != null && typeof item.purchase_order() == 'object')
- item.purchase_order( item.purchase_order().id() );
- }
- }
-
- var updateEntries = [];
- for(var id in widgetRegistry.acqie) {
- var reg = widgetRegistry.acqie[id];
- var entry = reg._object;
- if(entry.ischanged() || entry.isnew() || entry.isdeleted()) {
- entry.lineitem(entry.lineitem().id());
- entry.purchase_order(entry.purchase_order().id());
- updateEntries.push(entry);
- if(entry.isnew()) entry.id(null);
-
- for(var field in reg) {
- if(field != '_object')
- entry[field]( reg[field].getFormattedValue() );
- }
-
- // unflesh
- dojo.forEach(['purchase_order', 'lineitem'],
- function(field) {
- if(entry[field]() != null && typeof entry[field]() == 'object')
- entry[field]( entry[field]().id() );
- }
- );
- }
- }
-
- if(!invoice) {
- invoice = new fieldmapper.acqinv();
- invoice.isnew(true);
- } else {
- invoice.ischanged(true); // for now, just always update
- }
-
- dojo.forEach(invoicePane.fieldList,
- function(field) {
- invoice[field.name]( field.widget.getFormattedValue() );
- }
- );
-
- if(doClose)
- invoice.complete('t');
- }
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.invoice.update'],
- {
- params : [openils.User.authtoken, invoice, updateEntries, updateItems],
- oncomplete : function(r) {
- progressDialog.hide();
- var invoice = openils.Util.readResponse(r);
- if(invoice) {
- if(doProrate)
- return prorateInvoice(invoice);
- location.href = oilsBasePath + '/acq/invoice/view/' + invoice.id();
- }
- }
- }
- );
-}
-
-function prorateInvoice(invoice) {
- if(!confirm(localeStrings.INVOICE_CONFIRM_PRORATE)) return;
- progressDialog.show(true);
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.invoice.apply_prorate'],
- {
- params : [openils.User.authtoken, invoice.id()],
- oncomplete : function(r) {
- progressDialog.hide();
- var invoice = openils.Util.readResponse(r);
- if(invoice) {
- location.href = oilsBasePath + '/acq/invoice/view/' + invoice.id();
- }
- }
- }
- );
-}
-
-function storeExtraCopies(entry, numExtra) {
-
- dojo.byId('acq-invoice-extra-copies-message').innerHTML =
- dojo.string.substitute(
- localeStrings.INVOICE_EXTRA_COPIES, [numExtra]);
-
- var addCopyHandler;
- addCopyHandler = dojo.connect(
- extraCopiesGo,
- 'onClick',
- function() {
- extraCopies[entry.lineitem().id()] = {
- numExtra : numExtra,
- fund : extraCopiesFund.widget.attr('value')
- }
- extraItemsDialog.hide();
- dojo.disconnect(addCopyHandler);
- }
- );
-
- dojo.connect(
- extraCopiesCancel,
- 'onClick',
- function() {
- widgetRegistry.acqie[entry.id()].phys_item_count.widget.attr('value', '');
- extraItemsDialog.hide()
- }
- );
-
- extraItemsDialog.show();
-}
-
-function createExtraCopies(oncomplete) {
-
- var lids = [];
- for(var liId in extraCopies) {
- var data = extraCopies[liId];
- for(var i = 0; i < data.numExtra; i++) {
- var lid = new fieldmapper.acqlid();
- lid.isnew(true);
- lid.lineitem(liId);
- lid.fund(data.fund);
- lid.recv_time('now');
- lids.push(lid);
- }
- }
-
- if(lids.length == 0)
- return oncomplete();
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem_detail.cud.batch'],
- {
- params : [openils.User.authtoken, lids, true],
- oncomplete : function(r) {
- if(openils.Util.readResponse(r))
- oncomplete();
- }
- }
- );
-
-}
-
-
-openils.Util.addOnLoad(init);
-
-
+require([
+ "dojo/date/locale",
+ "dojo/date/stamp",
+ "dijit/form/CheckBox",
+ "dijit/form/CurrencyTextBox",
+ "dijit/form/NumberTextBox",
+ "openils/User",
+ "openils/Util",
+ "openils/CGI",
+ "openils/PermaCrud",
+ "openils/widget/EditPane",
+ "openils/widget/AutoFieldWidget",
+ "openils/widget/ProgressDialog",
+ "openils/acq/Lineitem"
+ ],
+function(dojo_date_locale,
+ dojo_date_stamp,
+ dijit_form_CheckBox,
+ dijit_form_CurrencyTextBox,
+ dijit_form_NumberTextBox,
+ openils_User,
+ openils_Util,
+ openils_CGI,
+ openils_PermaCrud,
+ openils_widget_EditPane,
+ openils_widget_AutoFieldWidget,
+ openils_widget_ProgressDialog,
+ openils_acq_Lineitem){
+
+ dojo.requireLocalization('openils.acq', 'acq');
+ var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
+
+ var fundLabelFormat = ['${0} (${1})', 'code', 'year'];
+ var fundSearchFormat = ['${0} (${1})', 'code', 'year'];
+
+ var cgi = new openils_CGI();
+ var pcrud = new openils_PermaCrud();
+ var attachLi;
+ var attachPo;
+ var invoice;
+ var itemTbody;
+ var itemTemplate;
+ var entryTemplate;
+ var totalInvoicedBox;
+ var totalPaidBox;
+ var balanceOwedBox;
+ var invoicePane;
+ var itemTypes;
+ var virtualId = -1;
+ var extraCopies = {};
+ var extraCopiesFund;
+ var widgetRegistry = {acqie : {}, acqii : {}};
+
+ function nodeByName(name, context) {
+ return dojo.query('[name='+name+']', context)[0];
+ }
+
+ function init() {
+
+ attachLi = cgi.param('attach_li');
+ attachPo = cgi.param('attach_po');
+
+ itemTypes = pcrud.retrieveAll('aiit');
+
+ if(cgi.param('create')) {
+ renderInvoice();
+
+ } else {
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.invoice.retrieve.authoritative'],
+ {
+ params : [openils_User.authtoken, invoiceId],
+ oncomplete : function(r) {
+ invoice = openils_Util.readResponse(r);
+ renderInvoice();
+ }
+ }
+ );
+ }
+
+ extraCopiesFund = new openils_widget_AutoFieldWidget({
+ fmField : 'fund',
+ fmClass : 'acqlid',
+ searchFilter : {active : 't'},
+ labelFormat : fundLabelFormat,
+ searchFormat : fundSearchFormat,
+ dijitArgs : {required : true},
+ parentNode : dojo.byId('acq-invoice-extra-copies-fund')
+ });
+ extraCopiesFund.build();
+ }
+
+ function renderInvoice() {
+
+ // in create mode, let the LI or PO render the invoice with seed data
+ if( !(cgi.param('create') && (attachPo || attachLi)) ) {
+ invoicePane = drawInvoicePane(dojo.byId('acq-view-invoice-div'), invoice);
+ }
+
+ dojo.byId('acq-invoice-new-item').onclick = function() {
+ var item = new fieldmapper.acqii();
+ item.id(virtualId--);
+ item.isnew(true);
+ addInvoiceItem(item);
+ }
+
+ updateTotalCost();
+
+ if(invoice && openils_Util.isTrue(invoice.complete())) {
+
+ dojo.forEach( // hide widgets that should not be visible for a completed invoice
+ dojo.query('.hide-complete'),
+ function(node) { openils_Util.hide(node); }
+ );
+
+ new openils_User().getPermOrgList(
+ 'ACQ_INVOICE_REOPEN',
+ function (orgs) {
+ if(orgs.indexOf(invoice.receiver()) >= 0)
+ openils_Util.show('acq-invoice-reopen-button-wrapper', 'inline');
+ },
+ true,
+ true
+ );
+ }
+
+ if(invoice) {
+ dojo.forEach(
+ invoice.items(),
+ function(item) {
+ addInvoiceItem(item);
+ }
+ );
+
+ dojo.forEach(
+ invoice.entries(),
+ function(entry) {
+ addInvoiceEntry(entry);
+ }
+ );
+ }
+
+ if(attachLi) doAttachLi();
+ if(attachPo) doAttachPo();
+ }
+
+ function doAttachLi() {
+
+ //var invoiceArgs = {provider : lineitem.provider(), shipper : lineitem.provider()};
+ if(cgi.param('create')) {
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem.retrieve.authoritative'],
+ {
+ params : [openils_User.authtoken, attachLi, {clear_marc:1}],
+ oncomplete : function(r) {
+ var li = openils_Util.readResponse(r);
+ invoicePane = drawInvoicePane(
+ dojo.byId('acq-view-invoice-div'), null,
+ {provider : li.provider(), shipper : li.provider()}
+ );
+ }
+ }
+ );
+ }
+
+ var entry = new fieldmapper.acqie();
+ entry.id(virtualId--);
+ entry.isnew(true);
+ entry.lineitem(attachLi);
+ addInvoiceEntry(entry);
+ }
+
+ function doAttachPo() {
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.retrieve'],
+ { async: true,
+ params: [
+ openils_User.authtoken, attachPo,
+ {flesh_lineitem_ids : true, flesh_po_items : true}
+ ],
+ oncomplete: function(r) {
+ var po = openils_Util.readResponse(r);
+
+ if(cgi.param('create')) {
+ // render the invoice using some seed data from the PO
+ var invoiceArgs = {provider : po.provider(), shipper : po.provider()};
+ invoicePane = drawInvoicePane(dojo.byId('acq-view-invoice-div'), null, invoiceArgs);
+ }
+
+ dojo.forEach(po.lineitems(),
+ function(lineitem) {
+ var entry = new fieldmapper.acqie();
+ entry.id(virtualId--);
+ entry.isnew(true);
+ entry.lineitem(lineitem);
+ entry.purchase_order(po);
+ addInvoiceEntry(entry);
+ }
+ );
+
+ dojo.forEach(po.po_items(),
+ function(poItem) {
+ var item = new fieldmapper.acqii();
+ item.id(virtualId--);
+ item.isnew(true);
+ item.fund(poItem.fund());
+ item.title(poItem.title());
+ item.author(poItem.author());
+ item.note(poItem.note());
+ item.inv_item_type(poItem.inv_item_type());
+ item.purchase_order(po);
+ item.po_item(poItem);
+ addInvoiceItem(item);
+ }
+ );
+ }
+ }
+ );
+ }
+
+ function updateTotalCost() {
+
+ var totalCost = 0;
+ for(var id in widgetRegistry.acqii)
+ if(!widgetRegistry.acqii[id]._object.isdeleted())
+ totalCost += Number(widgetRegistry.acqii[id].cost_billed.getFormattedValue());
+ for(var id in widgetRegistry.acqie)
+ if(!widgetRegistry.acqie[id]._object.isdeleted())
+ totalCost += Number(widgetRegistry.acqie[id].cost_billed.getFormattedValue());
+ totalInvoicedBox.attr('value', totalCost);
+
+ totalPaid = 0;
+ for(var id in widgetRegistry.acqii)
+ if(!widgetRegistry.acqii[id]._object.isdeleted())
+ totalPaid += Number(widgetRegistry.acqii[id].amount_paid.getFormattedValue());
+ for(var id in widgetRegistry.acqie)
+ if(!widgetRegistry.acqie[id]._object.isdeleted())
+ totalPaid += Number(widgetRegistry.acqie[id].amount_paid.getFormattedValue());
+ totalPaidBox.attr('value', totalPaid);
+
+ var buttonsDisabled = false;
+
+ if(totalPaid > totalCost || totalPaid < 0) {
+ openils_Util.addCSSClass(totalPaidBox.domNode, 'acq-invoice-invalid-amount');
+ invoiceSaveButton.attr('disabled', true);
+ invoiceProrateButton.attr('disabled', true);
+ buttonsDisabled = true;
+ } else {
+ openils_Util.removeCSSClass(totalPaidBox.domNode, 'acq-invoice-invalid-amount');
+ invoiceSaveButton.attr('disabled', false);
+ invoiceProrateButton.attr('disabled', false);
+ }
+
+ if(totalCost < 0) {
+ openils_Util.addCSSClass(totalInvoicedBox.domNode, 'acq-invoice-invalid-amount');
+ invoiceSaveButton.attr('disabled', true);
+ invoiceProrateButton.attr('disabled', true);
+ } else {
+ openils_Util.removeCSSClass(totalInvoicedBox.domNode, 'acq-invoice-invalid-amount');
+ if(!buttonsDisabled) {
+ invoiceSaveButton.attr('disabled', false);
+ invoiceProrateButton.attr('disabled', false);
+ }
+ }
+
+ if(totalPaid == totalCost) { // XXX: too rigid?
+ invoiceCloseButton.attr('disabled', false);
+ } else {
+ invoiceCloseButton.attr('disabled', true);
+ }
+
+ balanceOwedBox.attr('value', (totalCost - totalPaid));
+ }
+
+
+ function registerWidget(obj, field, widget, callback) {
+ var blob = widgetRegistry[obj.classname];
+ if(!blob[obj.id()])
+ blob[obj.id()] = {_object : obj};
+ blob[obj.id()][field] = widget;
+ widget.build(
+ function(w, ww) {
+ dojo.connect(w, 'onChange',
+ function(newVal) {
+ obj.ischanged(true);
+ updateTotalCost();
+ }
+ );
+ if(callback) callback(w, ww);
+ }
+ );
+ return widget;
+ }
+
+ function addInvoiceItem(item) {
+ itemTbody = dojo.byId('acq-invoice-item-tbody');
+ if(itemTemplate == null) {
+ itemTemplate = itemTbody.removeChild(dojo.byId('acq-invoice-item-template'));
+ }
+
+ var row = itemTemplate.cloneNode(true);
+ var itemType = itemTypes.filter(function(t) { return (t.code() == item.inv_item_type()) })[0];
+
+ dojo.forEach(
+ ['title', 'author', 'cost_billed', 'amount_paid'],
+ function(field) {
+
+ var args;
+ if(field == 'title' || field == 'author') {
+ //args = {style : 'width:10em'};
+ } else if(field == 'cost_billed' || field == 'amount_paid') {
+ args = {required : true, style : 'width: 8em'};
+ }
+ registerWidget(
+ item,
+ field,
+ new openils_widget_AutoFieldWidget({
+ fmClass : 'acqii',
+ fmObject : item,
+ fmField : field,
+ readOnly : invoice && openils_Util.isTrue(invoice.complete()),
+ dijitArgs : args,
+ parentNode : nodeByName(field, row)
+ })
+ )
+ }
+ );
+
+
+ /* ----------- fund -------------- */
+ var fundArgs = {
+ fmClass : 'acqii',
+ fmObject : item,
+ fmField : 'fund',
+ labelFormat : fundLabelFormat,
+ searchFormat : fundSearchFormat,
+ readOnly : invoice && openils_Util.isTrue(invoice.complete()),
+ dijitArgs : {required : true},
+ parentNode : nodeByName('fund', row)
+ }
+
+ if(item.fund_debit()) {
+ fundArgs.searchFilter = {'-or' : [{active : 't'}, {id : item.fund()}]};
+ } else {
+ fundArgs.searchFilter = {active : 't'}
+ if(itemType && openils_Util.isTrue(itemType.prorate()))
+ fundArgs.dijitArgs = {disabled : true};
+ }
+
+ var fundWidget = new openils_widget_AutoFieldWidget(fundArgs);
+ registerWidget(item, 'fund', fundWidget);
+
+ /* ---------- inv_item_type ------------- */
+
+ if(item.po_item()) {
+
+ // read-only item view for items that were the result of a po-item
+ var po = item.purchase_order();
+ var po_item = item.po_item();
+ var node = nodeByName('inv_item_type', row);
+ var itemType = itemTypes.filter(function(t) { return (t.code() == item.inv_item_type()) })[0];
+ orderDate = (!po.order_date()) ? '' :
+ dojo_date_locale.format(dojo_date_stamp.fromISOString(po.order_date()), {selector:'date'});
+
+ node.innerHTML = dojo.string.substitute(
+ localeStrings.INVOICE_ITEM_PO_DETAILS,
+ [
+ itemType.name(),
+ oilsBasePath,
+ po.id(),
+ po.name(),
+ orderDate,
+ po_item.estimated_cost()
+ ]
+ );
+
+ } else {
+
+ registerWidget(
+ item,
+ 'inv_item_type',
+ new openils_widget_AutoFieldWidget({
+ fmObject : item,
+ fmField : 'inv_item_type',
+ parentNode : nodeByName('inv_item_type', row),
+ readOnly : invoice && openils_Util.isTrue(invoice.complete()),
+ dijitArgs : {required : true}
+ }),
+ function(w, ww) {
+ // When the inv_item_type is set to prorate=true, don't allow the user the edit the fund
+ // since this charge will be prorated against (potentially) multiple funds
+ dojo.connect(w, 'onChange',
+ function() {
+ if(!item.fund_debit()) {
+ var itemType = itemTypes.filter(function(t) { return (t.code() == w.attr('value')) })[0];
+ if(!itemType) return;
+ if(openils_Util.isTrue(itemType.prorate())) {
+ fundWidget.widget.attr('disabled', true);
+ fundWidget.widget.attr('value', '');
+ } else {
+ fundWidget.widget.attr('disabled', false);
+ }
+ }
+ }
+ );
+ }
+ );
+ }
+
+ nodeByName('delete', row).onclick = function() {
+ var cost = widgetRegistry.acqii[item.id()].cost_billed.getFormattedValue();
+ var msg = dojo.string.substitute(
+ localeStrings.INVOICE_CONFIRM_ITEM_DELETE, [
+ cost || 0,
+ widgetRegistry.acqii[item.id()].inv_item_type.getFormattedValue() || ''
+ ]
+ );
+ if(!confirm(msg)) return;
+ itemTbody.removeChild(row);
+ item.isdeleted(true);
+ if(item.isnew())
+ delete widgetRegistry.acqii[item.id()];
+ updateTotalCost();
+ }
+
+ itemTbody.appendChild(row);
+ updateTotalCost();
+ }
+
+ function updateReceiveLink(li) {
+ if (!invoiceId)
+ return; /* can't do this with unsaved invoices */
+
+ var link = dojo.byId("acq-view-invoice-receive-link");
+ if (link.onclick) return; /* only need to do this once */
+
+ /* don't do this if there's nothing receivable on the lineitem */
+ if (li.order_summary().recv_count() + li.order_summary().cancel_count() >=
+ li.order_summary().item_count())
+ return;
+
+ openils_Util.show("acq-view-invoice-receive");
+ link.onclick = function() { location.href = oilsBasePath + '/acq/invoice/receive/' + invoiceId; };
+ }
+
+ function addInvoiceEntry(entry) {
+
+ openils_Util.removeCSSClass(dojo.byId('acq-invoice-entry-header'), 'hidden');
+ openils_Util.removeCSSClass(dojo.byId('acq-invoice-entry-thead'), 'hidden');
+ openils_Util.removeCSSClass(dojo.byId('acq-invoice-entry-tbody'), 'hidden');
+
+ entryTbody = dojo.byId('acq-invoice-entry-tbody');
+ if(entryTemplate == null) {
+ entryTemplate = entryTbody.removeChild(dojo.byId('acq-invoice-entry-template'));
+ }
+
+ if(dojo.query('[lineitem=' + entry.lineitem() +']', entryTbody)[0])
+ // Is it ever valid to have multiple entries for 1 lineitem in a single invoice?
+ return;
+
+ var row = entryTemplate.cloneNode(true);
+ row.setAttribute('lineitem', entry.lineitem());
+
+ openils_acq_Lineitem.fetchAndRender(
+ entry.lineitem(), {},
+ function(li, html) {
+ entry.lineitem(li);
+ entry.purchase_order(li.purchase_order());
+ nodeByName('title_details', row).innerHTML = html;
+
+ updateReceiveLink(li);
+
+ dojo.forEach(
+ ['inv_item_count', 'phys_item_count', 'cost_billed', 'amount_paid'],
+ function(field) {
+ var dijitArgs = {required : true, constraints : {min: 0}, style : 'width:6em'};
+ if(!field.match(/count/)) dijitArgs.style = 'width:9em';
+ if(entry.isnew() && field == 'phys_item_count') {
+ // by default, attempt to pay for all non-canceled and as-of-yet-un-invoiced items
+ var count = Number(li.order_summary().item_count() || 0) -
+ Number(li.order_summary().cancel_count() || 0) -
+ Number(li.order_summary().invoice_count() || 0);
+ if(count < 0) count = 0;
+ dijitArgs.value = count;
+ }
+ registerWidget(
+ entry,
+ field,
+ new openils_widget_AutoFieldWidget({
+ fmObject : entry,
+ fmClass : 'acqie',
+ fmField : field,
+ dijitArgs : dijitArgs,
+ readOnly : invoice && openils_Util.isTrue(invoice.complete()),
+ parentNode : nodeByName(field, row)
+ }),
+ function(w) {
+ if(field == 'phys_item_count') {
+ dojo.connect(w, 'onChange',
+ function() {
+ // staff entered a higher number in the receive field than was originally ordered
+ // taking into account already invoiced items
+ var extra = Number(this.attr('value')) -
+ (Number(entry.lineitem().item_count()) - Number(entry.lineitem().order_summary().invoice_count()));
+ if(extra > 0) {
+ storeExtraCopies(entry, extra);
+ }
+ }
+ )
+ }
+ }
+ );
+ }
+ );
+ }
+ );
+
+ nodeByName('detach', row).onclick = function() {
+ var cost = widgetRegistry.acqie[entry.id()].cost_billed.getFormattedValue();
+ var idents = [];
+ dojo.forEach(['isbn', 'upc', 'issn'],
+ function(ident) {
+ var val = liMarcAttr(entry.lineitem(), ident);
+ if(val) idents.push(val);
+ }
+ );
+
+ var msg = dojo.string.substitute(
+ localeStrings.INVOICE_CONFIRM_ENTRY_DETACH, [
+ cost || 0,
+ liMarcAttr(entry.lineitem(), 'title'),
+ liMarcAttr(entry.lineitem(), 'author'),
+ idents.join(',')
+ ]
+ );
+ if(!confirm(msg)) return;
+ entryTbody.removeChild(row);
+ entry.isdeleted(true);
+ if(entry.isnew())
+ delete widgetRegistry.acqie[entry.id()];
+ updateTotalCost();
+ }
+
+ entryTbody.appendChild(row);
+ updateTotalCost();
+ }
+
+ function liMarcAttr(lineitem, name) {
+ var attr = lineitem.attributes().filter(
+ function(attr) {
+ if(
+ attr.attr_type() == 'lineitem_marc_attr_definition' &&
+ attr.attr_name() == name)
+ return attr
+ }
+ )[0];
+ return (attr) ? attr.attr_value() : '';
+ }
+
+ function saveChanges(doProrate, doClose, doReopen) {
+ createExtraCopies(
+ function() {
+ saveChangesPartTwo(doProrate, doClose, doReopen);
+ }
+ );
+ }
+
+ function saveChangesPartTwo(doProrate, doClose, doReopen) {
+
+ progressDialog.show(true);
+
+ if(doReopen) {
+ invoice.complete('f');
+
+ } else {
+
+
+ var updateItems = [];
+ for(var id in widgetRegistry.acqii) {
+ var reg = widgetRegistry.acqii[id];
+ var item = reg._object;
+ if(item.ischanged() || item.isnew() || item.isdeleted()) {
+ updateItems.push(item);
+ if(item.isnew()) item.id(null);
+ for(var field in reg) {
+ if(field != '_object')
+ item[field]( reg[field].getFormattedValue() );
+ }
+
+ // unflesh
+ if(item.purchase_order() != null && typeof item.purchase_order() == 'object')
+ item.purchase_order( item.purchase_order().id() );
+ }
+ }
+
+ var updateEntries = [];
+ for(var id in widgetRegistry.acqie) {
+ var reg = widgetRegistry.acqie[id];
+ var entry = reg._object;
+ if(entry.ischanged() || entry.isnew() || entry.isdeleted()) {
+ entry.lineitem(entry.lineitem().id());
+ entry.purchase_order(entry.purchase_order().id());
+ updateEntries.push(entry);
+ if(entry.isnew()) entry.id(null);
+
+ for(var field in reg) {
+ if(field != '_object')
+ entry[field]( reg[field].getFormattedValue() );
+ }
+
+ // unflesh
+ dojo.forEach(['purchase_order', 'lineitem'],
+ function(field) {
+ if(entry[field]() != null && typeof entry[field]() == 'object')
+ entry[field]( entry[field]().id() );
+ }
+ );
+ }
+ }
+
+ if(!invoice) {
+ invoice = new fieldmapper.acqinv();
+ invoice.isnew(true);
+ } else {
+ invoice.ischanged(true); // for now, just always update
+ }
+
+ dojo.forEach(invoicePane.fieldList,
+ function(field) {
+ invoice[field.name]( field.widget.getFormattedValue() );
+ }
+ );
+
+ if(doClose)
+ invoice.complete('t');
+ }
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.invoice.update'],
+ {
+ params : [openils_User.authtoken, invoice, updateEntries, updateItems],
+ oncomplete : function(r) {
+ progressDialog.hide();
+ var invoice = openils_Util.readResponse(r);
+ if(invoice) {
+ if(doProrate)
+ return prorateInvoice(invoice);
+ location.href = oilsBasePath + '/acq/invoice/view/' + invoice.id();
+ }
+ }
+ }
+ );
+ }
+
+ function prorateInvoice(invoice) {
+ if(!confirm(localeStrings.INVOICE_CONFIRM_PRORATE)) return;
+ progressDialog.show(true);
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.invoice.apply_prorate'],
+ {
+ params : [openils_User.authtoken, invoice.id()],
+ oncomplete : function(r) {
+ progressDialog.hide();
+ var invoice = openils_Util.readResponse(r);
+ if(invoice) {
+ location.href = oilsBasePath + '/acq/invoice/view/' + invoice.id();
+ }
+ }
+ }
+ );
+ }
+
+ function storeExtraCopies(entry, numExtra) {
+
+ dojo.byId('acq-invoice-extra-copies-message').innerHTML =
+ dojo.string.substitute(
+ localeStrings.INVOICE_EXTRA_COPIES, [numExtra]);
+
+ var addCopyHandler;
+ addCopyHandler = dojo.connect(
+ extraCopiesGo,
+ 'onClick',
+ function() {
+ extraCopies[entry.lineitem().id()] = {
+ numExtra : numExtra,
+ fund : extraCopiesFund.widget.attr('value')
+ }
+ extraItemsDialog.hide();
+ dojo.disconnect(addCopyHandler);
+ }
+ );
+
+ dojo.connect(
+ extraCopiesCancel,
+ 'onClick',
+ function() {
+ widgetRegistry.acqie[entry.id()].phys_item_count.widget.attr('value', '');
+ extraItemsDialog.hide()
+ }
+ );
+
+ extraItemsDialog.show();
+ }
+
+ function createExtraCopies(oncomplete) {
+
+ var lids = [];
+ for(var liId in extraCopies) {
+ var data = extraCopies[liId];
+ for(var i = 0; i < data.numExtra; i++) {
+ var lid = new fieldmapper.acqlid();
+ lid.isnew(true);
+ lid.lineitem(liId);
+ lid.fund(data.fund);
+ lid.recv_time('now');
+ lids.push(lid);
+ }
+ }
+
+ if(lids.length == 0)
+ return oncomplete();
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem_detail.cud.batch'],
+ {
+ params : [openils_User.authtoken, lids, true],
+ oncomplete : function(r) {
+ if(openils_Util.readResponse(r))
+ oncomplete();
+ }
+ }
+ );
+
+ }
+
+
+ openils_Util.addOnLoad(init);
+
+
+
+
+});
\ No newline at end of file
-dojo.require('openils.Util');
-dojo.require('openils.BibTemplate');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.CGI');
-dojo.require('dijit.form.Button');
-dojo.require('openils.widget.ProgressDialog');
-
-var limit = 15;
-var offset = 0;
-var template;
-var container;
-
-function drawSearch() {
- container = dojo.byId('acq-findbib-container');
- template = container.removeChild(dojo.byId('acq-findbib-template'));
- var cgi = new openils.CGI();
- searchQuery.attr('value', cgi.param('query') || '');
- searchQuery.domNode.select();
- openils.Util.registerEnterHandler(searchQuery.domNode, doSearch);
-}
-
-function doSearch() {
- while(container.childNodes[0])
- container.removeChild(container.childNodes[0])
- progressDialog.show(true);
- var query = searchQuery.attr('value');
- fieldmapper.standardRequest(
- ['open-ils.search', 'open-ils.search.biblio.multiclass.query.staff'],
- {
- async : true,
- params : [{limit : limit}, query, 1],
- oncomplete : drawResult
- }
- );
-}
-
-function drawResult(r) {
- progressDialog.hide();
- var result = openils.Util.readResponse(r);
- dojo.forEach(
- result.ids,
- function(id) {
- id = id[0];
- var div = template.cloneNode(true);
- container.appendChild(div);
-
- var viewMarc = dojo.query('[name=view-marc]', div)[0];
- viewMarc.onclick = function() { showMARC(id); };
- var selectRec = dojo.query('[name=select-rec]', div)[0];
- selectRec.onclick = function() { selectRecord(id); };
-
- new openils.BibTemplate({
- record : id,
- org_unit : fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()).shortname(),
- root : div
- }).render();
- }
- );
-}
-
-function showMARC(bibId) {
- openils.Util.show(dojo.byId('marc-div'));
- fieldmapper.standardRequest(
- ['open-ils.search', 'open-ils.search.biblio.record.html'],
- {
- async: true,
- params: [bibId, true],
- oncomplete: function(r) {
- dojo.byId('marc-html-div').innerHTML = openils.Util.readResponse(r);
- }
- }
- );
-}
-
-function selectRecord(bibId) {
- if(window.recordFound) {
- window.recordFound(bibId);
- }
-}
-
-
-openils.Util.addOnLoad(drawSearch);
+require([
+ "openils/Util",
+ "openils/BibTemplate",
+ "fieldmapper/OrgUtils",
+ "openils/CGI",
+ "dijit/form/Button",
+ "openils/widget/ProgressDialog"
+ ],
+function(openils_Util,
+ openils_BibTemplate,
+ fieldmapper_OrgUtils,
+ openils_CGI,
+ dijit_form_Button,
+ openils_widget_ProgressDialog){
+
+ var limit = 15;
+ var offset = 0;
+ var template;
+ var container;
+
+ function drawSearch() {
+ container = dojo.byId('acq-findbib-container');
+ template = container.removeChild(dojo.byId('acq-findbib-template'));
+ var cgi = new openils_CGI();
+ searchQuery.attr('value', cgi.param('query') || '');
+ searchQuery.domNode.select();
+ openils_Util.registerEnterHandler(searchQuery.domNode, doSearch);
+ }
+
+ function doSearch() {
+ while(container.childNodes[0])
+ container.removeChild(container.childNodes[0])
+ progressDialog.show(true);
+ var query = searchQuery.attr('value');
+ fieldmapper.standardRequest(
+ ['open-ils.search', 'open-ils.search.biblio.multiclass.query.staff'],
+ {
+ async : true,
+ params : [{limit : limit}, query, 1],
+ oncomplete : drawResult
+ }
+ );
+ }
+
+ function drawResult(r) {
+ progressDialog.hide();
+ var result = openils_Util.readResponse(r);
+ dojo.forEach(
+ result.ids,
+ function(id) {
+ id = id[0];
+ var div = template.cloneNode(true);
+ container.appendChild(div);
+
+ var viewMarc = dojo.query('[name=view-marc]', div)[0];
+ viewMarc.onclick = function() { showMARC(id); };
+ var selectRec = dojo.query('[name=select-rec]', div)[0];
+ selectRec.onclick = function() { selectRecord(id); };
+
+ new openils_BibTemplate({
+ record : id,
+ org_unit : fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()).shortname(),
+ root : div
+ }).render();
+ }
+ );
+ }
+
+ function showMARC(bibId) {
+ openils_Util.show(dojo.byId('marc-div'));
+ fieldmapper.standardRequest(
+ ['open-ils.search', 'open-ils.search.biblio.record.html'],
+ {
+ async: true,
+ params: [bibId, true],
+ oncomplete: function(r) {
+ dojo.byId('marc-html-div').innerHTML = openils_Util.readResponse(r);
+ }
+ }
+ );
+ }
+
+ function selectRecord(bibId) {
+ if(window.recordFound) {
+ window.recordFound(bibId);
+ }
+ }
+
+
+ openils_Util.addOnLoad(drawSearch);
+
+
+});
\ No newline at end of file
-dojo.require("openils.acq.Lineitem");
-dojo.require("openils.Util");
-dojo.require("openils.XUL");
-dojo.require("openils.CGI");
-dojo.require("openils.PermaCrud");
-dojo.require('openils.BibTemplate');
-dojo.require('fieldmapper.OrgUtils');
-
-dojo.requireLocalization('openils.acq', 'acq');
-var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
-
-var liTable;
-var identTarget;
-var bibRecord;
-var paramPL;
-var paramPO;
-
-function fetchLi() {
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem.retrieve.authoritative"], {
- "async": true,
- "params": [openils.User.authtoken, targetId, {
- "flesh_attrs": true,
- "flesh_li_details": true,
- "flesh_fund_debit": true,
- "flesh_cancel_reason": true
- }],
- "oncomplete": function(r) {
- var li = openils.Util.readResponse(r);
- fetchBib(li.eg_bib_id());
- }
- }
- );
-}
-
-
-function fetchRelated() {
- var method = 'open-ils.acq.lineitems_for_bib.by_lineitem_id';
- if(identTarget == 'bib')
- var method = 'open-ils.acq.lineitems_for_bib.by_bib_id';
-
- var total = 0;
- fieldmapper.standardRequest(
- ["open-ils.acq", method], {
- "async": true,
- "params": [openils.User.authtoken, targetId, {
- "flesh_attrs": true,
- "flesh_notes": true,
- "flesh_cancel_reason": true
- }],
- "onresponse": function(r) {
- var resp = openils.Util.readResponse(r);
- if (resp) {
- total++;
- liTable.show("list");
- liTable.addLineitem(resp);
- }
- }
- }
- );
-}
-
-function fetchBib(bibId) {
- bibId = bibId || targetId;
- new openils.BibTemplate({
- record : bibId,
- org_unit : fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()).shortname()
- }).render();
-
- new openils.PermaCrud().retrieve('bre', bibId, {
- oncomplete : function(r) {
- bibRecord = openils.Util.readResponse(r);
- // render bib details
- // perhaps we just pull these from the beating heart of bibtemplate
- }
- })
-}
-
-function createLi(oncomplete) {
- return function() {
- progressDialog.show();
- liTable.reset();
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.biblio.create_by_id"], {
- "params": [
- openils.User.authtoken, [bibRecord.id()], {
- "flesh_attrs": true,
- "flesh_cancel_reason": true,
- "flesh_notes": true
- }
- ],
- "async": false,
- "onresponse": function(r) {
- var li = openils.Util.readResponse(r);
- if (typeof(li) == "object") {
- liTable.show("list");
- liTable.addLineitem(li);
- dojo.query(
- "input[name='selectbox']", liTable._findLiRow(li)
- )[0].checked = true;
- }
- },
- "oncomplete": function() {
- progressDialog.hide();
- oncomplete();
- }
- }
- );
- };
-}
-
-function prepareButtons() {
- addToPlButton.onClick = createLi(
- function() { /* oncomplete */
- acqLitSavePlDialog.show();
- }
- );
- addToPoButton.onClick = createLi(
- function() { /* oncomplete */
- addToPoDialog.show();
- }
- );
- createPoButton.onClick = createLi(
- function() { /* oncomplete */
- liTable._loadPOSelect();
- acqLitPoCreateDialog.show();
- }
- );
-}
-
-function load() {
- var cgi = new openils.CGI();
-
- identTarget = cgi.param('target');
- paramPL = cgi.param('pl');
-// paramPO = cgi.param('po');
-
- if (identTarget == 'bib') {
- fetchBib();
- } else {
- fetchLi();
- }
-
- liTable = new AcqLiTable();
- liTable.reset();
- liTable._isRelatedViewer = true;
-
- prepareButtons();
- fetchRelated();
- dojo.connect(addToPoSave, 'onClick', addToPo)
- openils.Util.registerEnterHandler(addToPoInput.domNode, addToPo);
-}
-
-var _addToPoHappened = false;
-function addToPo(args) {
- var poId = addToPoInput.attr('value');
- if (!poId) return false;
- if (_addToPoHappened) return false;
-
- var liId = liTable.getSelected()[0].id();
- console.log("adding li " + liId + " to PO " + poId);
-
- // hmm, addToPo is invoked twice for some reason...
- _addToPoHappened = true;
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.add_lineitem'],
- { async : true,
- params : [openils.User.authtoken, poId, liId],
- oncomplete : function(r) {
- var resp = openils.Util.readResponse(r);
- if (resp.success) {
- location.href = oilsBasePath + '/acq/po/view/' + poId;
- } else {
- _addToPoHappened = false;
- if (resp.error == 'bad-po-state') {
- alert(localeStrings.ADD_LI_TO_PO_BAD_PO_STATE);
- } else if (resp.error == 'bad-li-state') {
- alert(localeStrings.ADD_LI_TO_PO_BAD_LI_STATE);
- }
- }
- }
- }
- );
-
- addToPoDialog.hide();
- return false; // prevent form submission
-}
-
-openils.Util.addOnLoad(load);
+require([
+ "openils/acq/Lineitem",
+ "openils/Util",
+ "openils/XUL",
+ "openils/CGI",
+ "openils/PermaCrud",
+ "openils/BibTemplate",
+ "fieldmapper/OrgUtils"
+ ],
+function(openils_acq_Lineitem,
+ openils_Util,
+ openils_XUL,
+ openils_CGI,
+ openils_PermaCrud,
+ openils_BibTemplate,
+ fieldmapper_OrgUtils){
+
+ dojo.requireLocalization('openils.acq', 'acq');
+ var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
+
+ var liTable;
+ var identTarget;
+ var bibRecord;
+ var paramPL;
+ var paramPO;
+
+ function fetchLi() {
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem.retrieve.authoritative"], {
+ "async": true,
+ "params": [openils.User.authtoken, targetId, {
+ "flesh_attrs": true,
+ "flesh_li_details": true,
+ "flesh_fund_debit": true,
+ "flesh_cancel_reason": true
+ }],
+ "oncomplete": function(r) {
+ var li = openils_Util.readResponse(r);
+ fetchBib(li.eg_bib_id());
+ }
+ }
+ );
+ }
+
+
+ function fetchRelated() {
+ var method = 'open-ils.acq.lineitems_for_bib.by_lineitem_id';
+ if(identTarget == 'bib')
+ var method = 'open-ils.acq.lineitems_for_bib.by_bib_id';
+
+ var total = 0;
+ fieldmapper.standardRequest(
+ ["open-ils.acq", method], {
+ "async": true,
+ "params": [openils.User.authtoken, targetId, {
+ "flesh_attrs": true,
+ "flesh_notes": true,
+ "flesh_cancel_reason": true
+ }],
+ "onresponse": function(r) {
+ var resp = openils_Util.readResponse(r);
+ if (resp) {
+ total++;
+ liTable.show("list");
+ liTable.addLineitem(resp);
+ }
+ }
+ }
+ );
+ }
+
+ function fetchBib(bibId) {
+ bibId = bibId || targetId;
+ new openils_BibTemplate({
+ record : bibId,
+ org_unit : fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()).shortname()
+ }).render();
+
+ new openils_PermaCrud().retrieve('bre', bibId, {
+ oncomplete : function(r) {
+ bibRecord = openils_Util.readResponse(r);
+ // render bib details
+ // perhaps we just pull these from the beating heart of bibtemplate
+ }
+ })
+ }
+
+ function createLi(oncomplete) {
+ return function() {
+ progressDialog.show();
+ liTable.reset();
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.biblio.create_by_id"], {
+ "params": [
+ openils.User.authtoken, [bibRecord.id()], {
+ "flesh_attrs": true,
+ "flesh_cancel_reason": true,
+ "flesh_notes": true
+ }
+ ],
+ "async": false,
+ "onresponse": function(r) {
+ var li = openils_Util.readResponse(r);
+ if (typeof(li) == "object") {
+ liTable.show("list");
+ liTable.addLineitem(li);
+ dojo.query(
+ "input[name='selectbox']", liTable._findLiRow(li)
+ )[0].checked = true;
+ }
+ },
+ "oncomplete": function() {
+ progressDialog.hide();
+ oncomplete();
+ }
+ }
+ );
+ };
+ }
+
+ function prepareButtons() {
+ addToPlButton.onClick = createLi(
+ function() { /* oncomplete */
+ acqLitSavePlDialog.show();
+ }
+ );
+ addToPoButton.onClick = createLi(
+ function() { /* oncomplete */
+ addToPoDialog.show();
+ }
+ );
+ createPoButton.onClick = createLi(
+ function() { /* oncomplete */
+ liTable._loadPOSelect();
+ acqLitPoCreateDialog.show();
+ }
+ );
+ }
+
+ function load() {
+ var cgi = new openils_CGI();
+
+ identTarget = cgi.param('target');
+ paramPL = cgi.param('pl');
+ // paramPO = cgi.param('po');
+
+ if (identTarget == 'bib') {
+ fetchBib();
+ } else {
+ fetchLi();
+ }
+
+ liTable = new AcqLiTable();
+ liTable.reset();
+ liTable._isRelatedViewer = true;
+
+ prepareButtons();
+ fetchRelated();
+ dojo.connect(addToPoSave, 'onClick', addToPo)
+ openils_Util.registerEnterHandler(addToPoInput.domNode, addToPo);
+ }
+
+ var _addToPoHappened = false;
+ function addToPo(args) {
+ var poId = addToPoInput.attr('value');
+ if (!poId) return false;
+ if (_addToPoHappened) return false;
+
+ var liId = liTable.getSelected()[0].id();
+ console.log("adding li " + liId + " to PO " + poId);
+
+ // hmm, addToPo is invoked twice for some reason...
+ _addToPoHappened = true;
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.add_lineitem'],
+ { async : true,
+ params : [openils.User.authtoken, poId, liId],
+ oncomplete : function(r) {
+ var resp = openils_Util.readResponse(r);
+ if (resp.success) {
+ location.href = oilsBasePath + '/acq/po/view/' + poId;
+ } else {
+ _addToPoHappened = false;
+ if (resp.error == 'bad-po-state') {
+ alert(localeStrings.ADD_LI_TO_PO_BAD_PO_STATE);
+ } else if (resp.error == 'bad-li-state') {
+ alert(localeStrings.ADD_LI_TO_PO_BAD_LI_STATE);
+ }
+ }
+ }
+ }
+ );
+
+ addToPoDialog.hide();
+ return false; // prevent form submission
+ }
+
+ openils_Util.addOnLoad(load);
+
+
+});
\ No newline at end of file
-dojo.require("dijit.form.Form");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.RadioButton");
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("dojo.data.ItemFileReadStore");
-dojo.require("openils.User");
-dojo.require("openils.Util");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.XUL");
-dojo.require("openils.widget.AutoFieldWidget");
+require([
+ "dijit/form/Form",
+ "dijit/form/Button",
+ "dijit/form/RadioButton",
+ "dijit/form/TextBox",
+ "dijit/form/FilteringSelect",
+ "dojo/data/ItemFileReadStore",
+ "openils/User",
+ "openils/Util",
+ "openils/PermaCrud",
+ "openils/XUL",
+ "openils/widget/AutoFieldWidget"
+ ],
+function(dijit_form_Form,
+ dijit_form_Button,
+ dijit_form_RadioButton,
+ dijit_form_TextBox,
+ dijit_form_FilteringSelect,
+ dojo_data_ItemFileReadStore,
+ openils_User,
+ openils_Util,
+ openils_PermaCrud,
+ openils_XUL,
+ openils_widget_AutoFieldWidget){
+
+ var combinedAttrValueArray = [];
+ var scalarAttrSearchManager;
+ var liTable;
+
+ function prepareStateStore(pcrud) {
+ stateSelector.store = new dojo_data_ItemFileReadStore({
+ "data": {
+ "label": "description",
+ "identifier": "code",
+ "items": [
+ /* XXX i18n; Also, this list shouldn't be hardcoded here. */
+ {"code": "new", "description": "New"},
+ {"code": "on-order", "description": "On Order"},
+ {"code": "pending-order", "description": "Pending Order"}
+ ]
+ }
+ });
+ }
+
+ function prepareScalarSearchStore(pcrud) {
+ }
+
+ function prepareArraySearchStore(pcrud) {
+ attrArrayDefSelector.store = new dojo_data_ItemFileReadStore({
+ "data": acqliad.toStoreData(
+ pcrud.search("acqliad", {"code": li_exportable_attrs})
+ )
+ });
+ }
+
+ function prepareAgencySelector() {
+ new openils_widget_AutoFieldWidget({
+ "fmClass": "acqpo",
+ "fmField": "ordering_agency",
+ "parentNode": dojo.byId("agency_selector"),
+ "orgLimitPerms": ["VIEW_PURCHASE_ORDER"],
+ "dijitArgs": {"name": "agency", "required": false}
+ }).build();
+ }
+
+ function toggleAttrSearchType(which, checked) {
+ /* This would be cooler with a slick dispatch table instead of branchy
+ * logic, but whatever... */
+ if (checked) {
+ if (which == "scalar") {
+ if (scalarAttrSearchManager.index < 1)
+ scalarAttrSearchManager.add();
+ openils_Util.show("oils-acq-li-search-attr-scalar", "inline-block");
+ openils_Util.hide("oils-acq-li-search-attr-array");
+ } else if (which == "array") {
+ openils_Util.hide("oils-acq-li-search-attr-scalar");
+ openils_Util.show("oils-acq-li-search-attr-array", "inline");
+ } else {
+ openils_Util.hide("oils-acq-li-search-attr-scalar");
+ openils_Util.hide("oils-acq-li-search-attr-array");
+ }
+ }
+ }
+
+ var buildAttrSearchClause = {
+ "array": function(v) {
+ if (!v.array_def) {
+ throw new Error(localeStrings.SELECT_AN_LI_ATTRIBUTE);
+ }
+ return {
+ "attr_value_pairs":
+ [[Number(v.array_def), combinedAttrValueArray]] /* [[sic]] */
+ };
+ },
+ "scalar": function(v) {
+ var r = scalarAttrSearchManager.buildSearchClause();
+ if (r.attr_value_pairs.length < 1) {
+ throw new Error(localeStrings.SELECT_AN_LI_ATTRIBUTE);
+ } else {
+ return r;
+ }
+ },
+ "none": function(v) {
+ return {};
+ }
+ };
+
+ function naivelyParse(data) {
+ return data.split(/[\n, ]/).filter(function(o) {return o.length > 0; });
+ }
+
+ function clearTerms() {
+ combinedAttrValueArray = [];
+ dojo.byId("records-up").innerHTML = 0;
+ }
+
+ function loadTermsFromFile() {
+ var rawdata;
+
+ try {
+ /* FIXME 128k is completely arbitrary; needs researched for
+ * a sane limit and should also be made configurable. */
+ rawdata = openils_XUL.contentFromFileOpenDialog(
+ localeStrings.LI_ATTR_SEARCH_CHOOSE_FILE, 1024 * 128
+ );
+ } catch (E) {
+ alert(E);
+ }
+
+ if (rawdata) {
+ try {
+ combinedAttrValueArray =
+ combinedAttrValueArray.concat(naivelyParse(rawdata));
+ dojo.byId("records-up").innerHTML = combinedAttrValueArray.length;
+ } catch (E) {
+ alert(E);
+ }
+ }
+ }
+
+ function buildSearchClause(values) {
+ var o = {};
+ if (values.state) o.li_states = [values.state];
+ if (values.agency) o.po_agencies = [Number(values.agency)];
+ return o;
+ }
+
+ function doSearch(values) {
+ var results_this_time = 0;
+ liTable.reset();
+ try {
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem.search.by_attributes"], {
+ "params": [
+ openils_User.authtoken,
+ dojo.mixin(
+ buildAttrSearchClause[values.attr_search_type](values),
+ buildSearchClause(values)
+ ),
+ {
+ "clear_marc": true, "flesh_attrs": true,
+ "flesh_notes": true
+ }
+ ],
+ "async": true,
+ "onresponse": function(r) {
+ var li = openils_Util.readResponse(r);
+ if (li) {
+ results_this_time++;
+ liTable.addLineitem(li);
+ liTable.show("list");
+ }
+ },
+ "oncomplete": function() {
+ if (results_this_time < 1) {
+ alert(localeStrings.NO_RESULTS);
+ }
+ }
+ }
+ );
+ } catch (E) {
+ alert(E); // XXX
+ }
+ }
+
+ function myScalarAttrSearchManager(template_id, pcrud) {
+ this.template = dojo.byId(template_id);
+ this.store = new dojo_data_ItemFileReadStore({
+ "data": acqliad.toStoreData(
+ pcrud.search("acqliad", {"id": {"!=": null}})
+ )
+ });
+ this.rows = {};
+ this.index = 0;
+ };
+ myScalarAttrSearchManager.prototype.remove = function(n) {
+ dojo.destroy("scalar_attr_holder_" + n);
+ delete this.rows[n];
+ };
+ myScalarAttrSearchManager.prototype.add = function() {
+ var self = this;
+ var n = this.index;
+ var clone = dojo.clone(this.template);
+ var def = dojo.query('input[name="def"]', clone)[0];
+ var value = dojo.query('input[name="value"]', clone)[0];
+ var a = dojo.query('a', clone)[0];
+
+ clone.id = "scalar_attr_holder_" + n;
+ a.onclick = function() { self.remove(n); };
+
+ this.rows[n] = [
+ new dijit_form_FilteringSelect({
+ "id": "scalar_def_" + n,
+ "name": "scalar_def_" + n,
+ "store": this.store,
+ "labelAttr": "description",
+ "searchAttr": "description"
+ }, def),
+ new dijit_form_TextBox({
+ "id": "scalar_value_" + n,
+ "name": "scalar_value_" + n
+ }, value)
+ ];
+
+ this.index++;
+
+ dojo.place(clone, "oils-acq-li-search-scalar-adder", "before");
+ openils_Util.show(clone);
+ };
+ myScalarAttrSearchManager.prototype.buildSearchClause = function() {
+ var list = [];
+ for (var k in this.rows) {
+ var def = this.rows[k][0].attr("value");
+ var val = this.rows[k][1].attr("value");
+ if (def != "" && val != "")
+ list.push([Number(def), val]);
+ }
+ return {"attr_value_pairs": list};
+ };
+ myScalarAttrSearchManager.prototype.simplifiedPairs = function() {
+ var result = {};
+ for (var k in this.rows) {
+ result[this.rows[k][0].attr("value")] = this.rows[k][1].attr("value");
+ }
+ return result;
+ };
+ myScalarAttrSearchManager.prototype.newBrief = function() {
+ location.href = oilsBasePath + "/acq/picklist/brief_record?prepop=" +
+ encodeURIComponent(js2JSON(this.simplifiedPairs()));
+ };
+
+
+ function load() {
+ var pcrud = new openils_PermaCrud();
+
+ prepareStateStore(pcrud);
+ prepareArraySearchStore(pcrud);
+
+ prepareAgencySelector();
+
+ liTable = new AcqLiTable();
+ scalarAttrSearchManager = new myScalarAttrSearchManager(
+ "oils-acq-li-search-scalar-template", pcrud
+ );
+
+ openils_Util.show("oils-acq-li-search-form-holder");
+ }
+
+ openils_Util.addOnLoad(load);
+
-var combinedAttrValueArray = [];
-var scalarAttrSearchManager;
-var liTable;
-
-function prepareStateStore(pcrud) {
- stateSelector.store = new dojo.data.ItemFileReadStore({
- "data": {
- "label": "description",
- "identifier": "code",
- "items": [
- /* XXX i18n; Also, this list shouldn't be hardcoded here. */
- {"code": "new", "description": "New"},
- {"code": "on-order", "description": "On Order"},
- {"code": "pending-order", "description": "Pending Order"}
- ]
- }
- });
-}
-
-function prepareScalarSearchStore(pcrud) {
-}
-
-function prepareArraySearchStore(pcrud) {
- attrArrayDefSelector.store = new dojo.data.ItemFileReadStore({
- "data": acqliad.toStoreData(
- pcrud.search("acqliad", {"code": li_exportable_attrs})
- )
- });
-}
-
-function prepareAgencySelector() {
- new openils.widget.AutoFieldWidget({
- "fmClass": "acqpo",
- "fmField": "ordering_agency",
- "parentNode": dojo.byId("agency_selector"),
- "orgLimitPerms": ["VIEW_PURCHASE_ORDER"],
- "dijitArgs": {"name": "agency", "required": false}
- }).build();
-}
-
-function toggleAttrSearchType(which, checked) {
- /* This would be cooler with a slick dispatch table instead of branchy
- * logic, but whatever... */
- if (checked) {
- if (which == "scalar") {
- if (scalarAttrSearchManager.index < 1)
- scalarAttrSearchManager.add();
- openils.Util.show("oils-acq-li-search-attr-scalar", "inline-block");
- openils.Util.hide("oils-acq-li-search-attr-array");
- } else if (which == "array") {
- openils.Util.hide("oils-acq-li-search-attr-scalar");
- openils.Util.show("oils-acq-li-search-attr-array", "inline");
- } else {
- openils.Util.hide("oils-acq-li-search-attr-scalar");
- openils.Util.hide("oils-acq-li-search-attr-array");
- }
- }
-}
-
-var buildAttrSearchClause = {
- "array": function(v) {
- if (!v.array_def) {
- throw new Error(localeStrings.SELECT_AN_LI_ATTRIBUTE);
- }
- return {
- "attr_value_pairs":
- [[Number(v.array_def), combinedAttrValueArray]] /* [[sic]] */
- };
- },
- "scalar": function(v) {
- var r = scalarAttrSearchManager.buildSearchClause();
- if (r.attr_value_pairs.length < 1) {
- throw new Error(localeStrings.SELECT_AN_LI_ATTRIBUTE);
- } else {
- return r;
- }
- },
- "none": function(v) {
- return {};
- }
-};
-
-function naivelyParse(data) {
- return data.split(/[\n, ]/).filter(function(o) {return o.length > 0; });
-}
-
-function clearTerms() {
- combinedAttrValueArray = [];
- dojo.byId("records-up").innerHTML = 0;
-}
-
-function loadTermsFromFile() {
- var rawdata;
-
- try {
- /* FIXME 128k is completely arbitrary; needs researched for
- * a sane limit and should also be made configurable. */
- rawdata = openils.XUL.contentFromFileOpenDialog(
- localeStrings.LI_ATTR_SEARCH_CHOOSE_FILE, 1024 * 128
- );
- } catch (E) {
- alert(E);
- }
-
- if (rawdata) {
- try {
- combinedAttrValueArray =
- combinedAttrValueArray.concat(naivelyParse(rawdata));
- dojo.byId("records-up").innerHTML = combinedAttrValueArray.length;
- } catch (E) {
- alert(E);
- }
- }
-}
-
-function buildSearchClause(values) {
- var o = {};
- if (values.state) o.li_states = [values.state];
- if (values.agency) o.po_agencies = [Number(values.agency)];
- return o;
-}
-
-function doSearch(values) {
- var results_this_time = 0;
- liTable.reset();
- try {
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem.search.by_attributes"], {
- "params": [
- openils.User.authtoken,
- dojo.mixin(
- buildAttrSearchClause[values.attr_search_type](values),
- buildSearchClause(values)
- ),
- {
- "clear_marc": true, "flesh_attrs": true,
- "flesh_notes": true
- }
- ],
- "async": true,
- "onresponse": function(r) {
- var li = openils.Util.readResponse(r);
- if (li) {
- results_this_time++;
- liTable.addLineitem(li);
- liTable.show("list");
- }
- },
- "oncomplete": function() {
- if (results_this_time < 1) {
- alert(localeStrings.NO_RESULTS);
- }
- }
- }
- );
- } catch (E) {
- alert(E); // XXX
- }
-}
-
-function myScalarAttrSearchManager(template_id, pcrud) {
- this.template = dojo.byId(template_id);
- this.store = new dojo.data.ItemFileReadStore({
- "data": acqliad.toStoreData(
- pcrud.search("acqliad", {"id": {"!=": null}})
- )
- });
- this.rows = {};
- this.index = 0;
-};
-myScalarAttrSearchManager.prototype.remove = function(n) {
- dojo.destroy("scalar_attr_holder_" + n);
- delete this.rows[n];
-};
-myScalarAttrSearchManager.prototype.add = function() {
- var self = this;
- var n = this.index;
- var clone = dojo.clone(this.template);
- var def = dojo.query('input[name="def"]', clone)[0];
- var value = dojo.query('input[name="value"]', clone)[0];
- var a = dojo.query('a', clone)[0];
-
- clone.id = "scalar_attr_holder_" + n;
- a.onclick = function() { self.remove(n); };
-
- this.rows[n] = [
- new dijit.form.FilteringSelect({
- "id": "scalar_def_" + n,
- "name": "scalar_def_" + n,
- "store": this.store,
- "labelAttr": "description",
- "searchAttr": "description"
- }, def),
- new dijit.form.TextBox({
- "id": "scalar_value_" + n,
- "name": "scalar_value_" + n
- }, value)
- ];
-
- this.index++;
-
- dojo.place(clone, "oils-acq-li-search-scalar-adder", "before");
- openils.Util.show(clone);
-};
-myScalarAttrSearchManager.prototype.buildSearchClause = function() {
- var list = [];
- for (var k in this.rows) {
- var def = this.rows[k][0].attr("value");
- var val = this.rows[k][1].attr("value");
- if (def != "" && val != "")
- list.push([Number(def), val]);
- }
- return {"attr_value_pairs": list};
-};
-myScalarAttrSearchManager.prototype.simplifiedPairs = function() {
- var result = {};
- for (var k in this.rows) {
- result[this.rows[k][0].attr("value")] = this.rows[k][1].attr("value");
- }
- return result;
-};
-myScalarAttrSearchManager.prototype.newBrief = function() {
- location.href = oilsBasePath + "/acq/picklist/brief_record?prepop=" +
- encodeURIComponent(js2JSON(this.simplifiedPairs()));
-};
-
-
-function load() {
- var pcrud = new openils.PermaCrud();
-
- prepareStateStore(pcrud);
- prepareArraySearchStore(pcrud);
-
- prepareAgencySelector();
-
- liTable = new AcqLiTable();
- scalarAttrSearchManager = new myScalarAttrSearchManager(
- "oils-acq-li-search-scalar-template", pcrud
- );
-
- openils.Util.show("oils-acq-li-search-form-holder");
-}
-
-openils.Util.addOnLoad(load);
+});
\ No newline at end of file
-dojo.require('dijit.form.Button');
-dojo.require('openils.widget.ProgressDialog');
-dojo.requireLocalization("openils.acq", "acq");
-var localeStrings = dojo.i18n.getLocalization("openils.acq", "acq");
+require([
+ "dijit/form/Button",
+ "openils/widget/ProgressDialog"
+ ],
+function(dijit_form_Button,
+ openils_widget_ProgressDialog){
+ dojo.requireLocalization("openils.acq", "acq");
+ var localeStrings = dojo.i18n.getLocalization("openils.acq", "acq");
+
+ function load() {
+ progressDialog.show(true);
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem.format"], {
+ "params": [openils.User.authtoken, liId, "html"],
+ "async": true,
+ "oncomplete": function(r) {
+ r = openils.Util.readResponse(r);
+ progressDialog.hide();
+ var d = dojo.byId("acq-worksheet-contents");
+ if (r.template_output())
+ d.innerHTML = r.template_output().data();
+ else if (r.error_output())
+ d.innerHTML = r.error_output().data();
+ else
+ d.innerHTML = localeStrings.LI_FORMAT_ERROR;
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(load);
+
-function load() {
- progressDialog.show(true);
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem.format"], {
- "params": [openils.User.authtoken, liId, "html"],
- "async": true,
- "oncomplete": function(r) {
- r = openils.Util.readResponse(r);
- progressDialog.hide();
- var d = dojo.byId("acq-worksheet-contents");
- if (r.template_output())
- d.innerHTML = r.template_output().data();
- else if (r.error_output())
- d.innerHTML = r.error_output().data();
- else
- d.innerHTML = localeStrings.LI_FORMAT_ERROR;
- }
- }
- );
-}
-
-openils.Util.addOnLoad(load);
+});
\ No newline at end of file
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.ProgressBar');
-dojo.require('dijit.Dialog');
-dojo.require('dojox.form.CheckedMultiSelect');
-dojo.require('fieldmapper.Fieldmapper');
-dojo.require('dijit.form.Form');
-dojo.require('dijit.form.TextBox');
-dojo.require('dijit.form.NumberSpinner');
-dojo.require('openils.Event');
-dojo.require('openils.acq.Picklist');
-dojo.require('openils.acq.Lineitem');
-dojo.require('openils.User');
-dojo.require('openils.Util');
-
-var searchFields = [];
-var resultPicklist;
-var resultLIs;
-var selectedLIs;
-var recvCount = 0;
-var sourceCount = 0; // how many sources are we searching
-var user = new openils.User();
-var searchLimit = 10;
-var liCache = {};
-var liTable;
-
-function drawForm() {
- liTable = new AcqLiTable();
- liTable.skipInitialEligibilityCheck = true;
-
- fieldmapper.standardRequest(
- ['open-ils.search', 'open-ils.search.z3950.retrieve_services'],
- { async: true,
- params: [user.authtoken],
- oncomplete: _drawForm
- }
- );
-}
-
-function _drawForm(r) {
-
- var sources = openils.Util.readResponse(r);
- if(!sources) return;
-
- for(var name in sources) {
- source = sources[name];
- if(name == 'native-evergreen-catalog') continue;
- bibSourceSelect.addOption({value:name, label:source.label});
- for(var attr in source.attrs)
- if(!attr.match(/^#/)) // xml comment nodes
- searchFields.push(source.attrs[attr]);
- }
-
- searchFields = searchFields.sort(
- function(a,b) {
- if(a.label < b.label)
- return -1;
- if(a.label > b.label)
- return 1;
- return 0;
- }
- );
-
- var tbody = dojo.byId('oils-acq-search-fields-tbody');
- var tmpl = tbody.removeChild(dojo.byId('oils-acq-search-fields-template'));
-
- for(var f in searchFields) {
- var field = searchFields[f];
- if(dijit.byId('text_input_'+field.name)) continue;
- var row = tmpl.cloneNode(true);
- tbody.insertBefore(row, dojo.byId('oils-acq-seach-fields-count-row'));
- var labelCell = dojo.query('[name=label]', row)[0];
- var inputCell = dojo.query('[name=input]', row)[0];
- labelCell.appendChild(document.createTextNode(field.label));
- input = new dijit.form.TextBox({name:field.name, label:field.label, id:'text_input_'+field.name});
- inputCell.appendChild(input.domNode);
- }
-}
-
-function clearSearchForm() {
- for(var f in searchFields) {
- var field = searchFields[f];
- dijit.byId('text_input_'+field.name).setValue('');
- }
-}
-
-var resultRow;
-function doSearch(values) {
- liTable.reset();
- showDiv('oils-acq-pl-loading');
-
- search = {
- service : [],
- username : [],
- password : [],
- search : {},
- limit : values.limit,
- offset : searchOffset
- };
- searchLimit = values.limit;
- delete values.limit;
-
- var selected = bibSourceSelect.getValue();
- for(var i = 0; i < selected.length; i++) {
- search.service.push(selected[i]);
- search.username.push('');
- search.password.push('');
- sourceCount++;
- }
-
- for(var v in values) {
- if(values[v]) {
- var input = dijit.byId('text_input_'+v);
- search.search[v] = values[v];
- }
- }
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.picklist.search.z3950'],
- { async: true,
- params: [user.authtoken, search, null, {respond_li:1, flesh_attrs:1, clear_marc:1}],
- onresponse: handleResult
- }
- );
-}
-
-
-function setRowAttr(td, liWrapper, field) {
- var val = liWrapper.findAttr(field, 'lineitem_marc_attr_definition') || '';
- td.appendChild(document.createTextNode(val));
-}
-
-function handleResult(r) {
- var result = openils.Util.readResponse(r);
- liTable.show('list');
- dojo.style(dojo.byId('oils-acq-pl-search-results'), 'display', 'block');
- var tbody = dojo.byId('plist-tbody');
- if(result.lineitem)
- liTable.addLineitem(result.lineitem);
- if(result.complete) // hide the loading image
- dojo.style('oils-acq-pl-loading','display', 'none');
-}
-
-function showDiv(div) {
- var divs = [
- 'oils-acq-search-block',
- 'oils-acq-pl-loading' ];
- dojo.forEach(divs, function(d) {dojo.style(d,'display', 'none')});
- liTable.hide();
- dojo.style(div, 'display', 'block');
-}
-
-
-openils.Util.addOnLoad(drawForm);
-
-
+require([
+ "dijit/form/FilteringSelect",
+ "dijit/ProgressBar",
+ "dijit/Dialog",
+ "dojox/form/CheckedMultiSelect",
+ "fieldmapper/Fieldmapper",
+ "dijit/form/Form",
+ "dijit/form/TextBox",
+ "dijit/form/NumberSpinner",
+ "openils/Event",
+ "openils/acq/Picklist",
+ "openils/acq/Lineitem",
+ "openils/User",
+ "openils/Util"
+ ],
+function(dijit_form_FilteringSelect,
+ dijit_ProgressBar,
+ dijit_Dialog,
+ dojox_form_CheckedMultiSelect,
+ fieldmapper_Fieldmapper,
+ dijit_form_Form,
+ dijit_form_TextBox,
+ dijit_form_NumberSpinner,
+ openils_Event,
+ openils_acq_Picklist,
+ openils_acq_Lineitem,
+ openils_User,
+ openils_Util){
+
+ var searchFields = [];
+ var resultPicklist;
+ var resultLIs;
+ var selectedLIs;
+ var recvCount = 0;
+ var sourceCount = 0; // how many sources are we searching
+ var user = new openils_User();
+ var searchLimit = 10;
+ var liCache = {};
+ var liTable;
+
+ function drawForm() {
+ liTable = new AcqLiTable();
+ liTable.skipInitialEligibilityCheck = true;
+
+ fieldmapper.standardRequest(
+ ['open-ils.search', 'open-ils.search.z3950.retrieve_services'],
+ { async: true,
+ params: [user.authtoken],
+ oncomplete: _drawForm
+ }
+ );
+ }
+
+ function _drawForm(r) {
+
+ var sources = openils_Util.readResponse(r);
+ if(!sources) return;
+
+ for(var name in sources) {
+ source = sources[name];
+ if(name == 'native-evergreen-catalog') continue;
+ bibSourceSelect.addOption({value:name, label:source.label});
+ for(var attr in source.attrs)
+ if(!attr.match(/^#/)) // xml comment nodes
+ searchFields.push(source.attrs[attr]);
+ }
+
+ searchFields = searchFields.sort(
+ function(a,b) {
+ if(a.label < b.label)
+ return -1;
+ if(a.label > b.label)
+ return 1;
+ return 0;
+ }
+ );
+
+ var tbody = dojo.byId('oils-acq-search-fields-tbody');
+ var tmpl = tbody.removeChild(dojo.byId('oils-acq-search-fields-template'));
+
+ for(var f in searchFields) {
+ var field = searchFields[f];
+ if(dijit.byId('text_input_'+field.name)) continue;
+ var row = tmpl.cloneNode(true);
+ tbody.insertBefore(row, dojo.byId('oils-acq-seach-fields-count-row'));
+ var labelCell = dojo.query('[name=label]', row)[0];
+ var inputCell = dojo.query('[name=input]', row)[0];
+ labelCell.appendChild(document.createTextNode(field.label));
+ input = new dijit_form_TextBox({name:field.name, label:field.label, id:'text_input_'+field.name});
+ inputCell.appendChild(input.domNode);
+ }
+ }
+
+ function clearSearchForm() {
+ for(var f in searchFields) {
+ var field = searchFields[f];
+ dijit.byId('text_input_'+field.name).setValue('');
+ }
+ }
+
+ var resultRow;
+ function doSearch(values) {
+ liTable.reset();
+ showDiv('oils-acq-pl-loading');
+
+ search = {
+ service : [],
+ username : [],
+ password : [],
+ search : {},
+ limit : values.limit,
+ offset : searchOffset
+ };
+ searchLimit = values.limit;
+ delete values.limit;
+
+ var selected = bibSourceSelect.getValue();
+ for(var i = 0; i < selected.length; i++) {
+ search.service.push(selected[i]);
+ search.username.push('');
+ search.password.push('');
+ sourceCount++;
+ }
+
+ for(var v in values) {
+ if(values[v]) {
+ var input = dijit.byId('text_input_'+v);
+ search.search[v] = values[v];
+ }
+ }
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.picklist.search.z3950'],
+ { async: true,
+ params: [user.authtoken, search, null, {respond_li:1, flesh_attrs:1, clear_marc:1}],
+ onresponse: handleResult
+ }
+ );
+ }
+
+
+ function setRowAttr(td, liWrapper, field) {
+ var val = liWrapper.findAttr(field, 'lineitem_marc_attr_definition') || '';
+ td.appendChild(document.createTextNode(val));
+ }
+
+ function handleResult(r) {
+ var result = openils_Util.readResponse(r);
+ liTable.show('list');
+ dojo.style(dojo.byId('oils-acq-pl-search-results'), 'display', 'block');
+ var tbody = dojo.byId('plist-tbody');
+ if(result.lineitem)
+ liTable.addLineitem(result.lineitem);
+ if(result.complete) // hide the loading image
+ dojo.style('oils-acq-pl-loading','display', 'none');
+ }
+
+ function showDiv(div) {
+ var divs = [
+ 'oils-acq-search-block',
+ 'oils-acq-pl-loading' ];
+ dojo.forEach(divs, function(d) {dojo.style(d,'display', 'none')});
+ liTable.hide();
+ dojo.style(div, 'display', 'block');
+ }
+
+
+ openils_Util.addOnLoad(drawForm);
+
+
+
+
+});
\ No newline at end of file
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require('dijit.form.Form');
-dojo.require('dijit.form.TextBox');
-dojo.require('dijit.form.DateTextBox');
-dojo.require('dijit.form.Button');
-dojo.require('dijit.form.ComboBox');
-dojo.require('openils.User');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.MarcXPathParser');
-dojo.require('openils.acq.Picklist');
-dojo.require('openils.CGI');
-
-var attrDefs = {};
-var paramPL = null;
-var paramPO = null;
-var paramUR = null; // User Request ID
-
-function drawBriefRecordForm(fields) {
-
- var tbody = dojo.byId('acq-brief-record-tbody');
- var rowTmpl = dojo.byId('acq-brief-record-row');
- var cgi = new openils.CGI();
- paramPL = cgi.param('pl');
- paramPO = cgi.param('po');
- paramUR = cgi.param('ur');
- prepop = JSON2js(cgi.param('prepop'));
-
-
- if(paramPL) {
- openils.Util.hide('acq-brief-record-po-row');
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.picklist.retrieve.authoritative'],
- { async: true,
- params: [openils.User.authtoken, paramPL],
- oncomplete : function(r) {
- var pl = openils.Util.readResponse(r);
- plSelector.store =
- new dojo.data.ItemFileReadStore({data:acqpl.toStoreData([pl])});
- plSelector.attr('value', pl.name());
- plSelector.attr('disabled', true);
- }
- }
- );
-
- } else {
-
- if(paramPO) {
- openils.Util.hide('acq-brief-record-pl-row');
- poNumber.attr('value', paramPO);
-
- } else {
- openils.Util.hide('acq-brief-record-po-row');
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.picklist.user.retrieve.atomic'],
- { async: true,
- params: [openils.User.authtoken],
- oncomplete : function(r) {
- var list = openils.Util.readResponse(r);
- plSelector.store =
- new dojo.data.ItemFileReadStore({data:acqpl.toStoreData(list)});
- }
- }
- );
- }
- }
-
-
- /*
- marcEditButton.onClick = function(fields) {
- saveBriefRecord(fields, true);
- }
- */
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem_attr_definition.retrieve.all'],
- { async : true,
- params : [openils.User.authtoken],
-
- oncomplete : function(r) {
- var attrs = openils.Util.readResponse(r);
- if(attrs && attrs.marc) {
-
- attrs = attrs.marc.sort(
- function(a, b) {
- if(a.description < b.description)
- return 1;
- return -1;
- }
- );
-
- var xpathParser = new openils.MarcXPathParser();
- dojo.forEach(attrs,
- function(def) {
- attrDefs[def.code()] = xpathParser.parse(def.xpath());
- var row = rowTmpl.cloneNode(true);
- dojo.query('[name=name]', row)[0].innerHTML = def.description();
- var textbox = new dijit.form.TextBox(
- {"name": def.code()},
- dojo.query('[name=widget]', row)[0]
- );
- if (prepop && prepop[def.id()])
- textbox.attr("value", prepop[def.id()]);
- tbody.appendChild(row);
- }
- );
- }
- }
- }
- );
-}
-
-function saveBriefRecord(fields, editMarc) {
-
- if(paramPL) {
- fields.picklist = paramPL;
- delete fields.po;
- compileBriefRecord(fields, editMarc);
- return false;
- }
-
- if(paramPO) {
- fields.po = paramPO;
- delete fields.picklist;
- compileBriefRecord(fields, editMarc);
- return false;
- }
-
- // first, deal with the selection list
- var picklist = plSelector.attr('value');
-
- if(!picklist) {
- compileBriefRecord(fields, editMarc);
- return false;
- }
-
- // ComboBox value is the display string. find the actual picklist
- // and create a new one if necessary
- plSelector.store.fetch({
- query : {name:picklist},
-
- onComplete : function(items) {
- if(items.length == 0) {
-
- // create a new picklist for these items
- openils.acq.Picklist.create(
- {name:picklist, org_unit: openils.User.user.ws_ou()},
- function(plId) {
- fields.picklist = plId;
- compileBriefRecord(fields, editMarc);
- }
- );
-
- } else {
- var id = plSelector.store.getValue(items[0], 'id');
- fields.picklist = id;
- compileBriefRecord(fields, editMarc);
- }
- }
- });
-
- return false;
-}
-
-function compileBriefRecord(fields, editMarc) {
-
- var baseString = '<record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
- 'xmlns="http://www.loc.gov/MARC21/slim" ' +
- 'xmlns:marc="http://www.loc.gov/MARC21/slim" ' +
- 'xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim.xsd">' +
- '<leader>00000nam a22000007a 4500</leader></record>';
-
- var doc = new DOMParser().parseFromString(baseString, 'text/xml');
-
- for(var f in fields) {
-
- var def = attrDefs[f];
- if(!def) continue;
- var value = fields[f];
- if(!value) continue;
-
- var dfNode = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'marc:datafield');
- var sfNode = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'marc:subfield');
-
- // creates tags and fields in the document. If there are more than one
- // option for the tag or code, use the first in the list
- dfNode.setAttribute('tag', ''+def.tags[0]);
- dfNode.setAttribute('ind1', ' ');
- dfNode.setAttribute('ind2', ' ');
- sfNode.setAttribute('code', ''+def.subfields[0]);
- tNode = doc.createTextNode(value);
-
- sfNode.appendChild(tNode);
- dfNode.appendChild(sfNode);
- doc.documentElement.appendChild(dfNode);
- }
-
-
- var xmlString = new XMLSerializer().serializeToString(doc);
-
- var li = new fieldmapper.jub();
- li.marc(xmlString);
- li.picklist(fields.picklist);
- if(fields.po) li.purchase_order(fields.po);
- li.selector(openils.User.user.id());
- li.creator(openils.User.user.id());
- li.editor(openils.User.user.id());
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.create'],
- { async : true,
- params : [openils.User.authtoken, li],
- oncomplete : function(r) {
- var id = openils.Util.readResponse(r);
- if(!id) return;
- if(editMarc) {
- // XXX load marc editor
- } else if (paramUR) {
- // update User Request with Lineitem and reload request interface
- var pcrud = new openils.PermaCrud({ authtoken : openils.User.authtoken });
- var aur_obj = pcrud.retrieve('aur',paramUR);
- aur_obj.lineitem( id );
- pcrud.update( aur_obj, {
- 'oncomplete' : function(r, cudResults) {
- // Goes back to the list view
- location.href = oilsBasePath + '/acq/picklist/user_request';
- }
- });
- } else {
- if(fields.picklist)
- location.href = oilsBasePath + '/acq/picklist/view/' + fields.picklist;
- else
- location.href = oilsBasePath + '/acq/po/view/' + fields.po;
- }
- }
- }
- );
-
- return false;
-}
-
-openils.Util.addOnLoad(drawBriefRecordForm);
+require([
+ "dojo/data/ItemFileReadStore",
+ "dijit/form/Form",
+ "dijit/form/TextBox",
+ "dijit/form/DateTextBox",
+ "dijit/form/Button",
+ "dijit/form/ComboBox",
+ "openils/User",
+ "openils/widget/AutoFieldWidget",
+ "openils/MarcXPathParser",
+ "openils/acq/Picklist",
+ "openils/CGI"
+ ],
+function(dojo_data_ItemFileReadStore,
+ dijit_form_Form,
+ dijit_form_TextBox,
+ dijit_form_DateTextBox,
+ dijit_form_Button,
+ dijit_form_ComboBox,
+ openils_User,
+ openils_widget_AutoFieldWidget,
+ openils_MarcXPathParser,
+ openils_acq_Picklist,
+ openils_CGI){
+
+ var attrDefs = {};
+ var paramPL = null;
+ var paramPO = null;
+ var paramUR = null; // User Request ID
+
+ function drawBriefRecordForm(fields) {
+
+ var tbody = dojo.byId('acq-brief-record-tbody');
+ var rowTmpl = dojo.byId('acq-brief-record-row');
+ var cgi = new openils_CGI();
+ paramPL = cgi.param('pl');
+ paramPO = cgi.param('po');
+ paramUR = cgi.param('ur');
+ prepop = JSON2js(cgi.param('prepop'));
+
+
+ if(paramPL) {
+ openils.Util.hide('acq-brief-record-po-row');
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.picklist.retrieve.authoritative'],
+ { async: true,
+ params: [openils_User.authtoken, paramPL],
+ oncomplete : function(r) {
+ var pl = openils.Util.readResponse(r);
+ plSelector.store =
+ new dojo_data_ItemFileReadStore({data:acqpl.toStoreData([pl])});
+ plSelector.attr('value', pl.name());
+ plSelector.attr('disabled', true);
+ }
+ }
+ );
+
+ } else {
+
+ if(paramPO) {
+ openils.Util.hide('acq-brief-record-pl-row');
+ poNumber.attr('value', paramPO);
+
+ } else {
+ openils.Util.hide('acq-brief-record-po-row');
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.picklist.user.retrieve.atomic'],
+ { async: true,
+ params: [openils_User.authtoken],
+ oncomplete : function(r) {
+ var list = openils.Util.readResponse(r);
+ plSelector.store =
+ new dojo_data_ItemFileReadStore({data:acqpl.toStoreData(list)});
+ }
+ }
+ );
+ }
+ }
+
+
+ /*
+ marcEditButton.onClick = function(fields) {
+ saveBriefRecord(fields, true);
+ }
+ */
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem_attr_definition.retrieve.all'],
+ { async : true,
+ params : [openils_User.authtoken],
+
+ oncomplete : function(r) {
+ var attrs = openils.Util.readResponse(r);
+ if(attrs && attrs.marc) {
+
+ attrs = attrs.marc.sort(
+ function(a, b) {
+ if(a.description < b.description)
+ return 1;
+ return -1;
+ }
+ );
+
+ var xpathParser = new openils_MarcXPathParser();
+ dojo.forEach(attrs,
+ function(def) {
+ attrDefs[def.code()] = xpathParser.parse(def.xpath());
+ var row = rowTmpl.cloneNode(true);
+ dojo.query('[name=name]', row)[0].innerHTML = def.description();
+ var textbox = new dijit_form_TextBox(
+ {"name": def.code()},
+ dojo.query('[name=widget]', row)[0]
+ );
+ if (prepop && prepop[def.id()])
+ textbox.attr("value", prepop[def.id()]);
+ tbody.appendChild(row);
+ }
+ );
+ }
+ }
+ }
+ );
+ }
+
+ function saveBriefRecord(fields, editMarc) {
+
+ if(paramPL) {
+ fields.picklist = paramPL;
+ delete fields.po;
+ compileBriefRecord(fields, editMarc);
+ return false;
+ }
+
+ if(paramPO) {
+ fields.po = paramPO;
+ delete fields.picklist;
+ compileBriefRecord(fields, editMarc);
+ return false;
+ }
+
+ // first, deal with the selection list
+ var picklist = plSelector.attr('value');
+
+ if(!picklist) {
+ compileBriefRecord(fields, editMarc);
+ return false;
+ }
+
+ // ComboBox value is the display string. find the actual picklist
+ // and create a new one if necessary
+ plSelector.store.fetch({
+ query : {name:picklist},
+
+ onComplete : function(items) {
+ if(items.length == 0) {
+
+ // create a new picklist for these items
+ openils_acq_Picklist.create(
+ {name:picklist, org_unit: openils_User.user.ws_ou()},
+ function(plId) {
+ fields.picklist = plId;
+ compileBriefRecord(fields, editMarc);
+ }
+ );
+
+ } else {
+ var id = plSelector.store.getValue(items[0], 'id');
+ fields.picklist = id;
+ compileBriefRecord(fields, editMarc);
+ }
+ }
+ });
+
+ return false;
+ }
+
+ function compileBriefRecord(fields, editMarc) {
+
+ var baseString = '<record xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
+ 'xmlns="http://www.loc.gov/MARC21/slim" ' +
+ 'xmlns:marc="http://www.loc.gov/MARC21/slim" ' +
+ 'xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/ standards/marcxml/schema/MARC21slim.xsd">' +
+ '<leader>00000nam a22000007a 4500</leader></record>';
+
+ var doc = new DOMParser().parseFromString(baseString, 'text/xml');
+
+ for(var f in fields) {
+
+ var def = attrDefs[f];
+ if(!def) continue;
+ var value = fields[f];
+ if(!value) continue;
+
+ var dfNode = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'marc:datafield');
+ var sfNode = doc.createElementNS('http://www.loc.gov/MARC21/slim', 'marc:subfield');
+
+ // creates tags and fields in the document. If there are more than one
+ // option for the tag or code, use the first in the list
+ dfNode.setAttribute('tag', ''+def.tags[0]);
+ dfNode.setAttribute('ind1', ' ');
+ dfNode.setAttribute('ind2', ' ');
+ sfNode.setAttribute('code', ''+def.subfields[0]);
+ tNode = doc.createTextNode(value);
+
+ sfNode.appendChild(tNode);
+ dfNode.appendChild(sfNode);
+ doc.documentElement.appendChild(dfNode);
+ }
+
+
+ var xmlString = new XMLSerializer().serializeToString(doc);
+
+ var li = new fieldmapper.jub();
+ li.marc(xmlString);
+ li.picklist(fields.picklist);
+ if(fields.po) li.purchase_order(fields.po);
+ li.selector(openils_User.user.id());
+ li.creator(openils_User.user.id());
+ li.editor(openils_User.user.id());
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem.create'],
+ { async : true,
+ params : [openils_User.authtoken, li],
+ oncomplete : function(r) {
+ var id = openils.Util.readResponse(r);
+ if(!id) return;
+ if(editMarc) {
+ // XXX load marc editor
+ } else if (paramUR) {
+ // update User Request with Lineitem and reload request interface
+ var pcrud = new openils.PermaCrud({ authtoken : openils_User.authtoken });
+ var aur_obj = pcrud.retrieve('aur',paramUR);
+ aur_obj.lineitem( id );
+ pcrud.update( aur_obj, {
+ 'oncomplete' : function(r, cudResults) {
+ // Goes back to the list view
+ location.href = oilsBasePath + '/acq/picklist/user_request';
+ }
+ });
+ } else {
+ if(fields.picklist)
+ location.href = oilsBasePath + '/acq/picklist/view/' + fields.picklist;
+ else
+ location.href = oilsBasePath + '/acq/po/view/' + fields.po;
+ }
+ }
+ }
+ );
+
+ return false;
+ }
+
+ openils.Util.addOnLoad(drawBriefRecordForm);
+
+
+});
\ No newline at end of file
-dojo.require("dijit.form.Button");
-dojo.require("openils.widget.XULTermLoader");
+require([
+ "dijit/form/Button",
+ "openils/widget/XULTermLoader"
+ ],
+function(dijit_form_Button,
+ openils_widget_XULTermLoader){
+
+ var termLoader = null;
+ var liTable = null;
+ var pager = null;
+ var usingPl = null;
+
+ function fetchRecords() {
+ var data = openils.Util.uniqueElements(termLoader.attr("value"));
+ var result_count = 0;
+ // Don't show a total for now... This total is the total number of
+ // search terms, but a user would take it to mean the total number of
+ // results, which we don't have a straightfoward way of getting without
+ // doing the search more that once.
+
+ // pager.total = data.length;
+
+ progressDialog.show(true);
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.biblio.create_by_id"], {
+ "params": [
+ openils.User.authtoken,
+ data.slice(
+ pager.displayOffset,
+ pager.displayOffset + pager.displayLimit
+ ), {
+ "flesh_attrs": true,
+ "flesh_cancel_reason": true,
+ "flesh_notes": true,
+ "reuse_picklist": usingPl
+ }
+ ],
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ if (typeof(r) != "object") {
+ usingPl = r;
+ } else if (r.classname && r.classname == "jub") {
+ result_count++;
+ liTable.addLineitem(r);
+ }
+ /* The ML method is buggy and sometimes responds with
+ * more objects that we don't want, hence the specific
+ * conditionals above that don't necesarily consume all
+ * responses. */
+ }
+ }
+ }
+ );
+ pager.batch_length = result_count;
+ progressDialog.hide();
+ }
+
+ function beginSearch() {
+ var data = termLoader.attr("value");
+ if (!data || !data.length) {
+ alert(localeStrings.LOAD_TERMS_FIRST);
+ return;
+ }
+
+ pager.go(0);
+ openils.Util.hide("acq-frombib-upload-box");
+ openils.Util.show("acq-frombib-reload-box");
+ }
+
+ function init() {
+ new openils_widget_XULTermLoader(
+ {"parentNode": "acq-frombib-upload", "parseCSV": true}
+ ).build(function(w) { termLoader = w; });
+ liTable = new AcqLiTable();
+ pager = new LiTablePager(fetchRecords, liTable);
+
+ openils.Util.show("acq-frombib-begin-holder");
+ }
+
+ openils.Util.addOnLoad(init);
+
-var termLoader = null;
-var liTable = null;
-var pager = null;
-var usingPl = null;
-
-function fetchRecords() {
- var data = openils.Util.uniqueElements(termLoader.attr("value"));
- var result_count = 0;
- // Don't show a total for now... This total is the total number of
- // search terms, but a user would take it to mean the total number of
- // results, which we don't have a straightfoward way of getting without
- // doing the search more that once.
-
- // pager.total = data.length;
-
- progressDialog.show(true);
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.biblio.create_by_id"], {
- "params": [
- openils.User.authtoken,
- data.slice(
- pager.displayOffset,
- pager.displayOffset + pager.displayLimit
- ), {
- "flesh_attrs": true,
- "flesh_cancel_reason": true,
- "flesh_notes": true,
- "reuse_picklist": usingPl
- }
- ],
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- if (typeof(r) != "object") {
- usingPl = r;
- } else if (r.classname && r.classname == "jub") {
- result_count++;
- liTable.addLineitem(r);
- }
- /* The ML method is buggy and sometimes responds with
- * more objects that we don't want, hence the specific
- * conditionals above that don't necesarily consume all
- * responses. */
- }
- }
- }
- );
- pager.batch_length = result_count;
- progressDialog.hide();
-}
-
-function beginSearch() {
- var data = termLoader.attr("value");
- if (!data || !data.length) {
- alert(localeStrings.LOAD_TERMS_FIRST);
- return;
- }
-
- pager.go(0);
- openils.Util.hide("acq-frombib-upload-box");
- openils.Util.show("acq-frombib-reload-box");
-}
-
-function init() {
- new openils.widget.XULTermLoader(
- {"parentNode": "acq-frombib-upload", "parseCSV": true}
- ).build(function(w) { termLoader = w; });
- liTable = new AcqLiTable();
- pager = new LiTablePager(fetchRecords, liTable);
-
- openils.Util.show("acq-frombib-begin-holder");
-}
-
-openils.Util.addOnLoad(init);
+});
\ No newline at end of file
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dijit.ProgressBar');
-dojo.require('dijit.form.CheckBox');
-dojo.require('dijit.form.TextBox');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.form.ComboBox');
-dojo.require('dijit.form.Button');
-dojo.require("dojo.io.iframe");
-dojo.require('openils.User');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.acq.Picklist');
-dojo.require('openils.XUL');
-dojo.require('openils.PermaCrud');
-
-var VANDELAY_URL = '/vandelay-upload';
-var providerWidget;
-var orderAgencyWidget;
-var vlAgent;
-var usingNewPl = false;
-
-function init() {
- dojo.byId('acq-pl-upload-ses').value = openils.User.authtoken;
-
- new openils.widget.AutoFieldWidget({
- fmClass : 'acqpo',
- fmField : 'provider',
- orgLimitPerms : ['CREATE_PICKLIST', 'CREATE_PURCHASE_ORDER'],
- parentNode : dojo.byId('acq-pl-upload-provider'),
- }).build(
- function(w) { providerWidget = w }
- );
-
- new openils.widget.AutoFieldWidget({
- fmClass : 'acqpo',
- fmField : 'ordering_agency',
- orgLimitPerms : ['CREATE_PICKLIST', 'CREATE_PURCHASE_ORDER'],
- parentNode : dojo.byId('acq-pl-upload-agency'),
- }).build(
- function(w) { orderAgencyWidget = w }
- );
-
- vlAgent = new VLAgent();
- vlAgent.init();
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.picklist.user.retrieve.atomic'],
- { async: true,
- params: [openils.User.authtoken],
- oncomplete : function(r) {
- var list = openils.Util.readResponse(r);
- acqPlUploadPlSelector.store =
- new dojo.data.ItemFileWriteStore({data:acqpl.toStoreData(list)});
- }
- }
- );
-}
-
-function acqUploadRecords() {
- openils.Util.show('acq-pl-upload-progress');
- var picklist = acqPlUploadPlSelector.attr('value');
- if(picklist) {
- // ComboBox value is the display string. find the actual picklist
- // and create a new one if necessary
- acqPlUploadPlSelector.store.fetch({
- query : {name:picklist},
- onComplete : function(items) {
- if(items.length == 0) {
- // create a new picklist for these items
- usingNewPl = true;
- openils.acq.Picklist.create(
- {name:picklist, org_unit: orderAgencyWidget.attr('value')},
- function(plId) { acqSendUploadForm({picklist:plId}) }
- );
- } else {
- usingNewPl = false;
- acqSendUploadForm({picklist:items[0].id[0]});
- }
- }
- });
- } else {
- acqSendUploadForm({picklist:null});
- }
-}
-
-function acqSendUploadForm(args) {
- dojo.io.iframe.send({
- url: VANDELAY_URL,
- method: "post",
- handleAs: "html",
- form: dojo.byId('acq-pl-upload-form'),
- handle: function(data, ioArgs){
- acqHandlePostUpload(data.documentElement.textContent, args.picklist);
- }
- });
-}
-
-
-function acqHandlePostUpload(key, plId) {
-
- var args = {
- picklist : plId,
- provider : providerWidget.attr('value'),
- ordering_agency : orderAgencyWidget.attr('value'),
- create_po : acqPlUploadCreatePo.attr('value'),
- activate_po : acqPlUploadActivatePo.attr('value'),
- vandelay : vlAgent.values()
- };
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.process_upload_records'],
- { async: true,
- params: [openils.User.authtoken, key, args],
- onresponse : function(r) {
-
- vlAgent.handleResponse(
- openils.Util.readResponse(r),
- function(resp, res) {
-
- openils.Util.hide('acq-pl-upload-complete-pl');
- openils.Util.hide('acq-pl-upload-complete-po');
- openils.Util.hide('acq-pl-upload-complete-q');
- openils.Util.hide('acq-pl-upload-progress-bar');
- openils.Util.show('acq-pl-upload-complete');
-
- function activateLink(link, url, name) {
- link = dojo.byId(link);
- openils.Util.show(link);
- if (name) link.innerHTML = name;
- if (typeof xulG == 'undefined') { // browser
- link.setAttribute('href', url);
- } else {
- link.setAttribute('href', 'javascript:;'); // for linky-ness
- link.onclick = function() { openils.XUL.newTabEasy(url, null, null, true) };
- }
- }
-
- if(res.picklist_url) {
- activateLink('acq-pl-upload-complete-pl', res.picklist_url);
-
- // if the user entered a new picklist, refetch the set to pick
- // up the ID and redraw the list with the new one selected
- if (usingNewPl) {
- var newPl = new openils.PermaCrud().retrieve('acqpl', resp.picklist.id());
- acqPlUploadPlSelector.store.newItem(newPl.toStoreItem());
- acqPlUploadPlSelector.attr('value', newPl.name());
- }
- }
-
- if(res.po_url) {
- activateLink('acq-pl-upload-complete-po', res.po_url);
- }
-
- if (res.queue_url) {
- activateLink('acq-pl-upload-complete-q', res.queue_url);
- }
- }
- );
- },
- }
- );
-}
-
-
-openils.Util.addOnLoad(init);
-
+require([
+ "dojo/data/ItemFileReadStore",
+ "dojo/data/ItemFileWriteStore",
+ "dijit/ProgressBar",
+ "dijit/form/CheckBox",
+ "dijit/form/TextBox",
+ "dijit/form/FilteringSelect",
+ "dijit/form/ComboBox",
+ "dijit/form/Button",
+ "dojo/io/iframe",
+ "openils/User",
+ "openils/widget/AutoFieldWidget",
+ "openils/acq/Picklist",
+ "openils/XUL",
+ "openils/PermaCrud"
+ ],
+function(dojo_data_ItemFileReadStore,
+ dojo_data_ItemFileWriteStore,
+ dijit_ProgressBar,
+ dijit_form_CheckBox,
+ dijit_form_TextBox,
+ dijit_form_FilteringSelect,
+ dijit_form_ComboBox,
+ dijit_form_Button,
+ dojo_io_iframe,
+ openils_User,
+ openils_widget_AutoFieldWidget,
+ openils_acq_Picklist,
+ openils_XUL,
+ openils_PermaCrud){
+
+ var VANDELAY_URL = '/vandelay-upload';
+ var providerWidget;
+ var orderAgencyWidget;
+ var vlAgent;
+ var usingNewPl = false;
+
+ function init() {
+ dojo.byId('acq-pl-upload-ses').value = openils_User.authtoken;
+
+ new openils_widget_AutoFieldWidget({
+ fmClass : 'acqpo',
+ fmField : 'provider',
+ orgLimitPerms : ['CREATE_PICKLIST', 'CREATE_PURCHASE_ORDER'],
+ parentNode : dojo.byId('acq-pl-upload-provider'),
+ }).build(
+ function(w) { providerWidget = w }
+ );
+
+ new openils_widget_AutoFieldWidget({
+ fmClass : 'acqpo',
+ fmField : 'ordering_agency',
+ orgLimitPerms : ['CREATE_PICKLIST', 'CREATE_PURCHASE_ORDER'],
+ parentNode : dojo.byId('acq-pl-upload-agency'),
+ }).build(
+ function(w) { orderAgencyWidget = w }
+ );
+
+ vlAgent = new VLAgent();
+ vlAgent.init();
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.picklist.user.retrieve.atomic'],
+ { async: true,
+ params: [openils_User.authtoken],
+ oncomplete : function(r) {
+ var list = openils.Util.readResponse(r);
+ acqPlUploadPlSelector.store =
+ new dojo_data_ItemFileWriteStore({data:acqpl.toStoreData(list)});
+ }
+ }
+ );
+ }
+
+ function acqUploadRecords() {
+ openils.Util.show('acq-pl-upload-progress');
+ var picklist = acqPlUploadPlSelector.attr('value');
+ if(picklist) {
+ // ComboBox value is the display string. find the actual picklist
+ // and create a new one if necessary
+ acqPlUploadPlSelector.store.fetch({
+ query : {name:picklist},
+ onComplete : function(items) {
+ if(items.length == 0) {
+ // create a new picklist for these items
+ usingNewPl = true;
+ openils_acq_Picklist.create(
+ {name:picklist, org_unit: orderAgencyWidget.attr('value')},
+ function(plId) { acqSendUploadForm({picklist:plId}) }
+ );
+ } else {
+ usingNewPl = false;
+ acqSendUploadForm({picklist:items[0].id[0]});
+ }
+ }
+ });
+ } else {
+ acqSendUploadForm({picklist:null});
+ }
+ }
+
+ function acqSendUploadForm(args) {
+ dojo_io_iframe.send({
+ url: VANDELAY_URL,
+ method: "post",
+ handleAs: "html",
+ form: dojo.byId('acq-pl-upload-form'),
+ handle: function(data, ioArgs){
+ acqHandlePostUpload(data.documentElement.textContent, args.picklist);
+ }
+ });
+ }
+
+
+ function acqHandlePostUpload(key, plId) {
+
+ var args = {
+ picklist : plId,
+ provider : providerWidget.attr('value'),
+ ordering_agency : orderAgencyWidget.attr('value'),
+ create_po : acqPlUploadCreatePo.attr('value'),
+ activate_po : acqPlUploadActivatePo.attr('value'),
+ vandelay : vlAgent.values()
+ };
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.process_upload_records'],
+ { async: true,
+ params: [openils_User.authtoken, key, args],
+ onresponse : function(r) {
+
+ vlAgent.handleResponse(
+ openils.Util.readResponse(r),
+ function(resp, res) {
+
+ openils.Util.hide('acq-pl-upload-complete-pl');
+ openils.Util.hide('acq-pl-upload-complete-po');
+ openils.Util.hide('acq-pl-upload-complete-q');
+ openils.Util.hide('acq-pl-upload-progress-bar');
+ openils.Util.show('acq-pl-upload-complete');
+
+ function activateLink(link, url, name) {
+ link = dojo.byId(link);
+ openils.Util.show(link);
+ if (name) link.innerHTML = name;
+ if (typeof xulG == 'undefined') { // browser
+ link.setAttribute('href', url);
+ } else {
+ link.setAttribute('href', 'javascript:;'); // for linky-ness
+ link.onclick = function() { openils_XUL.newTabEasy(url, null, null, true) };
+ }
+ }
+
+ if(res.picklist_url) {
+ activateLink('acq-pl-upload-complete-pl', res.picklist_url);
+
+ // if the user entered a new picklist, refetch the set to pick
+ // up the ID and redraw the list with the new one selected
+ if (usingNewPl) {
+ var newPl = new openils_PermaCrud().retrieve('acqpl', resp.picklist.id());
+ acqPlUploadPlSelector.store.newItem(newPl.toStoreItem());
+ acqPlUploadPlSelector.attr('value', newPl.name());
+ }
+ }
+
+ if(res.po_url) {
+ activateLink('acq-pl-upload-complete-po', res.po_url);
+ }
+
+ if (res.queue_url) {
+ activateLink('acq-pl-upload-complete-q', res.queue_url);
+ }
+ }
+ );
+ },
+ }
+ );
+ }
+
+
+ openils.Util.addOnLoad(init);
+
+
+
+});
\ No newline at end of file
-dojo.require('openils.CGI');
-dojo.require('openils.Util');
-dojo.require('openils.User');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('openils.widget.EditPane');
-dojo.require("dijit.layout.StackContainer");
-dojo.require('openils.PermaCrud');
-dojo.requireLocalization("openils.acq", "acq");
-dojo.require('openils.acq.Lineitem');
-
-var contextOrg;
-var contextUsr;
-var contextUsrObj;
-var contextLI;
-var contextEg_bib;
-var aur_obj;
-var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
-var cgi = new openils.CGI();
-
-function setup() {
-
- changeBib(cgi.param('eg_bib'));
- changeLI(cgi.param('lineitem'));
-
- if (cgi.param('usr')) {
- var usr_obj = fieldmapper.standardRequest(
- [
- 'open-ils.actor',
- 'open-ils.actor.user.fleshed.retrieve.authoritative'
- ],
- {
- params: [openils.User.authtoken, cgi.param('usr')]
- }
- );
- if (typeof usr_obj.textcode == 'undefined') {
- contextUsrObj = usr_obj;
- changeUser(usr_obj.id(),usr_obj.card().barcode());
- } else {
- alert(usr_obj.textcode + ' : ' + usr_obj.desc);
- }
- }
-
- if(reqId) {
- drawRequest();
- } else {
- drawList();
- }
-}
-
-function drawRequest() {
- var pcrud = new openils.PermaCrud({ authtoken : openils.User.authtoken });
- aur_obj = pcrud.retrieve('aur',reqId);
-
- // hide the grid and the context selector
- dijit.byId('stackContainer').forward();
-
- // purge any previous lineitem display
- // FIXME: I thought it would be cool to have this, but I can't get it
- // to look right with our dojo div/contentPanes. So just testing for
- // a DOM hook for now.
- if (dojo.byId('lineitem')) {
- //openils.Util.hide( 'lineitem_container' );
- dojo.byId('lineitem').innerHTML = '';
- }
-
- // toggle the View Picklist/Add to Picklist button label
- if (aur_obj.lineitem()) {
- openils.Util.hide( 'add_to_picklist' );
- openils.Util.show( 'view_picklist' );
- } else {
- openils.Util.hide( 'view_picklist' );
- openils.Util.show( 'add_to_picklist' );
- }
-
- // draw a detail page for a particular request
- var div = document.getElementById('detail_content_pane');
- while (div.lastChild) { div.removeChild( div.lastChild ); }
- var pane = new openils.widget.EditPane({
- fmObject : aur_obj,
- readOnly : true
- });
- pane.domNode = div;
- pane.hideActionButtons = true;
- pane.startup();
-
- // lineitem summary
- if (dojo.byId('lineitem') && aur_obj.lineitem()) {
- //openils.Util.show( 'lineitem_container' );
- openils.acq.Lineitem.fetchAndRender(aur_obj.lineitem(), {},
- function(li, html) {
- dojo.byId('lineitem').innerHTML = html;
- }
- );
- }
-
- // including ability to add request to a picklist
- // and to "reject" it (aka apply a cancel reason)
-
- dojo.byId("acq-ur-cancel-reason").innerHTML = '';
- var widget = new openils.widget.AutoFieldWidget({
- "fmField": "cancel_reason",
- "fmClass": "aur",
- "parentNode": dojo.byId("acq-ur-cancel-reason"),
- "orgLimitPerms": ["CREATE_PURCHASE_REQUEST"],
- "forceSync": true
- });
-
- widget.build(
- function(w, ww) {
- acqUrCancelReasonSubmit.onClick = function() {
- if (w.attr("value")) {
- if (confirm( localeStrings.UR_CANCEL_CONFIRM )) {
- fieldmapper.standardRequest(
- [ 'open-ils.acq', 'open-ils.acq.user_request.cancel.batch' ],
- { async: true,
- params: [openils.User.authtoken, [reqId], w.attr("value")],
- oncomplete: function(r) {
- location.href = location.href; // kludge to reload the interface
- }
- }
- );
- }
- }
- };
- }
- );
-}
-
-function fooPicklist() {
- if (aur_obj.lineitem()) {
- viewPicklist();
- } else {
- addToPicklist();
- }
-}
-
-function viewPicklist() {
- var lineitem = fieldmapper.standardRequest(
- [ 'open-ils.acq', 'open-ils.acq.lineitem.retrieve.authoritative' ],
- {
- params: [openils.User.authtoken, aur_obj.lineitem()]
- }
- );
- location.href = oilsBasePath + "/acq/picklist/view/" + lineitem.picklist();
-}
-
-function addToPicklist() {
- // reqId, from detail view
- location.href = oilsBasePath + "/acq/picklist/brief_record?ur=" + reqId + "&prepop=" + encodeURIComponent(js2JSON({
- "1": aur_obj.title() || aur_obj.article_title() || aur_obj.volume(),
- "2": aur_obj.author(),
- "5": aur_obj.isxn(),
- "9": aur_obj.publisher(),
- "10": aur_obj.pubdate()
- }));
-}
-
-function setNoHold() {
- // reqId, from detail view
- fieldmapper.standardRequest(
- [ 'open-ils.acq', 'open-ils.acq.user_request.set_no_hold.batch' ],
- { async: true,
- params: [openils.User.authtoken, [reqId]],
- oncomplete: function(r) {
- location.href = location.href; // kludge to reload the interface
- }
- }
- );
-}
-
-// format the title data as id:title
-function getTitle(idx, item) {
- if(item) {
- return this.grid.store.getValue(item, 'id') + ':' +
- this.grid.store.getValue(item, 'title');
- }
- return '';
-}
-
-// turn id:title into a url
-function formatTitle(value) {
- if(value) {
- var parts = value.split(/:/);
- return '<a href="' + oilsBasePath +
- '/acq/picklist/user_request/' + parts[0] + '">' + parts[1] + '</a>';
- }
-}
-
-function drawList() {
- buildGrid();
-
- var connect = function() {
- dojo.connect(contextOrgSelector, 'onChange',
- function() {
- contextOrg = this.attr('value');
- rGrid.resetStore();
- buildGrid();
- }
- );
- };
-
- new openils.User().buildPermOrgSelector(
- 'CREATE_PICKLIST', contextOrgSelector, null, connect);
-}
-
-function buildGrid() {
-
- if(contextOrg == null)
- contextOrg = openils.User.user.ws_ou();
-
- var query = {
- cancel_reason : null,
- '+au' : {
- home_ou : fieldmapper.aou.descendantNodeList(contextOrg).map(
- function(item) { return item.id(); })
- }
- };
-
- if (contextUsr) {
- delete query['+au']['home_ou'];
- query['+au']['id'] = contextUsr;
- }
-
- if (contextEg_bib) {
- query['eg_bib'] = contextEg_bib;
- }
-
- if (contextLI) {
- query['lineitem'] = contextLI;
- }
-
- rGrid.resetStore();
- rGrid.loadAll(
- { order_by : {aur : 'request_date'},
- join : 'au'
- },
- query
- );
-}
-
-function changeBib(value) {
- contextEg_bib = value;
- rGrid.overrideEditWidgets.eg_bib = new dijit.form.TextBox({"disabled": true});
- rGrid.overrideEditWidgets.eg_bib.shove = { create : contextEg_bib };
-}
-
-function changeLI(value,display_value) {
- contextLI = value;
- contextLITextbox.setValue( contextLI );
- contextLITextbox.setDisplayedValue( display_value || contextLI );
- rGrid.overrideEditWidgets.lineitem = new dijit.form.TextBox({"disabled": true});
- rGrid.overrideEditWidgets.lineitem.shove = { create : contextLI };
-}
-
-function changeLIPrompt() {
- var lineitem = window.prompt(localeStrings.UR_FILTER_LINEITEM);
- if(lineitem != '' && (lineitem == null || Number(lineitem) == NaN)) {
- return;
- }
- changeLI(lineitem);
- buildGrid();
-}
-
-function changeUser(value,display_value) {
- contextUsr = value;
- contextUsrTextbox.setValue( contextUsr );
- contextUsrTextbox.setDisplayedValue( display_value || contextUsr );
- rGrid.overrideEditWidgets.usr = new dijit.form.TextBox({"disabled": true});
- rGrid.overrideEditWidgets.usr.shove = { create : contextUsr };
-}
-
-function changeUserPrompt() {
- var barcode = window.prompt(localeStrings.UR_FILTER_USER);
- if(barcode == null) {
- return;
- }
- if(typeof xulG != 'undefined' && xulG.get_barcode) {
- // We have a "complete the barcode" function, call it (actor = users only)
- var new_barcode = xulG.get_barcode(window, 'actor', barcode);
- // If we got a result (boolean false is "no result") check it
- if(new_barcode) {
- // user_false string means they picked "None of the above"
- // Abort before any other events can fire
- if(new_barcode == "user_false") return;
- // No error means we have a (hopefully valid) completed barcode to use.
- // Otherwise, fall through to other methods of checking
- if(typeof new_barcode.ilsevent == 'undefined')
- barcode = new_barcode.barcode;
- }
- }
- if (barcode == '') {
- contextUsrObj = null;
- changeUser('','');
- } else {
- var usr_obj = fieldmapper.standardRequest(
- [
- 'open-ils.actor',
- 'open-ils.actor.user.fleshed.retrieve_by_barcode.authoritative'
- ],
- {
- params: [openils.User.authtoken, barcode]
- }
- );
- if (typeof usr_obj.textcode != 'undefined') {
- alert(usr_obj.textcode + ' : ' + usr_obj.desc);
- return;
- } else {
- contextUsrObj = usr_obj;
- changeUser(usr_obj.id(),usr_obj.card().barcode());
- }
- }
- buildGrid();
-}
-
-function createRequest() {
- if (!contextUsr) {
- changeUserPrompt();
- }
- if (contextUsr) {
- rGrid.overrideEditWidgets.pickup_lib = new dijit.form.TextBox({"disabled": true});
- rGrid.overrideEditWidgets.pickup_lib.shove = { create : contextUsrObj.home_ou() };
- rGrid.showCreateDialog();
- }
-}
-
-openils.Util.addOnLoad(setup);
-
-
+require([
+ "openils/CGI",
+ "openils/Util",
+ "openils/User",
+ "openils/widget/AutoGrid",
+ "fieldmapper/OrgUtils",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/widget/EditPane",
+ "dijit/layout/StackContainer",
+ "openils/PermaCrud",
+ "openils/acq/Lineitem"
+ ],
+function(openils_CGI,
+ openils_Util,
+ openils_User,
+ openils_widget_AutoGrid,
+ fieldmapper_OrgUtils,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_widget_EditPane,
+ dijit_layout_StackContainer,
+ openils_PermaCrud,
+ openils_acq_Lineitem){
+ dojo.requireLocalization("openils.acq", "acq");
+
+ var contextOrg;
+ var contextUsr;
+ var contextUsrObj;
+ var contextLI;
+ var contextEg_bib;
+ var aur_obj;
+ var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
+ var cgi = new openils_CGI();
+
+ function setup() {
+
+ changeBib(cgi.param('eg_bib'));
+ changeLI(cgi.param('lineitem'));
+
+ if (cgi.param('usr')) {
+ var usr_obj = fieldmapper.standardRequest(
+ [
+ 'open-ils.actor',
+ 'open-ils.actor.user.fleshed.retrieve.authoritative'
+ ],
+ {
+ params: [openils_User.authtoken, cgi.param('usr')]
+ }
+ );
+ if (typeof usr_obj.textcode == 'undefined') {
+ contextUsrObj = usr_obj;
+ changeUser(usr_obj.id(),usr_obj.card().barcode());
+ } else {
+ alert(usr_obj.textcode + ' : ' + usr_obj.desc);
+ }
+ }
+
+ if(reqId) {
+ drawRequest();
+ } else {
+ drawList();
+ }
+ }
+
+ function drawRequest() {
+ var pcrud = new openils_PermaCrud({ authtoken : openils_User.authtoken });
+ aur_obj = pcrud.retrieve('aur',reqId);
+
+ // hide the grid and the context selector
+ dijit.byId('stackContainer').forward();
+
+ // purge any previous lineitem display
+ // FIXME: I thought it would be cool to have this, but I can't get it
+ // to look right with our dojo div/contentPanes. So just testing for
+ // a DOM hook for now.
+ if (dojo.byId('lineitem')) {
+ //openils_Util.hide( 'lineitem_container' );
+ dojo.byId('lineitem').innerHTML = '';
+ }
+
+ // toggle the View Picklist/Add to Picklist button label
+ if (aur_obj.lineitem()) {
+ openils_Util.hide( 'add_to_picklist' );
+ openils_Util.show( 'view_picklist' );
+ } else {
+ openils_Util.hide( 'view_picklist' );
+ openils_Util.show( 'add_to_picklist' );
+ }
+
+ // draw a detail page for a particular request
+ var div = document.getElementById('detail_content_pane');
+ while (div.lastChild) { div.removeChild( div.lastChild ); }
+ var pane = new openils_widget_EditPane({
+ fmObject : aur_obj,
+ readOnly : true
+ });
+ pane.domNode = div;
+ pane.hideActionButtons = true;
+ pane.startup();
+
+ // lineitem summary
+ if (dojo.byId('lineitem') && aur_obj.lineitem()) {
+ //openils_Util.show( 'lineitem_container' );
+ openils_acq_Lineitem.fetchAndRender(aur_obj.lineitem(), {},
+ function(li, html) {
+ dojo.byId('lineitem').innerHTML = html;
+ }
+ );
+ }
+
+ // including ability to add request to a picklist
+ // and to "reject" it (aka apply a cancel reason)
+
+ dojo.byId("acq-ur-cancel-reason").innerHTML = '';
+ var widget = new openils.widget.AutoFieldWidget({
+ "fmField": "cancel_reason",
+ "fmClass": "aur",
+ "parentNode": dojo.byId("acq-ur-cancel-reason"),
+ "orgLimitPerms": ["CREATE_PURCHASE_REQUEST"],
+ "forceSync": true
+ });
+
+ widget.build(
+ function(w, ww) {
+ acqUrCancelReasonSubmit.onClick = function() {
+ if (w.attr("value")) {
+ if (confirm( localeStrings.UR_CANCEL_CONFIRM )) {
+ fieldmapper.standardRequest(
+ [ 'open-ils.acq', 'open-ils.acq.user_request.cancel.batch' ],
+ { async: true,
+ params: [openils_User.authtoken, [reqId], w.attr("value")],
+ oncomplete: function(r) {
+ location.href = location.href; // kludge to reload the interface
+ }
+ }
+ );
+ }
+ }
+ };
+ }
+ );
+ }
+
+ function fooPicklist() {
+ if (aur_obj.lineitem()) {
+ viewPicklist();
+ } else {
+ addToPicklist();
+ }
+ }
+
+ function viewPicklist() {
+ var lineitem = fieldmapper.standardRequest(
+ [ 'open-ils.acq', 'open-ils.acq.lineitem.retrieve.authoritative' ],
+ {
+ params: [openils_User.authtoken, aur_obj.lineitem()]
+ }
+ );
+ location.href = oilsBasePath + "/acq/picklist/view/" + lineitem.picklist();
+ }
+
+ function addToPicklist() {
+ // reqId, from detail view
+ location.href = oilsBasePath + "/acq/picklist/brief_record?ur=" + reqId + "&prepop=" + encodeURIComponent(js2JSON({
+ "1": aur_obj.title() || aur_obj.article_title() || aur_obj.volume(),
+ "2": aur_obj.author(),
+ "5": aur_obj.isxn(),
+ "9": aur_obj.publisher(),
+ "10": aur_obj.pubdate()
+ }));
+ }
+
+ function setNoHold() {
+ // reqId, from detail view
+ fieldmapper.standardRequest(
+ [ 'open-ils.acq', 'open-ils.acq.user_request.set_no_hold.batch' ],
+ { async: true,
+ params: [openils_User.authtoken, [reqId]],
+ oncomplete: function(r) {
+ location.href = location.href; // kludge to reload the interface
+ }
+ }
+ );
+ }
+
+ // format the title data as id:title
+ function getTitle(idx, item) {
+ if(item) {
+ return this.grid.store.getValue(item, 'id') + ':' +
+ this.grid.store.getValue(item, 'title');
+ }
+ return '';
+ }
+
+ // turn id:title into a url
+ function formatTitle(value) {
+ if(value) {
+ var parts = value.split(/:/);
+ return '<a href="' + oilsBasePath +
+ '/acq/picklist/user_request/' + parts[0] + '">' + parts[1] + '</a>';
+ }
+ }
+
+ function drawList() {
+ buildGrid();
+
+ var connect = function() {
+ dojo.connect(contextOrgSelector, 'onChange',
+ function() {
+ contextOrg = this.attr('value');
+ rGrid.resetStore();
+ buildGrid();
+ }
+ );
+ };
+
+ new openils_User().buildPermOrgSelector(
+ 'CREATE_PICKLIST', contextOrgSelector, null, connect);
+ }
+
+ function buildGrid() {
+
+ if(contextOrg == null)
+ contextOrg = openils_User.user.ws_ou();
+
+ var query = {
+ cancel_reason : null,
+ '+au' : {
+ home_ou : fieldmapper.aou.descendantNodeList(contextOrg).map(
+ function(item) { return item.id(); })
+ }
+ };
+
+ if (contextUsr) {
+ delete query['+au']['home_ou'];
+ query['+au']['id'] = contextUsr;
+ }
+
+ if (contextEg_bib) {
+ query['eg_bib'] = contextEg_bib;
+ }
+
+ if (contextLI) {
+ query['lineitem'] = contextLI;
+ }
+
+ rGrid.resetStore();
+ rGrid.loadAll(
+ { order_by : {aur : 'request_date'},
+ join : 'au'
+ },
+ query
+ );
+ }
+
+ function changeBib(value) {
+ contextEg_bib = value;
+ rGrid.overrideEditWidgets.eg_bib = new dijit.form.TextBox({"disabled": true});
+ rGrid.overrideEditWidgets.eg_bib.shove = { create : contextEg_bib };
+ }
+
+ function changeLI(value,display_value) {
+ contextLI = value;
+ contextLITextbox.setValue( contextLI );
+ contextLITextbox.setDisplayedValue( display_value || contextLI );
+ rGrid.overrideEditWidgets.lineitem = new dijit.form.TextBox({"disabled": true});
+ rGrid.overrideEditWidgets.lineitem.shove = { create : contextLI };
+ }
+
+ function changeLIPrompt() {
+ var lineitem = window.prompt(localeStrings.UR_FILTER_LINEITEM);
+ if(lineitem != '' && (lineitem == null || Number(lineitem) == NaN)) {
+ return;
+ }
+ changeLI(lineitem);
+ buildGrid();
+ }
+
+ function changeUser(value,display_value) {
+ contextUsr = value;
+ contextUsrTextbox.setValue( contextUsr );
+ contextUsrTextbox.setDisplayedValue( display_value || contextUsr );
+ rGrid.overrideEditWidgets.usr = new dijit.form.TextBox({"disabled": true});
+ rGrid.overrideEditWidgets.usr.shove = { create : contextUsr };
+ }
+
+ function changeUserPrompt() {
+ var barcode = window.prompt(localeStrings.UR_FILTER_USER);
+ if(barcode == null) {
+ return;
+ }
+ if(typeof xulG != 'undefined' && xulG.get_barcode) {
+ // We have a "complete the barcode" function, call it (actor = users only)
+ var new_barcode = xulG.get_barcode(window, 'actor', barcode);
+ // If we got a result (boolean false is "no result") check it
+ if(new_barcode) {
+ // user_false string means they picked "None of the above"
+ // Abort before any other events can fire
+ if(new_barcode == "user_false") return;
+ // No error means we have a (hopefully valid) completed barcode to use.
+ // Otherwise, fall through to other methods of checking
+ if(typeof new_barcode.ilsevent == 'undefined')
+ barcode = new_barcode.barcode;
+ }
+ }
+ if (barcode == '') {
+ contextUsrObj = null;
+ changeUser('','');
+ } else {
+ var usr_obj = fieldmapper.standardRequest(
+ [
+ 'open-ils.actor',
+ 'open-ils.actor.user.fleshed.retrieve_by_barcode.authoritative'
+ ],
+ {
+ params: [openils_User.authtoken, barcode]
+ }
+ );
+ if (typeof usr_obj.textcode != 'undefined') {
+ alert(usr_obj.textcode + ' : ' + usr_obj.desc);
+ return;
+ } else {
+ contextUsrObj = usr_obj;
+ changeUser(usr_obj.id(),usr_obj.card().barcode());
+ }
+ }
+ buildGrid();
+ }
+
+ function createRequest() {
+ if (!contextUsr) {
+ changeUserPrompt();
+ }
+ if (contextUsr) {
+ rGrid.overrideEditWidgets.pickup_lib = new dijit.form.TextBox({"disabled": true});
+ rGrid.overrideEditWidgets.pickup_lib.shove = { create : contextUsrObj.home_ou() };
+ rGrid.showCreateDialog();
+ }
+ }
+
+ openils_Util.addOnLoad(setup);
+
+
+
+
+});
\ No newline at end of file
-dojo.require('dojo.date.stamp');
-dojo.require('dojo.date.locale');
-dojo.require('openils.User');
-dojo.require('openils.Util');
-dojo.require('dijit.layout.ContentPane');
-
-var plist;
-var plOffset = 0;
-var plLimit = 20;
-var liTable;
-
-
-function load() {
- liTable = new AcqLiTable();
- liTable.isPL = plId;
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.picklist.retrieve.authoritative'],
- { async: true,
- params: [openils.User.authtoken, plId,
- {flesh_lineitem_count:true, flesh_owner:true}],
- oncomplete: function(r) {
- plist = openils.Util.readResponse(r);
- drawPl(plist);
- }
- }
- );
-
-}
-
-function drawPl() {
-
- dojo.byId("oils-acq-picklist-name").innerHTML = plist.name();
- dojo.byId("oils-acq-picklist-attr-owner").innerHTML = plist.owner().usrname();
- dojo.byId("oils-acq-picklist-attr-count").innerHTML = plist.entry_count();
-
- dojo.byId("oils-acq-picklist-attr-cdate").innerHTML =
- dojo.date.locale.format(
- dojo.date.stamp.fromISOString(plist.create_time()),
- {selector:'date'}
- );
-
- dojo.byId("oils-acq-picklist-attr-edate").innerHTML =
- dojo.date.locale.format(
- dojo.date.stamp.fromISOString(plist.edit_time()),
- {selector:'date'}
- );
-
- loadLIs();
-}
-
-function loadLIs() {
- liTable.reset();
-
- if(plist.entry_count() > (plOffset + plLimit)) {
- liTable.setNext(
- function() {
- plOffset += plLimit;
- loadLIs();
- }
- );
- } else {
- liTable.setNext(null);
- }
-
- if(plOffset > 0) {
- liTable.setPrev(
- function() {
- plOffset -= plLimit;
- loadLIs();
- }
- );
- } else {
- liTable.setPrev(null);
- }
-
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.picklist.retrieve'],
- { async: true,
- params: [openils.User.authtoken, plId,
- {flesh_notes:true, flesh_cancel_reason:true, flesh_attrs:true, clear_marc:true, offset:plOffset, limit:plLimit}],
- onresponse: function(r) {
- var li = openils.Util.readResponse(r);
- if (li) { /* Not every response is an LI (for some reason) */
- liTable.addLineitem(li);
- liTable.show('list');
- }
- }
- }
- );
-}
-
-openils.Util.addOnLoad(load);
-
-
+require([
+ "dojo/date/stamp",
+ "dojo/date/locale",
+ "openils/User",
+ "openils/Util",
+ "dijit/layout/ContentPane"
+ ],
+function(dojo_date_stamp,
+ dojo_date_locale,
+ openils_User,
+ openils_Util,
+ dijit_layout_ContentPane){
+
+ var plist;
+ var plOffset = 0;
+ var plLimit = 20;
+ var liTable;
+
+
+ function load() {
+ liTable = new AcqLiTable();
+ liTable.isPL = plId;
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.picklist.retrieve.authoritative'],
+ { async: true,
+ params: [openils_User.authtoken, plId,
+ {flesh_lineitem_count:true, flesh_owner:true}],
+ oncomplete: function(r) {
+ plist = openils_Util.readResponse(r);
+ drawPl(plist);
+ }
+ }
+ );
+
+ }
+
+ function drawPl() {
+
+ dojo.byId("oils-acq-picklist-name").innerHTML = plist.name();
+ dojo.byId("oils-acq-picklist-attr-owner").innerHTML = plist.owner().usrname();
+ dojo.byId("oils-acq-picklist-attr-count").innerHTML = plist.entry_count();
+
+ dojo.byId("oils-acq-picklist-attr-cdate").innerHTML =
+ dojo_date_locale.format(
+ dojo_date_stamp.fromISOString(plist.create_time()),
+ {selector:'date'}
+ );
+
+ dojo.byId("oils-acq-picklist-attr-edate").innerHTML =
+ dojo_date_locale.format(
+ dojo_date_stamp.fromISOString(plist.edit_time()),
+ {selector:'date'}
+ );
+
+ loadLIs();
+ }
+
+ function loadLIs() {
+ liTable.reset();
+
+ if(plist.entry_count() > (plOffset + plLimit)) {
+ liTable.setNext(
+ function() {
+ plOffset += plLimit;
+ loadLIs();
+ }
+ );
+ } else {
+ liTable.setNext(null);
+ }
+
+ if(plOffset > 0) {
+ liTable.setPrev(
+ function() {
+ plOffset -= plLimit;
+ loadLIs();
+ }
+ );
+ } else {
+ liTable.setPrev(null);
+ }
+
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem.picklist.retrieve'],
+ { async: true,
+ params: [openils_User.authtoken, plId,
+ {flesh_notes:true, flesh_cancel_reason:true, flesh_attrs:true, clear_marc:true, offset:plOffset, limit:plLimit}],
+ onresponse: function(r) {
+ var li = openils_Util.readResponse(r);
+ if (li) { /* Not every response is an LI (for some reason) */
+ liTable.addLineitem(li);
+ liTable.show('list');
+ }
+ }
+ }
+ );
+ }
+
+ openils_Util.addOnLoad(load);
+
+
+
+
+});
\ No newline at end of file
-//dojo.require('dojox.grid.DataGrid');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dijit.Dialog');
-dojo.require('dijit.form.Button');
-dojo.require('dijit.form.TextBox');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.form.Button');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('openils.acq.Picklist');
-dojo.require('openils.Util');
-dojo.require('openils.widget.ProgressDialog');
-
-var listAll = false;
-var plCache = {};
-
-function loadGrid() {
- dojo.connect(plMergeDialog, 'onOpen', function(){loadLeadPlSelector();});
- plListGrid.dataLoader = gridDataLoader;
- gridDataLoader();
-}
-
-function gridDataLoader() {
-
- var method = 'open-ils.acq.picklist.user.retrieve';
- if(listAll)
- method = method.replace(/user/, 'user.all');
-
- plListGrid.showLoadProgressIndicator();
-
- fieldmapper.standardRequest(
- ['open-ils.acq', method],
- { async: true,
- params: [
- openils.User.authtoken,
- {
- flesh_lineitem_count:1,
- flesh_owner:1,
- offset : plListGrid.displayOffset,
- limit : plListGrid.displayLimit,
- }
- ],
- onresponse : function(r) {
- var pl = openils.Util.readResponse(r);
- if(pl) {
- plCache[pl.id()] = pl;
- plListGrid.store.newItem(acqpl.toStoreItem(pl));
- }
- },
- oncomplete : function() {
- plListGrid.hideLoadProgressIndicator();
- }
- }
- );
-}
-function getOwnerName(rowIndex, item) {
- if(!item) return '';
- var id= this.grid.store.getValue(item, 'id');
- var pl = plCache[id];
- return pl.owner().usrname();
-}
-
-function createPL(fields) {
- if(fields.name == '') return;
-
- openils.acq.Picklist.create(fields,
-
- function(plId) {
- fieldmapper.standardRequest(
-
- ['open-ils.acq', 'open-ils.acq.picklist.retrieve.authoritative'],
- { async: true,
- params: [openils.User.authtoken, plId,
- {flesh_lineitem_count:1, flesh_owner:1}],
-
- oncomplete: function(r) {
- if(pl = openils.Util.readResponse(r)) {
- plCache[pl.id()] = pl;
- plListGrid.store.newItem(acqpl.toStoreData([pl]).items[0]);
- }
- }
- }
- );
- }
- );
-}
-
-function getDateTimeField(rowIndex, item) {
- if(!item) return '';
- var data = this.grid.store.getValue(item, this.field);
- var date = dojo.date.stamp.fromISOString(data);
- return dojo.date.locale.format(date, {formatLength:'short'});
-}
-function deleteFromGrid() {
- progressDialog.show(true);
- var list = [];
- dojo.forEach(
- plListGrid.getSelectedItems(),
- function(item) {
- list.push(plListGrid.store.getValue(item, 'id'));
- plListGrid.store.deleteItem(item);
- }
- );
- openils.acq.Picklist.deleteList(list, function(){progressDialog.hide();});
-}
-
-function cloneSelectedPl(fields) {
-
- var item = plListGrid.getSelectedItems()[0];
- if(!item) return;
-
- var plId = plListGrid.store.getValue(item, 'id');
- var entryCount = Number(plListGrid.store.getValue(item, 'entry_count'));
-
- progressDialog.show();
- progressDialog.update({maximum:entryCount, progress:0});
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.picklist.clone'],
- { async: true,
- params: [openils.User.authtoken, plId, fields.name],
-
- onresponse : function(r) {
- var resp = openils.Util.readResponse(r);
- if(!resp) return;
- progressDialog.update({progress:resp.li});
-
- if(resp.complete) {
- progressDialog.hide();
- var pl = resp.picklist;
- plCache[pl.id()] = pl;
- pl.owner(openils.User.user);
- pl.entry_count(entryCount);
- plListGrid.store.newItem(fieldmapper.acqpl.toStoreItem(pl));
- }
- }
- }
- );
-}
-
-function loadLeadPlSelector() {
- var store = new dojo.data.ItemFileWriteStore({data:acqpl.initStoreData()});
- dojo.forEach(
- plListGrid.getSelectedItems(),
- function(item) {
- var pl = plCache[plListGrid.store.getValue(item, 'id')];
- store.newItem(fieldmapper.acqpl.toStoreItem(pl));
- }
- );
- plMergeLeadSelector.store = store;
- plMergeLeadSelector.startup();
-}
-
-function mergeSelectedPl(fields) {
- if(!fields.lead) return;
-
- var ids = [];
- var totalLi = 0;
- var leadPl = plCache[fields.lead];
- var leadPlItem;
-
- dojo.forEach(
- plListGrid.getSelectedItems(),
- function(item) {
- var id = plListGrid.store.getValue(item, 'id');
- if(id == fields.lead) {
- leadPlItem = item;
- return;
- }
- totalLi += new Number(plListGrid.store.getValue(item, 'entry_count'));
- ids.push(id);
- }
- );
-
- progressDialog.show();
- progressDialog.update({maximum:totalLi, progress:0});
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.picklist.merge'],
- { async: true,
- params: [openils.User.authtoken, fields.lead, ids],
- onresponse : function(r) {
- var resp = openils.Util.readResponse(r);
- if(!resp) return;
- progressDialog.update({progress:resp.li});
-
- if(resp.complete) {
- progressDialog.hide();
- leadPl.entry_count( leadPl.entry_count() + totalLi );
- plListGrid.store.setValue(leadPlItem, 'entry_count', leadPl.entry_count());
-
- // remove the deleted lists from the grid
- dojo.forEach(
- plListGrid.getSelectedItems(),
- function(item) {
- var id = plListGrid.store.getValue(item, 'id');
- if(id != fields.lead)
- plListGrid.store.deleteItem(item);
- }
- );
- }
- }
- }
- );
-}
-
-openils.Util.addOnLoad(loadGrid);
-
-
+require([
+ "dojox/grid/DataGrid", //dojo.require('dojox.grid.DataGrid');
+ "openils/widget/AutoGrid",
+ "dojo/data/ItemFileWriteStore",
+ "dijit/Dialog",
+ "dijit/form/Button",
+ "dijit/form/TextBox",
+ "dijit/form/FilteringSelect",
+ "dijit/form/Button",
+ "dojox/grid/cells/dijit",
+ "openils/acq/Picklist",
+ "openils/Util",
+ "openils/widget/ProgressDialog"
+ ],
+function(dojox_grid_DataGrid,
+ openils_widget_AutoGrid,
+ dojo_data_ItemFileWriteStore,
+ dijit_Dialog,
+ dijit_form_Button,
+ dijit_form_TextBox,
+ dijit_form_FilteringSelect,
+ dijit_form_Button,
+ dojox_grid_cells_dijit,
+ openils_acq_Picklist,
+ openils_Util,
+ openils_widget_ProgressDialog){
+
+ var listAll = false;
+ var plCache = {};
+
+ function loadGrid() {
+ dojo.connect(plMergeDialog, 'onOpen', function(){loadLeadPlSelector();});
+ plListGrid.dataLoader = gridDataLoader;
+ gridDataLoader();
+ }
+
+ function gridDataLoader() {
+
+ var method = 'open-ils.acq.picklist.user.retrieve';
+ if(listAll)
+ method = method.replace(/user/, 'user.all');
+
+ plListGrid.showLoadProgressIndicator();
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', method],
+ { async: true,
+ params: [
+ openils.User.authtoken,
+ {
+ flesh_lineitem_count:1,
+ flesh_owner:1,
+ offset : plListGrid.displayOffset,
+ limit : plListGrid.displayLimit,
+ }
+ ],
+ onresponse : function(r) {
+ var pl = openils_Util.readResponse(r);
+ if(pl) {
+ plCache[pl.id()] = pl;
+ plListGrid.store.newItem(acqpl.toStoreItem(pl));
+ }
+ },
+ oncomplete : function() {
+ plListGrid.hideLoadProgressIndicator();
+ }
+ }
+ );
+ }
+ function getOwnerName(rowIndex, item) {
+ if(!item) return '';
+ var id= this.grid.store.getValue(item, 'id');
+ var pl = plCache[id];
+ return pl.owner().usrname();
+ }
+
+ function createPL(fields) {
+ if(fields.name == '') return;
+
+ openils_acq_Picklist.create(fields,
+
+ function(plId) {
+ fieldmapper.standardRequest(
+
+ ['open-ils.acq', 'open-ils.acq.picklist.retrieve.authoritative'],
+ { async: true,
+ params: [openils.User.authtoken, plId,
+ {flesh_lineitem_count:1, flesh_owner:1}],
+
+ oncomplete: function(r) {
+ if(pl = openils_Util.readResponse(r)) {
+ plCache[pl.id()] = pl;
+ plListGrid.store.newItem(acqpl.toStoreData([pl]).items[0]);
+ }
+ }
+ }
+ );
+ }
+ );
+ }
+
+ function getDateTimeField(rowIndex, item) {
+ if(!item) return '';
+ var data = this.grid.store.getValue(item, this.field);
+ var date = dojo.date.stamp.fromISOString(data);
+ return dojo.date.locale.format(date, {formatLength:'short'});
+ }
+ function deleteFromGrid() {
+ progressDialog.show(true);
+ var list = [];
+ dojo.forEach(
+ plListGrid.getSelectedItems(),
+ function(item) {
+ list.push(plListGrid.store.getValue(item, 'id'));
+ plListGrid.store.deleteItem(item);
+ }
+ );
+ openils_acq_Picklist.deleteList(list, function(){progressDialog.hide();});
+ }
+
+ function cloneSelectedPl(fields) {
+
+ var item = plListGrid.getSelectedItems()[0];
+ if(!item) return;
+
+ var plId = plListGrid.store.getValue(item, 'id');
+ var entryCount = Number(plListGrid.store.getValue(item, 'entry_count'));
+
+ progressDialog.show();
+ progressDialog.update({maximum:entryCount, progress:0});
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.picklist.clone'],
+ { async: true,
+ params: [openils.User.authtoken, plId, fields.name],
+
+ onresponse : function(r) {
+ var resp = openils_Util.readResponse(r);
+ if(!resp) return;
+ progressDialog.update({progress:resp.li});
+
+ if(resp.complete) {
+ progressDialog.hide();
+ var pl = resp.picklist;
+ plCache[pl.id()] = pl;
+ pl.owner(openils.User.user);
+ pl.entry_count(entryCount);
+ plListGrid.store.newItem(fieldmapper.acqpl.toStoreItem(pl));
+ }
+ }
+ }
+ );
+ }
+
+ function loadLeadPlSelector() {
+ var store = new dojo_data_ItemFileWriteStore({data:acqpl.initStoreData()});
+ dojo.forEach(
+ plListGrid.getSelectedItems(),
+ function(item) {
+ var pl = plCache[plListGrid.store.getValue(item, 'id')];
+ store.newItem(fieldmapper.acqpl.toStoreItem(pl));
+ }
+ );
+ plMergeLeadSelector.store = store;
+ plMergeLeadSelector.startup();
+ }
+
+ function mergeSelectedPl(fields) {
+ if(!fields.lead) return;
+
+ var ids = [];
+ var totalLi = 0;
+ var leadPl = plCache[fields.lead];
+ var leadPlItem;
+
+ dojo.forEach(
+ plListGrid.getSelectedItems(),
+ function(item) {
+ var id = plListGrid.store.getValue(item, 'id');
+ if(id == fields.lead) {
+ leadPlItem = item;
+ return;
+ }
+ totalLi += new Number(plListGrid.store.getValue(item, 'entry_count'));
+ ids.push(id);
+ }
+ );
+
+ progressDialog.show();
+ progressDialog.update({maximum:totalLi, progress:0});
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.picklist.merge'],
+ { async: true,
+ params: [openils.User.authtoken, fields.lead, ids],
+ onresponse : function(r) {
+ var resp = openils_Util.readResponse(r);
+ if(!resp) return;
+ progressDialog.update({progress:resp.li});
+
+ if(resp.complete) {
+ progressDialog.hide();
+ leadPl.entry_count( leadPl.entry_count() + totalLi );
+ plListGrid.store.setValue(leadPlItem, 'entry_count', leadPl.entry_count());
+
+ // remove the deleted lists from the grid
+ dojo.forEach(
+ plListGrid.getSelectedItems(),
+ function(item) {
+ var id = plListGrid.store.getValue(item, 'id');
+ if(id != fields.lead)
+ plListGrid.store.deleteItem(item);
+ }
+ );
+ }
+ }
+ }
+ );
+ }
+
+ openils_Util.addOnLoad(loadGrid);
+
+
+
+
+});
\ No newline at end of file
-dojo.require("openils.widget.EditDialog");
-dojo.require("openils.widget.EditPane");
+require([
+ "openils/widget/EditDialog",
+ "openils/widget/EditPane"
+ ],
+function(openils_widget_EditDialog,
+ openils_widget_EditPane){
+
+ var editDialog;
+
+ function toPoListing() {
+ location.href = oilsBasePath + "/acq/search/unified?ca=po";
+ }
+
+ function toOnePo(id) {
+ location.href = oilsBasePath + "/acq/po/view/" + id;
+ }
+
+ openils.Util.addOnLoad(
+ function() {
+ editDialog = new openils_widget_EditDialog({
+ "editPane": new openils_widget_EditPane({
+ "fmObject": new acqpo(),
+ /* After realizing how many fields should be excluded from this
+ * interface because users shouldn't set them arbitrarily,
+ * it hardly seems like using these Edit widgets gives much
+ * much advantage over a hardcoded interface. */
+ "suppressFields": [
+ "create_time", "edit_time", "editor", "order_date",
+ "owner", "cancel_reason", "creator", "state", "name"
+ ],
+ "fieldOrder": ["ordering_agency", "provider"],
+ "mode": "create",
+ overrideWidgetArgs : {
+ provider : { dijitArgs : { store_options : { base_filter : { active :"t" } } } },
+ ordering_agency : { orgDefaultsToWs : true }
+ },
+ "onSubmit": function(po) {
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.purchase_order.create"],{
+ "async": false,
+ "params": [openils.User.authtoken, po],
+ "onresponse": function(r) {
+ toOnePo(
+ openils.Util.readResponse(r).
+ purchase_order.id()
+ );
+ }
+ }
+ );
+ },
+ "onCancel": function() {
+ editDialog.hide();
+ toPoListing();
+ /* I'd rather do window.close() or xulG.close_tab(),
+ * but neither of those seem to work here. */
+ }
+ })
+ });
+ editDialog.startup();
+ editDialog.show();
+ }
+ );
+
-var editDialog;
-
-function toPoListing() {
- location.href = oilsBasePath + "/acq/search/unified?ca=po";
-}
-
-function toOnePo(id) {
- location.href = oilsBasePath + "/acq/po/view/" + id;
-}
-
-openils.Util.addOnLoad(
- function() {
- editDialog = new openils.widget.EditDialog({
- "editPane": new openils.widget.EditPane({
- "fmObject": new acqpo(),
- /* After realizing how many fields should be excluded from this
- * interface because users shouldn't set them arbitrarily,
- * it hardly seems like using these Edit widgets gives much
- * much advantage over a hardcoded interface. */
- "suppressFields": [
- "create_time", "edit_time", "editor", "order_date",
- "owner", "cancel_reason", "creator", "state", "name"
- ],
- "fieldOrder": ["ordering_agency", "provider"],
- "mode": "create",
- overrideWidgetArgs : {
- provider : { dijitArgs : { store_options : { base_filter : { active :"t" } } } },
- ordering_agency : { orgDefaultsToWs : true }
- },
- "onSubmit": function(po) {
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.purchase_order.create"],{
- "async": false,
- "params": [openils.User.authtoken, po],
- "onresponse": function(r) {
- toOnePo(
- openils.Util.readResponse(r).
- purchase_order.id()
- );
- }
- }
- );
- },
- "onCancel": function() {
- editDialog.hide();
- toPoListing();
- /* I'd rather do window.close() or xulG.close_tab(),
- * but neither of those seem to work here. */
- }
- })
- });
- editDialog.startup();
- editDialog.show();
- }
-);
+});
\ No newline at end of file
-dojo.require('openils.widget.AutoGrid');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('dijit.form.DateTextBox');
-dojo.require('dojo.date.stamp');
-
-var eventState;
-var eventContextOrg;
-var eventList;
-var eventStartDateRange;
-var eventEndDateRange;
-var po_map = {};
-
-function eventInit() {
- try {
- buildStateSelector();
- buildOrgSelector();
- buildDatePickers();
- buildEventGrid();
-
- eventGrid.cancelSelected = function() { doSelected('open-ils.acq.purchase_order.event.cancel.batch') };
- eventGrid.resetSelected = function() { doSelected('open-ils.acq.purchase_order.event.reset.batch') };
- eventGrid.doSearch = function() {
- buildEventGrid();
- }
-
- } catch(E) {
- //dump('Error in acq/events.js, eventInit(): ' + E);
- throw(E);
- }
-}
-
-function buildDatePickers() {
- var today = new Date();
- var yesterday = new Date( today.getFullYear(), today.getMonth(), today.getDate() - 1);
- eventStartDatePicker.constraints.max = today;
- eventStartDatePicker.attr( 'value', yesterday );
- eventStartDateRange = eventStartDatePicker.attr('value');
- eventEndDatePicker.constraints.max = today;
- eventEndDatePicker.attr( 'value', today );
- eventEndDateRange = eventEndDatePicker.attr('value');
- dojo.connect(
- eventStartDatePicker,
- 'onChange',
- function() {
- var new_date = arguments[0];
- if (new_date > eventEndDatePicker.attr('value')) {
- var swap = eventEndDatePicker.attr('value');
- eventEndDatePicker.attr( 'value', new_date );
- this.attr( 'value', swap );
- }
- eventStartDateRange = this.attr('value');
- }
- );
- dojo.connect(
- eventEndDatePicker,
- 'onChange',
- function() {
- var new_date = arguments[0];
- if (new_date < eventStartDatePicker.attr('value')) {
- var swap = eventStartDatePicker.attr('value');
- eventStartDatePicker.attr( 'value', new_date );
- this.attr( 'value', swap );
- }
- eventEndDateRange = this.attr('value');
- }
- );
-
-}
-
-function buildStateSelector() {
- try {
- eventStateSelect.store = new dojo.data.ItemFileReadStore({
- data : {
- identifier:"value",
- label: "name",
- items: [
- /* FIXME: I18N? */
- {name:"Pending", value:'pending'},
- {name:"Complete", value:'complete'},
- {name:"Error", value:'error'}
- ]
- }
- });
- eventStateSelect.attr( 'value','pending' );
- dojo.connect(
- eventStateSelect,
- 'onChange',
- function() {
- try {
- eventState = this.attr('value');
- } catch(E) {
- //dump('Error in acq/events.js, eventInit, connect, onChange: ' + E);
- throw(E);
- }
- }
- );
-
- } catch(E) {
- //dump('Error in acq/events.js, buildStateSelector(): ' + E);
- throw(E);
- }
-}
-
-function buildOrgSelector() {
- try {
- var connect = function() {
- try {
- dojo.connect(
- eventContextOrgSelect,
- 'onChange',
- function() {
- try {
- eventContextOrg = this.attr('value');
- } catch(E) {
- //dump('Error in acq/events.js, eventInit, connect, onChange: ' + E);
- throw(E);
- }
- }
- );
- } catch(E) {
- //dump('Error in acq/events.js, eventInit, connect: ' + E);
- throw(E);
- }
- };
- new openils.User().buildPermOrgSelector('STAFF_LOGIN', eventContextOrgSelect, null, connect);
-
- } catch(E) {
- //dump('Error in acq/events.js, buildOrgSelector(): ' + E);
- throw(E);
- }
-}
-
-function doSelected(method) {
- try {
- var ids = [];
- dojo.forEach(
- eventGrid.getSelectedItems(),
- function(item) {
- ids.push( eventGrid.store.getValue(item,'id') );
- }
- );
- fieldmapper.standardRequest(
- [ 'open-ils.acq', method ],
- { async: true,
- params: [openils.User.authtoken, ids],
- onresponse: function(r) {
- try {
- var result = openils.Util.readResponse(r);
- if (typeof result.ilsevent != 'undefined') { throw(result); }
- } catch(E) {
- //dump('Error in acq/events.js, doSelected(), onresponse(): ' + E);
- throw(E);
- }
- },
- onerror: function(r) {
- try {
- var result = openils.Util.readResponse(r);
- throw(result);
- } catch(E) {
- //dump('Error in acq/events.js, doSelected(), onerror(): ' + E);
- throw(E);
- }
- },
- oncomplete: function(r) {
- try {
- var result = openils.Util.readResponse(r);
- buildEventGrid();
- } catch(E) {
- //dump('Error in acq/events.js, doSelected(), oncomplete(): ' + E);
- throw(E);
- }
- }
- }
- );
- } catch(E) {
- //dump('Error in acq/events.js, doSelected(): ' + E);
- throw(E);
- }
-}
-
-function buildEventGrid() {
- eventGrid.resetStore();
- if(eventContextOrg == null) {
- eventContextOrg = openils.User.user.ws_ou();
- }
- if(eventState == null) {
- eventState = 'pending';
- }
- var filter = {"state":eventState, "order_by":[{"class":"atev", "field":"run_time", "direction":"desc"}]};
- if(eventStartDateRange != null) {
- /* the dijit appears to always provide 00:00:00 for the timestamp component */
- var end_of_day = eventEndDateRange; end_of_day.setDate( end_of_day.getDate() + 1 );
- filter['start_time'] = {
- 'between' : [
- dojo.date.stamp.toISOString( eventStartDateRange ),
- dojo.date.stamp.toISOString( end_of_day )
- ]
- }
- }
- po_map = {};
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.events.ordering_agency'],
- { async: true,
- params: [openils.User.authtoken, eventContextOrg, filter],
- onresponse: function(r) {
- try {
- if(eventObject = openils.Util.readResponse(r)) {
- po_map[ eventObject.target().id() ] = eventObject.target();
- eventObject.target( eventObject.target().id() );
- eventGrid.store.newItem(atev.toStoreItem(eventObject));
- }
- } catch(E) {
- //dump('Error in acq/events.js, buildEventGrid, onresponse: ' + E);
- throw(E);
- }
- }
- }
- );
-}
-
-function format_po_link(value) {
- if (value) {
- // FIXME -- how do you escape the value from .name() ?
- return '<a href="' + oilsBasePath + '/acq/po/view/' + value + '">' + po_map[ value ].name() + '</a>';
- }
-}
-
-openils.Util.addOnLoad(eventInit);
-
-
+require([
+ "openils/widget/AutoGrid",
+ "fieldmapper/OrgUtils",
+ "openils/widget/OrgUnitFilteringSelect",
+ "dijit/form/DateTextBox",
+ "dojo/date/stamp"
+ ],
+function(openils_widget_AutoGrid,
+ fieldmapper_OrgUtils,
+ openils_widget_OrgUnitFilteringSelect,
+ dijit_form_DateTextBox,
+ dojo_date_stamp){
+
+ var eventState;
+ var eventContextOrg;
+ var eventList;
+ var eventStartDateRange;
+ var eventEndDateRange;
+ var po_map = {};
+
+ function eventInit() {
+ try {
+ buildStateSelector();
+ buildOrgSelector();
+ buildDatePickers();
+ buildEventGrid();
+
+ eventGrid.cancelSelected = function() { doSelected('open-ils.acq.purchase_order.event.cancel.batch') };
+ eventGrid.resetSelected = function() { doSelected('open-ils.acq.purchase_order.event.reset.batch') };
+ eventGrid.doSearch = function() {
+ buildEventGrid();
+ }
+
+ } catch(E) {
+ //dump('Error in acq/events.js, eventInit(): ' + E);
+ throw(E);
+ }
+ }
+
+ function buildDatePickers() {
+ var today = new Date();
+ var yesterday = new Date( today.getFullYear(), today.getMonth(), today.getDate() - 1);
+ eventStartDatePicker.constraints.max = today;
+ eventStartDatePicker.attr( 'value', yesterday );
+ eventStartDateRange = eventStartDatePicker.attr('value');
+ eventEndDatePicker.constraints.max = today;
+ eventEndDatePicker.attr( 'value', today );
+ eventEndDateRange = eventEndDatePicker.attr('value');
+ dojo.connect(
+ eventStartDatePicker,
+ 'onChange',
+ function() {
+ var new_date = arguments[0];
+ if (new_date > eventEndDatePicker.attr('value')) {
+ var swap = eventEndDatePicker.attr('value');
+ eventEndDatePicker.attr( 'value', new_date );
+ this.attr( 'value', swap );
+ }
+ eventStartDateRange = this.attr('value');
+ }
+ );
+ dojo.connect(
+ eventEndDatePicker,
+ 'onChange',
+ function() {
+ var new_date = arguments[0];
+ if (new_date < eventStartDatePicker.attr('value')) {
+ var swap = eventStartDatePicker.attr('value');
+ eventStartDatePicker.attr( 'value', new_date );
+ this.attr( 'value', swap );
+ }
+ eventEndDateRange = this.attr('value');
+ }
+ );
+
+ }
+
+ function buildStateSelector() {
+ try {
+ eventStateSelect.store = new dojo.data.ItemFileReadStore({
+ data : {
+ identifier:"value",
+ label: "name",
+ items: [
+ /* FIXME: I18N? */
+ {name:"Pending", value:'pending'},
+ {name:"Complete", value:'complete'},
+ {name:"Error", value:'error'}
+ ]
+ }
+ });
+ eventStateSelect.attr( 'value','pending' );
+ dojo.connect(
+ eventStateSelect,
+ 'onChange',
+ function() {
+ try {
+ eventState = this.attr('value');
+ } catch(E) {
+ //dump('Error in acq/events.js, eventInit, connect, onChange: ' + E);
+ throw(E);
+ }
+ }
+ );
+
+ } catch(E) {
+ //dump('Error in acq/events.js, buildStateSelector(): ' + E);
+ throw(E);
+ }
+ }
+
+ function buildOrgSelector() {
+ try {
+ var connect = function() {
+ try {
+ dojo.connect(
+ eventContextOrgSelect,
+ 'onChange',
+ function() {
+ try {
+ eventContextOrg = this.attr('value');
+ } catch(E) {
+ //dump('Error in acq/events.js, eventInit, connect, onChange: ' + E);
+ throw(E);
+ }
+ }
+ );
+ } catch(E) {
+ //dump('Error in acq/events.js, eventInit, connect: ' + E);
+ throw(E);
+ }
+ };
+ new openils.User().buildPermOrgSelector('STAFF_LOGIN', eventContextOrgSelect, null, connect);
+
+ } catch(E) {
+ //dump('Error in acq/events.js, buildOrgSelector(): ' + E);
+ throw(E);
+ }
+ }
+
+ function doSelected(method) {
+ try {
+ var ids = [];
+ dojo.forEach(
+ eventGrid.getSelectedItems(),
+ function(item) {
+ ids.push( eventGrid.store.getValue(item,'id') );
+ }
+ );
+ fieldmapper.standardRequest(
+ [ 'open-ils.acq', method ],
+ { async: true,
+ params: [openils.User.authtoken, ids],
+ onresponse: function(r) {
+ try {
+ var result = openils.Util.readResponse(r);
+ if (typeof result.ilsevent != 'undefined') { throw(result); }
+ } catch(E) {
+ //dump('Error in acq/events.js, doSelected(), onresponse(): ' + E);
+ throw(E);
+ }
+ },
+ onerror: function(r) {
+ try {
+ var result = openils.Util.readResponse(r);
+ throw(result);
+ } catch(E) {
+ //dump('Error in acq/events.js, doSelected(), onerror(): ' + E);
+ throw(E);
+ }
+ },
+ oncomplete: function(r) {
+ try {
+ var result = openils.Util.readResponse(r);
+ buildEventGrid();
+ } catch(E) {
+ //dump('Error in acq/events.js, doSelected(), oncomplete(): ' + E);
+ throw(E);
+ }
+ }
+ }
+ );
+ } catch(E) {
+ //dump('Error in acq/events.js, doSelected(): ' + E);
+ throw(E);
+ }
+ }
+
+ function buildEventGrid() {
+ eventGrid.resetStore();
+ if(eventContextOrg == null) {
+ eventContextOrg = openils.User.user.ws_ou();
+ }
+ if(eventState == null) {
+ eventState = 'pending';
+ }
+ var filter = {"state":eventState, "order_by":[{"class":"atev", "field":"run_time", "direction":"desc"}]};
+ if(eventStartDateRange != null) {
+ /* the dijit appears to always provide 00:00:00 for the timestamp component */
+ var end_of_day = eventEndDateRange; end_of_day.setDate( end_of_day.getDate() + 1 );
+ filter['start_time'] = {
+ 'between' : [
+ dojo_date_stamp.toISOString( eventStartDateRange ),
+ dojo_date_stamp.toISOString( end_of_day )
+ ]
+ }
+ }
+ po_map = {};
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.events.ordering_agency'],
+ { async: true,
+ params: [openils.User.authtoken, eventContextOrg, filter],
+ onresponse: function(r) {
+ try {
+ if(eventObject = openils.Util.readResponse(r)) {
+ po_map[ eventObject.target().id() ] = eventObject.target();
+ eventObject.target( eventObject.target().id() );
+ eventGrid.store.newItem(atev.toStoreItem(eventObject));
+ }
+ } catch(E) {
+ //dump('Error in acq/events.js, buildEventGrid, onresponse: ' + E);
+ throw(E);
+ }
+ }
+ }
+ );
+ }
+
+ function format_po_link(value) {
+ if (value) {
+ // FIXME -- how do you escape the value from .name() ?
+ return '<a href="' + oilsBasePath + '/acq/po/view/' + value + '">' + po_map[ value ].name() + '</a>';
+ }
+ }
+
+ openils.Util.addOnLoad(eventInit);
+
+
+
+
+});
\ No newline at end of file
-dojo.require('dijit.form.Form');
-dojo.require('dijit.form.Button');
-dojo.require('dijit.form.CheckBox');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.form.NumberTextBox');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dojo.date.locale');
-dojo.require('dojo.date.stamp');
-dojo.require('openils.User');
-dojo.require('openils.Util');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.PermaCrud');
+require([
+ "dijit/form/Form",
+ "dijit/form/Button",
+ "dijit/form/CheckBox",
+ "dijit/form/FilteringSelect",
+ "dijit/form/NumberTextBox",
+ "dojo/data/ItemFileWriteStore",
+ "dojo/date/locale",
+ "dojo/date/stamp",
+ "openils/User",
+ "openils/Util",
+ "openils/widget/AutoGrid",
+ "openils/widget/AutoFieldWidget",
+ "openils/PermaCrud"
+ ],
+function(dijit_form_Form,
+ dijit_form_Button,
+ dijit_form_CheckBox,
+ dijit_form_FilteringSelect,
+ dijit_form_NumberTextBox,
+ dojo_data_ItemFileWriteStore,
+ dojo_date_locale,
+ dojo_date_stamp,
+ openils_User,
+ openils_Util,
+ openils_widget_AutoGrid,
+ openils_widget_AutoFieldWidget,
+ openils_PermaCrud){
+
+ var metaPO;
+ var _last_fields;
+ var general_po_search_opts = {"order_by": {"acqpo": "edit_time DESC"}};
+
+ function getPOOwner(rowIndex, item) {
+ if(!item) return '';
+ var data = this.grid.store.getValue(item, 'owner');
+ return new openils_User({id:data}).user.usrname();
+ }
+
+ function doSearch(fields) {
+ _last_fields = dojo.clone(fields); /* Save for re-use */
+ var metapo_view = false;
+
+ /* Remove the metapo_view field from 'fields'... we'll use it later */
+ if (fields.metapo_view && fields.metapo_view[0]) {
+ metapo_view = true;
+ delete fields.metapo_view;
+ }
+
+ if (
+ !(fields.id && fields.id.constructor.name == 'Array') &&
+ isNaN(fields.id)
+ ) {
+ delete fields.id;
+ for(var k in fields) {
+ if(fields[k] == '' || fields[k] == null)
+ delete fields[k];
+ }
+ } else {
+ // ID search trumps other searches
+ fields = {id:fields.id};
+ }
+
+ // no search fields
+ var some = false;
+ for(var k in fields) some = true;
+ if(!some) fields.id = {'!=' : null};
+
+
+ if (metapo_view) {
+ openils_Util.hide("holds_po_grid");
+ loadMetaPO(fields);
+ } else {
+ if (metaPO) metaPO.myHide();
+ openils_Util.show("holds_po_grid");
+ poGrid.resetStore();
+ poGrid.loadAll(general_po_search_opts, fields);
+ }
+ }
+
+ function loadForm() {
+
+ new openils_widget_AutoFieldWidget({
+ fmClass : 'acqpo',
+ fmField : 'provider',
+ parentNode : dojo.byId('po-search-provider-selector'),
+ orgLimitPerms : ['VIEW_PURCHASE_ORDER'],
+ dijitArgs : {name:'provider', required:false}
+ }).build();
+
+ new openils_widget_AutoFieldWidget({
+ fmClass : 'acqpo',
+ fmField : 'ordering_agency',
+ parentNode : dojo.byId('po-search-agency-selector'),
+ orgLimitPerms : ['VIEW_PURCHASE_ORDER'],
+ dijitArgs : {name:'ordering_agency', required:false}
+ }).build();
+
+ if (poIds && poIds.length > 0) {
+ dijit.byId("metapo_view").attr("checked", true);
+ doSearch({"id": poIds, "metapo_view": [true] /* [sic] */});
+ } else {
+ doSearch({"ordering_agency": openils_User.user.ws_ou()});
+ }
+ }
+
+ function loadMetaPO(fields) {
+ var pcrud = new openils_PermaCrud();
+ var po_list = pcrud.search("acqpo", fields, general_po_search_opts);
+ if (!po_list || !po_list.length) {
+ alert(localeStrings.NO_PO_RESULTS);
+ } else {
+ if (!metaPO) {
+ metaPO = new AcqLiTable();
+
+ /* We need to know the width (in cells) of the template row for
+ * the LI table, and we don't want to hardcode it here. */
+ metaPO.n_cells = dojo.query("> td", metaPO.rowTemplate).length;
+
+ metaPO._copy_count_cb = function(liId, count) {
+ var poId = this.liCache[liId].purchase_order();
+
+ if (this.copy_counts[poId] == undefined)
+ this.copy_counts[poId] = {};
+ this.copy_counts[poId][liId] = count;
+
+ this.renderCopyCounts(poId);
+ this.renderSummary("copies");
+ };
+ metaPO.myHide = function() {
+ this.hide();
+ openils_Util.hide("oils-acq-holds-metapo-summary");
+ };
+ metaPO.renderSummary = function(part) {
+ var self = this;
+ /* The idea here will be that if "part" is defined, we'll
+ * just update that part of the metaPO summary, otherwise,
+ * the whole thing. */
+ if (part != undefined) {
+ var target = dojo.byId("oils-acq-metapo-summary-" + part);
+ switch (part) {
+ case "copies":
+ target.innerHTML = self.copiesTotal();
+ break;
+ case "po":
+ target.innerHTML = self.working_po_list.length;
+ break;
+ /* Any numeric fields should be named here. */
+ case "amount_encumbered":
+ case "amount_spent":
+ target.innerHTML = self.numericFieldTotal(part);
+ break;
+ default:
+ /* assume a field on the acqpo's themselves */
+ target.innerHTML = self.anyFieldTotal(part);
+ break;
+ }
+ } else {
+ openils_Util.show("oils-acq-holds-metapo-summary");
+ self.totalable_fields.forEach(
+ function(f) { self.renderSummary(f); }
+ );
+ }
+ };
+ metaPO.numericFieldTotal = function(field) {
+ var self = this;
+ var pennies = self.working_po_list.reduce(
+ /* working_po_list contains unfleshed acqpo's, so we must
+ * find the same PO in the poCache */
+ function(p, c) {
+ c = self.poCache[c.id()][field]();
+ return p + Number(c) * 100;
+ }, 0
+ );
+ return pennies / 100;
+ };
+ metaPO.anyFieldTotal = function(field) {
+ var self = this;
+ return self.working_po_list.reduce(
+ /* working_po_list contains unfleshed acqpo's, so we must
+ * find the same PO in the poCache */
+ function(p, c) {
+ c = self.poCache[c.id()][field]();
+ return p + Number(c);
+ }, 0
+ );
+ };
+ metaPO.renderCopyCounts = function(poId) {
+ try {
+ dojo.query("td#oils-acq-po-heading-" + poId +
+ ' span span[attr="copies"]')[0].innerHTML =
+ this.copiesByPOId(poId);
+ } catch (E) {
+ ;
+ }
+ };
+ metaPO.sectionHeadingById = function(id) {
+ var headings = dojo.query("#po-heading-" + id, this.tbody);
+ if (headings.length != 1) {
+ alert(localeStrings.PO_HEADING_ERROR);
+ return undefined;
+ } else {
+ return headings[0];
+ }
+ };
+ metaPO.sectionHeadingByPOId = function(poId) {
+ return this.sectionHeadingById(this.sections_by_poid[poId]);
+ };
+ metaPO.addSection = function(po) {
+ var s = this.sections_by_poid[po.id()] = this.sections++;
+
+ this.tbody.appendChild(
+ dojo.create("tr", {
+ "class": "acq-lit-po-heading", "id": "po-heading-" + s
+ })
+ );
+
+ return s;
+ };
+ metaPO.addLineitemToSection = function(li, section) {
+ dojo.place(
+ this.addLineitem(li, true /* skip_final_placement */),
+ this.sectionHeadingById(section),
+ "after"
+ );
+ };
+ metaPO.generateActivator = function(id) {
+ return function() {
+ progressDialog.show(true);
+ try {
+ fieldmapper.standardRequest(
+ ["open-ils.acq",
+ "open-ils.acq.purchase_order.activate"], {
+ "async": true,
+ "params": [openils_User.authtoken, id],
+ "oncomplete": function() {
+ progressDialog.hide();
+ doSearch(_last_fields);
+ }
+ }
+ );
+ } catch (E) {
+ progressDialog.hide();
+ alert(E); /* XXX */
+ }
+ };
+ };
+ metaPO.renderHeading = function(poId) {
+ var self = this;
+ var td = dojo.create("td", {"colspan": self.n_cells});
+ td.id = "oils-acq-po-heading-" + poId;
+
+ /* Build our HTML structure from the template... */
+ dojo.query("> span", "oils-acq-po-heading-template").forEach(
+ function(s) { td.appendChild(s.cloneNode(true)); }
+ );
+
+ /* Some fields straight from the PO object... */
+ self.po_fields_for_display.forEach(
+ function(f) {
+ dojo.query('[attr="' + f + '"]', td)[0].innerHTML =
+ self.poCache[poId][f]();
+ }
+ );
+
+ /* The name field needs special treatment: it's a link */
+ dojo.attr(
+ dojo.query('a[attr="name"]', td)[0],
+ "href",
+ oilsBasePath + '/acq/po/view/' + poId
+ );
+
+ /* Show an "activate" link, or not, based on "state"... */
+ var a = dojo.query('a[attr="activator"]', td)[0];
+ if (self.poCache[poId].state() == "pending") {
+ a.onclick = self.generateActivator(poId);
+ openils_Util.show(a, "inline");
+ } else {
+ openils_Util.hide(a);
+ }
+
+ /* Put the new heading cell in place... */
+ dojo.place(td, self.sectionHeadingByPOId(poId), "only");
+
+ /* And finally, render copy info (must happen _after_ heading
+ * is attached to the DOM tree */
+ this.renderCopyCounts(poId);
+ };
+ metaPO.copiesByPOId = function(poId) {
+ if (!this.copy_counts[poId]) return undefined;
+ var total = 0;
+ for (var liId in this.copy_counts[poId]) {
+ total += this.copy_counts[poId][liId];
+ }
+ return total;
+ };
+ metaPO.copiesTotal = function() {
+ var total = 0;
+ for (var poId in this.copy_counts)
+ total += this.copiesByPOId(poId);
+ return total;
+ };
+ metaPO.myReset = function() {
+ this.isMeta = true;
+ this.sections = 0;
+ this.sections_by_poid = {};
+ this.copy_counts = {};
+ this.po_fields_for_display = [
+ "name", "lineitem_count", "amount_encumbered",
+ "amount_spent", "state"
+ ];
+ this.totalable_fields = [
+ "po", "lineitem_count", "copies",
+ "amount_encumbered", "amount_spent"
+ ];
+ openils_Util.hide("oils-acq-holds-metapo-summary");
+ };
+ metaPO.populate = function(list) {
+ var self = this;
+ var done = 0;
+
+ self.working_po_list = [];
+
+ progressDialog.show(true);
+ list.forEach(function(po) {
+ var sec = self.addSection(po);
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.lineitem.search"], {
+ "async": true,
+ "params": [
+ openils_User.authtoken,
+ {"purchase_order": po.id()},
+ {"flesh_attrs": true, "flesh_notes": true}
+ ],
+ "onresponse": function(r) {
+ var li = openils_Util.readResponse(r);
+ if (li) /* sometimes empty string: disregard */
+ self.addLineitemToSection(li, sec);
+ },
+ "oncomplete": function(r) {
+ self.working_po_list.push(po);
+ self.renderHeading(po.id());
+ self.renderSummary();
+ /* This mechanism avoids calling .show() too
+ * often or before results are ready, and
+ * thus smooths out DOM rendering glitches. */
+ if (++done >= list.length) {
+ done = -1;
+ self.show("list");
+ progressDialog.hide();
+ }
+ }
+ }
+ );
+ });
+ /* This mechanism sees to it that we call .show() at least once
+ * even if the search result population seems to be timing
+ * out or failing. */
+ setTimeout(
+ function() {
+ if (done != -1) {
+ self.show("list");
+ progressDialog.hide();
+ }
+ }, 10000 /* 10 seconds: make this configurable? */
+ );
+ };
+ }
+
+ metaPO.reset();
+ metaPO.myReset();
+ metaPO.populate(po_list);
+ }
+ }
+
+ openils_Util.addOnLoad(loadForm);
+
-var metaPO;
-var _last_fields;
-var general_po_search_opts = {"order_by": {"acqpo": "edit_time DESC"}};
-
-function getPOOwner(rowIndex, item) {
- if(!item) return '';
- var data = this.grid.store.getValue(item, 'owner');
- return new openils.User({id:data}).user.usrname();
-}
-
-function doSearch(fields) {
- _last_fields = dojo.clone(fields); /* Save for re-use */
- var metapo_view = false;
-
- /* Remove the metapo_view field from 'fields'... we'll use it later */
- if (fields.metapo_view && fields.metapo_view[0]) {
- metapo_view = true;
- delete fields.metapo_view;
- }
-
- if (
- !(fields.id && fields.id.constructor.name == 'Array') &&
- isNaN(fields.id)
- ) {
- delete fields.id;
- for(var k in fields) {
- if(fields[k] == '' || fields[k] == null)
- delete fields[k];
- }
- } else {
- // ID search trumps other searches
- fields = {id:fields.id};
- }
-
- // no search fields
- var some = false;
- for(var k in fields) some = true;
- if(!some) fields.id = {'!=' : null};
-
-
- if (metapo_view) {
- openils.Util.hide("holds_po_grid");
- loadMetaPO(fields);
- } else {
- if (metaPO) metaPO.myHide();
- openils.Util.show("holds_po_grid");
- poGrid.resetStore();
- poGrid.loadAll(general_po_search_opts, fields);
- }
-}
-
-function loadForm() {
-
- new openils.widget.AutoFieldWidget({
- fmClass : 'acqpo',
- fmField : 'provider',
- parentNode : dojo.byId('po-search-provider-selector'),
- orgLimitPerms : ['VIEW_PURCHASE_ORDER'],
- dijitArgs : {name:'provider', required:false}
- }).build();
-
- new openils.widget.AutoFieldWidget({
- fmClass : 'acqpo',
- fmField : 'ordering_agency',
- parentNode : dojo.byId('po-search-agency-selector'),
- orgLimitPerms : ['VIEW_PURCHASE_ORDER'],
- dijitArgs : {name:'ordering_agency', required:false}
- }).build();
-
- if (poIds && poIds.length > 0) {
- dijit.byId("metapo_view").attr("checked", true);
- doSearch({"id": poIds, "metapo_view": [true] /* [sic] */});
- } else {
- doSearch({"ordering_agency": openils.User.user.ws_ou()});
- }
-}
-
-function loadMetaPO(fields) {
- var pcrud = new openils.PermaCrud();
- var po_list = pcrud.search("acqpo", fields, general_po_search_opts);
- if (!po_list || !po_list.length) {
- alert(localeStrings.NO_PO_RESULTS);
- } else {
- if (!metaPO) {
- metaPO = new AcqLiTable();
-
- /* We need to know the width (in cells) of the template row for
- * the LI table, and we don't want to hardcode it here. */
- metaPO.n_cells = dojo.query("> td", metaPO.rowTemplate).length;
-
- metaPO._copy_count_cb = function(liId, count) {
- var poId = this.liCache[liId].purchase_order();
-
- if (this.copy_counts[poId] == undefined)
- this.copy_counts[poId] = {};
- this.copy_counts[poId][liId] = count;
-
- this.renderCopyCounts(poId);
- this.renderSummary("copies");
- };
- metaPO.myHide = function() {
- this.hide();
- openils.Util.hide("oils-acq-holds-metapo-summary");
- };
- metaPO.renderSummary = function(part) {
- var self = this;
- /* The idea here will be that if "part" is defined, we'll
- * just update that part of the metaPO summary, otherwise,
- * the whole thing. */
- if (part != undefined) {
- var target = dojo.byId("oils-acq-metapo-summary-" + part);
- switch (part) {
- case "copies":
- target.innerHTML = self.copiesTotal();
- break;
- case "po":
- target.innerHTML = self.working_po_list.length;
- break;
- /* Any numeric fields should be named here. */
- case "amount_encumbered":
- case "amount_spent":
- target.innerHTML = self.numericFieldTotal(part);
- break;
- default:
- /* assume a field on the acqpo's themselves */
- target.innerHTML = self.anyFieldTotal(part);
- break;
- }
- } else {
- openils.Util.show("oils-acq-holds-metapo-summary");
- self.totalable_fields.forEach(
- function(f) { self.renderSummary(f); }
- );
- }
- };
- metaPO.numericFieldTotal = function(field) {
- var self = this;
- var pennies = self.working_po_list.reduce(
- /* working_po_list contains unfleshed acqpo's, so we must
- * find the same PO in the poCache */
- function(p, c) {
- c = self.poCache[c.id()][field]();
- return p + Number(c) * 100;
- }, 0
- );
- return pennies / 100;
- };
- metaPO.anyFieldTotal = function(field) {
- var self = this;
- return self.working_po_list.reduce(
- /* working_po_list contains unfleshed acqpo's, so we must
- * find the same PO in the poCache */
- function(p, c) {
- c = self.poCache[c.id()][field]();
- return p + Number(c);
- }, 0
- );
- };
- metaPO.renderCopyCounts = function(poId) {
- try {
- dojo.query("td#oils-acq-po-heading-" + poId +
- ' span span[attr="copies"]')[0].innerHTML =
- this.copiesByPOId(poId);
- } catch (E) {
- ;
- }
- };
- metaPO.sectionHeadingById = function(id) {
- var headings = dojo.query("#po-heading-" + id, this.tbody);
- if (headings.length != 1) {
- alert(localeStrings.PO_HEADING_ERROR);
- return undefined;
- } else {
- return headings[0];
- }
- };
- metaPO.sectionHeadingByPOId = function(poId) {
- return this.sectionHeadingById(this.sections_by_poid[poId]);
- };
- metaPO.addSection = function(po) {
- var s = this.sections_by_poid[po.id()] = this.sections++;
-
- this.tbody.appendChild(
- dojo.create("tr", {
- "class": "acq-lit-po-heading", "id": "po-heading-" + s
- })
- );
-
- return s;
- };
- metaPO.addLineitemToSection = function(li, section) {
- dojo.place(
- this.addLineitem(li, true /* skip_final_placement */),
- this.sectionHeadingById(section),
- "after"
- );
- };
- metaPO.generateActivator = function(id) {
- return function() {
- progressDialog.show(true);
- try {
- fieldmapper.standardRequest(
- ["open-ils.acq",
- "open-ils.acq.purchase_order.activate"], {
- "async": true,
- "params": [openils.User.authtoken, id],
- "oncomplete": function() {
- progressDialog.hide();
- doSearch(_last_fields);
- }
- }
- );
- } catch (E) {
- progressDialog.hide();
- alert(E); /* XXX */
- }
- };
- };
- metaPO.renderHeading = function(poId) {
- var self = this;
- var td = dojo.create("td", {"colspan": self.n_cells});
- td.id = "oils-acq-po-heading-" + poId;
-
- /* Build our HTML structure from the template... */
- dojo.query("> span", "oils-acq-po-heading-template").forEach(
- function(s) { td.appendChild(s.cloneNode(true)); }
- );
-
- /* Some fields straight from the PO object... */
- self.po_fields_for_display.forEach(
- function(f) {
- dojo.query('[attr="' + f + '"]', td)[0].innerHTML =
- self.poCache[poId][f]();
- }
- );
-
- /* The name field needs special treatment: it's a link */
- dojo.attr(
- dojo.query('a[attr="name"]', td)[0],
- "href",
- oilsBasePath + '/acq/po/view/' + poId
- );
-
- /* Show an "activate" link, or not, based on "state"... */
- var a = dojo.query('a[attr="activator"]', td)[0];
- if (self.poCache[poId].state() == "pending") {
- a.onclick = self.generateActivator(poId);
- openils.Util.show(a, "inline");
- } else {
- openils.Util.hide(a);
- }
-
- /* Put the new heading cell in place... */
- dojo.place(td, self.sectionHeadingByPOId(poId), "only");
-
- /* And finally, render copy info (must happen _after_ heading
- * is attached to the DOM tree */
- this.renderCopyCounts(poId);
- };
- metaPO.copiesByPOId = function(poId) {
- if (!this.copy_counts[poId]) return undefined;
- var total = 0;
- for (var liId in this.copy_counts[poId]) {
- total += this.copy_counts[poId][liId];
- }
- return total;
- };
- metaPO.copiesTotal = function() {
- var total = 0;
- for (var poId in this.copy_counts)
- total += this.copiesByPOId(poId);
- return total;
- };
- metaPO.myReset = function() {
- this.isMeta = true;
- this.sections = 0;
- this.sections_by_poid = {};
- this.copy_counts = {};
- this.po_fields_for_display = [
- "name", "lineitem_count", "amount_encumbered",
- "amount_spent", "state"
- ];
- this.totalable_fields = [
- "po", "lineitem_count", "copies",
- "amount_encumbered", "amount_spent"
- ];
- openils.Util.hide("oils-acq-holds-metapo-summary");
- };
- metaPO.populate = function(list) {
- var self = this;
- var done = 0;
-
- self.working_po_list = [];
-
- progressDialog.show(true);
- list.forEach(function(po) {
- var sec = self.addSection(po);
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.lineitem.search"], {
- "async": true,
- "params": [
- openils.User.authtoken,
- {"purchase_order": po.id()},
- {"flesh_attrs": true, "flesh_notes": true}
- ],
- "onresponse": function(r) {
- var li = openils.Util.readResponse(r);
- if (li) /* sometimes empty string: disregard */
- self.addLineitemToSection(li, sec);
- },
- "oncomplete": function(r) {
- self.working_po_list.push(po);
- self.renderHeading(po.id());
- self.renderSummary();
- /* This mechanism avoids calling .show() too
- * often or before results are ready, and
- * thus smooths out DOM rendering glitches. */
- if (++done >= list.length) {
- done = -1;
- self.show("list");
- progressDialog.hide();
- }
- }
- }
- );
- });
- /* This mechanism sees to it that we call .show() at least once
- * even if the search result population seems to be timing
- * out or failing. */
- setTimeout(
- function() {
- if (done != -1) {
- self.show("list");
- progressDialog.hide();
- }
- }, 10000 /* 10 seconds: make this configurable? */
- );
- };
- }
-
- metaPO.reset();
- metaPO.myReset();
- metaPO.populate(po_list);
- }
-}
-
-openils.Util.addOnLoad(loadForm);
+});
\ No newline at end of file
-dojo.require("dojo.string");
-dojo.require('dijit.layout.ContentPane');
-dojo.require('openils.PermaCrud');
-
-var pcrud = new openils.PermaCrud();
-var PO = null;
-var liTable;
-var poItemTable;
-var poNoteTable;
-var invoiceLinkDialogManager;
-
-function AcqPoNoteTable() {
- var self = this;
-
- this.notesTbody = dojo.byId("acq-po-notes-tbody");
- this.notesRow = this.notesTbody.removeChild(dojo.byId("acq-po-notes-row"));
-
- dojo.byId("acq-po-notes-back-button").onclick = function() { self.hide(); };
- dojo.byId("acq-po-view-notes").onclick = function() { self.show(); };
-
- /* widgets' event properties are cased likeThis */
- acqPoCreateNoteSubmit.onClick = function() {
- if (!acqPoCreateNoteText.attr("value")) return;
-
- /* prep new note */
- var note = new acqpon();
- note.vendor_public(
- Boolean(acqPoCreateNoteVendorPublic.attr('checked'))
- );
- note.value(acqPoCreateNoteText.attr("value"));
- note.purchase_order(PO.id());
- note.isnew(true);
-
- /* save it */
- self.updatePoNotes(note);
-
- /* reset fields for next use */
- acqPoCreateNoteText.attr("value", "");
- acqPoCreateNoteVendorPublic.attr("checked", false);
- };
-
- this.drawPoNote = function(note) {
- if (note.isdeleted())
- return;
-
- var row = dojo.clone(this.notesRow);
-
- nodeByName("value", row).innerHTML = note.value();
-
- if (openils.Util.isTrue(note.vendor_public()))
- nodeByName("vendor_public", row).innerHTML =
- localeStrings.VENDOR_PUBLIC;
-
- nodeByName("delete", row).onclick = function() {
- note.isdeleted(true);
- self.notesTbody.removeChild(row);
- self.updatePoNotes();
- };
-
- if (note.edit_time()) {
- nodeByName("edit_time", row).innerHTML =
- dojo.date.locale.format(
- dojo.date.stamp.fromISOString(note.edit_time()),
- {"formatLength": "short"}
- );
- }
-
- self.notesTbody.appendChild(row);
- };
-
- this.drawPoNotes = function() {
- /* sort */
- PO.notes(
- PO.notes().sort(
- function(a, b) {
- return (a.edit_time() < b.edit_time()) ? 1 : -1;
- }
- )
- );
-
- /* remove old renderings of notes */
- dojo.empty(this.notesTbody);
-
- PO.notes().forEach(function(o) { self.drawPoNote(o); });
- };
-
- this.updatePoNotesCount = function() {
- dojo.byId("acq-po-view-notes").innerHTML =
- "(" + PO.notes().length + ")";
- };
-
- this.updatePoNotes = function(newNote) {
- var notes = newNote ?
- [newNote] :
- PO.notes().filter(
- function(o) {
- if (o.ischanged() || o.isnew() || o.isdeleted())
- return o;
- }
- );
-
- if (notes.length < 1)
- return;
-
- progressDialog.show();
-
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.po_note.cud.batch"], {
- "async": true,
- "params": [openils.User.authtoken, notes],
- "onresponse": function(r) {
- var resp = openils.Util.readResponse(r);
- if (resp) {
- progressDialog.update(resp);
-
- if (!resp.note.isdeleted()) {
- resp.note.isnew(false);
- resp.note.ischanged(false);
- PO.notes().push(resp.note);
- }
- }
- },
- "oncomplete": function() {
- if (!newNote) {
- /* remove the old changed notes */
- var list = [];
- PO.notes(
- PO.notes().filter(
- function(o) {
- return (!(
- o.ischanged() || o.isnew() ||
- o.isdeleted()
- ));
- }
- )
- );
- }
-
- progressDialog.hide();
- self.updatePoNotesCount();
- self.drawPoNotes();
- }
- }
- );
- };
-
- this.hide = function() {
- openils.Util.hide("acq-po-notes-div");
- liTable.show("list");
- poItemTable.show();
- };
-
- this.show = function() {
- liTable.hide();
- poItemTable.hide();
- self.drawPoNotes();
- openils.Util.show("acq-po-notes-div");
- };
-}
-
-function updatePoState(po_info) {
- var data = po_info[PO.id()];
- if (data) {
- for (var key in data)
- PO[key](data[key]);
- renderPo();
- }
-}
-
-function cancellationUpdater(r) {
- var r = openils.Util.readResponse(r);
- if (r) {
- if (r.po) updatePoState(r.po);
- if (r.li) {
- for (var id in r.li) {
- liTable.liCache[id].state(r.li[id].state);
- liTable.liCache[id].cancel_reason(r.li[id].cancel_reason);
- liTable.updateLiState(liTable.liCache[id]);
- }
- }
- if (r.lid && liTable.copyCache) {
- for (var id in r.lid) {
- if (liTable.copyCache[id]) {
- liTable.copyCache[id].cancel_reason(
- r.lid[id].cancel_reason
- );
- liTable.updateLidState(liTable.copyCache[id]);
- }
- }
- }
- }
-}
-
-function makeProviderLink(node, provider) {
- return dojo.create(
- "a", {
- "href": oilsBasePath + "/conify/global/acq/provider/" + provider.id(),
- "innerHTML": provider.name() + " (" + provider.code() + ")",
- },
- node,
- "only"
- );
-}
-function makePrepayWidget(node, prepay) {
- if (prepay) {
- openils.Util.addCSSClass(node, "oils-acq-po-prepay");
- node.innerHTML = localeStrings.YES;
- } else {
- openils.Util.removeCSSClass(node, "oils-acq-po-prepay");
- node.innerHTML = localeStrings.NO;
- }
-}
-
-function makeCancelWidget(node, labelnode) {
- openils.Util.hide("acq-po-choose-cancel-reason");
-
- if (PO.cancel_reason()) {
- labelnode.innerHTML = localeStrings.CANCEL_REASON;
- node.innerHTML = PO.cancel_reason().description() + " (" +
- PO.cancel_reason().label() + ")";
- } else if (["on-order", "pending"].indexOf(PO.state()) == -1) {
- dojo.destroy(this.oldTip);
- labelnode.innerHTML = "";
- node.innerHTML = "";
- } else {
- dojo.destroy(this.oldTip);
- labelnode.innerHTML = localeStrings.CANCEL;
- node.innerHTML = "";
- if (!acqPoCancelReasonSubmit._prepared) {
- var widget = new openils.widget.AutoFieldWidget({
- "fmField": "cancel_reason",
- "fmClass": "acqpo",
- "parentNode": dojo.byId("acq-po-cancel-reason"),
- "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
- "forceSync": true
- });
- widget.build(
- function(w, ww) {
- acqPoCancelReasonSubmit.onClick = function() {
- if (w.attr("value")) {
- if (confirm(localeStrings.PO_CANCEL_CONFIRM)) {
- fieldmapper.standardRequest(
- ["open-ils.acq",
- "open-ils.acq.purchase_order.cancel"],
- {
- "params": [
- openils.User.authtoken,
- PO.id(),
- w.attr("value")
- ],
- "async": true,
- "oncomplete": cancellationUpdater
- }
- );
- }
- }
- };
- acqPoCancelReasonSubmit._prepared = true;
- }
- );
- }
- openils.Util.show("acq-po-choose-cancel-reason", "inline");
- }
-}
-
-function prepareInvoiceFeatures() {
- /* show the count of related invoices on the "view invoices" button */
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.invoice.unified_search.atomic"], {
- "params": [
- openils.User.authtoken,
- {"acqpo":[{"id": PO.id()}]},
- null,
- null,
- {"id_list": true}
- ],
- "async": true,
- "oncomplete": function(r) {
- dojo.byId("acq-po-view-invoice-count").innerHTML =
- openils.Util.readResponse(r).length;
- }
- }
- );
-
- /* view invoices button */
- dijit.byId("acq-po-view-invoice-link").onClick = function() {
- location.href = oilsBasePath + "/acq/search/unified?so=" +
- base64Encode({"acqpo":[{"id": PO.id()}]}) +
- "&rt=invoice";
- };
-
- /* create invoice button */
- dijit.byId("acq-po-create-invoice-link").onClick = function() {
- location.href = oilsBasePath +
- "/acq/invoice/view?create=1&attach_po=" + PO.id();
- };
-
- openils.Util.show("acq-po-invoice-stuff", "table-cell");
-}
-
-function renderPo() {
- dojo.byId("acq-po-view-id").innerHTML = PO.id();
- dojo.byId("acq-po-view-name").innerHTML = PO.name();
- makeProviderLink(
- dojo.byId("acq-po-view-provider"),
- PO.provider()
- );
- dojo.byId("acq-po-view-total-li").innerHTML = PO.lineitem_count();
- dojo.byId("acq-po-view-total-enc").innerHTML = PO.amount_encumbered().toFixed(2);
- dojo.byId("acq-po-view-total-spent").innerHTML = PO.amount_spent().toFixed(2);
- dojo.byId("acq-po-view-state").innerHTML = PO.state(); // TODO i18n
-
- if(PO.order_date()) {
- openils.Util.show('acq-po-activated-on', 'inline');
- dojo.byId('acq-po-activated-on').innerHTML =
- dojo.string.substitute(
- localeStrings.PO_ACTIVATED_ON, [
- openils.Util.timeStamp(PO.order_date(), {formatLength:'short'})
- ]
- );
-
- }
-
- makePrepayWidget(
- dojo.byId("acq-po-view-prepay"),
- openils.Util.isTrue(PO.prepayment_required())
- );
- makeCancelWidget(
- dojo.byId("acq-po-view-cancel-reason"),
- dojo.byId("acq-po-cancel-label")
- );
- // dojo.byId("acq-po-view-notes").innerHTML = PO.notes().length;
- poNoteTable.updatePoNotesCount();
-
- if (PO.state() == "pending") {
- checkCouldActivatePo();
- if (PO.lineitem_count() > 1)
- openils.Util.show("acq-po-split");
- } else {
- dojo.byId("acq-po-activate-checking").innerHTML = localeStrings.NO;
- }
-
- // XXX we probably don't *always* need to do this...
- poItemTable.reset();
- PO.po_items().forEach(
- function(po_item) { poItemTable.addItem(po_item); }
- );
- poItemTable.show();
-
- dojo.attr(
- "acq-po-view-history", "href",
- oilsBasePath + "/acq/po/history/" + PO.id()
- );
- openils.Util.show("acq-po-view-history", "inline");
-
- prepareInvoiceFeatures();
-}
-
-
-function init() {
- /* set up li table */
- liTable = new AcqLiTable();
- liTable.reset();
- liTable.isPO = poId;
- liTable.poUpdateCallback = updatePoState;
-
- /* set up po notes table */
- poNoteTable = new AcqPoNoteTable();
-
- /* retrieve data and populate */
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.retrieve'],
- { async: true,
- params: [openils.User.authtoken, poId, {
- "flesh_provider": true,
- "flesh_price_summary": true,
- "flesh_lineitem_count": true,
- "flesh_notes": true,
- "flesh_po_items": true
- }],
- oncomplete: function(r) {
- PO = openils.Util.readResponse(r); /* save PO globally */
-
- /* po item table */
- poItemTable = new PoItemTable(PO, pcrud);
-
- renderPo();
- }
- }
- );
-
- var totalEstimated = 0;
- var zeroLi = true;
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.search'],
- { async: true,
- params: [
- openils.User.authtoken,
- [{purchase_order:poId}, {"order_by": {"jub": "id ASC"}}],
- {flesh_attrs:true, flesh_notes:true, flesh_cancel_reason:true, clear_marc:true}
- ],
- onresponse: function(r) {
- zeroLi = false;
- liTable.show('list');
- var li = openils.Util.readResponse(r);
- // TODO: Add po_item's to total estimated amount
- totalEstimated += (Number(li.item_count() || 0) * Number(li.estimated_unit_price() || 0));
- liTable.addLineitem(li);
- },
-
- oncomplete : function() {
- dojo.byId("acq-po-view-total-estimated").innerHTML = totalEstimated.toFixed(2);
- if (liFocus) liTable.drawCopies(liFocus);
- if(zeroLi) openils.Util.show('acq-po-no-lineitems');
- }
- }
- );
-
- pcrud.search(
- 'acqedim',
- {purchase_order : poId},
- {
- id_list : true,
- oncomplete : function(r) {
- var resp = openils.Util.readResponse(r);
- // TODO: I18n
- if(resp) {
- dojo.byId('acq-po-view-edi-messages').innerHTML = '(' + resp.length + ')';
- dojo.byId('acq-po-view-edi-messages').setAttribute('href', oilsBasePath + '/acq/po/edi_messages/' + poId);
- } else {
- dojo.byId('acq-po-view-edi-messages').innerHTML = '0';
- dojo.byId('acq-po-view-edi-messages').setAttribute('href', '');
- }
- }
- }
- );
-}
-
-function checkCouldActivatePo() {
- var d = dojo.byId("acq-po-activate-checking");
- var a = dojo.byId("acq-po-activate-link");
- d.innerHTML = localeStrings.PO_CHECKING;
- var warnings = [];
- var stops = [];
- var other = [];
-
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.purchase_order.activate.dry_run"], {
- "params": [openils.User.authtoken, PO.id()],
- "async": true,
- "onresponse": function(r) {
- if ((r = openils.Util.readResponse(r, true /* eventOk */))) {
- if (typeof(r.textcode) != "undefined") {
- switch(r.textcode) {
- case "ACQ_FUND_EXCEEDS_STOP_PERCENT":
- stops.push(r);
- break;
- case "ACQ_FUND_EXCEEDS_WARN_PERCENT":
- warnings.push(r);
- break;
- default:
- other.push(r);
- }
- }
- }
- },
- "oncomplete": function() {
- /* XXX in the future, this might be tweaked to display info
- * about more than one stop or warning event from the ML. */
- if (!(warnings.length || stops.length || other.length)) {
- d.innerHTML = localeStrings.PO_COULD_ACTIVATE;
- openils.Util.show(a, "inline");
- } else {
- if (other.length) {
- /* XXX make the textcode part a tooltip one day */
- d.innerHTML = localeStrings.NO + ": " +
- other[0].desc + " (" + other[0].textcode + ")";
- openils.Util.hide(a);
- } else if (stops.length) {
- d.innerHTML =
- dojo.string.substitute(
- localeStrings.PO_STOP_BLOCKS_ACTIVATION, [
- stops[0].payload.fund.code(),
- stops[0].payload.fund.year()
- ]
- );
- openils.Util.hide(a);
- } else {
- PO._warning_hack = true;
- d.innerHTML =
- dojo.string.substitute(
- localeStrings.PO_WARNING_NO_BLOCK_ACTIVATION, [
- warnings[0].payload.fund.code(),
- warnings[0].payload.fund.year()
- ]
- );
- openils.Util.show(a, "inline");
- }
- }
- }
- }
- );
-}
-
-function activatePo() {
- if (openils.Util.isTrue(PO.prepayment_required())) {
- if (!confirm(localeStrings.PREPAYMENT_REQUIRED_REMINDER))
- return false;
- }
-
- if (PO._warning_hack) {
- if (!confirm(localeStrings.PO_FUND_WARNING_CONFIRM))
- return false;
- }
-
- liTable.showAssetCreator(activatePoStage2);
-}
-
-function activatePoStage2() {
-
- var want_refresh = false;
- progressDialog.show(true);
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.purchase_order.activate"], {
- "async": true,
- "params": [openils.User.authtoken, PO.id()],
- "onresponse": function(r) {
- want_refresh = Boolean(openils.Util.readResponse(r));
- },
- "oncomplete": function() {
- progressDialog.hide();
- if (want_refresh)
- location.href = location.href;
- }
- }
- );
-}
-
-function splitPo() {
- progressDialog.show(true);
- try {
- var list;
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.purchase_order.split_by_lineitems'],
- { async: true,
- params: [openils.User.authtoken, PO.id()],
- onresponse : function(r) {
- list = openils.Util.readResponse(r);
- },
- oncomplete : function() {
- progressDialog.hide();
- if (list) {
- location.href = oilsBasePath + '/acq/po/search/' +
- list.join(",");
- }
- }
- }
- );
- } catch(E) {
- progressDialog.hide();
- alert(E);
- }
-}
-
-function updatePoName() {
- var value = prompt('Enter new purchase order name:', PO.name()); // TODO i18n
- if(!value || value == PO.name()) return;
- PO.name(value);
- pcrud.update(PO, {
- oncomplete : function(r, cudResults) {
- var stat = cudResults[0];
- if(stat)
- dojo.byId('acq-po-view-name').innerHTML = value;
- }
- });
-}
-
-openils.Util.addOnLoad(init);
+require([
+ "dojo/string",
+ "dijit/layout/ContentPane",
+ "openils/PermaCrud"
+ ],
+function(dojo_string,
+ dijit_layout_ContentPane,
+ openils_PermaCrud){
+
+ var pcrud = new openils_PermaCrud();
+ var PO = null;
+ var liTable;
+ var poItemTable;
+ var poNoteTable;
+ var invoiceLinkDialogManager;
+
+ function AcqPoNoteTable() {
+ var self = this;
+
+ this.notesTbody = dojo.byId("acq-po-notes-tbody");
+ this.notesRow = this.notesTbody.removeChild(dojo.byId("acq-po-notes-row"));
+
+ dojo.byId("acq-po-notes-back-button").onclick = function() { self.hide(); };
+ dojo.byId("acq-po-view-notes").onclick = function() { self.show(); };
+
+ /* widgets' event properties are cased likeThis */
+ acqPoCreateNoteSubmit.onClick = function() {
+ if (!acqPoCreateNoteText.attr("value")) return;
+
+ /* prep new note */
+ var note = new acqpon();
+ note.vendor_public(
+ Boolean(acqPoCreateNoteVendorPublic.attr('checked'))
+ );
+ note.value(acqPoCreateNoteText.attr("value"));
+ note.purchase_order(PO.id());
+ note.isnew(true);
+
+ /* save it */
+ self.updatePoNotes(note);
+
+ /* reset fields for next use */
+ acqPoCreateNoteText.attr("value", "");
+ acqPoCreateNoteVendorPublic.attr("checked", false);
+ };
+
+ this.drawPoNote = function(note) {
+ if (note.isdeleted())
+ return;
+
+ var row = dojo.clone(this.notesRow);
+
+ nodeByName("value", row).innerHTML = note.value();
+
+ if (openils.Util.isTrue(note.vendor_public()))
+ nodeByName("vendor_public", row).innerHTML =
+ localeStrings.VENDOR_PUBLIC;
+
+ nodeByName("delete", row).onclick = function() {
+ note.isdeleted(true);
+ self.notesTbody.removeChild(row);
+ self.updatePoNotes();
+ };
+
+ if (note.edit_time()) {
+ nodeByName("edit_time", row).innerHTML =
+ dojo.date.locale.format(
+ dojo.date.stamp.fromISOString(note.edit_time()),
+ {"formatLength": "short"}
+ );
+ }
+
+ self.notesTbody.appendChild(row);
+ };
+
+ this.drawPoNotes = function() {
+ /* sort */
+ PO.notes(
+ PO.notes().sort(
+ function(a, b) {
+ return (a.edit_time() < b.edit_time()) ? 1 : -1;
+ }
+ )
+ );
+
+ /* remove old renderings of notes */
+ dojo.empty(this.notesTbody);
+
+ PO.notes().forEach(function(o) { self.drawPoNote(o); });
+ };
+
+ this.updatePoNotesCount = function() {
+ dojo.byId("acq-po-view-notes").innerHTML =
+ "(" + PO.notes().length + ")";
+ };
+
+ this.updatePoNotes = function(newNote) {
+ var notes = newNote ?
+ [newNote] :
+ PO.notes().filter(
+ function(o) {
+ if (o.ischanged() || o.isnew() || o.isdeleted())
+ return o;
+ }
+ );
+
+ if (notes.length < 1)
+ return;
+
+ progressDialog.show();
+
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.po_note.cud.batch"], {
+ "async": true,
+ "params": [openils.User.authtoken, notes],
+ "onresponse": function(r) {
+ var resp = openils.Util.readResponse(r);
+ if (resp) {
+ progressDialog.update(resp);
+
+ if (!resp.note.isdeleted()) {
+ resp.note.isnew(false);
+ resp.note.ischanged(false);
+ PO.notes().push(resp.note);
+ }
+ }
+ },
+ "oncomplete": function() {
+ if (!newNote) {
+ /* remove the old changed notes */
+ var list = [];
+ PO.notes(
+ PO.notes().filter(
+ function(o) {
+ return (!(
+ o.ischanged() || o.isnew() ||
+ o.isdeleted()
+ ));
+ }
+ )
+ );
+ }
+
+ progressDialog.hide();
+ self.updatePoNotesCount();
+ self.drawPoNotes();
+ }
+ }
+ );
+ };
+
+ this.hide = function() {
+ openils.Util.hide("acq-po-notes-div");
+ liTable.show("list");
+ poItemTable.show();
+ };
+
+ this.show = function() {
+ liTable.hide();
+ poItemTable.hide();
+ self.drawPoNotes();
+ openils.Util.show("acq-po-notes-div");
+ };
+ }
+
+ function updatePoState(po_info) {
+ var data = po_info[PO.id()];
+ if (data) {
+ for (var key in data)
+ PO[key](data[key]);
+ renderPo();
+ }
+ }
+
+ function cancellationUpdater(r) {
+ var r = openils.Util.readResponse(r);
+ if (r) {
+ if (r.po) updatePoState(r.po);
+ if (r.li) {
+ for (var id in r.li) {
+ liTable.liCache[id].state(r.li[id].state);
+ liTable.liCache[id].cancel_reason(r.li[id].cancel_reason);
+ liTable.updateLiState(liTable.liCache[id]);
+ }
+ }
+ if (r.lid && liTable.copyCache) {
+ for (var id in r.lid) {
+ if (liTable.copyCache[id]) {
+ liTable.copyCache[id].cancel_reason(
+ r.lid[id].cancel_reason
+ );
+ liTable.updateLidState(liTable.copyCache[id]);
+ }
+ }
+ }
+ }
+ }
+
+ function makeProviderLink(node, provider) {
+ return dojo.create(
+ "a", {
+ "href": oilsBasePath + "/conify/global/acq/provider/" + provider.id(),
+ "innerHTML": provider.name() + " (" + provider.code() + ")",
+ },
+ node,
+ "only"
+ );
+ }
+ function makePrepayWidget(node, prepay) {
+ if (prepay) {
+ openils.Util.addCSSClass(node, "oils-acq-po-prepay");
+ node.innerHTML = localeStrings.YES;
+ } else {
+ openils.Util.removeCSSClass(node, "oils-acq-po-prepay");
+ node.innerHTML = localeStrings.NO;
+ }
+ }
+
+ function makeCancelWidget(node, labelnode) {
+ openils.Util.hide("acq-po-choose-cancel-reason");
+
+ if (PO.cancel_reason()) {
+ labelnode.innerHTML = localeStrings.CANCEL_REASON;
+ node.innerHTML = PO.cancel_reason().description() + " (" +
+ PO.cancel_reason().label() + ")";
+ } else if (["on-order", "pending"].indexOf(PO.state()) == -1) {
+ dojo.destroy(this.oldTip);
+ labelnode.innerHTML = "";
+ node.innerHTML = "";
+ } else {
+ dojo.destroy(this.oldTip);
+ labelnode.innerHTML = localeStrings.CANCEL;
+ node.innerHTML = "";
+ if (!acqPoCancelReasonSubmit._prepared) {
+ var widget = new openils.widget.AutoFieldWidget({
+ "fmField": "cancel_reason",
+ "fmClass": "acqpo",
+ "parentNode": dojo.byId("acq-po-cancel-reason"),
+ "orgLimitPerms": ["CREATE_PURCHASE_ORDER"],
+ "forceSync": true
+ });
+ widget.build(
+ function(w, ww) {
+ acqPoCancelReasonSubmit.onClick = function() {
+ if (w.attr("value")) {
+ if (confirm(localeStrings.PO_CANCEL_CONFIRM)) {
+ fieldmapper.standardRequest(
+ ["open-ils.acq",
+ "open-ils.acq.purchase_order.cancel"],
+ {
+ "params": [
+ openils.User.authtoken,
+ PO.id(),
+ w.attr("value")
+ ],
+ "async": true,
+ "oncomplete": cancellationUpdater
+ }
+ );
+ }
+ }
+ };
+ acqPoCancelReasonSubmit._prepared = true;
+ }
+ );
+ }
+ openils.Util.show("acq-po-choose-cancel-reason", "inline");
+ }
+ }
+
+ function prepareInvoiceFeatures() {
+ /* show the count of related invoices on the "view invoices" button */
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.invoice.unified_search.atomic"], {
+ "params": [
+ openils.User.authtoken,
+ {"acqpo":[{"id": PO.id()}]},
+ null,
+ null,
+ {"id_list": true}
+ ],
+ "async": true,
+ "oncomplete": function(r) {
+ dojo.byId("acq-po-view-invoice-count").innerHTML =
+ openils.Util.readResponse(r).length;
+ }
+ }
+ );
+
+ /* view invoices button */
+ dijit.byId("acq-po-view-invoice-link").onClick = function() {
+ location.href = oilsBasePath + "/acq/search/unified?so=" +
+ base64Encode({"acqpo":[{"id": PO.id()}]}) +
+ "&rt=invoice";
+ };
+
+ /* create invoice button */
+ dijit.byId("acq-po-create-invoice-link").onClick = function() {
+ location.href = oilsBasePath +
+ "/acq/invoice/view?create=1&attach_po=" + PO.id();
+ };
+
+ openils.Util.show("acq-po-invoice-stuff", "table-cell");
+ }
+
+ function renderPo() {
+ dojo.byId("acq-po-view-id").innerHTML = PO.id();
+ dojo.byId("acq-po-view-name").innerHTML = PO.name();
+ makeProviderLink(
+ dojo.byId("acq-po-view-provider"),
+ PO.provider()
+ );
+ dojo.byId("acq-po-view-total-li").innerHTML = PO.lineitem_count();
+ dojo.byId("acq-po-view-total-enc").innerHTML = PO.amount_encumbered().toFixed(2);
+ dojo.byId("acq-po-view-total-spent").innerHTML = PO.amount_spent().toFixed(2);
+ dojo.byId("acq-po-view-state").innerHTML = PO.state(); // TODO i18n
+
+ if(PO.order_date()) {
+ openils.Util.show('acq-po-activated-on', 'inline');
+ dojo.byId('acq-po-activated-on').innerHTML =
+ dojo_string.substitute(
+ localeStrings.PO_ACTIVATED_ON, [
+ openils.Util.timeStamp(PO.order_date(), {formatLength:'short'})
+ ]
+ );
+
+ }
+
+ makePrepayWidget(
+ dojo.byId("acq-po-view-prepay"),
+ openils.Util.isTrue(PO.prepayment_required())
+ );
+ makeCancelWidget(
+ dojo.byId("acq-po-view-cancel-reason"),
+ dojo.byId("acq-po-cancel-label")
+ );
+ // dojo.byId("acq-po-view-notes").innerHTML = PO.notes().length;
+ poNoteTable.updatePoNotesCount();
+
+ if (PO.state() == "pending") {
+ checkCouldActivatePo();
+ if (PO.lineitem_count() > 1)
+ openils.Util.show("acq-po-split");
+ } else {
+ dojo.byId("acq-po-activate-checking").innerHTML = localeStrings.NO;
+ }
+
+ // XXX we probably don't *always* need to do this...
+ poItemTable.reset();
+ PO.po_items().forEach(
+ function(po_item) { poItemTable.addItem(po_item); }
+ );
+ poItemTable.show();
+
+ dojo.attr(
+ "acq-po-view-history", "href",
+ oilsBasePath + "/acq/po/history/" + PO.id()
+ );
+ openils.Util.show("acq-po-view-history", "inline");
+
+ prepareInvoiceFeatures();
+ }
+
+
+ function init() {
+ /* set up li table */
+ liTable = new AcqLiTable();
+ liTable.reset();
+ liTable.isPO = poId;
+ liTable.poUpdateCallback = updatePoState;
+
+ /* set up po notes table */
+ poNoteTable = new AcqPoNoteTable();
+
+ /* retrieve data and populate */
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.retrieve'],
+ { async: true,
+ params: [openils.User.authtoken, poId, {
+ "flesh_provider": true,
+ "flesh_price_summary": true,
+ "flesh_lineitem_count": true,
+ "flesh_notes": true,
+ "flesh_po_items": true
+ }],
+ oncomplete: function(r) {
+ PO = openils.Util.readResponse(r); /* save PO globally */
+
+ /* po item table */
+ poItemTable = new PoItemTable(PO, pcrud);
+
+ renderPo();
+ }
+ }
+ );
+
+ var totalEstimated = 0;
+ var zeroLi = true;
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem.search'],
+ { async: true,
+ params: [
+ openils.User.authtoken,
+ [{purchase_order:poId}, {"order_by": {"jub": "id ASC"}}],
+ {flesh_attrs:true, flesh_notes:true, flesh_cancel_reason:true, clear_marc:true}
+ ],
+ onresponse: function(r) {
+ zeroLi = false;
+ liTable.show('list');
+ var li = openils.Util.readResponse(r);
+ // TODO: Add po_item's to total estimated amount
+ totalEstimated += (Number(li.item_count() || 0) * Number(li.estimated_unit_price() || 0));
+ liTable.addLineitem(li);
+ },
+
+ oncomplete : function() {
+ dojo.byId("acq-po-view-total-estimated").innerHTML = totalEstimated.toFixed(2);
+ if (liFocus) liTable.drawCopies(liFocus);
+ if(zeroLi) openils.Util.show('acq-po-no-lineitems');
+ }
+ }
+ );
+
+ pcrud.search(
+ 'acqedim',
+ {purchase_order : poId},
+ {
+ id_list : true,
+ oncomplete : function(r) {
+ var resp = openils.Util.readResponse(r);
+ // TODO: I18n
+ if(resp) {
+ dojo.byId('acq-po-view-edi-messages').innerHTML = '(' + resp.length + ')';
+ dojo.byId('acq-po-view-edi-messages').setAttribute('href', oilsBasePath + '/acq/po/edi_messages/' + poId);
+ } else {
+ dojo.byId('acq-po-view-edi-messages').innerHTML = '0';
+ dojo.byId('acq-po-view-edi-messages').setAttribute('href', '');
+ }
+ }
+ }
+ );
+ }
+
+ function checkCouldActivatePo() {
+ var d = dojo.byId("acq-po-activate-checking");
+ var a = dojo.byId("acq-po-activate-link");
+ d.innerHTML = localeStrings.PO_CHECKING;
+ var warnings = [];
+ var stops = [];
+ var other = [];
+
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.purchase_order.activate.dry_run"], {
+ "params": [openils.User.authtoken, PO.id()],
+ "async": true,
+ "onresponse": function(r) {
+ if ((r = openils.Util.readResponse(r, true /* eventOk */))) {
+ if (typeof(r.textcode) != "undefined") {
+ switch(r.textcode) {
+ case "ACQ_FUND_EXCEEDS_STOP_PERCENT":
+ stops.push(r);
+ break;
+ case "ACQ_FUND_EXCEEDS_WARN_PERCENT":
+ warnings.push(r);
+ break;
+ default:
+ other.push(r);
+ }
+ }
+ }
+ },
+ "oncomplete": function() {
+ /* XXX in the future, this might be tweaked to display info
+ * about more than one stop or warning event from the ML. */
+ if (!(warnings.length || stops.length || other.length)) {
+ d.innerHTML = localeStrings.PO_COULD_ACTIVATE;
+ openils.Util.show(a, "inline");
+ } else {
+ if (other.length) {
+ /* XXX make the textcode part a tooltip one day */
+ d.innerHTML = localeStrings.NO + ": " +
+ other[0].desc + " (" + other[0].textcode + ")";
+ openils.Util.hide(a);
+ } else if (stops.length) {
+ d.innerHTML =
+ dojo_string.substitute(
+ localeStrings.PO_STOP_BLOCKS_ACTIVATION, [
+ stops[0].payload.fund.code(),
+ stops[0].payload.fund.year()
+ ]
+ );
+ openils.Util.hide(a);
+ } else {
+ PO._warning_hack = true;
+ d.innerHTML =
+ dojo_string.substitute(
+ localeStrings.PO_WARNING_NO_BLOCK_ACTIVATION, [
+ warnings[0].payload.fund.code(),
+ warnings[0].payload.fund.year()
+ ]
+ );
+ openils.Util.show(a, "inline");
+ }
+ }
+ }
+ }
+ );
+ }
+
+ function activatePo() {
+ if (openils.Util.isTrue(PO.prepayment_required())) {
+ if (!confirm(localeStrings.PREPAYMENT_REQUIRED_REMINDER))
+ return false;
+ }
+
+ if (PO._warning_hack) {
+ if (!confirm(localeStrings.PO_FUND_WARNING_CONFIRM))
+ return false;
+ }
+
+ liTable.showAssetCreator(activatePoStage2);
+ }
+
+ function activatePoStage2() {
+
+ var want_refresh = false;
+ progressDialog.show(true);
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.purchase_order.activate"], {
+ "async": true,
+ "params": [openils.User.authtoken, PO.id()],
+ "onresponse": function(r) {
+ want_refresh = Boolean(openils.Util.readResponse(r));
+ },
+ "oncomplete": function() {
+ progressDialog.hide();
+ if (want_refresh)
+ location.href = location.href;
+ }
+ }
+ );
+ }
+
+ function splitPo() {
+ progressDialog.show(true);
+ try {
+ var list;
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.purchase_order.split_by_lineitems'],
+ { async: true,
+ params: [openils.User.authtoken, PO.id()],
+ onresponse : function(r) {
+ list = openils.Util.readResponse(r);
+ },
+ oncomplete : function() {
+ progressDialog.hide();
+ if (list) {
+ location.href = oilsBasePath + '/acq/po/search/' +
+ list.join(",");
+ }
+ }
+ }
+ );
+ } catch(E) {
+ progressDialog.hide();
+ alert(E);
+ }
+ }
+
+ function updatePoName() {
+ var value = prompt('Enter new purchase order name:', PO.name()); // TODO i18n
+ if(!value || value == PO.name()) return;
+ PO.name(value);
+ pcrud.update(PO, {
+ oncomplete : function(r, cudResults) {
+ var stat = cudResults[0];
+ if(stat)
+ dojo.byId('acq-po-view-name').innerHTML = value;
+ }
+ });
+ }
+
+ openils.Util.addOnLoad(init);
+
+
+});
\ No newline at end of file
-dojo.require('fieldmapper.Fieldmapper');
-dojo.require('dijit.ProgressBar');
-dojo.require('dijit.form.Form');
-dojo.require('dijit.form.TextBox');
-dojo.require('dijit.form.CheckBox');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.form.Button');
-dojo.require("dijit.Dialog");
-dojo.require('openils.Event');
-dojo.require('openils.Util');
-dojo.require('openils.acq.Lineitem');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-
-var lineitems = [];
-
-function drawForm() {
- new openils.User().buildPermOrgSelector('VIEW_PURCHASE_ORDER', orderingAgencySelect);
-}
-
-var liReceived;
-function doSearch(values) {
-
- var search = {
- attr_values : [values.identifier],
- po_agencies : (values.ordering_agency) ? [values.ordering_agency] : null,
- li_states : ['in-process']
- };
-
- options = {clear_marc:1, flesh_attrs:1};
- liReceived = 0;
- dojo.style('searchProgress', 'visibility', 'visible');
-
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.lineitem.search.ident'],
- { async: true,
- params: [openils.User.authtoken, search, options],
- onresponse: handleResult,
- oncomplete: viewList
- }
- );
-}
-
-var searchLimit = 10; // ?
-function handleResult(r) {
- var result = r.recv().content();
- searchProgress.update({maximum: searchLimit, progress: ++liReceived});
- lineitems.push(result);
-}
-
-function viewList() {
- dojo.style('searchProgress', 'visibility', 'hidden');
- dojo.style('oils-acq-recv-grid', 'visibility', 'visible');
- var store = new dojo.data.ItemFileWriteStore(
- {data:jub.toStoreData(lineitems, null,
- {virtualFields:['estimated_price', 'actual_price']})});
- var model = new dojox.grid.data.DojoData(
- null, store, {rowsPerPage: 20, clientSort: true, query:{id:'*'}});
- JUBGrid.populate(liGrid, model, lineitems);
-}
-
-openils.Util.addOnLoad(drawForm);
+require([
+ "fieldmapper/Fieldmapper",
+ "dijit/ProgressBar",
+ "dijit/form/Form",
+ "dijit/form/TextBox",
+ "dijit/form/CheckBox",
+ "dijit/form/FilteringSelect",
+ "dijit/form/Button",
+ "dijit/Dialog",
+ "openils/Event",
+ "openils/Util",
+ "openils/acq/Lineitem",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(fieldmapper_Fieldmapper,
+ dijit_ProgressBar,
+ dijit_form_Form,
+ dijit_form_TextBox,
+ dijit_form_CheckBox,
+ dijit_form_FilteringSelect,
+ dijit_form_Button,
+ dijit_Dialog,
+ openils_Event,
+ openils_Util,
+ openils_acq_Lineitem,
+ openils_widget_OrgUnitFilteringSelect){
+
+ var lineitems = [];
+
+ function drawForm() {
+ new openils.User().buildPermOrgSelector('VIEW_PURCHASE_ORDER', orderingAgencySelect);
+ }
+
+ var liReceived;
+ function doSearch(values) {
+
+ var search = {
+ attr_values : [values.identifier],
+ po_agencies : (values.ordering_agency) ? [values.ordering_agency] : null,
+ li_states : ['in-process']
+ };
+
+ options = {clear_marc:1, flesh_attrs:1};
+ liReceived = 0;
+ dojo.style('searchProgress', 'visibility', 'visible');
+
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.lineitem.search.ident'],
+ { async: true,
+ params: [openils.User.authtoken, search, options],
+ onresponse: handleResult,
+ oncomplete: viewList
+ }
+ );
+ }
+
+ var searchLimit = 10; // ?
+ function handleResult(r) {
+ var result = r.recv().content();
+ searchProgress.update({maximum: searchLimit, progress: ++liReceived});
+ lineitems.push(result);
+ }
+
+ function viewList() {
+ dojo.style('searchProgress', 'visibility', 'hidden');
+ dojo.style('oils-acq-recv-grid', 'visibility', 'visible');
+ var store = new dojo.data.ItemFileWriteStore(
+ {data:jub.toStoreData(lineitems, null,
+ {virtualFields:['estimated_price', 'actual_price']})});
+ var model = new dojox.grid.data.DojoData(
+ null, store, {rowsPerPage: 20, clientSort: true, query:{id:'*'}});
+ JUBGrid.populate(liGrid, model, lineitems);
+ }
+
+ openils_Util.addOnLoad(drawForm);
+
+
+});
\ No newline at end of file
-dojo.require('openils.widget.ProgressDialog');
+require([
+ "openils/widget/ProgressDialog"
+ ],
+function(openils_widget_ProgressDialog){
+
+ function getInvIdent(rowIndex, item) {
+ if (item) {
+ return {
+ "inv_ident": this.grid.store.getValue(item, "inv_ident") ||
+ this.grid.store.getValue(item, "id"),
+ "id": this.grid.store.getValue(item, "id")
+ };
+ }
+ }
+
+ function formatInvIdent(inv) {
+ if (inv) {
+ return "<a href='" + oilsBasePath + "/acq/invoice/view/" +
+ inv.id + "'>" + inv.inv_ident + "</a>";
+ }
+ }
+
+ function printInvoiceVouchers() {
+ var inv_ids = dijit.byId("acq-unified-inv-grid").
+ getSelectedItems().map(function(o) {return o.id[0];});
+
+ progressDialog.show(true);
+
+ var html;
+ if (inv_ids.length) {
+ var win = null;
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.invoice.print.html"], {
+ "params": [openils.User.authtoken, inv_ids],
+ "async": true,
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ if(!html) {
+ html = "<style type='text/css'>.acq-invoice-" +
+ "voucher {page-break-after:always;}" +
+ "</style>\n";
+ }
+ html += r.template_output().data();
+ }
+ },
+ "oncomplete": function() {
+ progressDialog.hide();
+ openils.Util.printHtmlString(html);
+ }
+ }
+ );
+ }
+ }
+
-function getInvIdent(rowIndex, item) {
- if (item) {
- return {
- "inv_ident": this.grid.store.getValue(item, "inv_ident") ||
- this.grid.store.getValue(item, "id"),
- "id": this.grid.store.getValue(item, "id")
- };
- }
-}
-
-function formatInvIdent(inv) {
- if (inv) {
- return "<a href='" + oilsBasePath + "/acq/invoice/view/" +
- inv.id + "'>" + inv.inv_ident + "</a>";
- }
-}
-
-function printInvoiceVouchers() {
- var inv_ids = dijit.byId("acq-unified-inv-grid").
- getSelectedItems().map(function(o) {return o.id[0];});
-
- progressDialog.show(true);
-
- var html;
- if (inv_ids.length) {
- var win = null;
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.invoice.print.html"], {
- "params": [openils.User.authtoken, inv_ids],
- "async": true,
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- if(!html) {
- html = "<style type='text/css'>.acq-invoice-" +
- "voucher {page-break-after:always;}" +
- "</style>\n";
- }
- html += r.template_output().data();
- }
- },
- "oncomplete": function() {
- progressDialog.hide();
- openils.Util.printHtmlString(html);
- }
- }
- );
- }
-}
+});
\ No newline at end of file
-dojo.require("dojo.data.ItemFileWriteStore");
-dojo.require("dijit.Dialog");
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("dijit.form.Button");
-dojo.require("dojox.grid.cells.dijit");
-dojo.require("openils.acq.Picklist");
-dojo.require("openils.widget.ProgressDialog");
-
-function getPlOwnerName(rowIndex, item) {
- try {
- return resultManager.plCache[this.grid.store.getValue(item, "id")].
- owner().usrname();
- } catch (E) {
- return "";
- }
-}
-
-function formatPlName(pl) {
- if (pl) {
- return "<a href='" + oilsBasePath + "/acq/picklist/view/" +
- pl.id + "'>" + pl.name + "</a>";
- }
-}
-
-function deleteSelectedPl() {
- var grid = resultManager.result_types.picklist.interface;
-
- progressDialog.show(true);
-
- openils.acq.Picklist.deleteList(
- grid.getSelectedItems().map(
- function(item) {
- var id = grid.store.getValue(item, "id");
- grid.store.deleteItem(item);
- return id;
- }
- ), function() { progressDialog.hide(); }
- );
-}
-
-function cloneSelectedPl(fields) {
- var grid = resultManager.result_types.picklist.interface;
-
- var item = grid.getSelectedItems()[0];
- if (!item) return;
-
- var plId = grid.store.getValue(item, "id");
- var entryCount = Number(grid.store.getValue(item, "entry_count"));
-
- progressDialog.show();
- progressDialog.update({"maximum": entryCount, "progress": 0});
-
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.picklist.clone"], {
- "async": true,
- "params": [openils.User.authtoken, plId, fields.name],
- "onresponse": function(r) {
- var resp = openils.Util.readResponse(r);
- if (resp) {
- progressDialog.update({"progress": resp.li});
-
- if (resp.complete) {
- progressDialog.hide();
- var pl = resp.picklist;
- pl.owner(openils.User.user);
- pl.entry_count(entryCount);
- resultManager.plCache[pl.id()] = pl;
- grid.store.newItem(fieldmapper.acqpl.toStoreItem(pl));
- }
- }
- }
- }
- );
-}
-
-function loadLeadPlSelector() {
- var grid = resultManager.result_types.picklist.interface;
- var data = acqpl.initStoreData();
- var store = new dojo.data.ItemFileWriteStore({"data": data});
-
- grid.getSelectedItems().forEach(
- function(item) {
- store.newItem(
- fieldmapper.acqpl.toStoreItem(
- resultManager.plCache[grid.store.getValue(item, "id")]
- )
- );
- }
- );
-
- plMergeLeadSelector.store = store;
- plMergeLeadSelector.startup();
-}
-
-function mergeSelectedPl(fields) {
- var grid = resultManager.result_types.picklist.interface;
-
- if (!fields.lead) return;
-
- var ids = [];
- var totalLi = 0;
- var leadPl = resultManager.plCache[fields.lead];
- var leadPlItem;
-
- grid.getSelectedItems().forEach(
- function(item) {
- var id = grid.store.getValue(item, "id");
- if (id == fields.lead) {
- leadPlItem = item;
- return;
- }
- totalLi += new Number(grid.store.getValue(item, "entry_count"));
- ids.push(id);
- }
- );
-
- progressDialog.show();
- progressDialog.update({"maximum": totalLi, "progress": 0});
-
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.picklist.merge"], {
- "async": true,
- "params": [openils.User.authtoken, fields.lead, ids],
- "onresponse": function(r) {
- var resp = openils.Util.readResponse(r);
- if (resp) {
- if (resp.li)
- progressDialog.update({"progress": resp.li});
-
- if (resp.complete) {
- progressDialog.hide();
- leadPl.entry_count(leadPl.entry_count() + totalLi);
-
- grid.store.setValue(
- leadPlItem, "entry_count", leadPl.entry_count()
- );
- if (resp.picklist) {
- grid.store.setValue(
- leadPlItem, "edit_time",
- resp.picklist.edit_time()
- );
- }
-
- // remove the deleted lists from the grid
- grid.getSelectedItems().filter(
- function(o) {
- return grid.store.getValue(o, "id") !=
- fields.lead;
- }
- ).forEach(function(o) { grid.store.deleteItem(o); });
- }
- }
- }
- }
- );
-}
-
-function createPl(fields) {
- if (fields.name == '') return;
-
- var grid = resultManager.result_types.picklist.interface;
-
- openils.acq.Picklist.create(fields,
- function(plId) {
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.picklist.retrieve.authoritative"], {
- "async": true,
- "params": [
- openils.User.authtoken, plId,
- {"flesh_lineitem_count": 1, "flesh_owner": 1}
- ],
- "oncomplete": function(r) {
- var pl = openils.Util.readResponse(r);
- if (pl) {
- resultManager.plCache[pl.id()] = pl;
- grid.store.newItem(
- acqpl.toStoreData([pl]).items[0]
- );
- }
- }
- }
- );
- }
- );
-}
-
+require([
+ "dojo/data/ItemFileWriteStore",
+ "dijit/Dialog",
+ "dijit/form/Button",
+ "dijit/form/TextBox",
+ "dijit/form/FilteringSelect",
+ "dijit/form/Button",
+ "dojox/grid/cells/dijit",
+ "openils/acq/Picklist",
+ "openils/widget/ProgressDialog"
+ ],
+function(dojo_data_ItemFileWriteStore,
+ dijit_Dialog,
+ dijit_form_Button,
+ dijit_form_TextBox,
+ dijit_form_FilteringSelect,
+ dijit_form_Button,
+ dojox_grid_cells_dijit,
+ openils_acq_Picklist,
+ openils_widget_ProgressDialog){
+
+ function getPlOwnerName(rowIndex, item) {
+ try {
+ return resultManager.plCache[this.grid.store.getValue(item, "id")].
+ owner().usrname();
+ } catch (E) {
+ return "";
+ }
+ }
+
+ function formatPlName(pl) {
+ if (pl) {
+ return "<a href='" + oilsBasePath + "/acq/picklist/view/" +
+ pl.id + "'>" + pl.name + "</a>";
+ }
+ }
+
+ function deleteSelectedPl() {
+ var grid = resultManager.result_types.picklist.interface;
+
+ progressDialog.show(true);
+
+ openils_acq_Picklist.deleteList(
+ grid.getSelectedItems().map(
+ function(item) {
+ var id = grid.store.getValue(item, "id");
+ grid.store.deleteItem(item);
+ return id;
+ }
+ ), function() { progressDialog.hide(); }
+ );
+ }
+
+ function cloneSelectedPl(fields) {
+ var grid = resultManager.result_types.picklist.interface;
+
+ var item = grid.getSelectedItems()[0];
+ if (!item) return;
+
+ var plId = grid.store.getValue(item, "id");
+ var entryCount = Number(grid.store.getValue(item, "entry_count"));
+
+ progressDialog.show();
+ progressDialog.update({"maximum": entryCount, "progress": 0});
+
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.picklist.clone"], {
+ "async": true,
+ "params": [openils.User.authtoken, plId, fields.name],
+ "onresponse": function(r) {
+ var resp = openils.Util.readResponse(r);
+ if (resp) {
+ progressDialog.update({"progress": resp.li});
+
+ if (resp.complete) {
+ progressDialog.hide();
+ var pl = resp.picklist;
+ pl.owner(openils.User.user);
+ pl.entry_count(entryCount);
+ resultManager.plCache[pl.id()] = pl;
+ grid.store.newItem(fieldmapper.acqpl.toStoreItem(pl));
+ }
+ }
+ }
+ }
+ );
+ }
+
+ function loadLeadPlSelector() {
+ var grid = resultManager.result_types.picklist.interface;
+ var data = acqpl.initStoreData();
+ var store = new dojo_data_ItemFileWriteStore({"data": data});
+
+ grid.getSelectedItems().forEach(
+ function(item) {
+ store.newItem(
+ fieldmapper.acqpl.toStoreItem(
+ resultManager.plCache[grid.store.getValue(item, "id")]
+ )
+ );
+ }
+ );
+
+ plMergeLeadSelector.store = store;
+ plMergeLeadSelector.startup();
+ }
+
+ function mergeSelectedPl(fields) {
+ var grid = resultManager.result_types.picklist.interface;
+
+ if (!fields.lead) return;
+
+ var ids = [];
+ var totalLi = 0;
+ var leadPl = resultManager.plCache[fields.lead];
+ var leadPlItem;
+
+ grid.getSelectedItems().forEach(
+ function(item) {
+ var id = grid.store.getValue(item, "id");
+ if (id == fields.lead) {
+ leadPlItem = item;
+ return;
+ }
+ totalLi += new Number(grid.store.getValue(item, "entry_count"));
+ ids.push(id);
+ }
+ );
+
+ progressDialog.show();
+ progressDialog.update({"maximum": totalLi, "progress": 0});
+
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.picklist.merge"], {
+ "async": true,
+ "params": [openils.User.authtoken, fields.lead, ids],
+ "onresponse": function(r) {
+ var resp = openils.Util.readResponse(r);
+ if (resp) {
+ if (resp.li)
+ progressDialog.update({"progress": resp.li});
+
+ if (resp.complete) {
+ progressDialog.hide();
+ leadPl.entry_count(leadPl.entry_count() + totalLi);
+
+ grid.store.setValue(
+ leadPlItem, "entry_count", leadPl.entry_count()
+ );
+ if (resp.picklist) {
+ grid.store.setValue(
+ leadPlItem, "edit_time",
+ resp.picklist.edit_time()
+ );
+ }
+
+ // remove the deleted lists from the grid
+ grid.getSelectedItems().filter(
+ function(o) {
+ return grid.store.getValue(o, "id") !=
+ fields.lead;
+ }
+ ).forEach(function(o) { grid.store.deleteItem(o); });
+ }
+ }
+ }
+ }
+ );
+ }
+
+ function createPl(fields) {
+ if (fields.name == '') return;
+
+ var grid = resultManager.result_types.picklist.interface;
+
+ openils_acq_Picklist.create(fields,
+ function(plId) {
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.picklist.retrieve.authoritative"], {
+ "async": true,
+ "params": [
+ openils.User.authtoken, plId,
+ {"flesh_lineitem_count": 1, "flesh_owner": 1}
+ ],
+ "oncomplete": function(r) {
+ var pl = openils.Util.readResponse(r);
+ if (pl) {
+ resultManager.plCache[pl.id()] = pl;
+ grid.store.newItem(
+ acqpl.toStoreData([pl]).items[0]
+ );
+ }
+ }
+ }
+ );
+ }
+ );
+ }
+
+
+
+});
\ No newline at end of file
-dojo.require("dojo.date.stamp");
-dojo.require("dojox.encoding.base64");
-dojo.require("openils.widget.AutoGrid");
-dojo.require("openils.widget.AutoWidget");
-dojo.require("openils.widget.XULTermLoader");
-dojo.require("openils.PermaCrud");
-
-if (!localeStrings) { /* we can do this because javascript doesn't have block
- scope */
- dojo.requireLocalization('openils.acq', 'acq');
- var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
-}
-
-var termSelectorFactory;
-var termManager;
-var resultManager;
-var uriManager;
-var pcrud = new openils.PermaCrud();
-var cgi = new openils.CGI();
-
-/* typing save: add {get,set}Value() to all HTML <select> elements */
-HTMLSelectElement.prototype.getValue = function() {
- return this.options[this.selectedIndex].value;
-}
-
-/* only sets the selected value if such an option is actually available */
-HTMLSelectElement.prototype.setValue = function(s) {
- for (var i = 0; i < this.options.length; i++) {
- if (s == this.options[i].value) {
- this.selectedIndex = i;
- break;
- }
- }
-}
-
-/* minor formatting function used by autogrids in unified.tt2 */
-function getName(rowIndex, item) {
- if (item) {
- return {
- "name": this.grid.store.getValue(item, "name") ||
- localeStrings.UNNAMED,
- "id": this.grid.store.getValue(item, "id")
- };
- }
-}
-
-/* quickly find elements by the value of a "name" attribute */
-function nodeByName(name, root) {
- return dojo.query("[name='" + name + "']", root)[0];
-}
-
-function hideForm() {
- openils.Util.hide("acq-unified-hide-form");
- openils.Util.show("acq-unified-reveal-form", "inline");
- openils.Util.hide("acq-unified-form");
-}
-
-function revealForm() {
- openils.Util.hide("acq-unified-reveal-form");
- openils.Util.show("acq-unified-hide-form", "inline");
- openils.Util.show("acq-unified-form");
-}
-
-/* The TermSelectorFactory will be instantiated by the TermManager. It
- * provides HTML select controls whose options are all the searchable
- * fields. Selecting a field from one of these controls will create the
- * appopriate type of corresponding widget for the user to enter a search
- * term against the selected field.
- */
-function TermSelectorFactory(terms) {
- var self = this;
- this.terms = terms;
- this.onlyBibFriendly = false;
-
- this.template = dojo.create("select");
- this.template.appendChild(
- dojo.create("option", {
- "disabled": "disabled",
- "selected": "selected",
- "value": "",
- "innerHTML": localeStrings.SELECT_SEARCH_FIELD
- })
- );
-
- /* Create abbreviations for class names to make field categories
- * more readable in field selector control. */
- this._abbreviate = function(s) {
- var last, result;
- for (var i = 0; i < s.length; i++) {
- if (s[i] != " ") {
- if (!i) result = s[i];
- else if (last == " ") result += s[i];
- }
- last = s[i];
- }
- return result;
- };
-
- var selectorMethods = {
- /* Important: within the following functions, "this" refers to one
- * HTMLSelect object, and "self" refers to the TermSelectorFactory. */
- "getTerm": function() { return this.valueToTerm(this.getValue()); },
- "valueToTerm": function(value) {
- var parts = value.split(":");
- if (!parts || parts.length != 2) return null;
- return dojo.mixin(
- self.terms[parts[0]][parts[1]],
- {"hint": parts[0], "field": parts[1]}
- );
- },
- "onlyBibFriendly": function(yes) {
- if (yes) {
- for (var i = 0; i < this.options.length; i++) {
- if (this.options[i].value) {
- var term = this.valueToTerm(this.options[i].value);
- this.options[i].disabled = !term.bib_friendly;
- }
- }
- } else {
- for (var i = 0; i < this.options.length; i++) {
- if (this.options[i].value)
- this.options[i].disabled = false;
- }
- }
- },
- "makeWidget": function(
- parentNode, wStore, matchHow, value, noFocus, callback
- ) {
- var term = this.getTerm();
- var widgetKey = this.uniq;
- if (matchHow.getValue() == "__in") {
- new openils.widget.XULTermLoader({
- "parentNode": parentNode
- }).build(
- function(w) {
- wStore[widgetKey] = w;
- if (typeof(callback) == "function")
- callback(term, widgetKey);
- if (typeof(value) != "undefined")
- w.attr("value", value);
- /* I would love for the following call not to be
- * necessary, so that updating the value of the dijit
- * would lead to this automatically, but I can't yet
- * figure out the correct way to do this in Dojo.
- */
- w.updateCount();
- }
- );
- } else if (term.hint == "acqlia" ||
- (term.hint == "jub" && term.field == "eg_bib_id")) {
- /* The test for jub.eg_bib_id is a special case to prevent
- * AutoFieldWidget from trying to render a ridiculous dropdown
- * of every bib record ID in the system. */
- wStore[widgetKey] = dojo.create(
- "input", {"type": "text"}, parentNode, "only"
- );
- if (typeof(value) != "undefined")
- wStore[widgetKey].value = value;
- if (!noFocus)
- wStore[widgetKey].focus();
- if (typeof(callback) == "function")
- callback(term, widgetKey);
- } else {
- new openils.widget.AutoFieldWidget({
- "fmClass": term.hint,
- "fmField": term.field,
- "noDisablePkey": true,
- "parentNode": dojo.create("span", null, parentNode, "only")
- }).build(
- function(w) {
- wStore[widgetKey] = w;
- if (typeof(value) != "undefined") {
- if (w.declaredClass.match(/Check/))
- w.attr("checked", value == "t");
- else
- w.attr("value", value);
- }
- if (!noFocus)
- w.focus();
- if (typeof(callback) == "function")
- callback(term, widgetKey);
-
- // submit on enter
- openils.Util.registerEnterHandler(w.domNode,
- function() {
- resultManager.go(termManager.buildSearchObject());
- }
- );
- }
- );
- }
- }
- }
-
- for (var hint in this.terms) {
- var optgroup = dojo.create(
- "optgroup", {"value": "", "label": this.terms[hint].__label}
- );
- var prefix = this._abbreviate(this.terms[hint].__label);
-
- for (var field in this.terms[hint]) {
- if (!/^__/.test(field)) {
- optgroup.appendChild(
- dojo.create("option", {
- "class": "acq-unified-option-regular",
- "value": hint + ":" + field,
- "innerHTML": prefix + " - " +
- this.terms[hint][field].label
- })
- );
- }
- }
-
- this.template.appendChild(optgroup);
- }
-
- this.make = function(n) {
- var node = dojo.clone(this.template);
- node.uniq = n;
- dojo.attr(node, "id", "term-" + n);
- for (var name in selectorMethods)
- node[name] = selectorMethods[name];
- if (this.onlyBibFriendly)
- node.onlyBibFriendly(true);
- return node;
- };
-}
-
-/* The term manager retrieves information from the IDL about all the fields
- * in the classes that we consider searchable for our purpose. It maintains
- * a dynamic HTML table of search terms, using the TermSelectorFactory
- * to generate search field selectors, which in turn provide appropriate
- * widgets for entering search terms. The TermManager provides search term
- * modifiers (fuzzy searching, not searching). The TermManager also handles
- * adding and removing rows of search terms, as well as building the search
- * query to pass to the middle layer from the search term widgets.
- */
-function TermManager() {
- var self = this;
-
- /* All the keys in this object are bib-search-friendly attributes, but the
- * boolean values indicate whether they should be searched by their
- * field name as such, or simply mapped to "keyword". */
- this.bibFriendlyAttrNames = {
- "author": true, "title": true,
- "isbn": false, "issn": false, "upc": false
- };
-
- this.terms = {};
- ["jub", "acqpl", "acqpo", "acqinv"].forEach(
- function(hint) {
- var o = {};
- o.__label = fieldmapper.IDL.fmclasses[hint].label;
- fieldmapper.IDL.fmclasses[hint].fields.forEach(
- function(field) {
- if (!field.virtual) {
- o[field.name] = {
- "label": field.label, "datatype": field.datatype
- };
- }
- }
- );
- self.terms[hint] = o;
- }
- );
-
- this.terms.acqlia = {"__label": fieldmapper.IDL.fmclasses.acqlia.label};
- pcrud.retrieveAll("acqliad", {"order_by": {"acqliad": "id"}}).forEach(
- function(def) {
- self.terms.acqlia[def.id()] = {
- "label": def.description(),
- "datatype": "text",
- "bib_friendly":
- (typeof(self.bibFriendlyAttrNames[def.code()]) !=
- "undefined"),
- "bib_attr_name":
- self.bibFriendlyAttrNames[def.code()] ?
- def.code() : "keyword"
- };
- }
- );
-
- this.selectorFactory = new TermSelectorFactory(this.terms);
- this.template = dojo.byId("acq-unified-terms-tbody").
- removeChild(dojo.byId("acq-unified-terms-row-tmpl"));
- dojo.attr(this.template, "id");
-
- this.lastResultType = null;
-
- this.rowId = 0;
- this.widgets = {};
-
- dojo.byId("acq-unified-result-type").onchange = function() {
- self.resultTypeChange(this.getValue());
- };
-
- this.allRowIds = function() {
- return dojo.query("tr[id^='term-row-']", "acq-unified-terms-tbody").
- map(function(o) { return o.id.match(/^term-row-(\d+)$/)[1]; });
- };
-
- this._row = function(id) { return dojo.byId("term-row-" + id); };
- this._selector = function(id) { return dojo.byId("term-" + id); };
- this._match_how = function(id) { return dojo.byId("term-match-" + id); };
-
- this._updateMatchHowForField = function(term, key) {
- /* NOTE important to use self, not this, in this function.
- *
- * Based on the selected field (its datatype and the kind of widget
- * that AutoFieldWidget provides for it) we update the possible
- * choices in the mach_how selector.
- */
- var w = self.widgets[key];
- var can_do_fuzzy, can_do_in;
- if (term.datatype == "id") {
- can_do_fuzzy = false;
- can_do_in = true;
- } else if (term.datatype == "link") {
- var target = self.getLinkTarget(term);
- can_do_fuzzy = (target == "au");
- can_do_in = (target == "bre"); /* XXX might revise later */
- } else if (typeof(w.declaredClass) != "undefined") {
- can_do_fuzzy = can_do_in =
- Boolean(w.declaredClass.match(/form\.Text|XULT/));
- } else {
- var type = dojo.attr(w, "type");
- if (type)
- can_do_fuzzy = can_do_in = (type == "text");
- else
- can_do_fuzzy = can_do_in = false;
- }
-
- self.matchHowAllow(key, "__fuzzy", can_do_fuzzy);
- self.matchHowAllow(key, "__in", can_do_in);
-
- var inequalities = (term.datatype == "timestamp");
- self.matchHowAllow(key, "__gte", inequalities);
- self.matchHowAllow(key, "__lte", inequalities);
- };
-
- this.removerButton = function(n) {
- return dojo.create("button", {
- "innerHTML": "X",
- "class": "acq-unified-remover",
- "onclick": function() { self.removeRow(n); }
- });
- };
-
- this.matchHowAllow = function(where, what, which, exact) {
- dojo.query(
- "option[value" + (exact ? "" : "*") + "='" + what + "']",
- typeof(where) == "object" ? where : this._match_how(where)
- ).forEach(function(o) { o.disabled = !which; });
- };
-
- this.getLinkTarget = function(term) {
- return fieldmapper.IDL.fmclasses[term.hint].
- field_map[term.field]["class"];
- };
-
- this.updateRowWidget = function(id, value, noFocus) {
- var where = nodeByName("widget", this._row(id));
-
- delete this.widgets[id];
- dojo.empty(where);
-
- this._selector(id).makeWidget(
- where, this.widgets, this._match_how(id), value, noFocus,
- this._updateMatchHowForField
- );
- };
-
- this.resultTypeChange = function(resultType) {
- if (
- this.lastResultType == "lineitem_and_bib" &&
- resultType != "lineitem_and_bib"
- ) {
- /* Re-enable all non-bib-friendly fields in all search term
- * field selectors. */
- this.allRowIds().forEach(
- function(id) {
- self._selector(id).onlyBibFriendly(false);
- self.matchHowAllow(id, "", true, /* exact */ true);
- self.matchHowAllow(id, "__not", true, /* exact */ true);
- }
- );
- /* Tell the selector factory to create new search term field
- * selectors with all fields, not just bib-friendly ones. */
- this.selectorFactory.onlyBibFriendly = false;
- } else if (
- this.lastResultType != "lineitem_and_bib" &&
- resultType == "lineitem_and_bib"
- ) {
- /* Remove all search term rows set to non-bib-friendly fields. */
- this.allRowIds().forEach(
- function(id) {
- var term = self._selector(id).getTerm();
- if (term &&
- !self.terms[term.hint][term.field].bib_friendly) {
- self.removeRow(id);
- }
- }
- );
- /* Disable all non-bib-friendly fields in all remaining search term
- * field selectors. */
- this.allRowIds().forEach(
- function(id) {
- self._selector(id).onlyBibFriendly(true);
- self.matchHowAllow(id, "", false, /* exact */ true);
- self.matchHowAllow(id, "__not", false, /* exact */ true);
- }
- );
- /* Tell the selector factory to create new search term field
- * selectors with only bib friendly options. */
- this.selectorFactory.onlyBibFriendly = true;
- }
- this.lastResultType = resultType;
- };
-
- /* this method is particularly kludgy... puts back together a string
- * based on object properties that might arrive in indeterminate order. */
- this._term_reverse_match_how = function(term) {
- /* only two-key combination we use */
- if (term.__not && term.__fuzzy)
- return "__not,__fuzzy";
-
- /* only other possibilities are single-key or no key */
- for (var key in term) {
- if (/^__/.test(key))
- return key;
- }
-
- return null;
- };
-
-
- this._term_reverse_selector_field = function(term) {
- for (var key in term) {
- if (!/^__/.test(key))
- return key;
- }
- return null;
- };
-
- this._term_reverse_selector_value = function(term) {
- for (var key in term) {
- if (!/^__/.test(key))
- return term[key];
- }
- return null;
- };
-
- this.addRow = function(term, hint) {
- var uniq = (this.rowId)++;
-
- var row = dojo.clone(this.template);
- dojo.attr(row, "id", "term-row-" + uniq);
-
- var selector = this.selectorFactory.make(uniq);
- dojo.attr(
- selector, "onchange", function() { self.updateRowWidget(uniq); }
- );
-
- var match_how = dojo.query("select", nodeByName("match", row))[0];
- dojo.attr(match_how, "id", "term-match-" + uniq);
- dojo.attr(match_how, "selectedIndex", 0);
- dojo.attr(
- match_how, "onchange",
- function() {
- if (this.getValue() == "__in") {
- self.updateRowWidget(uniq);
- this.was_in = true;
- } else if (this.was_in) {
- self.updateRowWidget(uniq);
- this.was_in = false;
- }
- if (self.widgets[uniq]) self.widgets[uniq].focus();
- }
- );
-
- /* Kind of inelegant; could be improved: this section turns off
- * match-type options that don't apply to bib searching. */
- this.matchHowAllow(
- match_how, "",
- !this.selectorFactory.onlyBibFriendly, /* exact */ true
- );
- this.matchHowAllow(
- match_how, "__not",
- !this.selectorFactory.onlyBibFriendly, /* exact */ true
- );
- if (this.selectorFactory.onlyBibFriendly)
- match_how.setValue("__fuzzy");
-
- nodeByName("selector", row).appendChild(selector);
- nodeByName("remove", row).appendChild(this.removerButton(uniq));
-
- dojo.place(row, "acq-unified-terms-tbody", "last");
-
- if (term && hint) {
- var attr = this._term_reverse_selector_field(term);
- var field = hint + ":" + attr;
- selector.setValue(field);
-
- var match_how_value = this._term_reverse_match_how(term);
- if (match_how_value)
- match_how.setValue(match_how_value);
-
- var value = this._term_reverse_selector_value(term);
- if (this.terms[hint][attr].datatype == "timestamp")
- value = dojo.date.stamp.fromISOString(value);
- this.updateRowWidget(uniq, value, /* noFocus */ true);
-
- }
- }
-
- this.removeRow = function(id) {
- delete this.widgets[id];
- dojo.destroy(this._row(id));
- };
-
- this.reflect = function(search_object) {
- for (var hint in search_object) {
- search_object[hint].forEach(
- function(term) { self.addRow(term, hint); }
- );
- }
- };
-
- this.buildSearchObject = function() {
- var so = {};
-
- for (var id in this.widgets) {
- var kvlist = this._selector(id).getValue().split(":");
- var hint = kvlist[0];
- var attr = kvlist[1];
- if (!(hint && attr)) continue;
-
- var match_how =
- this._match_how(id).getValue().split(",").filter(Boolean);
-
- var value;
- if (typeof(this.widgets[id].declaredClass) != "undefined") {
- if (this.widgets[id].declaredClass.match(/Date/)) {
- value =
- dojo.date.stamp.toISOString(this.widgets[id].value).
- split("T")[0];
- } else {
- value = this.widgets[id].attr("value");
- if (this.widgets[id].declaredClass.match(/Check/))
- value = (value == "on") ? "t" : "f";
- }
- } else {
- value = this.widgets[id].value;
- }
-
- if (!so[hint])
- so[hint] = [];
-
- var unit = {};
- unit[attr] = value;
- match_how.forEach(function(key) { unit[key] = true; });
- if (this.terms[hint][attr].datatype == "timestamp")
- unit.__castdate = true;
-
- so[hint].push(unit);
- }
- return so;
- };
-
- this.buildBibSearchString = function() {
- var conj = {"and": " ", "or": " || "}[
- dojo.byId("acq-unified-conjunction").getValue()
- ];
-
- var sso = {};
- /* Notice that below we use conj in two places and a constant " || "
- * in one. That constant " || " is applied for the "file of terms"
- * search term type, which is in itself always an or search. */
- for (var id in this.widgets) {
- var term = this._selector(id).getTerm();
- var attr = term.bib_attr_name;
- var match_how = this._match_how(id).getValue();
- var widget = this.widgets[id];
-
- if (!sso[attr]) sso[attr] = [];
- var value = (
- typeof(widget.attr) == "function" ?
- widget.attr("value") : widget.value
- );
- if (typeof(value) != "string")
- value = value.join(" || ");
- sso[attr].push(
- (match_how.indexOf("__not") == -1 ? "" : "-") + value
- );
- }
- var ssa = [];
- for (var attr in sso)
- ssa.push(attr + ": " + sso[attr].join(conj));
- return "(" + ssa.join(conj) + ")";
- };
-}
-
-/* The result manager is used primarily when the users submits a search. It
- * consults the termManager to get the search query to send to the middl
- * layer, and it chooses which ML method to call as well as what widgets to use
- * to display the results.
- */
-function ResultManager(liPager, poGrid, plGrid, invGrid) {
- var self = this;
-
- this.liPager = liPager;
-
- this.poGrid = poGrid;
- this.plGrid = plGrid;
- this.invGrid = invGrid;
- this.poCache = {};
- this.plCache = {};
- this.invCache = {};
-
- this.result_types = {
- "lineitem": {
- "search_options": {
- "flesh_attrs": true,
- "flesh_cancel_reason": true,
- "flesh_notes": true
- },
- "revealer": function() {
- self.liPager.show();
- progressDialog.show(true);
- },
- "finisher": function() {
- self.liPager.batch_length = self.count_results;
- self.liPager.relabelControls();
- self.liPager.enableControls(true);
- progressDialog.hide();
- },
- "adder": function(li) {
- self.liPager.liTable.addLineitem(li);
- },
- "interface": self.liPager
- },
- "purchase_order": {
- "search_options": {
- "no_flesh_cancel_reason": true
- },
- "revealer": function() {
- self.poGrid.resetStore();
- self.poGrid.showLoadProgressIndicator();
- self.poCache = {};
- },
- "finisher": function() {
- self.poGrid.hideLoadProgressIndicator();
- },
- "adder": function(po) {
- self.poCache[po.id()] = po;
- self.poGrid.store.newItem(acqpo.toStoreItem(po));
- },
- "interface": self.poGrid
- },
- "picklist": {
- "search_options": {
- "flesh_lineitem_count": true,
- "flesh_owner": true
- },
- "revealer": function() {
- self.plGrid.resetStore();
- self.plGrid.showLoadProgressIndicator();
- self.plCache = {};
- },
- "finisher": function() {
- self.plGrid.hideLoadProgressIndicator();
- },
- "adder": function(pl) {
- self.plCache[pl.id()] = pl;
- self.plGrid.store.newItem(acqpl.toStoreItem(pl));
- },
- "interface": self.plGrid
- },
- "invoice": {
- "search_options": {
- "no_flesh_misc": true
- },
- "finisher": function() {
- self.invGrid.hideLoadProgressIndicator();
- },
- "revealer": function() {
- self.invGrid.resetStore();
- self.invCache = {};
- },
- "adder": function(inv) {
- self.invCache[inv.id()] = inv;
- self.invGrid.store.newItem(acqinv.toStoreItem(inv));
- },
- "interface": self.invGrid
- },
- "no_results": {
- "revealer": function() { alert(localeStrings.NO_RESULTS); }
- }
- };
-
- this._dataLoader = function(opts) {
- /* This function must contain references to "self" only, not "this." */
- var grid = self.result_types[self.result_type].interface;
-
- if (!opts)
- opts = {};
-
- self.count_results = 0;
-
- var use_params = dojo.clone(self.params); /* need copy, not ref */
-
- if (!opts.skip_paging) {
- use_params[4].offset = grid.displayOffset;
- use_params[4].limit = grid.displayLimit;
- }
-
- var method = self.method_name;
- if (opts.atomic)
- method += ".atomic";
-
- if (opts.id_list)
- use_params[4].id_list = true;
-
- var request_options = {
- "params": use_params,
- "async": true
- };
-
- if (typeof opts.onresponse != "undefined") {
- request_options.onresponse = opts.onresponse;
- } else {
- /* normal onresponse handler for most times we call this method */
- request_options.onresponse = function(r) {
- if (r = openils.Util.readResponse(r)) {
- if (!self.count_results++)
- self.show(self.result_type);
- self.add(self.result_type, r);
- }
- };
- }
-
- if (typeof opts.oncomplete != "undefined") {
- request_options.oncomplete = opts.oncomplete;
- } else {
- /* normal oncomplete handler for most times we call this method */
- request_options.oncomplete = function() { self.resultsComplete(); };
- }
-
- fieldmapper.standardRequest(["open-ils.acq", method], request_options);
- };
-
- this.add = function(which, what) {
- var f = this.result_types[which].adder;
- if (f) f(what);
- };
-
- this.finish = function(which) {
- var f = this.result_types[which].finisher;
- if (f) f();
- };
-
- this.show = function(which) {
- openils.Util.objectProperties(this.result_types).forEach(
- function(rt) {
- openils.Util[rt == which ? "show" : "hide"](
- "acq-unified-results-" + rt
- );
- }
- );
- this.result_types[which].revealer();
- };
-
- this.resultsComplete = function() {
- if (!this.count_results)
- this.show("no_results");
- else this.finish(this.result_type);
- };
-
- this.go = function(search_object) {
- location.href = oilsBasePath + "/acq/search/unified?" +
- "so=" + base64Encode(search_object) +
- "&rt=" + dojo.byId("acq-unified-result-type").getValue() +
- "&c=" + dojo.byId("acq-unified-conjunction").getValue();
- };
-
- this.search = function(uriManager, termManager) {
- var bib_search_string = null;
- this.count_results = 0;
- this.result_type = dojo.byId("acq-unified-result-type").getValue();
-
- /* lineitem_and_bib: a special case */
- if (this.result_type == "lineitem_and_bib") {
- this.result_type = "lineitem";
- bib_search_string = termManager.buildBibSearchString();
- }
-
- this.method_name = "open-ils.acq." + this.result_type +
- ".unified_search";
- /* Except for building the API method name that we want to call,
- * we want to treat lineitem_and_bib the same way as lineitem from
- * here forward. */
-
- this.params = [
- openils.User.authtoken,
- null, null, null,
- this.result_types[this.result_type].search_options
- ];
-
- this.params[
- dojo.byId("acq-unified-conjunction").getValue() == "and" ? 1 : 2
- ] = uriManager.search_object;
- if (uriManager.order_by)
- this.params[4].order_by = uriManager.order_by;
-
- var interface = this.result_types[this.result_type].interface;
- interface.dataLoader = this._dataLoader;
-
- if (bib_search_string) {
- /* Have the ML do the bib search first, which incidentally has the
- * side effect of creating line items that will show up when
- * we do the LI part of the search (so we don't actually want
- * to display these results directly). */
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.biblio.wrapped_search.atomic"], {
- "params": [
- openils.User.authtoken, bib_search_string, {
- "clear_marc": true
- }
- ],
- "onresponse": function(r) {
- r = openils.Util.readResponse(r, false, true);
- }
- }
- );
- }
-
- interface.dataLoader();
- };
-}
-
-function URIManager() {
- var self = this;
- this.cannedSearches = {
- "po": {
- "search_object": {
- "acqpo": [
- {"ordering_agency": openils.User.user.ws_ou()},
- {"state": "on-order"}
- ]
- },
- "half_search": true,
- "result_type": "purchase_order",
- "conjunction": "and",
- "order_by": [
- {"class": "acqpo", "field": "edit_time", "direction": "desc"}
- ]
- },
- "pl": {
- "search_object": {
- "acqpl": [
- {"owner": openils.User.user.usrname()}
- ]
- },
- "result_type": "picklist",
- "conjunction": "and",
- "order_by": [
- {"class": "acqpl", "field": "edit_time", "direction": "desc"}
- ]
- },
- "inv": {
- "search_object": {
- "acqinv": [
- {"complete": "f"},
- {"receiver": openils.User.user.ws_ou()}
- ]
- },
- "half_search": true,
- "result_type": "invoice",
- "conjunction": "and",
- "order_by": [
- {"class": "acqinv", "field": "recv_date", "direction": "desc"}
- ]
- }
- };
-
- if (this.canned = cgi.param("ca")) { /* assignment */
- dojo.mixin(this, this.cannedSearches[this.canned]);
- dojo.byId("acq-unified-result-type").setValue(this.result_type);
- dojo.byId("acq-unified-result-type").onchange();
- dojo.byId("acq-unified-conjunction").setValue(this.conjunction);
- } else {
- this.search_object = cgi.param("so");
- if (this.search_object)
- this.search_object = base64Decode(this.search_object);
-
- this.result_type = cgi.param("rt");
- if (this.result_type) {
- dojo.byId("acq-unified-result-type").setValue(this.result_type);
- dojo.byId("acq-unified-result-type").onchange();
- }
-
- this.conjunction = cgi.param("c");
- if (this.conjunction)
- dojo.byId("acq-unified-conjunction").setValue(this.conjunction);
- }
-}
-
-/* onload */
-openils.Util.addOnLoad(
- function() {
- termManager = new TermManager();
- resultManager = new ResultManager(
- new LiTablePager(null, new AcqLiTable()),
- dijit.byId("acq-unified-po-grid"),
- dijit.byId("acq-unified-pl-grid"),
- dijit.byId("acq-unified-inv-grid")
- );
-
- uriManager = new URIManager();
- if (uriManager.search_object) {
- if (!uriManager.half_search)
- hideForm();
- openils.Util.show("acq-unified-body");
- termManager.reflect(uriManager.search_object);
-
- if (!uriManager.half_search)
- resultManager.search(uriManager, termManager);
- } else {
- termManager.addRow();
- openils.Util.show("acq-unified-body");
- }
- }
-);
+require([
+ "dojo/date/stamp",
+ "dojox/encoding/base64",
+ "openils/widget/AutoGrid",
+ "openils/widget/AutoWidget",
+ "openils/widget/XULTermLoader",
+ "openils/PermaCrud"
+ ],
+function(dojo_date_stamp,
+ dojox_encoding_base64,
+ openils_widget_AutoGrid,
+ openils_widget_AutoWidget,
+ openils_widget_XULTermLoader,
+ openils_PermaCrud){
+
+ if (!localeStrings) { /* we can do this because javascript doesn't have block
+ scope */
+ dojo.requireLocalization('openils.acq', 'acq');
+ var localeStrings = dojo.i18n.getLocalization('openils.acq', 'acq');
+ }
+
+ var termSelectorFactory;
+ var termManager;
+ var resultManager;
+ var uriManager;
+ var pcrud = new openils_PermaCrud();
+ var cgi = new openils.CGI();
+
+ /* typing save: add {get,set}Value() to all HTML <select> elements */
+ HTMLSelectElement.prototype.getValue = function() {
+ return this.options[this.selectedIndex].value;
+ }
+
+ /* only sets the selected value if such an option is actually available */
+ HTMLSelectElement.prototype.setValue = function(s) {
+ for (var i = 0; i < this.options.length; i++) {
+ if (s == this.options[i].value) {
+ this.selectedIndex = i;
+ break;
+ }
+ }
+ }
+
+ /* minor formatting function used by autogrids in unified.tt2 */
+ function getName(rowIndex, item) {
+ if (item) {
+ return {
+ "name": this.grid.store.getValue(item, "name") ||
+ localeStrings.UNNAMED,
+ "id": this.grid.store.getValue(item, "id")
+ };
+ }
+ }
+
+ /* quickly find elements by the value of a "name" attribute */
+ function nodeByName(name, root) {
+ return dojo.query("[name='" + name + "']", root)[0];
+ }
+
+ function hideForm() {
+ openils.Util.hide("acq-unified-hide-form");
+ openils.Util.show("acq-unified-reveal-form", "inline");
+ openils.Util.hide("acq-unified-form");
+ }
+
+ function revealForm() {
+ openils.Util.hide("acq-unified-reveal-form");
+ openils.Util.show("acq-unified-hide-form", "inline");
+ openils.Util.show("acq-unified-form");
+ }
+
+ /* The TermSelectorFactory will be instantiated by the TermManager. It
+ * provides HTML select controls whose options are all the searchable
+ * fields. Selecting a field from one of these controls will create the
+ * appopriate type of corresponding widget for the user to enter a search
+ * term against the selected field.
+ */
+ function TermSelectorFactory(terms) {
+ var self = this;
+ this.terms = terms;
+ this.onlyBibFriendly = false;
+
+ this.template = dojo.create("select");
+ this.template.appendChild(
+ dojo.create("option", {
+ "disabled": "disabled",
+ "selected": "selected",
+ "value": "",
+ "innerHTML": localeStrings.SELECT_SEARCH_FIELD
+ })
+ );
+
+ /* Create abbreviations for class names to make field categories
+ * more readable in field selector control. */
+ this._abbreviate = function(s) {
+ var last, result;
+ for (var i = 0; i < s.length; i++) {
+ if (s[i] != " ") {
+ if (!i) result = s[i];
+ else if (last == " ") result += s[i];
+ }
+ last = s[i];
+ }
+ return result;
+ };
+
+ var selectorMethods = {
+ /* Important: within the following functions, "this" refers to one
+ * HTMLSelect object, and "self" refers to the TermSelectorFactory. */
+ "getTerm": function() { return this.valueToTerm(this.getValue()); },
+ "valueToTerm": function(value) {
+ var parts = value.split(":");
+ if (!parts || parts.length != 2) return null;
+ return dojo.mixin(
+ self.terms[parts[0]][parts[1]],
+ {"hint": parts[0], "field": parts[1]}
+ );
+ },
+ "onlyBibFriendly": function(yes) {
+ if (yes) {
+ for (var i = 0; i < this.options.length; i++) {
+ if (this.options[i].value) {
+ var term = this.valueToTerm(this.options[i].value);
+ this.options[i].disabled = !term.bib_friendly;
+ }
+ }
+ } else {
+ for (var i = 0; i < this.options.length; i++) {
+ if (this.options[i].value)
+ this.options[i].disabled = false;
+ }
+ }
+ },
+ "makeWidget": function(
+ parentNode, wStore, matchHow, value, noFocus, callback
+ ) {
+ var term = this.getTerm();
+ var widgetKey = this.uniq;
+ if (matchHow.getValue() == "__in") {
+ new openils_widget_XULTermLoader({
+ "parentNode": parentNode
+ }).build(
+ function(w) {
+ wStore[widgetKey] = w;
+ if (typeof(callback) == "function")
+ callback(term, widgetKey);
+ if (typeof(value) != "undefined")
+ w.attr("value", value);
+ /* I would love for the following call not to be
+ * necessary, so that updating the value of the dijit
+ * would lead to this automatically, but I can't yet
+ * figure out the correct way to do this in Dojo.
+ */
+ w.updateCount();
+ }
+ );
+ } else if (term.hint == "acqlia" ||
+ (term.hint == "jub" && term.field == "eg_bib_id")) {
+ /* The test for jub.eg_bib_id is a special case to prevent
+ * AutoFieldWidget from trying to render a ridiculous dropdown
+ * of every bib record ID in the system. */
+ wStore[widgetKey] = dojo.create(
+ "input", {"type": "text"}, parentNode, "only"
+ );
+ if (typeof(value) != "undefined")
+ wStore[widgetKey].value = value;
+ if (!noFocus)
+ wStore[widgetKey].focus();
+ if (typeof(callback) == "function")
+ callback(term, widgetKey);
+ } else {
+ new openils.widget.AutoFieldWidget({
+ "fmClass": term.hint,
+ "fmField": term.field,
+ "noDisablePkey": true,
+ "parentNode": dojo.create("span", null, parentNode, "only")
+ }).build(
+ function(w) {
+ wStore[widgetKey] = w;
+ if (typeof(value) != "undefined") {
+ if (w.declaredClass.match(/Check/))
+ w.attr("checked", value == "t");
+ else
+ w.attr("value", value);
+ }
+ if (!noFocus)
+ w.focus();
+ if (typeof(callback) == "function")
+ callback(term, widgetKey);
+
+ // submit on enter
+ openils.Util.registerEnterHandler(w.domNode,
+ function() {
+ resultManager.go(termManager.buildSearchObject());
+ }
+ );
+ }
+ );
+ }
+ }
+ }
+
+ for (var hint in this.terms) {
+ var optgroup = dojo.create(
+ "optgroup", {"value": "", "label": this.terms[hint].__label}
+ );
+ var prefix = this._abbreviate(this.terms[hint].__label);
+
+ for (var field in this.terms[hint]) {
+ if (!/^__/.test(field)) {
+ optgroup.appendChild(
+ dojo.create("option", {
+ "class": "acq-unified-option-regular",
+ "value": hint + ":" + field,
+ "innerHTML": prefix + " - " +
+ this.terms[hint][field].label
+ })
+ );
+ }
+ }
+
+ this.template.appendChild(optgroup);
+ }
+
+ this.make = function(n) {
+ var node = dojo.clone(this.template);
+ node.uniq = n;
+ dojo.attr(node, "id", "term-" + n);
+ for (var name in selectorMethods)
+ node[name] = selectorMethods[name];
+ if (this.onlyBibFriendly)
+ node.onlyBibFriendly(true);
+ return node;
+ };
+ }
+
+ /* The term manager retrieves information from the IDL about all the fields
+ * in the classes that we consider searchable for our purpose. It maintains
+ * a dynamic HTML table of search terms, using the TermSelectorFactory
+ * to generate search field selectors, which in turn provide appropriate
+ * widgets for entering search terms. The TermManager provides search term
+ * modifiers (fuzzy searching, not searching). The TermManager also handles
+ * adding and removing rows of search terms, as well as building the search
+ * query to pass to the middle layer from the search term widgets.
+ */
+ function TermManager() {
+ var self = this;
+
+ /* All the keys in this object are bib-search-friendly attributes, but the
+ * boolean values indicate whether they should be searched by their
+ * field name as such, or simply mapped to "keyword". */
+ this.bibFriendlyAttrNames = {
+ "author": true, "title": true,
+ "isbn": false, "issn": false, "upc": false
+ };
+
+ this.terms = {};
+ ["jub", "acqpl", "acqpo", "acqinv"].forEach(
+ function(hint) {
+ var o = {};
+ o.__label = fieldmapper.IDL.fmclasses[hint].label;
+ fieldmapper.IDL.fmclasses[hint].fields.forEach(
+ function(field) {
+ if (!field.virtual) {
+ o[field.name] = {
+ "label": field.label, "datatype": field.datatype
+ };
+ }
+ }
+ );
+ self.terms[hint] = o;
+ }
+ );
+
+ this.terms.acqlia = {"__label": fieldmapper.IDL.fmclasses.acqlia.label};
+ pcrud.retrieveAll("acqliad", {"order_by": {"acqliad": "id"}}).forEach(
+ function(def) {
+ self.terms.acqlia[def.id()] = {
+ "label": def.description(),
+ "datatype": "text",
+ "bib_friendly":
+ (typeof(self.bibFriendlyAttrNames[def.code()]) !=
+ "undefined"),
+ "bib_attr_name":
+ self.bibFriendlyAttrNames[def.code()] ?
+ def.code() : "keyword"
+ };
+ }
+ );
+
+ this.selectorFactory = new TermSelectorFactory(this.terms);
+ this.template = dojo.byId("acq-unified-terms-tbody").
+ removeChild(dojo.byId("acq-unified-terms-row-tmpl"));
+ dojo.attr(this.template, "id");
+
+ this.lastResultType = null;
+
+ this.rowId = 0;
+ this.widgets = {};
+
+ dojo.byId("acq-unified-result-type").onchange = function() {
+ self.resultTypeChange(this.getValue());
+ };
+
+ this.allRowIds = function() {
+ return dojo.query("tr[id^='term-row-']", "acq-unified-terms-tbody").
+ map(function(o) { return o.id.match(/^term-row-(\d+)$/)[1]; });
+ };
+
+ this._row = function(id) { return dojo.byId("term-row-" + id); };
+ this._selector = function(id) { return dojo.byId("term-" + id); };
+ this._match_how = function(id) { return dojo.byId("term-match-" + id); };
+
+ this._updateMatchHowForField = function(term, key) {
+ /* NOTE important to use self, not this, in this function.
+ *
+ * Based on the selected field (its datatype and the kind of widget
+ * that AutoFieldWidget provides for it) we update the possible
+ * choices in the mach_how selector.
+ */
+ var w = self.widgets[key];
+ var can_do_fuzzy, can_do_in;
+ if (term.datatype == "id") {
+ can_do_fuzzy = false;
+ can_do_in = true;
+ } else if (term.datatype == "link") {
+ var target = self.getLinkTarget(term);
+ can_do_fuzzy = (target == "au");
+ can_do_in = (target == "bre"); /* XXX might revise later */
+ } else if (typeof(w.declaredClass) != "undefined") {
+ can_do_fuzzy = can_do_in =
+ Boolean(w.declaredClass.match(/form\.Text|XULT/));
+ } else {
+ var type = dojo.attr(w, "type");
+ if (type)
+ can_do_fuzzy = can_do_in = (type == "text");
+ else
+ can_do_fuzzy = can_do_in = false;
+ }
+
+ self.matchHowAllow(key, "__fuzzy", can_do_fuzzy);
+ self.matchHowAllow(key, "__in", can_do_in);
+
+ var inequalities = (term.datatype == "timestamp");
+ self.matchHowAllow(key, "__gte", inequalities);
+ self.matchHowAllow(key, "__lte", inequalities);
+ };
+
+ this.removerButton = function(n) {
+ return dojo.create("button", {
+ "innerHTML": "X",
+ "class": "acq-unified-remover",
+ "onclick": function() { self.removeRow(n); }
+ });
+ };
+
+ this.matchHowAllow = function(where, what, which, exact) {
+ dojo.query(
+ "option[value" + (exact ? "" : "*") + "='" + what + "']",
+ typeof(where) == "object" ? where : this._match_how(where)
+ ).forEach(function(o) { o.disabled = !which; });
+ };
+
+ this.getLinkTarget = function(term) {
+ return fieldmapper.IDL.fmclasses[term.hint].
+ field_map[term.field]["class"];
+ };
+
+ this.updateRowWidget = function(id, value, noFocus) {
+ var where = nodeByName("widget", this._row(id));
+
+ delete this.widgets[id];
+ dojo.empty(where);
+
+ this._selector(id).makeWidget(
+ where, this.widgets, this._match_how(id), value, noFocus,
+ this._updateMatchHowForField
+ );
+ };
+
+ this.resultTypeChange = function(resultType) {
+ if (
+ this.lastResultType == "lineitem_and_bib" &&
+ resultType != "lineitem_and_bib"
+ ) {
+ /* Re-enable all non-bib-friendly fields in all search term
+ * field selectors. */
+ this.allRowIds().forEach(
+ function(id) {
+ self._selector(id).onlyBibFriendly(false);
+ self.matchHowAllow(id, "", true, /* exact */ true);
+ self.matchHowAllow(id, "__not", true, /* exact */ true);
+ }
+ );
+ /* Tell the selector factory to create new search term field
+ * selectors with all fields, not just bib-friendly ones. */
+ this.selectorFactory.onlyBibFriendly = false;
+ } else if (
+ this.lastResultType != "lineitem_and_bib" &&
+ resultType == "lineitem_and_bib"
+ ) {
+ /* Remove all search term rows set to non-bib-friendly fields. */
+ this.allRowIds().forEach(
+ function(id) {
+ var term = self._selector(id).getTerm();
+ if (term &&
+ !self.terms[term.hint][term.field].bib_friendly) {
+ self.removeRow(id);
+ }
+ }
+ );
+ /* Disable all non-bib-friendly fields in all remaining search term
+ * field selectors. */
+ this.allRowIds().forEach(
+ function(id) {
+ self._selector(id).onlyBibFriendly(true);
+ self.matchHowAllow(id, "", false, /* exact */ true);
+ self.matchHowAllow(id, "__not", false, /* exact */ true);
+ }
+ );
+ /* Tell the selector factory to create new search term field
+ * selectors with only bib friendly options. */
+ this.selectorFactory.onlyBibFriendly = true;
+ }
+ this.lastResultType = resultType;
+ };
+
+ /* this method is particularly kludgy... puts back together a string
+ * based on object properties that might arrive in indeterminate order. */
+ this._term_reverse_match_how = function(term) {
+ /* only two-key combination we use */
+ if (term.__not && term.__fuzzy)
+ return "__not,__fuzzy";
+
+ /* only other possibilities are single-key or no key */
+ for (var key in term) {
+ if (/^__/.test(key))
+ return key;
+ }
+
+ return null;
+ };
+
+
+ this._term_reverse_selector_field = function(term) {
+ for (var key in term) {
+ if (!/^__/.test(key))
+ return key;
+ }
+ return null;
+ };
+
+ this._term_reverse_selector_value = function(term) {
+ for (var key in term) {
+ if (!/^__/.test(key))
+ return term[key];
+ }
+ return null;
+ };
+
+ this.addRow = function(term, hint) {
+ var uniq = (this.rowId)++;
+
+ var row = dojo.clone(this.template);
+ dojo.attr(row, "id", "term-row-" + uniq);
+
+ var selector = this.selectorFactory.make(uniq);
+ dojo.attr(
+ selector, "onchange", function() { self.updateRowWidget(uniq); }
+ );
+
+ var match_how = dojo.query("select", nodeByName("match", row))[0];
+ dojo.attr(match_how, "id", "term-match-" + uniq);
+ dojo.attr(match_how, "selectedIndex", 0);
+ dojo.attr(
+ match_how, "onchange",
+ function() {
+ if (this.getValue() == "__in") {
+ self.updateRowWidget(uniq);
+ this.was_in = true;
+ } else if (this.was_in) {
+ self.updateRowWidget(uniq);
+ this.was_in = false;
+ }
+ if (self.widgets[uniq]) self.widgets[uniq].focus();
+ }
+ );
+
+ /* Kind of inelegant; could be improved: this section turns off
+ * match-type options that don't apply to bib searching. */
+ this.matchHowAllow(
+ match_how, "",
+ !this.selectorFactory.onlyBibFriendly, /* exact */ true
+ );
+ this.matchHowAllow(
+ match_how, "__not",
+ !this.selectorFactory.onlyBibFriendly, /* exact */ true
+ );
+ if (this.selectorFactory.onlyBibFriendly)
+ match_how.setValue("__fuzzy");
+
+ nodeByName("selector", row).appendChild(selector);
+ nodeByName("remove", row).appendChild(this.removerButton(uniq));
+
+ dojo.place(row, "acq-unified-terms-tbody", "last");
+
+ if (term && hint) {
+ var attr = this._term_reverse_selector_field(term);
+ var field = hint + ":" + attr;
+ selector.setValue(field);
+
+ var match_how_value = this._term_reverse_match_how(term);
+ if (match_how_value)
+ match_how.setValue(match_how_value);
+
+ var value = this._term_reverse_selector_value(term);
+ if (this.terms[hint][attr].datatype == "timestamp")
+ value = dojo_date_stamp.fromISOString(value);
+ this.updateRowWidget(uniq, value, /* noFocus */ true);
+
+ }
+ }
+
+ this.removeRow = function(id) {
+ delete this.widgets[id];
+ dojo.destroy(this._row(id));
+ };
+
+ this.reflect = function(search_object) {
+ for (var hint in search_object) {
+ search_object[hint].forEach(
+ function(term) { self.addRow(term, hint); }
+ );
+ }
+ };
+
+ this.buildSearchObject = function() {
+ var so = {};
+
+ for (var id in this.widgets) {
+ var kvlist = this._selector(id).getValue().split(":");
+ var hint = kvlist[0];
+ var attr = kvlist[1];
+ if (!(hint && attr)) continue;
+
+ var match_how =
+ this._match_how(id).getValue().split(",").filter(Boolean);
+
+ var value;
+ if (typeof(this.widgets[id].declaredClass) != "undefined") {
+ if (this.widgets[id].declaredClass.match(/Date/)) {
+ value =
+ dojo_date_stamp.toISOString(this.widgets[id].value).
+ split("T")[0];
+ } else {
+ value = this.widgets[id].attr("value");
+ if (this.widgets[id].declaredClass.match(/Check/))
+ value = (value == "on") ? "t" : "f";
+ }
+ } else {
+ value = this.widgets[id].value;
+ }
+
+ if (!so[hint])
+ so[hint] = [];
+
+ var unit = {};
+ unit[attr] = value;
+ match_how.forEach(function(key) { unit[key] = true; });
+ if (this.terms[hint][attr].datatype == "timestamp")
+ unit.__castdate = true;
+
+ so[hint].push(unit);
+ }
+ return so;
+ };
+
+ this.buildBibSearchString = function() {
+ var conj = {"and": " ", "or": " || "}[
+ dojo.byId("acq-unified-conjunction").getValue()
+ ];
+
+ var sso = {};
+ /* Notice that below we use conj in two places and a constant " || "
+ * in one. That constant " || " is applied for the "file of terms"
+ * search term type, which is in itself always an or search. */
+ for (var id in this.widgets) {
+ var term = this._selector(id).getTerm();
+ var attr = term.bib_attr_name;
+ var match_how = this._match_how(id).getValue();
+ var widget = this.widgets[id];
+
+ if (!sso[attr]) sso[attr] = [];
+ var value = (
+ typeof(widget.attr) == "function" ?
+ widget.attr("value") : widget.value
+ );
+ if (typeof(value) != "string")
+ value = value.join(" || ");
+ sso[attr].push(
+ (match_how.indexOf("__not") == -1 ? "" : "-") + value
+ );
+ }
+ var ssa = [];
+ for (var attr in sso)
+ ssa.push(attr + ": " + sso[attr].join(conj));
+ return "(" + ssa.join(conj) + ")";
+ };
+ }
+
+ /* The result manager is used primarily when the users submits a search. It
+ * consults the termManager to get the search query to send to the middl
+ * layer, and it chooses which ML method to call as well as what widgets to use
+ * to display the results.
+ */
+ function ResultManager(liPager, poGrid, plGrid, invGrid) {
+ var self = this;
+
+ this.liPager = liPager;
+
+ this.poGrid = poGrid;
+ this.plGrid = plGrid;
+ this.invGrid = invGrid;
+ this.poCache = {};
+ this.plCache = {};
+ this.invCache = {};
+
+ this.result_types = {
+ "lineitem": {
+ "search_options": {
+ "flesh_attrs": true,
+ "flesh_cancel_reason": true,
+ "flesh_notes": true
+ },
+ "revealer": function() {
+ self.liPager.show();
+ progressDialog.show(true);
+ },
+ "finisher": function() {
+ self.liPager.batch_length = self.count_results;
+ self.liPager.relabelControls();
+ self.liPager.enableControls(true);
+ progressDialog.hide();
+ },
+ "adder": function(li) {
+ self.liPager.liTable.addLineitem(li);
+ },
+ "interface": self.liPager
+ },
+ "purchase_order": {
+ "search_options": {
+ "no_flesh_cancel_reason": true
+ },
+ "revealer": function() {
+ self.poGrid.resetStore();
+ self.poGrid.showLoadProgressIndicator();
+ self.poCache = {};
+ },
+ "finisher": function() {
+ self.poGrid.hideLoadProgressIndicator();
+ },
+ "adder": function(po) {
+ self.poCache[po.id()] = po;
+ self.poGrid.store.newItem(acqpo.toStoreItem(po));
+ },
+ "interface": self.poGrid
+ },
+ "picklist": {
+ "search_options": {
+ "flesh_lineitem_count": true,
+ "flesh_owner": true
+ },
+ "revealer": function() {
+ self.plGrid.resetStore();
+ self.plGrid.showLoadProgressIndicator();
+ self.plCache = {};
+ },
+ "finisher": function() {
+ self.plGrid.hideLoadProgressIndicator();
+ },
+ "adder": function(pl) {
+ self.plCache[pl.id()] = pl;
+ self.plGrid.store.newItem(acqpl.toStoreItem(pl));
+ },
+ "interface": self.plGrid
+ },
+ "invoice": {
+ "search_options": {
+ "no_flesh_misc": true
+ },
+ "finisher": function() {
+ self.invGrid.hideLoadProgressIndicator();
+ },
+ "revealer": function() {
+ self.invGrid.resetStore();
+ self.invCache = {};
+ },
+ "adder": function(inv) {
+ self.invCache[inv.id()] = inv;
+ self.invGrid.store.newItem(acqinv.toStoreItem(inv));
+ },
+ "interface": self.invGrid
+ },
+ "no_results": {
+ "revealer": function() { alert(localeStrings.NO_RESULTS); }
+ }
+ };
+
+ this._dataLoader = function(opts) {
+ /* This function must contain references to "self" only, not "this." */
+ var grid = self.result_types[self.result_type].interface;
+
+ if (!opts)
+ opts = {};
+
+ self.count_results = 0;
+
+ var use_params = dojo.clone(self.params); /* need copy, not ref */
+
+ if (!opts.skip_paging) {
+ use_params[4].offset = grid.displayOffset;
+ use_params[4].limit = grid.displayLimit;
+ }
+
+ var method = self.method_name;
+ if (opts.atomic)
+ method += ".atomic";
+
+ if (opts.id_list)
+ use_params[4].id_list = true;
+
+ var request_options = {
+ "params": use_params,
+ "async": true
+ };
+
+ if (typeof opts.onresponse != "undefined") {
+ request_options.onresponse = opts.onresponse;
+ } else {
+ /* normal onresponse handler for most times we call this method */
+ request_options.onresponse = function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ if (!self.count_results++)
+ self.show(self.result_type);
+ self.add(self.result_type, r);
+ }
+ };
+ }
+
+ if (typeof opts.oncomplete != "undefined") {
+ request_options.oncomplete = opts.oncomplete;
+ } else {
+ /* normal oncomplete handler for most times we call this method */
+ request_options.oncomplete = function() { self.resultsComplete(); };
+ }
+
+ fieldmapper.standardRequest(["open-ils.acq", method], request_options);
+ };
+
+ this.add = function(which, what) {
+ var f = this.result_types[which].adder;
+ if (f) f(what);
+ };
+
+ this.finish = function(which) {
+ var f = this.result_types[which].finisher;
+ if (f) f();
+ };
+
+ this.show = function(which) {
+ openils.Util.objectProperties(this.result_types).forEach(
+ function(rt) {
+ openils.Util[rt == which ? "show" : "hide"](
+ "acq-unified-results-" + rt
+ );
+ }
+ );
+ this.result_types[which].revealer();
+ };
+
+ this.resultsComplete = function() {
+ if (!this.count_results)
+ this.show("no_results");
+ else this.finish(this.result_type);
+ };
+
+ this.go = function(search_object) {
+ location.href = oilsBasePath + "/acq/search/unified?" +
+ "so=" + base64Encode(search_object) +
+ "&rt=" + dojo.byId("acq-unified-result-type").getValue() +
+ "&c=" + dojo.byId("acq-unified-conjunction").getValue();
+ };
+
+ this.search = function(uriManager, termManager) {
+ var bib_search_string = null;
+ this.count_results = 0;
+ this.result_type = dojo.byId("acq-unified-result-type").getValue();
+
+ /* lineitem_and_bib: a special case */
+ if (this.result_type == "lineitem_and_bib") {
+ this.result_type = "lineitem";
+ bib_search_string = termManager.buildBibSearchString();
+ }
+
+ this.method_name = "open-ils.acq." + this.result_type +
+ ".unified_search";
+ /* Except for building the API method name that we want to call,
+ * we want to treat lineitem_and_bib the same way as lineitem from
+ * here forward. */
+
+ this.params = [
+ openils.User.authtoken,
+ null, null, null,
+ this.result_types[this.result_type].search_options
+ ];
+
+ this.params[
+ dojo.byId("acq-unified-conjunction").getValue() == "and" ? 1 : 2
+ ] = uriManager.search_object;
+ if (uriManager.order_by)
+ this.params[4].order_by = uriManager.order_by;
+
+ var interface = this.result_types[this.result_type].interface;
+ interface.dataLoader = this._dataLoader;
+
+ if (bib_search_string) {
+ /* Have the ML do the bib search first, which incidentally has the
+ * side effect of creating line items that will show up when
+ * we do the LI part of the search (so we don't actually want
+ * to display these results directly). */
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.biblio.wrapped_search.atomic"], {
+ "params": [
+ openils.User.authtoken, bib_search_string, {
+ "clear_marc": true
+ }
+ ],
+ "onresponse": function(r) {
+ r = openils.Util.readResponse(r, false, true);
+ }
+ }
+ );
+ }
+
+ interface.dataLoader();
+ };
+ }
+
+ function URIManager() {
+ var self = this;
+ this.cannedSearches = {
+ "po": {
+ "search_object": {
+ "acqpo": [
+ {"ordering_agency": openils.User.user.ws_ou()},
+ {"state": "on-order"}
+ ]
+ },
+ "half_search": true,
+ "result_type": "purchase_order",
+ "conjunction": "and",
+ "order_by": [
+ {"class": "acqpo", "field": "edit_time", "direction": "desc"}
+ ]
+ },
+ "pl": {
+ "search_object": {
+ "acqpl": [
+ {"owner": openils.User.user.usrname()}
+ ]
+ },
+ "result_type": "picklist",
+ "conjunction": "and",
+ "order_by": [
+ {"class": "acqpl", "field": "edit_time", "direction": "desc"}
+ ]
+ },
+ "inv": {
+ "search_object": {
+ "acqinv": [
+ {"complete": "f"},
+ {"receiver": openils.User.user.ws_ou()}
+ ]
+ },
+ "half_search": true,
+ "result_type": "invoice",
+ "conjunction": "and",
+ "order_by": [
+ {"class": "acqinv", "field": "recv_date", "direction": "desc"}
+ ]
+ }
+ };
+
+ if (this.canned = cgi.param("ca")) { /* assignment */
+ dojo.mixin(this, this.cannedSearches[this.canned]);
+ dojo.byId("acq-unified-result-type").setValue(this.result_type);
+ dojo.byId("acq-unified-result-type").onchange();
+ dojo.byId("acq-unified-conjunction").setValue(this.conjunction);
+ } else {
+ this.search_object = cgi.param("so");
+ if (this.search_object)
+ this.search_object = base64Decode(this.search_object);
+
+ this.result_type = cgi.param("rt");
+ if (this.result_type) {
+ dojo.byId("acq-unified-result-type").setValue(this.result_type);
+ dojo.byId("acq-unified-result-type").onchange();
+ }
+
+ this.conjunction = cgi.param("c");
+ if (this.conjunction)
+ dojo.byId("acq-unified-conjunction").setValue(this.conjunction);
+ }
+ }
+
+ /* onload */
+ openils.Util.addOnLoad(
+ function() {
+ termManager = new TermManager();
+ resultManager = new ResultManager(
+ new LiTablePager(null, new AcqLiTable()),
+ dijit.byId("acq-unified-po-grid"),
+ dijit.byId("acq-unified-pl-grid"),
+ dijit.byId("acq-unified-inv-grid")
+ );
+
+ uriManager = new URIManager();
+ if (uriManager.search_object) {
+ if (!uriManager.half_search)
+ hideForm();
+ openils.Util.show("acq-unified-body");
+ termManager.reflect(uriManager.search_object);
+
+ if (!uriManager.half_search)
+ resultManager.search(uriManager, termManager);
+ } else {
+ termManager.addRow();
+ openils.Util.show("acq-unified-body");
+ }
+ }
+ );
+
+
+});
\ No newline at end of file
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require('dijit.form.Form');
-dojo.require('dijit.form.Textarea');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.form.ComboBox');
-dojo.require('dijit.form.NumberSpinner');
-dojo.require('fieldmapper.IDL');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.widget.ProgressDialog');
-dojo.require('dijit.form.CheckBox');
-dojo.require('dijit.form.Button');
-dojo.require('dojo.date');
-dojo.require('openils.CGI');
-dojo.require('openils.XUL');
-dojo.require('openils.Util');
-dojo.require('openils.Event');
-
-dojo.requireLocalization('openils.actor', 'register');
-var localeStrings = dojo.i18n.getLocalization('openils.actor', 'register');
-
-
-var pcrud;
-var fmClasses = ['au', 'ac', 'aua', 'actsc', 'asv', 'asvq', 'asva'];
-var fieldDoc = {};
-var statCats;
-var statCatTemplate;
-var surveys;
-var staff;
-var patron;
-var uEditUsePhonePw = false;
-var widgetPile = [];
-var uEditCardVirtId = -1;
-var uEditAddrVirtId = -1;
-var orgSettings = {};
-var userSettings = {};
-var userSettingsToUpdate = {};
-var userSettingTypes;
-var tbody;
-var addrTemplateRows;
-var cgi;
-var cloneUser;
-var cloneUserObj;
-var stageUser;
-var optInSettings;
-var allCardsTemplate;
-var uEditCloneCopyAddr; // if true, copy addrs on clone instead of link
-var homeOuTypes = {};
-var holdPickupTypes = {};
-var cardPerms = {};
-var editCard;
-var prevBillingAddress;
-var prevMailingAddress;
-
-var dupeUsrname = false;
-var dupeBarcode = false;
-
-// allow for a pause after typing before sending address alert queries
-var addressAlertTimeout = 2000;
-var addressAlertFields =
- ['street1', 'street2', 'city', 'state', 'county', 'country', 'post_code'];
-
-if(!window.xulG) var xulG = null;
-var lock_ready = false;
-var already_locked = false;
-
-function load() {
- staff = new openils.User().user;
- pcrud = new openils.PermaCrud();
- cgi = new openils.CGI();
- cloneUser = cgi.param('clone');
- var userId = cgi.param('usr');
- var stageUname = cgi.param('stage');
-
- saveButton.attr("label", localeStrings.SAVE);
- saveCloneButton.attr("label", localeStrings.SAVE_CLONE);
- replaceBarcode.attr("label", localeStrings.REPLACE_BARCODE);
- dojo.byId('uedit-show-required').innerHTML = localeStrings.SHOW_REQUIRED;
- dojo.byId('uedit-show-suggested').innerHTML = localeStrings.SHOW_SUGGESTED;
- dojo.byId('uedit-show-all').innerHTML = localeStrings.SHOW_ALL;
- dojo.byId('uedit-dupe-barcode-warning').innerHTML = localeStrings.BARCODE_IN_USE;
- allCards.attr("label", localeStrings.SEE_ALL);
- dojo.byId('uedit-dupe-username-warning').innerHTML = localeStrings.DUPE_USERNAME;
- generatePassword.attr("label", localeStrings.RESET_PASSWORD);
- dojo.byId('verifyPassword').innerHTML = localeStrings.VERIFY_PASSWORD;
- dojo.byId('parentGuardian').innerHTML = localeStrings.PARENT_OR_GUARDIAN;
- dojo.byId('userSettings').innerHTML = localeStrings.USER_SETTINGS;
- dojo.byId('statCats').innerHTML = localeStrings.STAT_CATS;
- dojo.byId('uedit-all-cards-barcode').innerHTML = localeStrings.ALL_CARDS_BARCODE;
- dojo.byId('uedit-all-cards-active').innerHTML = localeStrings.ALL_CARDS_ACTIVE;
- dojo.byId('uedit-all-cards-primary').innerHTML = localeStrings.ALL_CARDS_PRIMARY;
- allCardsClose.attr("label", localeStrings.ALL_CARDS_CLOSE);
- allCardsApply.attr("label", localeStrings.ALL_CARDS_APPLY);
-
- dojo.query("td[name='addressHeader']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_HEADER; });
- dojo.query("span[name='mailingAddress']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_MAILING; });
- dojo.query("span[name='billingAddress']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_BILLING; });
- dojo.query("span[name='addressPending']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_PENDING; });
- dojo.query("button[name='approve-button']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_APPROVE; });
- dojo.query("span[name='address-already-owned']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_OWNED; });
- dojo.query("button[name='addressNew']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_NEW; });
-
- if(xulG) {
- if(xulG.ses) openils.User.authtoken = xulG.ses;
- if(typeof xulG.clone != 'undefined') cloneUser = xulG.clone;
- if(typeof xulG.usr != 'undefined') userId = xulG.usr
- if(typeof xulG.params != 'undefined') {
- var parms = xulG.params;
- if(typeof parms.ses != 'undefined')
- openils.User.authtoken = parms.ses;
- if(typeof parms.clone != 'undefined')
- cloneUser = parms.clone;
- if(typeof parms.usr != 'undefined')
- userId = parms.usr;
- if(typeof parms.stage != 'undefined')
- stageUname = parms.stage
- }
- }
-
- orgSettings = fieldmapper.aou.fetchOrgSettingBatch(staff.ws_ou(), [
- 'global.password_regex',
- 'global.juvenile_age_threshold',
- 'patron.password.use_phone',
- 'ui.patron.default_inet_access_level',
- 'ui.patron.default_ident_type',
- 'ui.patron.default_country',
- 'ui.patron.registration.require_address',
- 'circ.holds.behind_desk_pickup_supported',
- 'circ.patron_edit.clone.copy_address',
- 'ui.patron.edit.au.prefix.require',
- 'ui.patron.edit.au.prefix.show',
- 'ui.patron.edit.au.prefix.suggest',
- 'ui.patron.edit.au.second_given_name.show',
- 'ui.patron.edit.au.second_given_name.suggest',
- 'ui.patron.edit.au.suffix.show',
- 'ui.patron.edit.au.suffix.suggest',
- 'ui.patron.edit.au.alias.show',
- 'ui.patron.edit.au.alias.suggest',
- 'ui.patron.edit.au.dob.require',
- 'ui.patron.edit.au.dob.show',
- 'ui.patron.edit.au.dob.suggest',
- 'ui.patron.edit.au.dob.calendar',
- 'ui.patron.edit.au.juvenile.show',
- 'ui.patron.edit.au.juvenile.suggest',
- 'ui.patron.edit.au.ident_value.show',
- 'ui.patron.edit.au.ident_value.suggest',
- 'ui.patron.edit.au.ident_value2.show',
- 'ui.patron.edit.au.ident_value2.suggest',
- 'ui.patron.edit.au.email.require',
- 'ui.patron.edit.au.email.show',
- 'ui.patron.edit.au.email.suggest',
- 'ui.patron.edit.au.email.regex',
- 'ui.patron.edit.au.email.example',
- 'ui.patron.edit.au.day_phone.require',
- 'ui.patron.edit.au.day_phone.show',
- 'ui.patron.edit.au.day_phone.suggest',
- 'ui.patron.edit.au.day_phone.regex',
- 'ui.patron.edit.au.day_phone.example',
- 'ui.patron.edit.au.evening_phone.require',
- 'ui.patron.edit.au.evening_phone.show',
- 'ui.patron.edit.au.evening_phone.suggest',
- 'ui.patron.edit.au.evening_phone.regex',
- 'ui.patron.edit.au.evening_phone.example',
- 'ui.patron.edit.au.other_phone.require',
- 'ui.patron.edit.au.other_phone.show',
- 'ui.patron.edit.au.other_phone.suggest',
- 'ui.patron.edit.au.other_phone.regex',
- 'ui.patron.edit.au.other_phone.example',
- 'ui.patron.edit.phone.regex',
- 'ui.patron.edit.phone.example',
- 'ui.patron.edit.au.active.show',
- 'ui.patron.edit.au.active.suggest',
- 'ui.patron.edit.au.barred.show',
- 'ui.patron.edit.au.barred.suggest',
- 'ui.patron.edit.au.master_account.show',
- 'ui.patron.edit.au.master_account.suggest',
- 'ui.patron.edit.au.claims_returned_count.show',
- 'ui.patron.edit.au.claims_returned_count.suggest',
- 'ui.patron.edit.au.claims_never_checked_out_count.show',
- 'ui.patron.edit.au.claims_never_checked_out_count.suggest',
- 'ui.patron.edit.au.alert_message.show',
- 'ui.patron.edit.au.alert_message.suggest',
- 'ui.patron.edit.aua.post_code.regex',
- 'ui.patron.edit.aua.post_code.example',
- 'ui.patron.edit.aua.county.require',
- 'format.date',
- 'ui.patron.edit.default_suggested',
- 'opac.barcode_regex',
- 'opac.username_regex',
- 'sms.enable'
- ]);
-
- for(k in orgSettings)
- if(orgSettings[k])
- orgSettings[k] = orgSettings[k].value;
-
- uEditCloneCopyAddr = orgSettings['circ.patron_edit.clone.copy_address'];
- uEditUsePhonePw = orgSettings['patron.password.use_phone'];
- uEditFetchUserSettings(userId);
-
- if(userId) {
- patron = uEditLoadUser(userId);
- } else {
- if(stageUname) {
- patron = uEditLoadStageUser(stageUname);
- } else {
- patron = uEditNewPatron();
- if(cloneUser)
- uEditCopyCloneData(patron);
- }
- }
-
-
- var list = pcrud.search('fdoc', {fm_class:fmClasses});
- for(var i in list) {
- var doc = list[i];
- if(!fieldDoc[doc.fm_class()])
- fieldDoc[doc.fm_class()] = {};
- fieldDoc[doc.fm_class()][doc.field()] = doc;
- }
-
- list = pcrud.search('aout', {can_have_users: 'true'});
- for(var i in list) {
- var type = list[i];
- homeOuTypes[type.id()] = true;
- }
- list = pcrud.search('aout', {can_have_vols: 'true'});
- for(var i in list) {
- var type = list[i];
- holdPickupTypes[type.id()] = true;
- }
-
- tbody = dojo.byId('uedit-tbody');
-
- if(orgSettings['ui.patron.edit.default_suggested'])
- uEditToggleRequired(2);
-
- addrTemplateRows = dojo.query('tr[type=addr-template]', tbody);
- dojo.forEach(addrTemplateRows, function(row) { row.parentNode.removeChild(row); } );
- statCatTemplate = tbody.removeChild(dojo.byId('stat-cat-row-template'));
- surveyTemplate = tbody.removeChild(dojo.byId('survey-row-template'));
- surveyQuestionTemplate = tbody.removeChild(dojo.byId('survey-question-row-template'));
-
- checkGrpAppPerm(); // to do the initial load
- loadStaticFields();
-
-
- if(patron.isnew() && patron.addresses().length == 0)
- uEditNewAddr(null, uEditAddrVirtId, true);
- else loadAllAddrs();
- loadStatCats();
- loadSurveys();
- checkClaimsReturnCountPerm();
- checkClaimsNoCheckoutCountPerm();
-
- dojo.connect(replaceBarcode, 'onClick', replaceCardHandler);
- dojo.connect(allCards, 'onClick', drawAllCards);
- if(patron.isnew()) {
- dojo.addClass(dojo.byId('uedit-all-barcodes'), 'hidden');
- } else if(checkGrpAppPerm(patron.profile())) {
- new openils.User().getPermOrgList(
- 'UPDATE_PATRON_ACTIVE_CARD',
- function(orgList) {
- if(orgList.indexOf(patron.home_ou()) != -1)
- cardPerms['UPDATE_PATRON_ACTIVE_CARD'] = true;
- },
- true,
- true
- );
- new openils.User().getPermOrgList(
- 'UPDATE_PATRON_PRIMARY_CARD',
- function(orgList) {
- if(orgList.indexOf(patron.home_ou()) != -1)
- cardPerms['UPDATE_PATRON_PRIMARY_CARD'] = true;
- },
- true,
- true
- );
- }
-
- var input = findWidget('ac', 'barcode');
- if (patron.isnew()) {
- replaceBarcode.attr('disabled', true);
- } else {
- input.widget.attr('disabled', true).attr('readOnly', true);
- }
-
- dojo.connect(generatePassword, 'onClick', generatePasswordHandler);
-
- if(!patron.isnew() && !checkGrpAppPerm(patron.profile()) && patron.id() != openils.User.user.id()) {
- // we are not allowed to edit this user, so disable the save option
- saveButton.attr('disabled', true);
- saveCloneButton.attr('disabled', true);
- }
-
- uUpdateContactInvalidators();
- lock_ready = true;
-}
-
-var permGroups;
-var noPermGroups = [];
-// Returns true if the user is allowed to edit the selected group
-function checkGrpAppPerm(grpId) {
-
- if(!permGroups) {
-
- // get the groups
- permGroups = new openils.PermaCrud().retrieveAll('pgt');
- var permGroupPerms = []
-
- // collect the group permissions
- dojo.forEach(permGroups,
- function(grp) {
- if(grp.application_perm())
- permGroupPerms.push(grp.application_perm());
- }
- );
-
- // see which of the group application perms I do not have
- var myPerms = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.has_work_perm_at.batch'],
- [openils.User.authtoken, permGroupPerms]
- );
-
- var failedPerms = [];
- for(var p in myPerms) {
- if(myPerms[p].length == 0)
- failedPerms.push(p);
- }
-
- // identify which groups I cannot edit because I do not have permisssion
-
- function checkTree(grp, failed) {
- failed = failed || failedPerms.indexOf(grp.application_perm()) > -1;
- if(failed) noPermGroups.push(grp.id()+'');
- dojo.forEach(
- permGroups.filter(function(g) { return g.parent() == grp.id() } ),
- function(child) {
- checkTree(child, failed);
- }
- );
- }
-
- checkTree(permGroups.filter(function(g) { return g.parent() == null })[0]);
- }
-
- return noPermGroups.indexOf(grpId+'') == -1;
-}
-
-
-function drawAllCards() {
-
- var tbody = dojo.byId('uedit-all-cards-tbody');
- if(!allCardsTemplate) {
- allCardsTemplate = tbody.removeChild(dojo.byId('uedit-all-cards-tr-template'));
- } else {
- while(tbody.childNodes[0])
- tbody.removeChild(tbody.childNodes[0]);
- }
-
- if(cardPerms['UPDATE_PATRON_ACTIVE_CARD'] || cardPerms['UPDATE_PATRON_PRIMARY_CARD']) {
- dojo.removeClass(dojo.byId('uedit-apply-card-changes'), 'hidden');
- } else {
- dojo.addClass(dojo.byId('uedit-apply-card-changes'), 'hidden');
- }
-
- var first = true;
- dojo.forEach(
- patron.cards().filter(function(c) { return c.id() == patron.card().id(); }).concat(patron.cards()), // grab the main card first
- function(card) {
- if(!first) {
- if(card.id() == patron.card().id())
- return;
- }
- var row = allCardsTemplate.cloneNode(true);
- row.setAttribute("cardid", card.id());
- row.card = card;
- getByName(row, 'barcode').innerHTML = card.barcode();
- if(cardPerms['UPDATE_PATRON_ACTIVE_CARD']) {
- row.active_checkbox = new dijit.form.CheckBox({
- scrollOnFocus:false,
- checked: openils.Util.isTrue(card.active())
- }, getByName(row, 'active'));
- } else {
- getByName(row, 'active').appendChild(
- openils.Util.isTrue(card.active()) ?
- dojo.byId('true').cloneNode(true) :
- dojo.byId('false').cloneNode(true)
- );
- }
- if(cardPerms['UPDATE_PATRON_PRIMARY_CARD']) {
- row.primary_radiobutton = new dijit.form.RadioButton({
- scrollOnFocus:false,
- checked: card.id() == patron.card().id(),
- value: card.id(),
- name: 'card_primary'
- }, getByName(row, 'primary'));
- } else {
- getByName(row, 'primary').appendChild(
- openils.Util.isTrue(card.id() == patron.card().id()) ?
- dojo.byId('true').cloneNode(true) :
- dojo.byId('false').cloneNode(true)
- );
- }
- tbody.appendChild(row);
- first = false;
- }
- );
-
- allCardsDialog.show();
-}
-
-function applyCardChanges() {
- var cardrows = dojo.query('[cardid]', allCardsDialog.domNode);
- var changed = false;
- dojo.forEach(cardrows,
- function(row) {
- if(cardPerms['UPDATE_PATRON_ACTIVE_CARD']) {
- var active = row.active_checkbox.checked ? 't' : 'f'
- if(row.card.active() != active) {
- row.card.active(active);
- row.card.ischanged(1);
- changed = true;
- }
- }
- if(cardPerms['UPDATE_PATRON_PRIMARY_CARD']) {
- if(row.primary_radiobutton.checked && row.card.id() != patron.card().id()) {
- patron.card(row.card);
- changed = true;
- }
- }
- }
- );
- if(changed && lock_ready && xulG && typeof xulG.lock_tab == 'function' && !already_locked) {
- xulG.lock_tab();
- already_locked = true;
- }
- allCardsDialog.hide();
-}
-
-/**
- * Mark the current card inactive, create a new primary card
- */
-function replaceCardHandler() {
- var input = findWidget('ac', 'barcode');
- input.widget.attr('disabled', false).attr('readOnly', false).attr('value', null).focus();
- replaceBarcode.attr('disabled', true);
-
- // pull old card off the cards list so we don't have a dupe sitting in there
- if (patron.cards().length > 0) {
- var old = patron.cards().filter(function(c){return (c.id() == patron.card().id())})[0];
- old.active('f');
- old.ischanged(1);
- }
-
- var newc = new fieldmapper.ac();
- newc.id(uEditCardVirtId--);
- newc.isnew(1);
- newc.active('t');
- patron.card(newc);
- editCard = newc;
- var t = patron.cards();
- if (!t) { t = []; }
- t.push(newc);
- patron.cards(t);
-}
-
-/**
- * Generate a random password for the patron.
- */
-function generatePasswordHandler() {
- uEditMakeRandomPw(patron);
- var f = findWidget('au', 'passwd');
- f.widget.attr('value', patron.passwd());
- f = findWidget('au', 'passwd2');
- f.widget.attr('value', patron.passwd());
-}
-
-/**
- * Loads a staged user and turns them into something the editor can understand
- */
-function uEditLoadStageUser(stageUname) {
-
- var data = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.stage.retrieve.by_username'],
- { params : [openils.User.authtoken, stageUname] }
- );
-
- stageUser = data.user;
- patron = uEditNewPatron();
-
- if(!stageUser)
- return patron;
-
- // copy the data into our new user object
- for(var key in fieldmapper.IDL.fmclasses.stgu.field_map) {
- if(fieldmapper.IDL.fmclasses.au.field_map[key] && !fieldmapper.IDL.fmclasses.stgu.field_map[key].virtual) {
- if(data.user[key]() !== null)
- patron[key]( data.user[key]() );
- }
- }
-
- // copy the data into our new address objects
- // TODO: uses the first mailing address only
- if(data.mailing_addresses.length) {
-
- var mail_addr = new fieldmapper.aua();
- mail_addr.id(-1); // virtual ID
- mail_addr.usr(-1);
- mail_addr.isnew(1);
- patron.mailing_address(mail_addr);
- var t = patron.addresses();
- if (!t) { t = []; }
- t.push(mail_addr);
- patron.addresses(t);
-
- for(var key in fieldmapper.IDL.fmclasses.stgma.field_map) {
- if(fieldmapper.IDL.fmclasses.aua.field_map[key] && !fieldmapper.IDL.fmclasses.stgma.field_map[key].virtual) {
- if(data.mailing_addresses[0][key]() !== null)
- mail_addr[key]( data.mailing_addresses[0][key]() );
- }
- }
- }
-
- // copy the data into our new address objects
- // TODO uses the first billing address only
- if(data.billing_addresses.length) {
-
- var bill_addr = new fieldmapper.aua();
- bill_addr.id(-2); // virtual ID
- bill_addr.usr(-1);
- bill_addr.isnew(1);
- patron.billing_address(bill_addr);
- var t = patron.addresses();
- if (!t) { t = []; }
- t.push(bill_addr);
- patron.addresses(t);
-
- for(var key in fieldmapper.IDL.fmclasses.stgba.field_map) {
- if(fieldmapper.IDL.fmclasses.aua.field_map[key] && !fieldmapper.IDL.fmclasses.stgba.field_map[key].virtual) {
- if(data.billing_addresses[0][key]() !== null)
- bill_addr[key]( data.billing_addresses[0][key]() );
- }
- }
- }
-
- // TODO: uses the first card only
- if(data.cards.length) {
- var card = new fieldmapper.ac();
- card.id(-1); // virtual ID
- patron.card().barcode(data.cards[0].barcode());
- }
-
- return patron;
-}
-
-/*
- * clone the home org, phone numbers, and billing/mailing address
- */
-function uEditCopyCloneData(patron) {
- cloneUserObj = uEditLoadUser(cloneUser);
-
- var cloneFields = [
- 'home_ou',
- 'day_phone',
- 'evening_phone',
- 'other_phone',
- 'usrgroup'
- ];
-
- if(!uEditCloneCopyAddr)
- cloneFields = cloneFields.concat(['mailing_address', 'billing_address']);
-
- dojo.forEach(
- cloneFields,
- function(field) {
- patron[field](cloneUserObj[field]());
- }
- );
-
- if(uEditCloneCopyAddr) {
- var billAddr, mailAddr;
-
- // copy the billing and mailing addresses into new addresses
- function cloneAddr(addr) {
- var newAddr = addr.clone();
- newAddr.isnew(true);
- newAddr.id(uEditAddrVirtId--);
- newAddr.usr(patron.id());
- patron.addresses().push(newAddr);
- return newAddr;
- }
-
- if(billAddr = cloneUserObj.billing_address())
- patron.billing_address(cloneAddr(billAddr));
-
- if(mailAddr = cloneUserObj.mailing_address()) {
- if (billAddr && billAddr.id() == mailAddr.id()) {
- patron.mailing_address(patron.billing_address());
- } else {
- patron.mailing_address(cloneAddr(mailAddr));
- }
- }
-
- if(!billAddr) // if there was no billing addr, use the mailing addr
- patron.billing_address(patron.mailing_address());
-
- } else {
-
- // link the billing and mailing addresses
- if(patron.billing_address()) {
- var t = patron.addresses();
- if (!t) { t = []; }
- t.push(patron.billing_address());
- patron.addresses(t);
- }
-
- if(patron.mailing_address() && (
- patron.addresses().length == 0 ||
- patron.mailing_address().id() != patron.billing_address().id()) ) {
- var t = patron.addresses();
- if (!t) { t = []; }
- t.push(patron.mailing_address());
- patron.addresses(t);
- }
- }
-}
-
-
-function uEditFetchUserSettings(userId) {
-
- var baseNode = fieldmapper.aou.findOrgUnit(staff.ws_ou());
- var orgs = fieldmapper.aou.orgNodeTrail(baseNode);
- orgs = orgs.map(function(node) { return node.id(); });
-
- /* fetch any user setting types we need + any that offer opt-in */
- userSettingTypes = pcrud.search('cust', {
- '-or' : [
- {name:['circ.holds_behind_desk', 'circ.collections.exempt', 'opac.hold_notify', 'opac.default_phone', 'opac.default_pickup_location', 'opac.default_sms_carrier', 'opac.default_sms_notify']},
- {name : {
- 'in': {
- select : {atevdef : ['opt_in_setting']},
- from : 'atevdef',
- // we only care about opt-in settings for event_defs our users encounter
- where : {'+atevdef' : {owner : orgs}}
- }
- }}
- ]
- });
-
- var names = userSettingTypes.map(function(obj) { return obj.name() });
-
- /* fetch any values set for this user */
- if(userId) {
- userSettings = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.patron.settings.retrieve.authoritative'],
- {params : [openils.User.authtoken, userId, names]});
- }
-}
-
-
-function uEditLoadUser(userId) {
- var patron = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.fleshed.retrieve.authoritative'],
- {params : [openils.User.authtoken, userId]}
- );
- openils.Event.parse_and_raise(patron);
- return patron;
-}
-
-function loadStaticFields() {
- for(var idx = 0; tbody.childNodes[idx]; idx++) {
- var row = tbody.childNodes[idx];
- if(row.nodeType != row.ELEMENT_NODE) continue;
- var fmcls = row.getAttribute('fmclass');
- if(fmcls) {
- fleshFMRow(row, fmcls);
- } else {
-
- if(row.id == 'uedit-settings-divider') {
-
- var template = tbody.removeChild(dojo.byId('uedit-user-setting-template'));
- dojo.forEach(userSettingTypes, function(type) { uEditDrawSettingRow(tbody, row, template, type); } );
-
- if(userSettingTypes.length > 1 || orgSettings['circ.holds.behind_desk_pickup_supported']) {
- openils.Util.show('uedit-settings-divider', 'table-row');
- }
- }
- }
- }
-}
-
-function uEditDrawSettingRow(tbody, dividerRow, template, stype) {
- var row = template.cloneNode(true);
- row.setAttribute('user_setting', stype.name());
- getByName(row, 'label').innerHTML = stype.label();
- switch(stype.name()) {
- case 'opac.hold_notify':
- var template = localeStrings.HOLD_NOTIFY_PHONE + '<span name="hold_phone"></span> '
- + localeStrings.HOLD_NOTIFY_EMAIL + '<span name="hold_email"></span>';
- if(orgSettings['sms.enable']) {
- template += ' ' + localeStrings.HOLD_NOTIFY_SMS + '<span name="hold_sms"></span>';
- }
- getByName(row, 'widget').innerHTML = template;
- var setting = userSettings['opac.hold_notify'];
- if(setting == null) setting = 'phone:email';
- var cb_phone = new dijit.form.CheckBox({scrollOnFocus:false}, getByName(row, 'hold_phone'));
- cb_phone.attr('value', setting.indexOf('phone') != -1);
- var cb_email = new dijit.form.CheckBox({scrollOnFocus:false}, getByName(row, 'hold_email'));
- cb_email.attr('value', setting.indexOf('email') != -1);
- var cb_sms = null;
- if(orgSettings['sms.enable']) {
- cb_sms = new dijit.form.CheckBox({scrollOnFocus:false}, getByName(row, 'hold_sms'));
- cb_sms.attr('value', setting.indexOf('sms') != -1);
- }
- var func = function() {
- var newVal = '';
- var splitter = '';
- if(cb_phone.checked) {
- newVal+= splitter + 'phone';
- splitter = ':';
- }
- if(cb_email.checked) {
- newVal+= splitter + 'email';
- splitter = ':';
- }
- if(orgSettings['sms.enable'] && cb_sms.checked) {
- newVal+= splitter + 'sms';
- splitter = ':';
- }
- userSettingsToUpdate['opac.hold_notify'] = newVal;
- };
- dojo.connect(cb_phone, 'onChange', func);
- dojo.connect(cb_email, 'onChange', func);
- if(cb_sms) dojo.connect(cb_sms, 'onChange', func);
- break;
- case 'opac.default_pickup_location':
- var sb = new openils.widget.FilteringTreeSelect({
- scrollOnFocus: false,
- labelAttr: 'name',
- searchAttr: 'name',
- parentField: 'parent_ou',
- }, getByName(row, 'widget'));
- sb.tree = fieldmapper.aou.globalOrgTree;
- sb.startup();
- sb.attr('value', userSettings[stype.name()]);
-
- sb.isValid = function() {
- if(this.item) {
- if(holdPickupTypes[this.store.getValue(this.item, 'ou_type')]) {
- return true;
- }
- return false;
- }
- return true;
- };
-
- dojo.connect(sb, 'onChange', function(newVal) { userSettingsToUpdate[stype.name()] = newVal; });
- break;
- case 'opac.default_sms_carrier':
- if(!orgSettings['sms.enable']) return; // Skip when SMS is disabled
- var carriers = pcrud.search('csc', {active: 'true'}, {'order_by':[{'class':'csc', 'field':'name'},{'class':'csc', 'field':'region'}]});
- var storedata = fieldmapper.csc.toStoreData(carriers);
- for(var i in storedata.items) storedata.items[i].label = storedata.items[i].name + ' (' + storedata.items[i].region + ')';
- var store = new dojo.data.ItemFileReadStore({data:storedata});
- var select = new dijit.form.FilteringSelect({store:store,scrollOnFocus:false,labelAttr:'label',searchAttr:'label'}, getByName(row, 'widget'));
- select.attr('value', userSettings[stype.name()]);
- select.isValid = function() { return true; };
- dojo.connect(select, 'onChange', function(newVal) { userSettingsToUpdate[stype.name()] = newVal; });
- break;
- case 'opac.default_sms_notify':
- if(!orgSettings['sms.enable']) return; // Skip when SMS is disabled
- case 'opac.default_phone':
- var tb = new dijit.form.TextBox({scrollOnFocus:false}, getByName(row, 'widget'));
- tb.attr('value', userSettings[stype.name()]);
- dojo.connect(tb, 'onChange', function(newVal) { userSettingsToUpdate[stype.name()] = newVal; });
- break;
- default:
- var cb = new dijit.form.CheckBox({scrollOnFocus:false}, getByName(row, 'widget'));
- cb.attr('value', userSettings[stype.name()]);
- dojo.connect(cb, 'onChange', function(newVal) { userSettingsToUpdate[stype.name()] = newVal; });
- if(stype.name() == 'circ.collections.exempt') {
- checkCollectionsExemptPerm(cb);
- }
- }
- tbody.insertBefore(row, dividerRow.nextSibling);
- openils.Util.show(row, 'table-row');
-}
-
-function uEditUpdateUserSettings(userId) {
- return fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.patron.settings.update'],
- {params : [openils.User.authtoken, userId, userSettingsToUpdate]});
-}
-
-function loadAllAddrs() {
- dojo.forEach(patron.addresses(),
- function(addr) {
- uEditNewAddr(null, addr.id());
- }
- );
-}
-
-function loadStatCats() {
-
- statCats = fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.stat_cat.actor.retrieve.all'],
- {params : [openils.User.authtoken, staff.ws_ou()]}
- );
-
- // draw stat cats
- for(var idx in statCats) {
- var stat = statCats[idx];
- var row = statCatTemplate.cloneNode(true);
- row.id = 'stat-cat-row-' + idx;
- row.setAttribute('stat_cat_owner',stat.owner());
- row.setAttribute('stat_cat_name',stat.name());
- row.setAttribute('stat_cat_id',stat.id());
- tbody.appendChild(row);
- getByName(row, 'name').innerHTML = stat.name();
- var valtd = getByName(row, 'widget');
- var span = valtd.appendChild(document.createElement('span'));
- var store = new dojo.data.ItemFileReadStore(
- {data:fieldmapper.actsc.toStoreData(stat.entries())});
- var comboBox = new dijit.form.ComboBox({store:store,scrollOnFocus:false,fetchProperties:{sort:[{attribute: 'value'}]}}, span);
- comboBox.labelAttr = 'value';
- comboBox.searchAttr = 'value';
-
- comboBox._wtype = 'statcat';
- comboBox._statcat = stat.id();
- widgetPile.push(comboBox);
-
- // populate existing cats
- var map = patron.stat_cat_entries().filter(
- function(mp) { return (mp.stat_cat() == stat.id()) })[0];
- if(map) comboBox.attr('value', map.stat_cat_entry());
-
- }
-}
-
-function loadSurveys() {
-
- surveys = fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.survey.retrieve.all'],
- {params : [openils.User.authtoken]}
- );
-
- // draw surveys
- for(var idx in surveys) {
- var survey = surveys[idx];
- var required = openils.Util.isTrue(survey.required());
- var srow = surveyTemplate.cloneNode(true);
- if(required) srow.setAttribute('required','required');
- tbody.appendChild(srow);
- getByName(srow, 'name').innerHTML = survey.name();
-
- for(var q in survey.questions()) {
- var quest = survey.questions()[q];
- var qrow = surveyQuestionTemplate.cloneNode(true);
- if(required) qrow.setAttribute('required','required');
- tbody.appendChild(qrow);
- getByName(qrow, 'question').innerHTML = quest.question();
-
- var span = getByName(qrow, 'answers').appendChild(document.createElement('span'));
- var store = new dojo.data.ItemFileReadStore(
- {data:fieldmapper.asva.toStoreData(quest.answers())});
- var select = new dijit.form.FilteringSelect({store:store,scrollOnFocus:false}, span);
- if (! required ) {
- select.isValid = function() { return true; };
- }
- select.labelAttr = 'answer';
- select.searchAttr = 'answer';
-
- select._wtype = 'survey';
- select._survey = survey.id();
- select._question = quest.id();
- widgetPile.push(select);
- }
- }
-}
-
-
-function fleshFMRow(row, fmcls, args) {
- var fmfield = row.getAttribute('fmfield');
- var wclass = row.getAttribute('wclass');
- var wstyle = row.getAttribute('wstyle');
- var wconstraints = row.getAttribute('wconstraints');
- /* use CSS to set the zindex for widgets you want to disable. */
- var disabled = dojo.style(row, 'zIndex') == -1 ? true : false;
- var isphone = (fmcls == 'au') && (fmfield.search('_phone') != -1);
-
- var isPasswd2 = (fmfield == 'passwd2');
- if(isPasswd2) fmfield = 'passwd';
- var fieldIdl = fieldmapper.IDL.fmclasses[fmcls].field_map[fmfield];
- if(!args) args = {};
-
- var existing = dojo.query('td', row);
- var htd = existing[0] || row.appendChild(document.createElement('td'));
- var ltd = existing[1] || row.appendChild(document.createElement('td'));
- var wtd = existing[2] || row.appendChild(document.createElement('td'));
- var ftd = existing[3] || row.appendChild(document.createElement('td'));
-
- openils.Util.addCSSClass(htd, 'uedit-help');
- if(fieldDoc[fmcls] && fieldDoc[fmcls][fmfield]) {
- var link = dojo.byId('uedit-help-template').cloneNode(true);
- link.id = '';
- link.onclick = function() { ueLoadContextHelp(fmcls, fmfield) };
- openils.Util.removeCSSClass(link, 'hidden');
- htd.appendChild(link);
- }
-
- if(!ltd.textContent) {
- ltd.appendChild(document.createTextNode(fieldIdl.label));
- }
-
- if(!ftd.textContent) {
- if(orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.example']) {
- ftd.appendChild(document.createTextNode(localeStrings.EXAMPLE + orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.example']));
- }
- else if(isphone && orgSettings['ui.patron.edit.phone.example']) {
- ftd.appendChild(document.createTextNode(localeStrings.EXAMPLE + orgSettings['ui.patron.edit.phone.example']));
- }
- else if(fieldIdl.datatype == 'timestamp') {
- ftd.appendChild(document.createTextNode(localeStrings.EXAMPLE + dojo.date.locale.format(new Date(1970,0,31),{selector: "date", fullYear: true, datePattern: (orgSettings['format.date'] ? orgSettings['format.date'] : null)})));
- }
-
- if (fmcls == "au" && (isphone || fmfield == "email")) {
- var span = dojo.create(
- "span", {
- "className": "hidden",
- "id": "wrap_invalidate_" + fmfield
- }
- );
- uGenerateInvalidatorWidget(span, fmfield);
- ftd.appendChild(span);
- }
- }
-
- var span = document.createElement('span');
- wtd.appendChild(span);
-
- var fmObject = null;
- switch(fmcls) {
- case 'au' :
- fmObject = patron;
- if(fmfield == 'barred') {
- // Are we allowed to touch the barred state?
- var permission = 'BAR_PATRON';
- if(fmObject.barred() == 't') {
- permission = 'UNBAR_PATRON';
- }
- var ou = staff.ws_ou();
- if(fmObject.home_ou() != null) {
- ou = fmObject.home_ou();
- }
- var resp = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.perm.check'],
- { params : [openils.User.authtoken, staff.id(), ou, [permission] ] }
- );
- if(resp[0]) { // No permission to adjust barred state from current
- disabled = true;
- }
- }
- break;
- case 'ac' : if(!editCard) editCard = patron.card(); fmObject = editCard; break;
- case 'aua' :
- fmObject = patron.addresses().filter(
- function(i) { return (i.id() == args.addr) })[0];
- if(fmObject && fmObject.usr() != patron.id())
- disabled = true;
- break;
- }
-
- // Adjust required value by org settings
- var curRequired = row.getAttribute('required');
- var required = curRequired == 'required';
- if(orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.require']) {
- row.setAttribute('required', 'required');
- required = true;
- }
- else if (curRequired != 'required' && orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.show']) {
- row.setAttribute('required', 'show');
- }
- else if (curRequired != 'required' && curRequired != 'show' && orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.suggest']) {
- row.setAttribute('required', 'suggested');
- }
-
- // password data is not fetched/required/displayed for existing users
- if(!patron.isnew() && 'passwd' == fmfield)
- required = false;
-
- var dijitArgs = {
- style: wstyle,
- required : required,
- constraints : (wconstraints) ? eval('('+wconstraints+')') : {}, // the ()'s prevent Invalid Label errors with eval
- disabled : disabled
- };
-
- // Org settings provided regex?
- if(orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.regex']) {
- dijitArgs.regExp = orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.regex'];
- }
- else if(isphone && orgSettings['ui.patron.edit.phone.regex']) {
- dijitArgs.regExp = orgSettings['ui.patron.edit.phone.regex'];
- }
-
- if(fmcls == 'au' && fmfield == 'passwd') {
- if (orgSettings['global.password_regex']) {
- dijitArgs.regExp = orgSettings['global.password_regex'];
- }
- }
-
- if(fmcls == 'au' && fmfield == 'dob' && !orgSettings['ui.patron.edit.au.dob.calendar'])
- dijitArgs.popupClass = "";
-
- var value = row.getAttribute('wvalue');
- if(value !== null)
- dijitArgs.value = value;
-
- var wargs = {
- idlField : fieldIdl,
- fmObject : fmObject,
- fmClass : fmcls,
- parentNode : span,
- widgetClass : wclass,
- dijitArgs : dijitArgs,
- orgDefaultsToWs : true,
- orgLimitPerms : ['UPDATE_USER'],
- };
-
- if(fmfield == 'profile') {
- // fetch profile groups non-async so existing expire_date is
- // not overwritten when the profile groups arrive and update
- wargs.forceSync = true;
- wargs.disableQuery = {usergroup : 'f'};
- } else {
- wargs.forceSync = false;
- }
-
- if(fmcls == 'au' && fmfield == 'home_ou'){
- wargs.labelAttr = 'name';
- wargs.searchAttr = 'name';
- }
-
- var widget = new openils.widget.AutoFieldWidget(wargs);
- widget.build(
- function(w, ww) {
- if(fmfield == 'profile') {
- trimGrpTree(ww);
- if(!patron.isnew() && !checkGrpAppPerm(patron.profile())){
- w.attr('disabled', true);
- }
- }
- }
- );
-
- // now put it back before we register the widget
- if(isPasswd2) fmfield = 'passwd2';
-
- widget._wtype = fmcls;
- widget._fmfield = fmfield;
- widget._addr = args.addr;
- widgetPile.push(widget);
- attachWidgetEvents(fmcls, fmfield, widget);
- return widget;
-}
-
-function trimGrpTree(autoWidget) {
- var store = autoWidget.widget.store;
- if(!store) return;
- // remove all groups that this user are not allowed to edit,
- // except the profile group of an existing user
- store.fetch({onItem :
- function(item) {
- if(!checkGrpAppPerm(item.id[0]) && patron.profile() != item.id[0])
- store.deleteItem(item);
- }
- });
-}
-
-function findWidget(wtype, fmfield, callback) {
- return widgetPile.filter(
- function(i){
- if(i._wtype == wtype && i._fmfield == fmfield) {
- if(callback) return callback(i);
- return true;
- }
- }
- ).pop();
-}
-
-/**
- * if the user does not have the UPDATE_PATRON_CLAIM_RETURN_COUNT,
- * they are not allowed to directly alter the claim return count.
- * This function checks the perm and disable/enables the widget.
- */
-function checkClaimsReturnCountPerm() {
- new openils.User().getPermOrgList(
- 'UPDATE_PATRON_CLAIM_RETURN_COUNT',
- function(orgList) {
- var cr = findWidget('au', 'claims_returned_count');
- if(orgList.indexOf(patron.home_ou()) == -1)
- cr.widget.attr('disabled', true);
- else
- cr.widget.attr('disabled', false);
- },
- true,
- true
- );
-}
-
-
-function checkClaimsNoCheckoutCountPerm() {
- new openils.User().getPermOrgList(
- 'UPDATE_PATRON_CLAIM_NEVER_CHECKED_OUT_COUNT',
- function(orgList) {
- var cr = findWidget('au', 'claims_never_checked_out_count');
- if(orgList.indexOf(patron.home_ou()) == -1)
- cr.widget.attr('disabled', true);
- else
- cr.widget.attr('disabled', false);
- },
- true,
- true
- );
-}
-
-var collectExemptCBox;
-function checkCollectionsExemptPerm(cbox) {
- if(cbox) collectExemptCBox = cbox;
- new openils.User().getPermOrgList(
- 'UPDATE_PATRON_COLLECTIONS_EXEMPT',
- function(orgList) {
- if(orgList.indexOf(patron.home_ou()) == -1)
- collectExemptCBox.attr('disabled', true);
- else
- collectExemptCBox.attr('disabled', false);
- },
- true,
- true
- );
-}
-
-function usePhonePw(newVal) {
- var newPw = false;
- if(this.regExp) {
- matches = RegExp(this.regExp).exec(newVal);
- if(matches.length > 1) newPw = matches[1];
- }
- if(!newPw && newVal && newVal.length >= 4) {
- newPw = newVal.substring(newVal.length - 4);
- }
- if(newPw) {
- var p1 = findWidget('au', 'passwd');
- var p2 = findWidget('au', 'passwd2');
- if (p1 && p2) {
- p1.widget.attr('value', newPw);
- p2.widget.attr('value', newPw);
- }
- return newPw;
- } else {
- return null;
- }
-}
-
-function attachWidgetEvents(fmcls, fmfield, widget) {
-
- dojo.connect(
- widget.widget,
- 'onKeyPress',
- function(ev){
- netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
- if (!(ev.altKey || ev.ctrlKey || ev.metaKey)) {
- if (lock_ready && xulG && typeof xulG.lock_tab == 'function') {
- if (! already_locked) {
- xulG.lock_tab();
- already_locked = true;
- }
- }
- }
- }
- );
- dojo.connect(
- widget.widget,
- 'onChange',
- function(){
- if (lock_ready && xulG && typeof xulG.lock_tab == 'function') {
- if (! already_locked) {
- xulG.lock_tab();
- already_locked = true;
- }
- }
- }
- );
-
-
- if(fmcls == 'ac') {
- if(fmfield == 'barcode') {
- dojo.connect(widget.widget, 'onChange',
- function() {
- var barcode = this.attr('value');
- dupeBarcode = false;
- dojo.addClass(dojo.byId('uedit-dupe-barcode-warning'), 'hidden');
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.barcode.exists'],
- {
- params: [openils.User.authtoken, barcode],
- oncomplete : function(r) {
- var res = openils.Util.readResponse(r);
- if(res == '1') {
- dupeBarcode = true;
- dojo.removeClass(dojo.byId('uedit-dupe-barcode-warning'), 'hidden');
- } else {
- dupeBarcode = false;
- dojo.addClass(dojo.byId('uedit-dupe-barcode-warning'), 'hidden');
- editCard.barcode(barcode); // Keep the "All" interface up to date
- var un = findWidget('au', 'usrname');
- if(!un.widget.attr('value'))
- un.widget.attr('value', barcode);
- }
- }
- }
- );
- }
- );
- return;
- }
- }
-
- if(fmcls == 'au') {
- switch(fmfield) {
-
- case 'usrname':
- widget.widget.isValid = function() {
- // No spaces
- if(this.attr("value").match(/\s/)) {
- return false;
- }
- // Can look like a barcode (for initial value)
- if(orgSettings['opac.barcode_regex']) {
- var test_regexp = new RegExp(orgSettings['opac.barcode_regex']);
- if(test_regexp.test(this.attr("value"))) {
- return true;
- }
- }
- // Can look like a username
- if(orgSettings['opac.username_regex']) {
- var test_regexp = new RegExp(orgSettings['opac.username_regex']);
- if(test_regexp.test(this.attr("value"))) {
- return true;
- }
- }
- // If we know what a barcode and username look like and we got here, reject
- if(orgSettings['opac.barcode_regex'] && orgSettings['opac.username_regex'])
- return false;
- // Otherwise we don't have enough info to say either way, let it through.
- return true;
- }
- dojo.connect(widget.widget, 'onChange',
- function() {
- var input = findWidget('au', 'usrname');
- var usrname = input.widget.attr('value');
-
- if(!usrname) {
- dupeUsrname = false;
- dojo.addClass(dojo.byId('uedit-dupe-username-warning'), 'hidden');
- return;
- }
-
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.username.exists'],
- {
- params: [openils.User.authtoken, usrname],
- oncomplete : function(r) {
- var res = openils.Util.readResponse(r);
- if(res) {
- dupeUsrname = true;
- dojo.removeClass(dojo.byId('uedit-dupe-username-warning'), 'hidden');
- } else {
- dupeUsrname = false;
- dojo.addClass(dojo.byId('uedit-dupe-username-warning'), 'hidden');
- }
- }
- }
- );
- }
- );
-
- return;
-
- case 'profile': // when the profile changes, update the expire date
- dojo.connect(widget.widget, 'onChange',
- function() {
- var self = this;
- var expireWidget = findWidget('au', 'expire_date');
- function found(items) {
- if(items.length == 0) return;
- var item = items[0];
- var interval = self.store.getValue(item, 'perm_interval');
- expireWidget.widget.attr('value', dojo.date.add(new Date(),
- 'second', openils.Util.intervalToSeconds(interval)));
- }
- this.store.fetch({onComplete:found, query:{id:this.attr('value')}});
- }
- );
- return;
-
- case 'dob':
- widget.widget.isValid = function() {
- return this.attr("value") < new Date();
- };
- dojo.connect(widget.widget, 'onChange',
- function(newDob) {
- if(!newDob) return;
- var oldDob = patron.dob();
- if(dojo.date.stamp.fromISOString(oldDob) == newDob) return;
-
- var juvInterval = orgSettings['global.juvenile_age_threshold'] || '18 years';
- var juvWidget = findWidget('au', 'juvenile');
- var base = new Date();
- base.setTime(base.getTime() - Number(openils.Util.intervalToSeconds(juvInterval) + '000'));
-
- if(newDob <= base) // older than global.juvenile_age_threshold
- juvWidget.widget.attr('value', false);
- else
- juvWidget.widget.attr('value', true);
- }
- );
- return;
-
- case 'first_given_name':
- case 'family_name':
- dojo.connect(widget.widget, 'onChange',
- function(newVal) { uEditDupeSearch('name', newVal); });
- return;
-
- case 'email':
- dojo.connect(widget.widget, 'onChange',
- function(newVal) { uEditDupeSearch('email', newVal); });
- return;
-
- case 'ident_value':
- case 'ident_value2':
- dojo.connect(widget.widget, 'onChange',
- function(newVal) { uEditDupeSearch('ident', newVal); });
- return;
-
- case 'day_phone':
- // if configured, use the last four digits of the day phone number as the password
- // Alt, use the first capture group of the validator regex
- if(uEditUsePhonePw && patron.isnew()) {
- dojo.connect(widget.widget, 'onChange', widget.widget, usePhonePw);
- if (patron.day_phone()) {
- usePhonePw(patron.day_phone());
- }
- }
- case 'evening_phone':
- case 'other_phone':
- dojo.connect(widget.widget, 'onChange',
- function(newVal) { uEditDupeSearch('phone', newVal); });
- return;
-
- case 'home_ou':
- widget.widget.isValid = function() {
- if(this.item) {
- if(homeOuTypes[this.store.getValue(this.item, 'ou_type')]) {
- return true;
- }
- return false;
- }
- return true;
- };
- dojo.connect(widget.widget, 'onChange',
- function(newVal) {
- checkClaimsReturnCountPerm();
- checkClaimsNoCheckoutCountPerm();
- checkCollectionsExemptPerm();
- }
- );
- return;
-
- case 'passwd':
- dojo.connect(widget.widget, 'onChange',
- function(newVal) {
- var pw1 = findWidget('au', 'passwd').widget;
- var pw2 = findWidget('au', 'passwd2').widget;
- var preserved_value = pw2.attr('value');
- // Ensure that the pw2 field match the pw1 field to validate
- pw2.regExp = newVal.replace(/([.\\^$*+?\(\)\[\]\{\}])/g, '\\$1');
- pw2.reset();
- pw2.attr('value',preserved_value);
- });
- return;
- }
- }
-
- if(fmclass = 'aua') {
-
- // map post code to city, state, and county
- if (fmfield == 'post_code') {
- dojo.connect(widget.widget, 'onChange',
- function(e) {
- fieldmapper.standardRequest(
- ['open-ils.search', 'open-ils.search.zip'],
- { async: true,
- params: [e],
- oncomplete : function(r) {
- var res = openils.Util.readResponse(r);
- if(!res) return;
- var callback = function(w) { return w._addr == widget._addr; };
- if(res.city) findWidget('aua', 'city', callback).widget.attr('value', res.city);
- if(res.state) findWidget('aua', 'state', callback).widget.attr('value', res.state);
- if(res.county) findWidget('aua', 'county', callback).widget.attr('value', res.county);
- if(res.alert) alert(res.alert);
- }
- }
- );
- }
- );
- }
-
- // duplicate address search
- if (['street1', 'street2', 'city'].indexOf(fmfield) > -1) {
- dojo.connect(widget.widget, 'onChange',
- function(e) {
- var callback = function(w) { return w._addr == widget._addr; };
- var args = {
- street1 : findWidget('aua', 'street1', callback).widget.attr('value'),
- street2 : findWidget('aua', 'street2', callback).widget.attr('value'),
- city : findWidget('aua', 'city', callback).widget.attr('value'),
- post_code : findWidget('aua', 'post_code', callback).widget.attr('value')
- };
- if(args.street1 && args.city && args.post_code)
- uEditDupeSearch('address', args);
- }
- );
- }
-
- if (addressAlertFields.indexOf(fmfield) > -1) {
- dojo.connect(
- widget.widget, 'onChange',
- function() { uEditAddressAlertMarshal(widget._addr) }
- );
- }
- }
-}
-
-function uEditAddressAlertMarshal(addrId, changeBilling, changeMailing) {
-
- if (changeBilling) {
- uEditAddressAlertMarshal(prevBillingAddress);
- prevBillingAddress = addrId;
- }
-
- if (changeMailing) {
- uEditAddressAlertMarshal(prevMailingAddress);
- prevMailingAddress = addrId;
- }
-
- var callback = function(w) { return w._addr == addrId; };
- var args = {};
- dojo.forEach(addressAlertFields,
- function(field) {
- args[field] = findWidget('aua', field, callback).widget.attr('value')
- }
- );
- args.mailing_address = dojo.byId('uedit-mailing-address-' + addrId).checked;
- args.billing_address = dojo.byId('uedit-billing-address-' + addrId).checked;
- uEditAddressAlertSearch(args, addrId);
-}
-
-var _addrAlertTimeout = {};
-function uEditAddressAlertSearch(args, addrId) {
-
- _addrAlertTimeout[addrId] = setTimeout(
- function() {
- if (_addrAlertTimeout[addrId])
- clearTimeout(_addrAlertTimeout[addrId]);
-
- console.log('creating addr alert search for ' + addrId);
-
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.address_alert.test'],
- { async: true,
- params: [openils.User.authtoken, staff.ws_ou(), args],
- oncomplete : function(r) {
- var alerts = openils.Util.readResponse(r);
- var msgNode = dojo.byId('uedit-address-alert-message');
- var headerRow = dojo.filter(
- dojo.query('[name=uedit-addr-divider]'),
- function(row) { return row.getAttribute('addr') == addrId })[0]
-
- msgNode.innerHTML = '';
-
- if (alerts.length) {
-
- // show the alert box
- openils.Util.hide('uedit-help-div');
- openils.Util.hide('uedit-dupe-div');
- openils.Util.show('uedit-address-alert');
-
- // style the address header row
- openils.Util.addCSSClass(headerRow, 'uedit-address-alert-divider');
-
- dojo.forEach(alerts,
- function(addr) {
- msgNode.innerHTML += addr.alert_message() + '<br/>';
- }
- );
-
- } else {
- openils.Util.hide('uedit-address-alert');
- openils.Util.removeCSSClass(headerRow, 'uedit-address-alert-divider');
- }
- }
- }
- );
- },
- addressAlertTimeout
- );
-}
-
-function uEditDupeSearch(type, value) {
- if(!value) return;
- var search;
- switch(type) {
-
- case 'name':
- openils.Util.hide('uedit-dupe-names-link');
- var fname = findWidget('au', 'first_given_name').widget.attr('value');
- var lname = findWidget('au', 'family_name').widget.attr('value');
- if( !(fname && lname) ) return;
- search = {
- first_given_name : {value : fname, group : 0},
- family_name : {value : lname, group : 0},
- };
- break;
-
- case 'email':
- openils.Util.hide('uedit-dupe-email-link');
- search = {email : {value : value, group : 0}};
- break;
-
- case 'ident':
- openils.Util.hide('uedit-dupe-ident-link');
- search = {ident : {value : value, group : 2}};
- break;
-
- case 'phone':
- openils.Util.hide('uedit-dupe-phone-link');
- search = {phone : {value : value, group : 2}};
- break;
-
- case 'address':
- openils.Util.hide('uedit-dupe-address-link');
- search = {};
- dojo.forEach(['street1', 'street2', 'city', 'post_code'],
- function(field) {
- if(value[field])
- search[field] = {value : value[field], group: 1};
- }
- );
- break;
- }
-
- // find possible duplicate patrons
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.patron.search.advanced'],
- { async: true,
- params: [openils.User.authtoken, search],
- oncomplete : function(r) {
- var resp = openils.Util.readResponse(r);
- resp = resp.filter(function(id) { return (id != patron.id()); });
-
- if(resp && resp.length > 0) {
-
- openils.Util.hide('uedit-help-div');
- openils.Util.hide('uedit-address-alert');
- openils.Util.show('uedit-dupe-div');
- var link;
-
- switch(type) {
- case 'name':
- link = dojo.byId('uedit-dupe-names-link');
- link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_NAME, [resp.length]);
- break;
- case 'email':
- link = dojo.byId('uedit-dupe-email-link');
- link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_EMAIL, [resp.length]);
- break;
- case 'ident':
- link = dojo.byId('uedit-dupe-ident-link');
- link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_IDENT, [resp.length]);
- break;
- case 'phone':
- link = dojo.byId('uedit-dupe-phone-link');
- link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_PHONE, [resp.length]);
- break;
- case 'address':
- link = dojo.byId('uedit-dupe-address-link');
- link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_ADDR, [resp.length]);
- break;
- }
-
- openils.Util.show(link);
- link.onclick = function() {
- search.search_sort = js2JSON(["penalties", "family_name", "first_given_name"]);
- if(window.xulG)
- window.xulG.spawn_search(search);
- else
- console.log("running XUL patron search " + js2JSON(search));
- }
- }
- }
- }
- );
-}
-
-function getByName(node, name) {
- return dojo.query('[name='+name+']', node)[0];
-}
-
-
-function ueLoadContextHelp(fmcls, fmfield) {
- openils.Util.hide('uedit-dupe-div');
- openils.Util.hide('uedit-dupe-div');
- openils.Util.show('uedit-help-div');
- dojo.byId('uedit-help-field').innerHTML = fieldmapper.IDL.fmclasses[fmcls].field_map[fmfield].label;
- dojo.byId('uedit-help-text').innerHTML = fieldDoc[fmcls][fmfield].string();
-}
-
-
-/* creates a new patron object with card attached */
-function uEditNewPatron() {
- patron = new au();
- patron.isnew(1);
- patron.id(-1);
- card = new ac();
- card.id(uEditCardVirtId--);
- card.isnew(1);
- patron.active(1);
- patron.card(card);
- patron.cards([card]);
- patron.net_access_level(orgSettings['ui.patron.default_inet_access_level'] || 1);
- patron.ident_type(orgSettings['ui.patron.default_ident_type']);
- patron.stat_cat_entries([]);
- patron.survey_responses([]);
- patron.addresses([]);
- uEditMakeRandomPw(patron);
- return patron;
-}
-
-function uEditMakeRandomPw(patron) {
- var rand = Math.random();
- rand = parseInt(rand * 10000) + '';
- while(rand.length < 4) rand += '0';
-/*
- appendClear($('ue_password_plain'),text(rand));
- unHideMe($('ue_password_gen'));
-*/
- patron.passwd(rand);
- return rand;
-}
-
-function uEditWidgetVal(w) {
- var val = (w.getFormattedValue) ? w.getFormattedValue() : w.attr('value');
- if(val === '') val = null;
- return val;
-}
-
-function uEditSave() { _uEditSave(); }
-function uEditSaveClone() { _uEditSave(true); }
-
-function _uEditSave(doClone) {
-
- if ( (! myForm.isValid()) || dupeUsrname || dupeBarcode ) {
- alert(localeStrings.INVALID_FORM);
- return;
- }
-
- for(var idx in widgetPile) {
- var w = widgetPile[idx];
- var val = uEditWidgetVal(w);
-
- switch(w._wtype) {
- case 'au':
- if(w._fmfield != 'passwd2')
- patron[w._fmfield](val);
- break;
-
- case 'ac':
- if(!editCard) editCard = patron.card();
- editCard[w._fmfield](val);
- break;
-
- case 'aua':
- var addr = patron.addresses().filter(function(i){return (i.id() == w._addr)})[0];
- if(!addr) {
- addr = new fieldmapper.aua();
- addr.id(w._addr);
- addr.isnew(1);
- addr.usr(patron.id());
- addr.country(orgSettings['ui.patron.default_country']);
- var t = patron.addresses();
- if (!t) { t = []; }
- t.push(addr);
- patron.addresses(t);
- } else {
- if(addr[w._fmfield]() != val)
- addr.ischanged(1);
- }
- addr[w._fmfield](val);
-
- if(dojo.byId('uedit-billing-address-' + addr.id()).checked)
- patron.billing_address(addr.id());
-
- if(dojo.byId('uedit-mailing-address-' + addr.id()).checked)
- patron.mailing_address(addr.id());
-
- break;
-
- case 'survey':
- if(val == null) break;
- var resp = new fieldmapper.asvr();
- resp.isnew(1);
- resp.survey(w._survey)
- resp.usr(patron.id());
- resp.question(w._question)
- resp.answer(val);
- var t = patron.survey_responses();
- if (!t) { t = []; }
- t.push(resp);
- patron.survey_responses(t);
- break;
-
- case 'statcat':
- var map = patron.stat_cat_entries().filter(
- function(m){
- return (m.stat_cat() == w._statcat) })[0];
-
- if(map) {
- if(map.stat_cat_entry() == val)
- break;
- if(val == null) {
- val = '';
- map.isdeleted(1);
- } else {
- map.ischanged(1);
- }
- } else {
- if(val == null)
- break;
- map = new fieldmapper.actscecm();
- map.isnew(1);
- }
-
- map.stat_cat(w._statcat);
- map.stat_cat_entry(val);
- map.target_usr(patron.id());
- var t = patron.stat_cat_entries();
- if (!t) { t = []; }
- t.push(map);
- patron.stat_cat_entries(t);
- break;
- }
- }
-
- patron.ischanged(1);
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.patron.update'],
- { async: true,
- params: [openils.User.authtoken, patron],
- oncomplete: function(r) {
- lock_ready = false;
- if (xulG && typeof xulG.unlock_tab == 'function') {
- xulG.unlock_tab();
- already_locked = false;
- }
- /* There's something that seems to just make the form reload
- * on all saves, so this uUpdate... isn't needed here after
- * all. */
- //uUpdateContactInvalidators();
-
- newPatron = openils.Util.readResponse(r);
- if(newPatron) {
- uEditUpdateUserSettings(newPatron.id());
- if(stageUser) uEditRemoveStage();
- uEditFinishSave(newPatron, doClone);
- }
- }
- }
- );
-}
-
-function uUpdateContactInvalidators() {
- /* show invalidator buttons for fields that having anything in them */
- ["email", "day_phone", "evening_phone", "other_phone"].forEach(
- function(f) {
- openils.Util[patron[f]() ? "show" : "hide"]("wrap_invalidate_" + f);
- }
- );
-}
-
-function uGenerateInvalidatorWidget(container_node, field) {
- new dijit.form.Button(
- {
- "label": localeStrings.INVALIDATE,
- "scrollOnFocus": false,
- "onClick": function() {
- progressDialog.show(true);
- fieldmapper.standardRequest(
- ["open-ils.actor", "open-ils.actor.invalidate." + field], {
- "async": true,
- "params": [openils.User.authtoken, patron.id(), null, patron.home_ou()],
- "oncomplete": function(r) {
- progressDialog.hide();
- // alerts on non-success event
- var res = openils.Util.readResponse(r);
-
- if (res.payload.last_xact_id) {
- for (var id in res.payload.last_xact_id) {
- if (patron.id() == id)
- patron.last_xact_id(
- res.payload.last_xact_id[id]
- );
- }
-
- findWidget("au",field).widget.attr("value","");
- openils.Util.hide(container_node);
- }
- }
- }
- );
- }
- }, dojo.create("span", null, container_node, "only")
- );
-}
-
-function uEditRemoveStage() {
- var resp = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.stage.delete'],
- { params : [openils.User.authtoken, stageUser.row_id()] }
- )
-}
-
-function uEditFinishSave(newPatron, doClone) {
-
- if(doClone && cloneUser == null)
- cloneUser = newPatron.id();
-
- if( doClone ) {
-
- if(xulG && typeof xulG.spawn_editor == 'function' && !patron.isnew() ) {
- window.xulG.spawn_editor({ses:openils.User.authtoken,clone:cloneUser});
- uEditRefresh();
-
+require([
+ "dojo/data/ItemFileReadStore",
+ "dijit/form/Form",
+ "dijit/form/Textarea",
+ "dijit/form/FilteringSelect",
+ "dijit/form/ComboBox",
+ "dijit/form/NumberSpinner",
+ "fieldmapper/IDL",
+ "fieldmapper/OrgUtils",
+ "openils/PermaCrud",
+ "openils/widget/AutoGrid",
+ "openils/widget/AutoFieldWidget",
+ "openils/widget/ProgressDialog",
+ "dijit/form/CheckBox",
+ "dijit/form/Button",
+ "dojo/date",
+ "openils/CGI",
+ "openils/XUL",
+ "openils/Util",
+ "openils/Event"
+ ],
+function(dojo_data_ItemFileReadStore,
+ dijit_form_Form,
+ dijit_form_Textarea,
+ dijit_form_FilteringSelect,
+ dijit_form_ComboBox,
+ dijit_form_NumberSpinner,
+ fieldmapper_IDL,
+ fieldmapper_OrgUtils,
+ openils_PermaCrud,
+ openils_widget_AutoGrid,
+ openils_widget_AutoFieldWidget,
+ openils_widget_ProgressDialog,
+ dijit_form_CheckBox,
+ dijit_form_Button,
+ dojo_date,
+ openils_CGI,
+ openils_XUL,
+ openils_Util,
+ openils_Event){
+
+ dojo.requireLocalization('openils.actor', 'register');
+ var localeStrings = dojo.i18n.getLocalization('openils.actor', 'register');
+
+
+ var pcrud;
+ var fmClasses = ['au', 'ac', 'aua', 'actsc', 'asv', 'asvq', 'asva'];
+ var fieldDoc = {};
+ var statCats;
+ var statCatTemplate;
+ var surveys;
+ var staff;
+ var patron;
+ var uEditUsePhonePw = false;
+ var widgetPile = [];
+ var uEditCardVirtId = -1;
+ var uEditAddrVirtId = -1;
+ var orgSettings = {};
+ var userSettings = {};
+ var userSettingsToUpdate = {};
+ var userSettingTypes;
+ var tbody;
+ var addrTemplateRows;
+ var cgi;
+ var cloneUser;
+ var cloneUserObj;
+ var stageUser;
+ var optInSettings;
+ var allCardsTemplate;
+ var uEditCloneCopyAddr; // if true, copy addrs on clone instead of link
+ var homeOuTypes = {};
+ var holdPickupTypes = {};
+ var cardPerms = {};
+ var editCard;
+ var prevBillingAddress;
+ var prevMailingAddress;
+
+ var dupeUsrname = false;
+ var dupeBarcode = false;
+
+ // allow for a pause after typing before sending address alert queries
+ var addressAlertTimeout = 2000;
+ var addressAlertFields =
+ ['street1', 'street2', 'city', 'state', 'county', 'country', 'post_code'];
+
+ if(!window.xulG) var xulG = null;
+ var lock_ready = false;
+ var already_locked = false;
+
+ function load() {
+ staff = new openils.User().user;
+ pcrud = new openils_PermaCrud();
+ cgi = new openils_CGI();
+ cloneUser = cgi.param('clone');
+ var userId = cgi.param('usr');
+ var stageUname = cgi.param('stage');
+
+ saveButton.attr("label", localeStrings.SAVE);
+ saveCloneButton.attr("label", localeStrings.SAVE_CLONE);
+ replaceBarcode.attr("label", localeStrings.REPLACE_BARCODE);
+ dojo.byId('uedit-show-required').innerHTML = localeStrings.SHOW_REQUIRED;
+ dojo.byId('uedit-show-suggested').innerHTML = localeStrings.SHOW_SUGGESTED;
+ dojo.byId('uedit-show-all').innerHTML = localeStrings.SHOW_ALL;
+ dojo.byId('uedit-dupe-barcode-warning').innerHTML = localeStrings.BARCODE_IN_USE;
+ allCards.attr("label", localeStrings.SEE_ALL);
+ dojo.byId('uedit-dupe-username-warning').innerHTML = localeStrings.DUPE_USERNAME;
+ generatePassword.attr("label", localeStrings.RESET_PASSWORD);
+ dojo.byId('verifyPassword').innerHTML = localeStrings.VERIFY_PASSWORD;
+ dojo.byId('parentGuardian').innerHTML = localeStrings.PARENT_OR_GUARDIAN;
+ dojo.byId('userSettings').innerHTML = localeStrings.USER_SETTINGS;
+ dojo.byId('statCats').innerHTML = localeStrings.STAT_CATS;
+ dojo.byId('uedit-all-cards-barcode').innerHTML = localeStrings.ALL_CARDS_BARCODE;
+ dojo.byId('uedit-all-cards-active').innerHTML = localeStrings.ALL_CARDS_ACTIVE;
+ dojo.byId('uedit-all-cards-primary').innerHTML = localeStrings.ALL_CARDS_PRIMARY;
+ allCardsClose.attr("label", localeStrings.ALL_CARDS_CLOSE);
+ allCardsApply.attr("label", localeStrings.ALL_CARDS_APPLY);
+
+ dojo.query("td[name='addressHeader']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_HEADER; });
+ dojo.query("span[name='mailingAddress']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_MAILING; });
+ dojo.query("span[name='billingAddress']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_BILLING; });
+ dojo.query("span[name='addressPending']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_PENDING; });
+ dojo.query("button[name='approve-button']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_APPROVE; });
+ dojo.query("span[name='address-already-owned']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_OWNED; });
+ dojo.query("button[name='addressNew']").forEach( function(item) { item.innerHTML = localeStrings.ADDRESS_NEW; });
+
+ if(xulG) {
+ if(xulG.ses) openils.User.authtoken = xulG.ses;
+ if(typeof xulG.clone != 'undefined') cloneUser = xulG.clone;
+ if(typeof xulG.usr != 'undefined') userId = xulG.usr
+ if(typeof xulG.params != 'undefined') {
+ var parms = xulG.params;
+ if(typeof parms.ses != 'undefined')
+ openils.User.authtoken = parms.ses;
+ if(typeof parms.clone != 'undefined')
+ cloneUser = parms.clone;
+ if(typeof parms.usr != 'undefined')
+ userId = parms.usr;
+ if(typeof parms.stage != 'undefined')
+ stageUname = parms.stage
+ }
+ }
+
+ orgSettings = fieldmapper.aou.fetchOrgSettingBatch(staff.ws_ou(), [
+ 'global.password_regex',
+ 'global.juvenile_age_threshold',
+ 'patron.password.use_phone',
+ 'ui.patron.default_inet_access_level',
+ 'ui.patron.default_ident_type',
+ 'ui.patron.default_country',
+ 'ui.patron.registration.require_address',
+ 'circ.holds.behind_desk_pickup_supported',
+ 'circ.patron_edit.clone.copy_address',
+ 'ui.patron.edit.au.prefix.require',
+ 'ui.patron.edit.au.prefix.show',
+ 'ui.patron.edit.au.prefix.suggest',
+ 'ui.patron.edit.au.second_given_name.show',
+ 'ui.patron.edit.au.second_given_name.suggest',
+ 'ui.patron.edit.au.suffix.show',
+ 'ui.patron.edit.au.suffix.suggest',
+ 'ui.patron.edit.au.alias.show',
+ 'ui.patron.edit.au.alias.suggest',
+ 'ui.patron.edit.au.dob.require',
+ 'ui.patron.edit.au.dob.show',
+ 'ui.patron.edit.au.dob.suggest',
+ 'ui.patron.edit.au.dob.calendar',
+ 'ui.patron.edit.au.juvenile.show',
+ 'ui.patron.edit.au.juvenile.suggest',
+ 'ui.patron.edit.au.ident_value.show',
+ 'ui.patron.edit.au.ident_value.suggest',
+ 'ui.patron.edit.au.ident_value2.show',
+ 'ui.patron.edit.au.ident_value2.suggest',
+ 'ui.patron.edit.au.email.require',
+ 'ui.patron.edit.au.email.show',
+ 'ui.patron.edit.au.email.suggest',
+ 'ui.patron.edit.au.email.regex',
+ 'ui.patron.edit.au.email.example',
+ 'ui.patron.edit.au.day_phone.require',
+ 'ui.patron.edit.au.day_phone.show',
+ 'ui.patron.edit.au.day_phone.suggest',
+ 'ui.patron.edit.au.day_phone.regex',
+ 'ui.patron.edit.au.day_phone.example',
+ 'ui.patron.edit.au.evening_phone.require',
+ 'ui.patron.edit.au.evening_phone.show',
+ 'ui.patron.edit.au.evening_phone.suggest',
+ 'ui.patron.edit.au.evening_phone.regex',
+ 'ui.patron.edit.au.evening_phone.example',
+ 'ui.patron.edit.au.other_phone.require',
+ 'ui.patron.edit.au.other_phone.show',
+ 'ui.patron.edit.au.other_phone.suggest',
+ 'ui.patron.edit.au.other_phone.regex',
+ 'ui.patron.edit.au.other_phone.example',
+ 'ui.patron.edit.phone.regex',
+ 'ui.patron.edit.phone.example',
+ 'ui.patron.edit.au.active.show',
+ 'ui.patron.edit.au.active.suggest',
+ 'ui.patron.edit.au.barred.show',
+ 'ui.patron.edit.au.barred.suggest',
+ 'ui.patron.edit.au.master_account.show',
+ 'ui.patron.edit.au.master_account.suggest',
+ 'ui.patron.edit.au.claims_returned_count.show',
+ 'ui.patron.edit.au.claims_returned_count.suggest',
+ 'ui.patron.edit.au.claims_never_checked_out_count.show',
+ 'ui.patron.edit.au.claims_never_checked_out_count.suggest',
+ 'ui.patron.edit.au.alert_message.show',
+ 'ui.patron.edit.au.alert_message.suggest',
+ 'ui.patron.edit.aua.post_code.regex',
+ 'ui.patron.edit.aua.post_code.example',
+ 'ui.patron.edit.aua.county.require',
+ 'format.date',
+ 'ui.patron.edit.default_suggested',
+ 'opac.barcode_regex',
+ 'opac.username_regex',
+ 'sms.enable'
+ ]);
+
+ for(k in orgSettings)
+ if(orgSettings[k])
+ orgSettings[k] = orgSettings[k].value;
+
+ uEditCloneCopyAddr = orgSettings['circ.patron_edit.clone.copy_address'];
+ uEditUsePhonePw = orgSettings['patron.password.use_phone'];
+ uEditFetchUserSettings(userId);
+
+ if(userId) {
+ patron = uEditLoadUser(userId);
+ } else {
+ if(stageUname) {
+ patron = uEditLoadStageUser(stageUname);
+ } else {
+ patron = uEditNewPatron();
+ if(cloneUser)
+ uEditCopyCloneData(patron);
+ }
+ }
+
+
+ var list = pcrud.search('fdoc', {fm_class:fmClasses});
+ for(var i in list) {
+ var doc = list[i];
+ if(!fieldDoc[doc.fm_class()])
+ fieldDoc[doc.fm_class()] = {};
+ fieldDoc[doc.fm_class()][doc.field()] = doc;
+ }
+
+ list = pcrud.search('aout', {can_have_users: 'true'});
+ for(var i in list) {
+ var type = list[i];
+ homeOuTypes[type.id()] = true;
+ }
+ list = pcrud.search('aout', {can_have_vols: 'true'});
+ for(var i in list) {
+ var type = list[i];
+ holdPickupTypes[type.id()] = true;
+ }
+
+ tbody = dojo.byId('uedit-tbody');
+
+ if(orgSettings['ui.patron.edit.default_suggested'])
+ uEditToggleRequired(2);
+
+ addrTemplateRows = dojo.query('tr[type=addr-template]', tbody);
+ dojo.forEach(addrTemplateRows, function(row) { row.parentNode.removeChild(row); } );
+ statCatTemplate = tbody.removeChild(dojo.byId('stat-cat-row-template'));
+ surveyTemplate = tbody.removeChild(dojo.byId('survey-row-template'));
+ surveyQuestionTemplate = tbody.removeChild(dojo.byId('survey-question-row-template'));
+
+ checkGrpAppPerm(); // to do the initial load
+ loadStaticFields();
+
+
+ if(patron.isnew() && patron.addresses().length == 0)
+ uEditNewAddr(null, uEditAddrVirtId, true);
+ else loadAllAddrs();
+ loadStatCats();
+ loadSurveys();
+ checkClaimsReturnCountPerm();
+ checkClaimsNoCheckoutCountPerm();
+
+ dojo.connect(replaceBarcode, 'onClick', replaceCardHandler);
+ dojo.connect(allCards, 'onClick', drawAllCards);
+ if(patron.isnew()) {
+ dojo.addClass(dojo.byId('uedit-all-barcodes'), 'hidden');
+ } else if(checkGrpAppPerm(patron.profile())) {
+ new openils.User().getPermOrgList(
+ 'UPDATE_PATRON_ACTIVE_CARD',
+ function(orgList) {
+ if(orgList.indexOf(patron.home_ou()) != -1)
+ cardPerms['UPDATE_PATRON_ACTIVE_CARD'] = true;
+ },
+ true,
+ true
+ );
+ new openils.User().getPermOrgList(
+ 'UPDATE_PATRON_PRIMARY_CARD',
+ function(orgList) {
+ if(orgList.indexOf(patron.home_ou()) != -1)
+ cardPerms['UPDATE_PATRON_PRIMARY_CARD'] = true;
+ },
+ true,
+ true
+ );
+ }
+
+ var input = findWidget('ac', 'barcode');
+ if (patron.isnew()) {
+ replaceBarcode.attr('disabled', true);
+ } else {
+ input.widget.attr('disabled', true).attr('readOnly', true);
+ }
+
+ dojo.connect(generatePassword, 'onClick', generatePasswordHandler);
+
+ if(!patron.isnew() && !checkGrpAppPerm(patron.profile()) && patron.id() != openils.User.user.id()) {
+ // we are not allowed to edit this user, so disable the save option
+ saveButton.attr('disabled', true);
+ saveCloneButton.attr('disabled', true);
+ }
+
+ uUpdateContactInvalidators();
+ lock_ready = true;
+ }
+
+ var permGroups;
+ var noPermGroups = [];
+ // Returns true if the user is allowed to edit the selected group
+ function checkGrpAppPerm(grpId) {
+
+ if(!permGroups) {
+
+ // get the groups
+ permGroups = new openils_PermaCrud().retrieveAll('pgt');
+ var permGroupPerms = []
+
+ // collect the group permissions
+ dojo.forEach(permGroups,
+ function(grp) {
+ if(grp.application_perm())
+ permGroupPerms.push(grp.application_perm());
+ }
+ );
+
+ // see which of the group application perms I do not have
+ var myPerms = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.has_work_perm_at.batch'],
+ [openils.User.authtoken, permGroupPerms]
+ );
+
+ var failedPerms = [];
+ for(var p in myPerms) {
+ if(myPerms[p].length == 0)
+ failedPerms.push(p);
+ }
+
+ // identify which groups I cannot edit because I do not have permisssion
+
+ function checkTree(grp, failed) {
+ failed = failed || failedPerms.indexOf(grp.application_perm()) > -1;
+ if(failed) noPermGroups.push(grp.id()+'');
+ dojo.forEach(
+ permGroups.filter(function(g) { return g.parent() == grp.id() } ),
+ function(child) {
+ checkTree(child, failed);
+ }
+ );
+ }
+
+ checkTree(permGroups.filter(function(g) { return g.parent() == null })[0]);
+ }
+
+ return noPermGroups.indexOf(grpId+'') == -1;
+ }
+
+
+ function drawAllCards() {
+
+ var tbody = dojo.byId('uedit-all-cards-tbody');
+ if(!allCardsTemplate) {
+ allCardsTemplate = tbody.removeChild(dojo.byId('uedit-all-cards-tr-template'));
+ } else {
+ while(tbody.childNodes[0])
+ tbody.removeChild(tbody.childNodes[0]);
+ }
+
+ if(cardPerms['UPDATE_PATRON_ACTIVE_CARD'] || cardPerms['UPDATE_PATRON_PRIMARY_CARD']) {
+ dojo.removeClass(dojo.byId('uedit-apply-card-changes'), 'hidden');
+ } else {
+ dojo.addClass(dojo.byId('uedit-apply-card-changes'), 'hidden');
+ }
+
+ var first = true;
+ dojo.forEach(
+ patron.cards().filter(function(c) { return c.id() == patron.card().id(); }).concat(patron.cards()), // grab the main card first
+ function(card) {
+ if(!first) {
+ if(card.id() == patron.card().id())
+ return;
+ }
+ var row = allCardsTemplate.cloneNode(true);
+ row.setAttribute("cardid", card.id());
+ row.card = card;
+ getByName(row, 'barcode').innerHTML = card.barcode();
+ if(cardPerms['UPDATE_PATRON_ACTIVE_CARD']) {
+ row.active_checkbox = new dijit_form_CheckBox({
+ scrollOnFocus:false,
+ checked: openils_Util.isTrue(card.active())
+ }, getByName(row, 'active'));
+ } else {
+ getByName(row, 'active').appendChild(
+ openils_Util.isTrue(card.active()) ?
+ dojo.byId('true').cloneNode(true) :
+ dojo.byId('false').cloneNode(true)
+ );
+ }
+ if(cardPerms['UPDATE_PATRON_PRIMARY_CARD']) {
+ row.primary_radiobutton = new dijit.form.RadioButton({
+ scrollOnFocus:false,
+ checked: card.id() == patron.card().id(),
+ value: card.id(),
+ name: 'card_primary'
+ }, getByName(row, 'primary'));
+ } else {
+ getByName(row, 'primary').appendChild(
+ openils_Util.isTrue(card.id() == patron.card().id()) ?
+ dojo.byId('true').cloneNode(true) :
+ dojo.byId('false').cloneNode(true)
+ );
+ }
+ tbody.appendChild(row);
+ first = false;
+ }
+ );
+
+ allCardsDialog.show();
+ }
+
+ function applyCardChanges() {
+ var cardrows = dojo.query('[cardid]', allCardsDialog.domNode);
+ var changed = false;
+ dojo.forEach(cardrows,
+ function(row) {
+ if(cardPerms['UPDATE_PATRON_ACTIVE_CARD']) {
+ var active = row.active_checkbox.checked ? 't' : 'f'
+ if(row.card.active() != active) {
+ row.card.active(active);
+ row.card.ischanged(1);
+ changed = true;
+ }
+ }
+ if(cardPerms['UPDATE_PATRON_PRIMARY_CARD']) {
+ if(row.primary_radiobutton.checked && row.card.id() != patron.card().id()) {
+ patron.card(row.card);
+ changed = true;
+ }
+ }
+ }
+ );
+ if(changed && lock_ready && xulG && typeof xulG.lock_tab == 'function' && !already_locked) {
+ xulG.lock_tab();
+ already_locked = true;
+ }
+ allCardsDialog.hide();
+ }
+
+ /**
+ * Mark the current card inactive, create a new primary card
+ */
+ function replaceCardHandler() {
+ var input = findWidget('ac', 'barcode');
+ input.widget.attr('disabled', false).attr('readOnly', false).attr('value', null).focus();
+ replaceBarcode.attr('disabled', true);
+
+ // pull old card off the cards list so we don't have a dupe sitting in there
+ if (patron.cards().length > 0) {
+ var old = patron.cards().filter(function(c){return (c.id() == patron.card().id())})[0];
+ old.active('f');
+ old.ischanged(1);
+ }
+
+ var newc = new fieldmapper.ac();
+ newc.id(uEditCardVirtId--);
+ newc.isnew(1);
+ newc.active('t');
+ patron.card(newc);
+ editCard = newc;
+ var t = patron.cards();
+ if (!t) { t = []; }
+ t.push(newc);
+ patron.cards(t);
+ }
+
+ /**
+ * Generate a random password for the patron.
+ */
+ function generatePasswordHandler() {
+ uEditMakeRandomPw(patron);
+ var f = findWidget('au', 'passwd');
+ f.widget.attr('value', patron.passwd());
+ f = findWidget('au', 'passwd2');
+ f.widget.attr('value', patron.passwd());
+ }
+
+ /**
+ * Loads a staged user and turns them into something the editor can understand
+ */
+ function uEditLoadStageUser(stageUname) {
+
+ var data = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.stage.retrieve.by_username'],
+ { params : [openils.User.authtoken, stageUname] }
+ );
+
+ stageUser = data.user;
+ patron = uEditNewPatron();
+
+ if(!stageUser)
+ return patron;
+
+ // copy the data into our new user object
+ for(var key in fieldmapper_IDL.fmclasses.stgu.field_map) {
+ if(fieldmapper_IDL.fmclasses.au.field_map[key] && !fieldmapper_IDL.fmclasses.stgu.field_map[key].virtual) {
+ if(data.user[key]() !== null)
+ patron[key]( data.user[key]() );
+ }
+ }
+
+ // copy the data into our new address objects
+ // TODO: uses the first mailing address only
+ if(data.mailing_addresses.length) {
+
+ var mail_addr = new fieldmapper.aua();
+ mail_addr.id(-1); // virtual ID
+ mail_addr.usr(-1);
+ mail_addr.isnew(1);
+ patron.mailing_address(mail_addr);
+ var t = patron.addresses();
+ if (!t) { t = []; }
+ t.push(mail_addr);
+ patron.addresses(t);
+
+ for(var key in fieldmapper_IDL.fmclasses.stgma.field_map) {
+ if(fieldmapper_IDL.fmclasses.aua.field_map[key] && !fieldmapper_IDL.fmclasses.stgma.field_map[key].virtual) {
+ if(data.mailing_addresses[0][key]() !== null)
+ mail_addr[key]( data.mailing_addresses[0][key]() );
+ }
+ }
+ }
+
+ // copy the data into our new address objects
+ // TODO uses the first billing address only
+ if(data.billing_addresses.length) {
+
+ var bill_addr = new fieldmapper.aua();
+ bill_addr.id(-2); // virtual ID
+ bill_addr.usr(-1);
+ bill_addr.isnew(1);
+ patron.billing_address(bill_addr);
+ var t = patron.addresses();
+ if (!t) { t = []; }
+ t.push(bill_addr);
+ patron.addresses(t);
+
+ for(var key in fieldmapper_IDL.fmclasses.stgba.field_map) {
+ if(fieldmapper_IDL.fmclasses.aua.field_map[key] && !fieldmapper_IDL.fmclasses.stgba.field_map[key].virtual) {
+ if(data.billing_addresses[0][key]() !== null)
+ bill_addr[key]( data.billing_addresses[0][key]() );
+ }
+ }
+ }
+
+ // TODO: uses the first card only
+ if(data.cards.length) {
+ var card = new fieldmapper.ac();
+ card.id(-1); // virtual ID
+ patron.card().barcode(data.cards[0].barcode());
+ }
+
+ return patron;
+ }
+
+ /*
+ * clone the home org, phone numbers, and billing/mailing address
+ */
+ function uEditCopyCloneData(patron) {
+ cloneUserObj = uEditLoadUser(cloneUser);
+
+ var cloneFields = [
+ 'home_ou',
+ 'day_phone',
+ 'evening_phone',
+ 'other_phone',
+ 'usrgroup'
+ ];
+
+ if(!uEditCloneCopyAddr)
+ cloneFields = cloneFields.concat(['mailing_address', 'billing_address']);
+
+ dojo.forEach(
+ cloneFields,
+ function(field) {
+ patron[field](cloneUserObj[field]());
+ }
+ );
+
+ if(uEditCloneCopyAddr) {
+ var billAddr, mailAddr;
+
+ // copy the billing and mailing addresses into new addresses
+ function cloneAddr(addr) {
+ var newAddr = addr.clone();
+ newAddr.isnew(true);
+ newAddr.id(uEditAddrVirtId--);
+ newAddr.usr(patron.id());
+ patron.addresses().push(newAddr);
+ return newAddr;
+ }
+
+ if(billAddr = cloneUserObj.billing_address())
+ patron.billing_address(cloneAddr(billAddr));
+
+ if(mailAddr = cloneUserObj.mailing_address()) {
+ if (billAddr && billAddr.id() == mailAddr.id()) {
+ patron.mailing_address(patron.billing_address());
+ } else {
+ patron.mailing_address(cloneAddr(mailAddr));
+ }
+ }
+
+ if(!billAddr) // if there was no billing addr, use the mailing addr
+ patron.billing_address(patron.mailing_address());
+
+ } else {
+
+ // link the billing and mailing addresses
+ if(patron.billing_address()) {
+ var t = patron.addresses();
+ if (!t) { t = []; }
+ t.push(patron.billing_address());
+ patron.addresses(t);
+ }
+
+ if(patron.mailing_address() && (
+ patron.addresses().length == 0 ||
+ patron.mailing_address().id() != patron.billing_address().id()) ) {
+ var t = patron.addresses();
+ if (!t) { t = []; }
+ t.push(patron.mailing_address());
+ patron.addresses(t);
+ }
+ }
+ }
+
+
+ function uEditFetchUserSettings(userId) {
+
+ var baseNode = fieldmapper.aou.findOrgUnit(staff.ws_ou());
+ var orgs = fieldmapper.aou.orgNodeTrail(baseNode);
+ orgs = orgs.map(function(node) { return node.id(); });
+
+ /* fetch any user setting types we need + any that offer opt-in */
+ userSettingTypes = pcrud.search('cust', {
+ '-or' : [
+ {name:['circ.holds_behind_desk', 'circ.collections.exempt', 'opac.hold_notify', 'opac.default_phone', 'opac.default_pickup_location', 'opac.default_sms_carrier', 'opac.default_sms_notify']},
+ {name : {
+ 'in': {
+ select : {atevdef : ['opt_in_setting']},
+ from : 'atevdef',
+ // we only care about opt-in settings for event_defs our users encounter
+ where : {'+atevdef' : {owner : orgs}}
+ }
+ }}
+ ]
+ });
+
+ var names = userSettingTypes.map(function(obj) { return obj.name() });
+
+ /* fetch any values set for this user */
+ if(userId) {
+ userSettings = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.patron.settings.retrieve.authoritative'],
+ {params : [openils.User.authtoken, userId, names]});
+ }
+ }
+
+
+ function uEditLoadUser(userId) {
+ var patron = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.fleshed.retrieve.authoritative'],
+ {params : [openils.User.authtoken, userId]}
+ );
+ openils_Event.parse_and_raise(patron);
+ return patron;
+ }
+
+ function loadStaticFields() {
+ for(var idx = 0; tbody.childNodes[idx]; idx++) {
+ var row = tbody.childNodes[idx];
+ if(row.nodeType != row.ELEMENT_NODE) continue;
+ var fmcls = row.getAttribute('fmclass');
+ if(fmcls) {
+ fleshFMRow(row, fmcls);
+ } else {
+
+ if(row.id == 'uedit-settings-divider') {
+
+ var template = tbody.removeChild(dojo.byId('uedit-user-setting-template'));
+ dojo.forEach(userSettingTypes, function(type) { uEditDrawSettingRow(tbody, row, template, type); } );
+
+ if(userSettingTypes.length > 1 || orgSettings['circ.holds.behind_desk_pickup_supported']) {
+ openils_Util.show('uedit-settings-divider', 'table-row');
+ }
+ }
+ }
+ }
+ }
+
+ function uEditDrawSettingRow(tbody, dividerRow, template, stype) {
+ var row = template.cloneNode(true);
+ row.setAttribute('user_setting', stype.name());
+ getByName(row, 'label').innerHTML = stype.label();
+ switch(stype.name()) {
+ case 'opac.hold_notify':
+ var template = localeStrings.HOLD_NOTIFY_PHONE + '<span name="hold_phone"></span> '
+ + localeStrings.HOLD_NOTIFY_EMAIL + '<span name="hold_email"></span>';
+ if(orgSettings['sms.enable']) {
+ template += ' ' + localeStrings.HOLD_NOTIFY_SMS + '<span name="hold_sms"></span>';
+ }
+ getByName(row, 'widget').innerHTML = template;
+ var setting = userSettings['opac.hold_notify'];
+ if(setting == null) setting = 'phone:email';
+ var cb_phone = new dijit_form_CheckBox({scrollOnFocus:false}, getByName(row, 'hold_phone'));
+ cb_phone.attr('value', setting.indexOf('phone') != -1);
+ var cb_email = new dijit_form_CheckBox({scrollOnFocus:false}, getByName(row, 'hold_email'));
+ cb_email.attr('value', setting.indexOf('email') != -1);
+ var cb_sms = null;
+ if(orgSettings['sms.enable']) {
+ cb_sms = new dijit_form_CheckBox({scrollOnFocus:false}, getByName(row, 'hold_sms'));
+ cb_sms.attr('value', setting.indexOf('sms') != -1);
+ }
+ var func = function() {
+ var newVal = '';
+ var splitter = '';
+ if(cb_phone.checked) {
+ newVal+= splitter + 'phone';
+ splitter = ':';
+ }
+ if(cb_email.checked) {
+ newVal+= splitter + 'email';
+ splitter = ':';
+ }
+ if(orgSettings['sms.enable'] && cb_sms.checked) {
+ newVal+= splitter + 'sms';
+ splitter = ':';
+ }
+ userSettingsToUpdate['opac.hold_notify'] = newVal;
+ };
+ dojo.connect(cb_phone, 'onChange', func);
+ dojo.connect(cb_email, 'onChange', func);
+ if(cb_sms) dojo.connect(cb_sms, 'onChange', func);
+ break;
+ case 'opac.default_pickup_location':
+ var sb = new openils.widget.FilteringTreeSelect({
+ scrollOnFocus: false,
+ labelAttr: 'name',
+ searchAttr: 'name',
+ parentField: 'parent_ou',
+ }, getByName(row, 'widget'));
+ sb.tree = fieldmapper.aou.globalOrgTree;
+ sb.startup();
+ sb.attr('value', userSettings[stype.name()]);
+
+ sb.isValid = function() {
+ if(this.item) {
+ if(holdPickupTypes[this.store.getValue(this.item, 'ou_type')]) {
+ return true;
+ }
+ return false;
+ }
+ return true;
+ };
+
+ dojo.connect(sb, 'onChange', function(newVal) { userSettingsToUpdate[stype.name()] = newVal; });
+ break;
+ case 'opac.default_sms_carrier':
+ if(!orgSettings['sms.enable']) return; // Skip when SMS is disabled
+ var carriers = pcrud.search('csc', {active: 'true'}, {'order_by':[{'class':'csc', 'field':'name'},{'class':'csc', 'field':'region'}]});
+ var storedata = fieldmapper.csc.toStoreData(carriers);
+ for(var i in storedata.items) storedata.items[i].label = storedata.items[i].name + ' (' + storedata.items[i].region + ')';
+ var store = new dojo_data_ItemFileReadStore({data:storedata});
+ var select = new dijit_form_FilteringSelect({store:store,scrollOnFocus:false,labelAttr:'label',searchAttr:'label'}, getByName(row, 'widget'));
+ select.attr('value', userSettings[stype.name()]);
+ select.isValid = function() { return true; };
+ dojo.connect(select, 'onChange', function(newVal) { userSettingsToUpdate[stype.name()] = newVal; });
+ break;
+ case 'opac.default_sms_notify':
+ if(!orgSettings['sms.enable']) return; // Skip when SMS is disabled
+ case 'opac.default_phone':
+ var tb = new dijit.form.TextBox({scrollOnFocus:false}, getByName(row, 'widget'));
+ tb.attr('value', userSettings[stype.name()]);
+ dojo.connect(tb, 'onChange', function(newVal) { userSettingsToUpdate[stype.name()] = newVal; });
+ break;
+ default:
+ var cb = new dijit_form_CheckBox({scrollOnFocus:false}, getByName(row, 'widget'));
+ cb.attr('value', userSettings[stype.name()]);
+ dojo.connect(cb, 'onChange', function(newVal) { userSettingsToUpdate[stype.name()] = newVal; });
+ if(stype.name() == 'circ.collections.exempt') {
+ checkCollectionsExemptPerm(cb);
+ }
+ }
+ tbody.insertBefore(row, dividerRow.nextSibling);
+ openils_Util.show(row, 'table-row');
+ }
+
+ function uEditUpdateUserSettings(userId) {
+ return fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.patron.settings.update'],
+ {params : [openils.User.authtoken, userId, userSettingsToUpdate]});
+ }
+
+ function loadAllAddrs() {
+ dojo.forEach(patron.addresses(),
+ function(addr) {
+ uEditNewAddr(null, addr.id());
+ }
+ );
+ }
+
+ function loadStatCats() {
+
+ statCats = fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.stat_cat.actor.retrieve.all'],
+ {params : [openils.User.authtoken, staff.ws_ou()]}
+ );
+
+ // draw stat cats
+ for(var idx in statCats) {
+ var stat = statCats[idx];
+ var row = statCatTemplate.cloneNode(true);
+ row.id = 'stat-cat-row-' + idx;
+ row.setAttribute('stat_cat_owner',stat.owner());
+ row.setAttribute('stat_cat_name',stat.name());
+ row.setAttribute('stat_cat_id',stat.id());
+ tbody.appendChild(row);
+ getByName(row, 'name').innerHTML = stat.name();
+ var valtd = getByName(row, 'widget');
+ var span = valtd.appendChild(document.createElement('span'));
+ var store = new dojo_data_ItemFileReadStore(
+ {data:fieldmapper.actsc.toStoreData(stat.entries())});
+ var comboBox = new dijit_form_ComboBox({store:store,scrollOnFocus:false,fetchProperties:{sort:[{attribute: 'value'}]}}, span);
+ comboBox.labelAttr = 'value';
+ comboBox.searchAttr = 'value';
+
+ comboBox._wtype = 'statcat';
+ comboBox._statcat = stat.id();
+ widgetPile.push(comboBox);
+
+ // populate existing cats
+ var map = patron.stat_cat_entries().filter(
+ function(mp) { return (mp.stat_cat() == stat.id()) })[0];
+ if(map) comboBox.attr('value', map.stat_cat_entry());
+
+ }
+ }
+
+ function loadSurveys() {
+
+ surveys = fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.survey.retrieve.all'],
+ {params : [openils.User.authtoken]}
+ );
+
+ // draw surveys
+ for(var idx in surveys) {
+ var survey = surveys[idx];
+ var required = openils_Util.isTrue(survey.required());
+ var srow = surveyTemplate.cloneNode(true);
+ if(required) srow.setAttribute('required','required');
+ tbody.appendChild(srow);
+ getByName(srow, 'name').innerHTML = survey.name();
+
+ for(var q in survey.questions()) {
+ var quest = survey.questions()[q];
+ var qrow = surveyQuestionTemplate.cloneNode(true);
+ if(required) qrow.setAttribute('required','required');
+ tbody.appendChild(qrow);
+ getByName(qrow, 'question').innerHTML = quest.question();
+
+ var span = getByName(qrow, 'answers').appendChild(document.createElement('span'));
+ var store = new dojo_data_ItemFileReadStore(
+ {data:fieldmapper.asva.toStoreData(quest.answers())});
+ var select = new dijit_form_FilteringSelect({store:store,scrollOnFocus:false}, span);
+ if (! required ) {
+ select.isValid = function() { return true; };
+ }
+ select.labelAttr = 'answer';
+ select.searchAttr = 'answer';
+
+ select._wtype = 'survey';
+ select._survey = survey.id();
+ select._question = quest.id();
+ widgetPile.push(select);
+ }
+ }
+ }
+
+
+ function fleshFMRow(row, fmcls, args) {
+ var fmfield = row.getAttribute('fmfield');
+ var wclass = row.getAttribute('wclass');
+ var wstyle = row.getAttribute('wstyle');
+ var wconstraints = row.getAttribute('wconstraints');
+ /* use CSS to set the zindex for widgets you want to disable. */
+ var disabled = dojo.style(row, 'zIndex') == -1 ? true : false;
+ var isphone = (fmcls == 'au') && (fmfield.search('_phone') != -1);
+
+ var isPasswd2 = (fmfield == 'passwd2');
+ if(isPasswd2) fmfield = 'passwd';
+ var fieldIdl = fieldmapper_IDL.fmclasses[fmcls].field_map[fmfield];
+ if(!args) args = {};
+
+ var existing = dojo.query('td', row);
+ var htd = existing[0] || row.appendChild(document.createElement('td'));
+ var ltd = existing[1] || row.appendChild(document.createElement('td'));
+ var wtd = existing[2] || row.appendChild(document.createElement('td'));
+ var ftd = existing[3] || row.appendChild(document.createElement('td'));
+
+ openils_Util.addCSSClass(htd, 'uedit-help');
+ if(fieldDoc[fmcls] && fieldDoc[fmcls][fmfield]) {
+ var link = dojo.byId('uedit-help-template').cloneNode(true);
+ link.id = '';
+ link.onclick = function() { ueLoadContextHelp(fmcls, fmfield) };
+ openils_Util.removeCSSClass(link, 'hidden');
+ htd.appendChild(link);
+ }
+
+ if(!ltd.textContent) {
+ ltd.appendChild(document.createTextNode(fieldIdl.label));
+ }
+
+ if(!ftd.textContent) {
+ if(orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.example']) {
+ ftd.appendChild(document.createTextNode(localeStrings.EXAMPLE + orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.example']));
+ }
+ else if(isphone && orgSettings['ui.patron.edit.phone.example']) {
+ ftd.appendChild(document.createTextNode(localeStrings.EXAMPLE + orgSettings['ui.patron.edit.phone.example']));
+ }
+ else if(fieldIdl.datatype == 'timestamp') {
+ ftd.appendChild(document.createTextNode(localeStrings.EXAMPLE + dojo_date.locale.format(new Date(1970,0,31),{selector: "date", fullYear: true, datePattern: (orgSettings['format.date'] ? orgSettings['format.date'] : null)})));
+ }
+
+ if (fmcls == "au" && (isphone || fmfield == "email")) {
+ var span = dojo.create(
+ "span", {
+ "className": "hidden",
+ "id": "wrap_invalidate_" + fmfield
+ }
+ );
+ uGenerateInvalidatorWidget(span, fmfield);
+ ftd.appendChild(span);
+ }
+ }
+
+ var span = document.createElement('span');
+ wtd.appendChild(span);
+
+ var fmObject = null;
+ switch(fmcls) {
+ case 'au' :
+ fmObject = patron;
+ if(fmfield == 'barred') {
+ // Are we allowed to touch the barred state?
+ var permission = 'BAR_PATRON';
+ if(fmObject.barred() == 't') {
+ permission = 'UNBAR_PATRON';
+ }
+ var ou = staff.ws_ou();
+ if(fmObject.home_ou() != null) {
+ ou = fmObject.home_ou();
+ }
+ var resp = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.perm.check'],
+ { params : [openils.User.authtoken, staff.id(), ou, [permission] ] }
+ );
+ if(resp[0]) { // No permission to adjust barred state from current
+ disabled = true;
+ }
+ }
+ break;
+ case 'ac' : if(!editCard) editCard = patron.card(); fmObject = editCard; break;
+ case 'aua' :
+ fmObject = patron.addresses().filter(
+ function(i) { return (i.id() == args.addr) })[0];
+ if(fmObject && fmObject.usr() != patron.id())
+ disabled = true;
+ break;
+ }
+
+ // Adjust required value by org settings
+ var curRequired = row.getAttribute('required');
+ var required = curRequired == 'required';
+ if(orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.require']) {
+ row.setAttribute('required', 'required');
+ required = true;
+ }
+ else if (curRequired != 'required' && orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.show']) {
+ row.setAttribute('required', 'show');
+ }
+ else if (curRequired != 'required' && curRequired != 'show' && orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.suggest']) {
+ row.setAttribute('required', 'suggested');
+ }
+
+ // password data is not fetched/required/displayed for existing users
+ if(!patron.isnew() && 'passwd' == fmfield)
+ required = false;
+
+ var dijitArgs = {
+ style: wstyle,
+ required : required,
+ constraints : (wconstraints) ? eval('('+wconstraints+')') : {}, // the ()'s prevent Invalid Label errors with eval
+ disabled : disabled
+ };
+
+ // Org settings provided regex?
+ if(orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.regex']) {
+ dijitArgs.regExp = orgSettings['ui.patron.edit.' + fmcls + '.' + fmfield + '.regex'];
+ }
+ else if(isphone && orgSettings['ui.patron.edit.phone.regex']) {
+ dijitArgs.regExp = orgSettings['ui.patron.edit.phone.regex'];
+ }
+
+ if(fmcls == 'au' && fmfield == 'passwd') {
+ if (orgSettings['global.password_regex']) {
+ dijitArgs.regExp = orgSettings['global.password_regex'];
+ }
+ }
+
+ if(fmcls == 'au' && fmfield == 'dob' && !orgSettings['ui.patron.edit.au.dob.calendar'])
+ dijitArgs.popupClass = "";
+
+ var value = row.getAttribute('wvalue');
+ if(value !== null)
+ dijitArgs.value = value;
+
+ var wargs = {
+ idlField : fieldIdl,
+ fmObject : fmObject,
+ fmClass : fmcls,
+ parentNode : span,
+ widgetClass : wclass,
+ dijitArgs : dijitArgs,
+ orgDefaultsToWs : true,
+ orgLimitPerms : ['UPDATE_USER'],
+ };
+
+ if(fmfield == 'profile') {
+ // fetch profile groups non-async so existing expire_date is
+ // not overwritten when the profile groups arrive and update
+ wargs.forceSync = true;
+ wargs.disableQuery = {usergroup : 'f'};
+ } else {
+ wargs.forceSync = false;
+ }
+
+ if(fmcls == 'au' && fmfield == 'home_ou'){
+ wargs.labelAttr = 'name';
+ wargs.searchAttr = 'name';
+ }
+
+ var widget = new openils_widget_AutoFieldWidget(wargs);
+ widget.build(
+ function(w, ww) {
+ if(fmfield == 'profile') {
+ trimGrpTree(ww);
+ if(!patron.isnew() && !checkGrpAppPerm(patron.profile())){
+ w.attr('disabled', true);
+ }
+ }
+ }
+ );
+
+ // now put it back before we register the widget
+ if(isPasswd2) fmfield = 'passwd2';
+
+ widget._wtype = fmcls;
+ widget._fmfield = fmfield;
+ widget._addr = args.addr;
+ widgetPile.push(widget);
+ attachWidgetEvents(fmcls, fmfield, widget);
+ return widget;
+ }
+
+ function trimGrpTree(autoWidget) {
+ var store = autoWidget.widget.store;
+ if(!store) return;
+ // remove all groups that this user are not allowed to edit,
+ // except the profile group of an existing user
+ store.fetch({onItem :
+ function(item) {
+ if(!checkGrpAppPerm(item.id[0]) && patron.profile() != item.id[0])
+ store.deleteItem(item);
+ }
+ });
+ }
+
+ function findWidget(wtype, fmfield, callback) {
+ return widgetPile.filter(
+ function(i){
+ if(i._wtype == wtype && i._fmfield == fmfield) {
+ if(callback) return callback(i);
+ return true;
+ }
+ }
+ ).pop();
+ }
+
+ /**
+ * if the user does not have the UPDATE_PATRON_CLAIM_RETURN_COUNT,
+ * they are not allowed to directly alter the claim return count.
+ * This function checks the perm and disable/enables the widget.
+ */
+ function checkClaimsReturnCountPerm() {
+ new openils.User().getPermOrgList(
+ 'UPDATE_PATRON_CLAIM_RETURN_COUNT',
+ function(orgList) {
+ var cr = findWidget('au', 'claims_returned_count');
+ if(orgList.indexOf(patron.home_ou()) == -1)
+ cr.widget.attr('disabled', true);
+ else
+ cr.widget.attr('disabled', false);
+ },
+ true,
+ true
+ );
+ }
+
+
+ function checkClaimsNoCheckoutCountPerm() {
+ new openils.User().getPermOrgList(
+ 'UPDATE_PATRON_CLAIM_NEVER_CHECKED_OUT_COUNT',
+ function(orgList) {
+ var cr = findWidget('au', 'claims_never_checked_out_count');
+ if(orgList.indexOf(patron.home_ou()) == -1)
+ cr.widget.attr('disabled', true);
+ else
+ cr.widget.attr('disabled', false);
+ },
+ true,
+ true
+ );
+ }
+
+ var collectExemptCBox;
+ function checkCollectionsExemptPerm(cbox) {
+ if(cbox) collectExemptCBox = cbox;
+ new openils.User().getPermOrgList(
+ 'UPDATE_PATRON_COLLECTIONS_EXEMPT',
+ function(orgList) {
+ if(orgList.indexOf(patron.home_ou()) == -1)
+ collectExemptCBox.attr('disabled', true);
+ else
+ collectExemptCBox.attr('disabled', false);
+ },
+ true,
+ true
+ );
+ }
+
+ function usePhonePw(newVal) {
+ var newPw = false;
+ if(this.regExp) {
+ matches = RegExp(this.regExp).exec(newVal);
+ if(matches.length > 1) newPw = matches[1];
+ }
+ if(!newPw && newVal && newVal.length >= 4) {
+ newPw = newVal.substring(newVal.length - 4);
+ }
+ if(newPw) {
+ var p1 = findWidget('au', 'passwd');
+ var p2 = findWidget('au', 'passwd2');
+ if (p1 && p2) {
+ p1.widget.attr('value', newPw);
+ p2.widget.attr('value', newPw);
+ }
+ return newPw;
+ } else {
+ return null;
+ }
+ }
+
+ function attachWidgetEvents(fmcls, fmfield, widget) {
+
+ dojo.connect(
+ widget.widget,
+ 'onKeyPress',
+ function(ev){
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+ if (!(ev.altKey || ev.ctrlKey || ev.metaKey)) {
+ if (lock_ready && xulG && typeof xulG.lock_tab == 'function') {
+ if (! already_locked) {
+ xulG.lock_tab();
+ already_locked = true;
+ }
+ }
+ }
+ }
+ );
+ dojo.connect(
+ widget.widget,
+ 'onChange',
+ function(){
+ if (lock_ready && xulG && typeof xulG.lock_tab == 'function') {
+ if (! already_locked) {
+ xulG.lock_tab();
+ already_locked = true;
+ }
+ }
+ }
+ );
+
+
+ if(fmcls == 'ac') {
+ if(fmfield == 'barcode') {
+ dojo.connect(widget.widget, 'onChange',
+ function() {
+ var barcode = this.attr('value');
+ dupeBarcode = false;
+ dojo.addClass(dojo.byId('uedit-dupe-barcode-warning'), 'hidden');
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.barcode.exists'],
+ {
+ params: [openils.User.authtoken, barcode],
+ oncomplete : function(r) {
+ var res = openils_Util.readResponse(r);
+ if(res == '1') {
+ dupeBarcode = true;
+ dojo.removeClass(dojo.byId('uedit-dupe-barcode-warning'), 'hidden');
+ } else {
+ dupeBarcode = false;
+ dojo.addClass(dojo.byId('uedit-dupe-barcode-warning'), 'hidden');
+ editCard.barcode(barcode); // Keep the "All" interface up to date
+ var un = findWidget('au', 'usrname');
+ if(!un.widget.attr('value'))
+ un.widget.attr('value', barcode);
+ }
+ }
+ }
+ );
+ }
+ );
+ return;
+ }
+ }
+
+ if(fmcls == 'au') {
+ switch(fmfield) {
+
+ case 'usrname':
+ widget.widget.isValid = function() {
+ // No spaces
+ if(this.attr("value").match(/\s/)) {
+ return false;
+ }
+ // Can look like a barcode (for initial value)
+ if(orgSettings['opac.barcode_regex']) {
+ var test_regexp = new RegExp(orgSettings['opac.barcode_regex']);
+ if(test_regexp.test(this.attr("value"))) {
+ return true;
+ }
+ }
+ // Can look like a username
+ if(orgSettings['opac.username_regex']) {
+ var test_regexp = new RegExp(orgSettings['opac.username_regex']);
+ if(test_regexp.test(this.attr("value"))) {
+ return true;
+ }
+ }
+ // If we know what a barcode and username look like and we got here, reject
+ if(orgSettings['opac.barcode_regex'] && orgSettings['opac.username_regex'])
+ return false;
+ // Otherwise we don't have enough info to say either way, let it through.
+ return true;
+ }
+ dojo.connect(widget.widget, 'onChange',
+ function() {
+ var input = findWidget('au', 'usrname');
+ var usrname = input.widget.attr('value');
+
+ if(!usrname) {
+ dupeUsrname = false;
+ dojo.addClass(dojo.byId('uedit-dupe-username-warning'), 'hidden');
+ return;
+ }
+
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.username.exists'],
+ {
+ params: [openils.User.authtoken, usrname],
+ oncomplete : function(r) {
+ var res = openils_Util.readResponse(r);
+ if(res) {
+ dupeUsrname = true;
+ dojo.removeClass(dojo.byId('uedit-dupe-username-warning'), 'hidden');
+ } else {
+ dupeUsrname = false;
+ dojo.addClass(dojo.byId('uedit-dupe-username-warning'), 'hidden');
+ }
+ }
+ }
+ );
+ }
+ );
+
+ return;
+
+ case 'profile': // when the profile changes, update the expire date
+ dojo.connect(widget.widget, 'onChange',
+ function() {
+ var self = this;
+ var expireWidget = findWidget('au', 'expire_date');
+ function found(items) {
+ if(items.length == 0) return;
+ var item = items[0];
+ var interval = self.store.getValue(item, 'perm_interval');
+ expireWidget.widget.attr('value', dojo_date.add(new Date(),
+ 'second', openils_Util.intervalToSeconds(interval)));
+ }
+ this.store.fetch({onComplete:found, query:{id:this.attr('value')}});
+ }
+ );
+ return;
+
+ case 'dob':
+ widget.widget.isValid = function() {
+ return this.attr("value") < new Date();
+ };
+ dojo.connect(widget.widget, 'onChange',
+ function(newDob) {
+ if(!newDob) return;
+ var oldDob = patron.dob();
+ if(dojo_date.stamp.fromISOString(oldDob) == newDob) return;
+
+ var juvInterval = orgSettings['global.juvenile_age_threshold'] || '18 years';
+ var juvWidget = findWidget('au', 'juvenile');
+ var base = new Date();
+ base.setTime(base.getTime() - Number(openils_Util.intervalToSeconds(juvInterval) + '000'));
+
+ if(newDob <= base) // older than global.juvenile_age_threshold
+ juvWidget.widget.attr('value', false);
+ else
+ juvWidget.widget.attr('value', true);
+ }
+ );
+ return;
+
+ case 'first_given_name':
+ case 'family_name':
+ dojo.connect(widget.widget, 'onChange',
+ function(newVal) { uEditDupeSearch('name', newVal); });
+ return;
+
+ case 'email':
+ dojo.connect(widget.widget, 'onChange',
+ function(newVal) { uEditDupeSearch('email', newVal); });
+ return;
+
+ case 'ident_value':
+ case 'ident_value2':
+ dojo.connect(widget.widget, 'onChange',
+ function(newVal) { uEditDupeSearch('ident', newVal); });
+ return;
+
+ case 'day_phone':
+ // if configured, use the last four digits of the day phone number as the password
+ // Alt, use the first capture group of the validator regex
+ if(uEditUsePhonePw && patron.isnew()) {
+ dojo.connect(widget.widget, 'onChange', widget.widget, usePhonePw);
+ if (patron.day_phone()) {
+ usePhonePw(patron.day_phone());
+ }
+ }
+ case 'evening_phone':
+ case 'other_phone':
+ dojo.connect(widget.widget, 'onChange',
+ function(newVal) { uEditDupeSearch('phone', newVal); });
+ return;
+
+ case 'home_ou':
+ widget.widget.isValid = function() {
+ if(this.item) {
+ if(homeOuTypes[this.store.getValue(this.item, 'ou_type')]) {
+ return true;
+ }
+ return false;
+ }
+ return true;
+ };
+ dojo.connect(widget.widget, 'onChange',
+ function(newVal) {
+ checkClaimsReturnCountPerm();
+ checkClaimsNoCheckoutCountPerm();
+ checkCollectionsExemptPerm();
+ }
+ );
+ return;
+
+ case 'passwd':
+ dojo.connect(widget.widget, 'onChange',
+ function(newVal) {
+ var pw1 = findWidget('au', 'passwd').widget;
+ var pw2 = findWidget('au', 'passwd2').widget;
+ var preserved_value = pw2.attr('value');
+ // Ensure that the pw2 field match the pw1 field to validate
+ pw2.regExp = newVal.replace(/([.\\^$*+?\(\)\[\]\{\}])/g, '\\$1');
+ pw2.reset();
+ pw2.attr('value',preserved_value);
+ });
+ return;
+ }
+ }
+
+ if(fmclass = 'aua') {
+
+ // map post code to city, state, and county
+ if (fmfield == 'post_code') {
+ dojo.connect(widget.widget, 'onChange',
+ function(e) {
+ fieldmapper.standardRequest(
+ ['open-ils.search', 'open-ils.search.zip'],
+ { async: true,
+ params: [e],
+ oncomplete : function(r) {
+ var res = openils_Util.readResponse(r);
+ if(!res) return;
+ var callback = function(w) { return w._addr == widget._addr; };
+ if(res.city) findWidget('aua', 'city', callback).widget.attr('value', res.city);
+ if(res.state) findWidget('aua', 'state', callback).widget.attr('value', res.state);
+ if(res.county) findWidget('aua', 'county', callback).widget.attr('value', res.county);
+ if(res.alert) alert(res.alert);
+ }
+ }
+ );
+ }
+ );
+ }
+
+ // duplicate address search
+ if (['street1', 'street2', 'city'].indexOf(fmfield) > -1) {
+ dojo.connect(widget.widget, 'onChange',
+ function(e) {
+ var callback = function(w) { return w._addr == widget._addr; };
+ var args = {
+ street1 : findWidget('aua', 'street1', callback).widget.attr('value'),
+ street2 : findWidget('aua', 'street2', callback).widget.attr('value'),
+ city : findWidget('aua', 'city', callback).widget.attr('value'),
+ post_code : findWidget('aua', 'post_code', callback).widget.attr('value')
+ };
+ if(args.street1 && args.city && args.post_code)
+ uEditDupeSearch('address', args);
+ }
+ );
+ }
+
+ if (addressAlertFields.indexOf(fmfield) > -1) {
+ dojo.connect(
+ widget.widget, 'onChange',
+ function() { uEditAddressAlertMarshal(widget._addr) }
+ );
+ }
+ }
+ }
+
+ function uEditAddressAlertMarshal(addrId, changeBilling, changeMailing) {
+
+ if (changeBilling) {
+ uEditAddressAlertMarshal(prevBillingAddress);
+ prevBillingAddress = addrId;
+ }
+
+ if (changeMailing) {
+ uEditAddressAlertMarshal(prevMailingAddress);
+ prevMailingAddress = addrId;
+ }
+
+ var callback = function(w) { return w._addr == addrId; };
+ var args = {};
+ dojo.forEach(addressAlertFields,
+ function(field) {
+ args[field] = findWidget('aua', field, callback).widget.attr('value')
+ }
+ );
+ args.mailing_address = dojo.byId('uedit-mailing-address-' + addrId).checked;
+ args.billing_address = dojo.byId('uedit-billing-address-' + addrId).checked;
+ uEditAddressAlertSearch(args, addrId);
+ }
+
+ var _addrAlertTimeout = {};
+ function uEditAddressAlertSearch(args, addrId) {
+
+ _addrAlertTimeout[addrId] = setTimeout(
+ function() {
+ if (_addrAlertTimeout[addrId])
+ clearTimeout(_addrAlertTimeout[addrId]);
+
+ console.log('creating addr alert search for ' + addrId);
+
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.address_alert.test'],
+ { async: true,
+ params: [openils.User.authtoken, staff.ws_ou(), args],
+ oncomplete : function(r) {
+ var alerts = openils_Util.readResponse(r);
+ var msgNode = dojo.byId('uedit-address-alert-message');
+ var headerRow = dojo.filter(
+ dojo.query('[name=uedit-addr-divider]'),
+ function(row) { return row.getAttribute('addr') == addrId })[0]
+
+ msgNode.innerHTML = '';
+
+ if (alerts.length) {
+
+ // show the alert box
+ openils_Util.hide('uedit-help-div');
+ openils_Util.hide('uedit-dupe-div');
+ openils_Util.show('uedit-address-alert');
+
+ // style the address header row
+ openils_Util.addCSSClass(headerRow, 'uedit-address-alert-divider');
+
+ dojo.forEach(alerts,
+ function(addr) {
+ msgNode.innerHTML += addr.alert_message() + '<br/>';
+ }
+ );
+
+ } else {
+ openils_Util.hide('uedit-address-alert');
+ openils_Util.removeCSSClass(headerRow, 'uedit-address-alert-divider');
+ }
+ }
+ }
+ );
+ },
+ addressAlertTimeout
+ );
+ }
+
+ function uEditDupeSearch(type, value) {
+ if(!value) return;
+ var search;
+ switch(type) {
+
+ case 'name':
+ openils_Util.hide('uedit-dupe-names-link');
+ var fname = findWidget('au', 'first_given_name').widget.attr('value');
+ var lname = findWidget('au', 'family_name').widget.attr('value');
+ if( !(fname && lname) ) return;
+ search = {
+ first_given_name : {value : fname, group : 0},
+ family_name : {value : lname, group : 0},
+ };
+ break;
+
+ case 'email':
+ openils_Util.hide('uedit-dupe-email-link');
+ search = {email : {value : value, group : 0}};
+ break;
+
+ case 'ident':
+ openils_Util.hide('uedit-dupe-ident-link');
+ search = {ident : {value : value, group : 2}};
+ break;
+
+ case 'phone':
+ openils_Util.hide('uedit-dupe-phone-link');
+ search = {phone : {value : value, group : 2}};
+ break;
+
+ case 'address':
+ openils_Util.hide('uedit-dupe-address-link');
+ search = {};
+ dojo.forEach(['street1', 'street2', 'city', 'post_code'],
+ function(field) {
+ if(value[field])
+ search[field] = {value : value[field], group: 1};
+ }
+ );
+ break;
+ }
+
+ // find possible duplicate patrons
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.patron.search.advanced'],
+ { async: true,
+ params: [openils.User.authtoken, search],
+ oncomplete : function(r) {
+ var resp = openils_Util.readResponse(r);
+ resp = resp.filter(function(id) { return (id != patron.id()); });
+
+ if(resp && resp.length > 0) {
+
+ openils_Util.hide('uedit-help-div');
+ openils_Util.hide('uedit-address-alert');
+ openils_Util.show('uedit-dupe-div');
+ var link;
+
+ switch(type) {
+ case 'name':
+ link = dojo.byId('uedit-dupe-names-link');
+ link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_NAME, [resp.length]);
+ break;
+ case 'email':
+ link = dojo.byId('uedit-dupe-email-link');
+ link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_EMAIL, [resp.length]);
+ break;
+ case 'ident':
+ link = dojo.byId('uedit-dupe-ident-link');
+ link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_IDENT, [resp.length]);
+ break;
+ case 'phone':
+ link = dojo.byId('uedit-dupe-phone-link');
+ link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_PHONE, [resp.length]);
+ break;
+ case 'address':
+ link = dojo.byId('uedit-dupe-address-link');
+ link.innerHTML = dojo.string.substitute(localeStrings.DUPE_PATRON_ADDR, [resp.length]);
+ break;
+ }
+
+ openils_Util.show(link);
+ link.onclick = function() {
+ search.search_sort = js2JSON(["penalties", "family_name", "first_given_name"]);
+ if(window.xulG)
+ window.xulG.spawn_search(search);
+ else
+ console.log("running XUL patron search " + js2JSON(search));
+ }
+ }
+ }
+ }
+ );
+ }
+
+ function getByName(node, name) {
+ return dojo.query('[name='+name+']', node)[0];
+ }
+
+
+ function ueLoadContextHelp(fmcls, fmfield) {
+ openils_Util.hide('uedit-dupe-div');
+ openils_Util.hide('uedit-dupe-div');
+ openils_Util.show('uedit-help-div');
+ dojo.byId('uedit-help-field').innerHTML = fieldmapper_IDL.fmclasses[fmcls].field_map[fmfield].label;
+ dojo.byId('uedit-help-text').innerHTML = fieldDoc[fmcls][fmfield].string();
+ }
+
+
+ /* creates a new patron object with card attached */
+ function uEditNewPatron() {
+ patron = new au();
+ patron.isnew(1);
+ patron.id(-1);
+ card = new ac();
+ card.id(uEditCardVirtId--);
+ card.isnew(1);
+ patron.active(1);
+ patron.card(card);
+ patron.cards([card]);
+ patron.net_access_level(orgSettings['ui.patron.default_inet_access_level'] || 1);
+ patron.ident_type(orgSettings['ui.patron.default_ident_type']);
+ patron.stat_cat_entries([]);
+ patron.survey_responses([]);
+ patron.addresses([]);
+ uEditMakeRandomPw(patron);
+ return patron;
+ }
+
+ function uEditMakeRandomPw(patron) {
+ var rand = Math.random();
+ rand = parseInt(rand * 10000) + '';
+ while(rand.length < 4) rand += '0';
+ /*
+ appendClear($('ue_password_plain'),text(rand));
+ unHideMe($('ue_password_gen'));
+ */
+ patron.passwd(rand);
+ return rand;
+ }
+
+ function uEditWidgetVal(w) {
+ var val = (w.getFormattedValue) ? w.getFormattedValue() : w.attr('value');
+ if(val === '') val = null;
+ return val;
+ }
+
+ function uEditSave() { _uEditSave(); }
+ function uEditSaveClone() { _uEditSave(true); }
+
+ function _uEditSave(doClone) {
+
+ if ( (! myForm.isValid()) || dupeUsrname || dupeBarcode ) {
+ alert(localeStrings.INVALID_FORM);
+ return;
+ }
+
+ for(var idx in widgetPile) {
+ var w = widgetPile[idx];
+ var val = uEditWidgetVal(w);
+
+ switch(w._wtype) {
+ case 'au':
+ if(w._fmfield != 'passwd2')
+ patron[w._fmfield](val);
+ break;
+
+ case 'ac':
+ if(!editCard) editCard = patron.card();
+ editCard[w._fmfield](val);
+ break;
+
+ case 'aua':
+ var addr = patron.addresses().filter(function(i){return (i.id() == w._addr)})[0];
+ if(!addr) {
+ addr = new fieldmapper.aua();
+ addr.id(w._addr);
+ addr.isnew(1);
+ addr.usr(patron.id());
+ addr.country(orgSettings['ui.patron.default_country']);
+ var t = patron.addresses();
+ if (!t) { t = []; }
+ t.push(addr);
+ patron.addresses(t);
+ } else {
+ if(addr[w._fmfield]() != val)
+ addr.ischanged(1);
+ }
+ addr[w._fmfield](val);
+
+ if(dojo.byId('uedit-billing-address-' + addr.id()).checked)
+ patron.billing_address(addr.id());
+
+ if(dojo.byId('uedit-mailing-address-' + addr.id()).checked)
+ patron.mailing_address(addr.id());
+
+ break;
+
+ case 'survey':
+ if(val == null) break;
+ var resp = new fieldmapper.asvr();
+ resp.isnew(1);
+ resp.survey(w._survey)
+ resp.usr(patron.id());
+ resp.question(w._question)
+ resp.answer(val);
+ var t = patron.survey_responses();
+ if (!t) { t = []; }
+ t.push(resp);
+ patron.survey_responses(t);
+ break;
+
+ case 'statcat':
+ var map = patron.stat_cat_entries().filter(
+ function(m){
+ return (m.stat_cat() == w._statcat) })[0];
+
+ if(map) {
+ if(map.stat_cat_entry() == val)
+ break;
+ if(val == null) {
+ val = '';
+ map.isdeleted(1);
+ } else {
+ map.ischanged(1);
+ }
+ } else {
+ if(val == null)
+ break;
+ map = new fieldmapper.actscecm();
+ map.isnew(1);
+ }
+
+ map.stat_cat(w._statcat);
+ map.stat_cat_entry(val);
+ map.target_usr(patron.id());
+ var t = patron.stat_cat_entries();
+ if (!t) { t = []; }
+ t.push(map);
+ patron.stat_cat_entries(t);
+ break;
+ }
+ }
+
+ patron.ischanged(1);
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.patron.update'],
+ { async: true,
+ params: [openils.User.authtoken, patron],
+ oncomplete: function(r) {
+ lock_ready = false;
+ if (xulG && typeof xulG.unlock_tab == 'function') {
+ xulG.unlock_tab();
+ already_locked = false;
+ }
+ /* There's something that seems to just make the form reload
+ * on all saves, so this uUpdate... isn't needed here after
+ * all. */
+ //uUpdateContactInvalidators();
+
+ newPatron = openils_Util.readResponse(r);
+ if(newPatron) {
+ uEditUpdateUserSettings(newPatron.id());
+ if(stageUser) uEditRemoveStage();
+ uEditFinishSave(newPatron, doClone);
+ }
+ }
+ }
+ );
+ }
+
+ function uUpdateContactInvalidators() {
+ /* show invalidator buttons for fields that having anything in them */
+ ["email", "day_phone", "evening_phone", "other_phone"].forEach(
+ function(f) {
+ openils_Util[patron[f]() ? "show" : "hide"]("wrap_invalidate_" + f);
+ }
+ );
+ }
+
+ function uGenerateInvalidatorWidget(container_node, field) {
+ new dijit_form_Button(
+ {
+ "label": localeStrings.INVALIDATE,
+ "scrollOnFocus": false,
+ "onClick": function() {
+ progressDialog.show(true);
+ fieldmapper.standardRequest(
+ ["open-ils.actor", "open-ils.actor.invalidate." + field], {
+ "async": true,
+ "params": [openils.User.authtoken, patron.id(), null, patron.home_ou()],
+ "oncomplete": function(r) {
+ progressDialog.hide();
+ // alerts on non-success event
+ var res = openils_Util.readResponse(r);
+
+ if (res.payload.last_xact_id) {
+ for (var id in res.payload.last_xact_id) {
+ if (patron.id() == id)
+ patron.last_xact_id(
+ res.payload.last_xact_id[id]
+ );
+ }
+
+ findWidget("au",field).widget.attr("value","");
+ openils_Util.hide(container_node);
+ }
+ }
+ }
+ );
+ }
+ }, dojo.create("span", null, container_node, "only")
+ );
+ }
+
+ function uEditRemoveStage() {
+ var resp = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.stage.delete'],
+ { params : [openils.User.authtoken, stageUser.row_id()] }
+ )
+ }
+
+ function uEditFinishSave(newPatron, doClone) {
+
+ if(doClone && cloneUser == null)
+ cloneUser = newPatron.id();
+
+ if( doClone ) {
+
+ if(xulG && typeof xulG.spawn_editor == 'function' && !patron.isnew() ) {
+ window.xulG.spawn_editor({ses:openils.User.authtoken,clone:cloneUser});
+ uEditRefresh();
+
+ } else {
+ location.href = location.href.replace(/\?.*/, '') + '?clone=' + cloneUser;
+ }
+
} else {
- location.href = location.href.replace(/\?.*/, '') + '?clone=' + cloneUser;
+
+ uEditRefresh();
}
-
- } else {
-
- uEditRefresh();
+
+ uEditRefreshXUL(newPatron);
}
+
+ function uEditRefresh() {
+ var usr = cgi.param('usr');
+ var href = location.href.replace(/\?.*/, '');
+ href += ((usr) ? '?usr=' + usr : '');
+ location.href = href;
+ }
+
+ function uEditRefreshXUL(newuser) {
+ if (window.xulG && typeof window.xulG.on_save == 'function')
+ window.xulG.on_save(newuser);
+ }
+
+
+ /**
+ * Create a new address and insert it into the DOM
+ * @param evt ignored
+ * @param id The address id
+ * @param mkLinks If true, set the new address as the
+ * mailing/billing address for the user
+ */
+ function uEditNewAddr(evt, id, mkLinks) {
+
+ if(id == null)
+ id = --uEditAddrVirtId; // new address
+
+ var addr = patron.addresses().filter(
+ function(i) { return (i.id() == id) })[0];
+
+ dojo.forEach(addrTemplateRows,
+ function(row) {
+
+ row = tbody.insertBefore(row.cloneNode(true), dojo.byId('new-addr-row'));
+ row.setAttribute('type', '');
+ row.setAttribute('addr', id+'');
+
+ if(row.getAttribute('fmclass')) {
+ var widget = fleshFMRow(row, 'aua', {addr:id});
+
+ // make new addresses a default address type
+ if(id < 0 && row.getAttribute('fmfield') == 'address_type')
+ widget.widget.attr('value', localeStrings.DEFAULT_ADDRESS_TYPE);
+
+ // make new addresses valid by default
+ if(id < 0 && row.getAttribute('fmfield') == 'valid')
+ widget.widget.attr('value', true);
+
+ // make new addresses use the org setting for default country
+ if(id < 0 && row.getAttribute('fmfield') == 'country')
+ widget.widget.attr('value',orgSettings['ui.patron.default_country']);
+
+ } else if(row.getAttribute('name') == 'uedit-addr-pending-row') {
+
+ // if it's a pending address, show the 'approve' button
+ if(addr && openils_Util.isTrue(addr.pending())) {
+ openils_Util.show(row, 'table-row');
+ dojo.query('[name=approve-button]', row)[0].onclick =
+ function() { uEditApproveAddress(addr); };
+
+ if(addr.replaces()) {
+ var div = dojo.query('[name=replaced-addr]', row)[0]
+ var replaced = patron.addresses().filter(
+ function(i) { return (i.id() == addr.replaces()) })[0];
+
+ div.innerHTML = dojo.string.substitute(localeStrings.REPLACED_ADDRESS, [
+ replaced.address_type() || '',
+ replaced.street1() || '',
+ replaced.street2() || '',
+ replaced.city() || '',
+ replaced.state() || '',
+ replaced.post_code() || ''
+ ]);
+
+ } else {
+ openils_Util.hide(dojo.query('[name=replaced-addr-div]', row)[0]);
+ }
+ }
+
+ } else if(row.getAttribute('name') == 'uedit-addr-owner-row') {
+ // address is owned by someone else. provide option to load the
+ // user in a different tab
+
+ if(addr && addr.usr() != patron.id()) {
+ openils_Util.show(row, 'table-row');
+ var link = getByName(row, 'addr-owner');
+
+ // fetch the linked user so we can present their name in the UI
+ var addrUser;
+ if(cloneUserObj && cloneUserObj.id() == addr.usr()) {
+ addrUser = [
+ cloneUserObj.first_given_name(),
+ cloneUserObj.second_given_name(),
+ cloneUserObj.family_name()
+ ];
+ } else {
+ addrUser = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.retrieve.parts'],
+ {params: [
+ openils.User.authtoken,
+ addr.usr(),
+ ['first_given_name', 'second_given_name', 'family_name']
+ ]}
+ );
+ }
+
+ link.innerHTML = (addrUser.map(function(name) { return (name) ? name+' ' : '' })+'').replace(/,/g,''); // TODO i18n
+ link.onclick = function() {
+ if(openils_XUL.isXUL()) {
+ window.xulG.spawn_editor({ses:openils.User.authtoken, usr:addr.usr()})
+ } else {
+ parent.location.href = location.href.replace(/clone=\d+/, 'usr=' + addr.usr());
+ }
+ }
+ }
+
+ } else if(row.getAttribute('name') == 'uedit-addr-divider') {
+ // link up the billing/mailing address and give the inputs IDs so we can access the later
+
+ // billing address
+ var ba = getByName(row, 'billing_address');
+ ba.id = 'uedit-billing-address-' + id;
+ if(mkLinks || (patron.billing_address() && patron.billing_address().id() == id)) {
+ ba.checked = true;
+ prevBillingAddress = id;
+ }
+
+ // mailing address
+ var ma = getByName(row, 'mailing_address');
+ ma.id = 'uedit-mailing-address-' + id;
+ if(mkLinks || (patron.mailing_address() && patron.mailing_address().id() == id)) {
+ ma.checked = true;
+ prevMailingAddress = id;
+ }
+
+ ba.onclick = function() { console.log('ba.onchange ' + id); uEditAddressAlertMarshal(id, true) };
+ ma.onclick = function() { uEditAddressAlertMarshal(id, false, true) };
+
+ var btn = dojo.query('[name=delete-button]', row)[0];
+ if(btn) btn.onclick = function(){ uEditDeleteAddr(id) };
+ }
+ }
+ );
+ }
+
+ function uEditApproveAddress(addr) {
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.pending_address.approve'],
+ { async: true,
+ params: [openils.User.authtoken, addr],
+
+ oncomplete : function(r) {
+ var oldId = openils_Util.readResponse(r);
+
+ // remove addrs from UI
+ dojo.forEach(
+ patron.addresses(),
+ function(addr) { uEditDeleteAddr(addr.id(), true); }
+ );
+
+ if(oldId != null) {
+
+ // remove the replaced address
+ if(oldId != addr.id()) {
+ patron.addresses(
+ patron.addresses().filter(
+ function(i) { return (i.id() != oldId); }
+ )
+ );
+ }
+
+ // fix the the new address
+ addr.id(oldId);
+ addr.replaces(null);
+ addr.pending('f');
+
+ }
+
+ // redraw addrs
+ loadAllAddrs();
+ }
+ }
+ );
+ }
+
+
+ function uEditDeleteAddr(id, noAlert) {
+ if (patron.isnew() && orgSettings['ui.patron.registration.require_address']) {
+ if (dojo.query('tr[name=uedit-addr-divider]').length < 2) {
+ alert(localeStrings.NEED_ADDRESS);
+ return;
+ }
+ }
+ if(!noAlert) {
+ if(!confirm(dojo.string.substitute(localeStrings.DELETE_ADDRESS, [id]))) return;
+ }
+ var addr = patron.addresses().filter(function(i){return (i.id() == id)})[0];
+ if (addr) { addr.isdeleted(1); }
+ var m_a = patron.mailing_address();
+ if (typeof m_a == 'object' && m_a != null) { m_a = m_a.id(); }
+ if (m_a == id) { patron.mailing_address(null); }
+ var b_a = patron.billing_address();
+ if (typeof b_a == 'object' && b_a != null) { b_a = b_a.id(); }
+ if (b_a == id) { patron.billing_address(null); }
+
+ var rows = dojo.query('tr[addr='+id+']', tbody);
+ for(var i = 0; i < rows.length; i++)
+ rows[i].parentNode.removeChild(rows[i]);
+ widgetPile = widgetPile.filter(function(w){return (w._addr != id)});
+ }
+
+ function uEditToggleRequired(level) {
+ openils_Util.removeCSSClass(tbody, 'hide-non-required');
+ openils_Util.removeCSSClass(tbody, 'hide-non-suggested');
+ openils_Util.show('uedit-show-required');
+ openils_Util.show('uedit-show-required-br');
+ openils_Util.show('uedit-show-suggested');
+ openils_Util.show('uedit-show-suggested-br');
+ openils_Util.show('uedit-show-all');
+ switch(level) {
+ case 1:
+ openils_Util.hide('uedit-show-required');
+ openils_Util.hide('uedit-show-required-br');
+ openils_Util.addCSSClass(tbody, 'hide-non-required');
+ break;
+ case 2:
+ openils_Util.hide('uedit-show-suggested');
+ openils_Util.hide('uedit-show-suggested-br');
+ openils_Util.addCSSClass(tbody, 'hide-non-suggested');
+ break;
+ default:
+ openils_Util.hide('uedit-show-all');
+ break;
+ }
+ }
+
+ function printable_output() {
+ var temp; var s = '=-=-=-=\r\n';
+ for (var idx in widgetPile) {
+ var w = widgetPile[idx];
+ var val = uEditWidgetVal(w);
+ var label;
+ if (typeof w.idlField == 'undefined') {
+ label = w._wtype;
+ if (w._wtype == 'statcat') {
+ var stat = statCats.filter(
+ function(m){
+ return (m.id() == w._statcat) })[0];
+ label = stat.name();
+ } else if (w._wtype == 'survey') {
+ var survey = surveys.filter(
+ function(m){
+ return (m.id() == w._survey) })[0];
+ var question = survey.questions().filter(
+ function(m){
+ return (m.id() == w._question) })[0];
+ label = survey.name() + ' : ' + question.question();
+ } else {
+ label = 'FIXME';
+ }
+ } else {
+ label = w.idlField.label;
+ }
+ if (temp != w._wtype) {
+ temp = w._wtype;
+ s += '-------\r\n';
+ }
+ s += label + ':\t' + (typeof val == 'object' ? '' : val) + '\r\n';
+ }
+ s += '=-=-=-=\r\n';
+ return s;
+ }
+
+ openils_Util.addOnLoad(load);
+
- uEditRefreshXUL(newPatron);
-}
-
-function uEditRefresh() {
- var usr = cgi.param('usr');
- var href = location.href.replace(/\?.*/, '');
- href += ((usr) ? '?usr=' + usr : '');
- location.href = href;
-}
-
-function uEditRefreshXUL(newuser) {
- if (window.xulG && typeof window.xulG.on_save == 'function')
- window.xulG.on_save(newuser);
-}
-
-
-/**
- * Create a new address and insert it into the DOM
- * @param evt ignored
- * @param id The address id
- * @param mkLinks If true, set the new address as the
- * mailing/billing address for the user
- */
-function uEditNewAddr(evt, id, mkLinks) {
-
- if(id == null)
- id = --uEditAddrVirtId; // new address
-
- var addr = patron.addresses().filter(
- function(i) { return (i.id() == id) })[0];
-
- dojo.forEach(addrTemplateRows,
- function(row) {
-
- row = tbody.insertBefore(row.cloneNode(true), dojo.byId('new-addr-row'));
- row.setAttribute('type', '');
- row.setAttribute('addr', id+'');
-
- if(row.getAttribute('fmclass')) {
- var widget = fleshFMRow(row, 'aua', {addr:id});
-
- // make new addresses a default address type
- if(id < 0 && row.getAttribute('fmfield') == 'address_type')
- widget.widget.attr('value', localeStrings.DEFAULT_ADDRESS_TYPE);
-
- // make new addresses valid by default
- if(id < 0 && row.getAttribute('fmfield') == 'valid')
- widget.widget.attr('value', true);
-
- // make new addresses use the org setting for default country
- if(id < 0 && row.getAttribute('fmfield') == 'country')
- widget.widget.attr('value',orgSettings['ui.patron.default_country']);
-
- } else if(row.getAttribute('name') == 'uedit-addr-pending-row') {
-
- // if it's a pending address, show the 'approve' button
- if(addr && openils.Util.isTrue(addr.pending())) {
- openils.Util.show(row, 'table-row');
- dojo.query('[name=approve-button]', row)[0].onclick =
- function() { uEditApproveAddress(addr); };
-
- if(addr.replaces()) {
- var div = dojo.query('[name=replaced-addr]', row)[0]
- var replaced = patron.addresses().filter(
- function(i) { return (i.id() == addr.replaces()) })[0];
-
- div.innerHTML = dojo.string.substitute(localeStrings.REPLACED_ADDRESS, [
- replaced.address_type() || '',
- replaced.street1() || '',
- replaced.street2() || '',
- replaced.city() || '',
- replaced.state() || '',
- replaced.post_code() || ''
- ]);
-
- } else {
- openils.Util.hide(dojo.query('[name=replaced-addr-div]', row)[0]);
- }
- }
-
- } else if(row.getAttribute('name') == 'uedit-addr-owner-row') {
- // address is owned by someone else. provide option to load the
- // user in a different tab
-
- if(addr && addr.usr() != patron.id()) {
- openils.Util.show(row, 'table-row');
- var link = getByName(row, 'addr-owner');
-
- // fetch the linked user so we can present their name in the UI
- var addrUser;
- if(cloneUserObj && cloneUserObj.id() == addr.usr()) {
- addrUser = [
- cloneUserObj.first_given_name(),
- cloneUserObj.second_given_name(),
- cloneUserObj.family_name()
- ];
- } else {
- addrUser = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.retrieve.parts'],
- {params: [
- openils.User.authtoken,
- addr.usr(),
- ['first_given_name', 'second_given_name', 'family_name']
- ]}
- );
- }
-
- link.innerHTML = (addrUser.map(function(name) { return (name) ? name+' ' : '' })+'').replace(/,/g,''); // TODO i18n
- link.onclick = function() {
- if(openils.XUL.isXUL()) {
- window.xulG.spawn_editor({ses:openils.User.authtoken, usr:addr.usr()})
- } else {
- parent.location.href = location.href.replace(/clone=\d+/, 'usr=' + addr.usr());
- }
- }
- }
-
- } else if(row.getAttribute('name') == 'uedit-addr-divider') {
- // link up the billing/mailing address and give the inputs IDs so we can access the later
-
- // billing address
- var ba = getByName(row, 'billing_address');
- ba.id = 'uedit-billing-address-' + id;
- if(mkLinks || (patron.billing_address() && patron.billing_address().id() == id)) {
- ba.checked = true;
- prevBillingAddress = id;
- }
-
- // mailing address
- var ma = getByName(row, 'mailing_address');
- ma.id = 'uedit-mailing-address-' + id;
- if(mkLinks || (patron.mailing_address() && patron.mailing_address().id() == id)) {
- ma.checked = true;
- prevMailingAddress = id;
- }
-
- ba.onclick = function() { console.log('ba.onchange ' + id); uEditAddressAlertMarshal(id, true) };
- ma.onclick = function() { uEditAddressAlertMarshal(id, false, true) };
-
- var btn = dojo.query('[name=delete-button]', row)[0];
- if(btn) btn.onclick = function(){ uEditDeleteAddr(id) };
- }
- }
- );
-}
-
-function uEditApproveAddress(addr) {
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.pending_address.approve'],
- { async: true,
- params: [openils.User.authtoken, addr],
-
- oncomplete : function(r) {
- var oldId = openils.Util.readResponse(r);
-
- // remove addrs from UI
- dojo.forEach(
- patron.addresses(),
- function(addr) { uEditDeleteAddr(addr.id(), true); }
- );
-
- if(oldId != null) {
-
- // remove the replaced address
- if(oldId != addr.id()) {
- patron.addresses(
- patron.addresses().filter(
- function(i) { return (i.id() != oldId); }
- )
- );
- }
-
- // fix the the new address
- addr.id(oldId);
- addr.replaces(null);
- addr.pending('f');
-
- }
-
- // redraw addrs
- loadAllAddrs();
- }
- }
- );
-}
-
-
-function uEditDeleteAddr(id, noAlert) {
- if (patron.isnew() && orgSettings['ui.patron.registration.require_address']) {
- if (dojo.query('tr[name=uedit-addr-divider]').length < 2) {
- alert(localeStrings.NEED_ADDRESS);
- return;
- }
- }
- if(!noAlert) {
- if(!confirm(dojo.string.substitute(localeStrings.DELETE_ADDRESS, [id]))) return;
- }
- var addr = patron.addresses().filter(function(i){return (i.id() == id)})[0];
- if (addr) { addr.isdeleted(1); }
- var m_a = patron.mailing_address();
- if (typeof m_a == 'object' && m_a != null) { m_a = m_a.id(); }
- if (m_a == id) { patron.mailing_address(null); }
- var b_a = patron.billing_address();
- if (typeof b_a == 'object' && b_a != null) { b_a = b_a.id(); }
- if (b_a == id) { patron.billing_address(null); }
-
- var rows = dojo.query('tr[addr='+id+']', tbody);
- for(var i = 0; i < rows.length; i++)
- rows[i].parentNode.removeChild(rows[i]);
- widgetPile = widgetPile.filter(function(w){return (w._addr != id)});
-}
-
-function uEditToggleRequired(level) {
- openils.Util.removeCSSClass(tbody, 'hide-non-required');
- openils.Util.removeCSSClass(tbody, 'hide-non-suggested');
- openils.Util.show('uedit-show-required');
- openils.Util.show('uedit-show-required-br');
- openils.Util.show('uedit-show-suggested');
- openils.Util.show('uedit-show-suggested-br');
- openils.Util.show('uedit-show-all');
- switch(level) {
- case 1:
- openils.Util.hide('uedit-show-required');
- openils.Util.hide('uedit-show-required-br');
- openils.Util.addCSSClass(tbody, 'hide-non-required');
- break;
- case 2:
- openils.Util.hide('uedit-show-suggested');
- openils.Util.hide('uedit-show-suggested-br');
- openils.Util.addCSSClass(tbody, 'hide-non-suggested');
- break;
- default:
- openils.Util.hide('uedit-show-all');
- break;
- }
-}
-
-function printable_output() {
- var temp; var s = '=-=-=-=\r\n';
- for (var idx in widgetPile) {
- var w = widgetPile[idx];
- var val = uEditWidgetVal(w);
- var label;
- if (typeof w.idlField == 'undefined') {
- label = w._wtype;
- if (w._wtype == 'statcat') {
- var stat = statCats.filter(
- function(m){
- return (m.id() == w._statcat) })[0];
- label = stat.name();
- } else if (w._wtype == 'survey') {
- var survey = surveys.filter(
- function(m){
- return (m.id() == w._survey) })[0];
- var question = survey.questions().filter(
- function(m){
- return (m.id() == w._question) })[0];
- label = survey.name() + ' : ' + question.question();
- } else {
- label = 'FIXME';
- }
- } else {
- label = w.idlField.label;
- }
- if (temp != w._wtype) {
- temp = w._wtype;
- s += '-------\r\n';
- }
- s += label + ':\t' + (typeof val == 'object' ? '' : val) + '\r\n';
- }
- s += '=-=-=-=\r\n';
- return s;
-}
-
-openils.Util.addOnLoad(load);
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('openils.Util');
-dojo.require('openils.User');
-
-// need these to represent the event def name
-dojo.requireLocalization('openils.conify', 'conify');
-var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
-
-var evtCache = {};
-
-function init() {
- var store = new dojo.data.ItemFileWriteStore({data:acqf.initStoreData()});
- evtGrid.setStore(store);
- evtGrid.render();
-
- function onResponse(r) {
- var evt = openils.Util.readResponse(r);
- evtCache[evt.id()] = evt;
- evtGrid.store.newItem(evt.toStoreItem());
- }
-
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.events.circ'],
- { async: true,
- params: [openils.User.authtoken, patronId],
- onresponse : onResponse
- }
- );
-
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.events.ahr'],
- { async: true,
- params: [openils.User.authtoken, patronId],
- onresponse : onResponse
- }
- );
-}
-
-function getField(rowIdx, item) {
- if(!item) return '';
- var evt = evtCache[this.grid.store.getValue(item, 'id')];
-
- switch(this.field) {
- case 'event_def':
- return dojo.string.substitute(
- localeStrings.EVENT_DEF_LABEL, [
- fieldmapper.aou.findOrgUnit(evt.event_def().owner()).shortname(),
- evt.event_def().name()
- ]);
- case 'reactor':
- return evt.event_def().reactor().module();
- case 'validator':
- return evt.event_def().validator().module();
- case 'hook':
- return evt.event_def().hook();
- case 'target':
- switch(evt.target().classname) {
- case 'circ':
- return evt.target().target_copy().barcode();
- case 'ahr':
- if(evt.target().currrent_copy())
- return evt.target().currrent_copy().barcode();
- }
-
- }
-
- return this.grid.store.getValue(item, this.field) || '';
-}
-
-function evtCancelSelected() {
- var selected = evtGrid.selection.getSelected();
- if(selected.length == 0) return;
- var eventIds = selected.map(
- function(item) { return evtGrid.store.getValue(item, 'id') } );
- alert(eventIds);
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.event.cancel.batch'],
- { async: true,
- params: [openils.User.authtoken, eventIds],
- oncomplete : init
- }
- );
-}
-
-openils.Util.addOnLoad(init);
+require([
+ "dojox/grid/DataGrid",
+ "dojo/data/ItemFileWriteStore",
+ "openils/Util",
+ "openils/User"
+ ],
+function(dojox_grid_DataGrid,
+ dojo_data_ItemFileWriteStore,
+ openils_Util,
+ openils_User){
+
+ // need these to represent the event def name
+ dojo.requireLocalization('openils.conify', 'conify');
+ var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
+
+ var evtCache = {};
+
+ function init() {
+ var store = new dojo_data_ItemFileWriteStore({data:acqf.initStoreData()});
+ evtGrid.setStore(store);
+ evtGrid.render();
+
+ function onResponse(r) {
+ var evt = openils_Util.readResponse(r);
+ evtCache[evt.id()] = evt;
+ evtGrid.store.newItem(evt.toStoreItem());
+ }
+
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.events.circ'],
+ { async: true,
+ params: [openils_User.authtoken, patronId],
+ onresponse : onResponse
+ }
+ );
+
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.events.ahr'],
+ { async: true,
+ params: [openils_User.authtoken, patronId],
+ onresponse : onResponse
+ }
+ );
+ }
+
+ function getField(rowIdx, item) {
+ if(!item) return '';
+ var evt = evtCache[this.grid.store.getValue(item, 'id')];
+
+ switch(this.field) {
+ case 'event_def':
+ return dojo.string.substitute(
+ localeStrings.EVENT_DEF_LABEL, [
+ fieldmapper.aou.findOrgUnit(evt.event_def().owner()).shortname(),
+ evt.event_def().name()
+ ]);
+ case 'reactor':
+ return evt.event_def().reactor().module();
+ case 'validator':
+ return evt.event_def().validator().module();
+ case 'hook':
+ return evt.event_def().hook();
+ case 'target':
+ switch(evt.target().classname) {
+ case 'circ':
+ return evt.target().target_copy().barcode();
+ case 'ahr':
+ if(evt.target().currrent_copy())
+ return evt.target().currrent_copy().barcode();
+ }
+
+ }
+
+ return this.grid.store.getValue(item, this.field) || '';
+ }
+
+ function evtCancelSelected() {
+ var selected = evtGrid.selection.getSelected();
+ if(selected.length == 0) return;
+ var eventIds = selected.map(
+ function(item) { return evtGrid.store.getValue(item, 'id') } );
+ alert(eventIds);
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.event.cancel.batch'],
+ { async: true,
+ params: [openils_User.authtoken, eventIds],
+ oncomplete : init
+ }
+ );
+ }
+
+ openils_Util.addOnLoad(init);
+
+
+});
\ No newline at end of file
-dojo.require("openils.User");
-dojo.require("openils.widget.OrgUnitFilteringSelect");
-dojo.requireLocalization("openils.booking", "capture");
-
-const CAPTURE_FAILURE = 0;
-const CAPTURE_SUCCESS = 1;
-const CAPTURE_UNKNOWN = 2;
-
-var localeStrings = dojo.i18n.getLocalization("openils.booking", "capture");
-
-function CaptureDisplay(control_holder, data_holder) {
- this.control_holder = control_holder;
- this.data_holder = data_holder;
-}
-CaptureDisplay.prototype.no_payload = function() {
- this.data_holder.appendChild(
- document.createTextNode(localeStrings.NO_PAYLOAD)
- );
-};
-CaptureDisplay.prototype.dump = function(payload) {
- var div = document.createElement("div");
- div.appendChild(document.createTextNode(localeStrings.HERES_WHAT_WE_KNOW));
- this.data_holder.appendChild(div);
-
- var ul = document.createElement("ul");
- for (var k in payload) {
- var li = document.createElement("li");
- li.appendChild(document.createTextNode(k + ": " + payload[k]));
- ul.appendChild(li);
- }
- this.data_holder.appendChild(ul);
-};
-CaptureDisplay.prototype._generate_barcode_line = function(payload) {
- var div = document.createElement("div");
- div.appendChild(document.createTextNode(
- localeStrings.BARCODE + ": " + payload.resource.barcode()
- ));
- return div;
-};
-CaptureDisplay.prototype._generate_title_line = function(payload) {
- var div = document.createElement("div");
- div.appendChild(document.createTextNode(
- localeStrings.TITLE + ": " +
- (payload.mvr ? payload.mvr.title() : payload.type.name())
- ));
- return div;
-};
-CaptureDisplay.prototype._generate_author_line = function(payload) {
- var div = document.createElement("div");
- if (payload.mvr) {
- div.appendChild(document.createTextNode(
- localeStrings.AUTHOR + ": " + payload.mvr.author()
- ));
- }
- return div;
-};
-CaptureDisplay.prototype._generate_transit_notice = function(payload) {
- var div = document.createElement("div");
- if (payload.transit) {
- div.setAttribute("class", "transit_notice");
- div.appendChild(document.createTextNode(localeStrings.TRANSIT));
- }
- return div;
-};
-CaptureDisplay.prototype._generate_route_line = function(payload) {
- var div = document.createElement("div");
- var strong = document.createElement("strong");
- strong.appendChild(document.createTextNode(
- (payload.transit ?
- fieldmapper.aou.findOrgUnit(payload.transit.dest()).shortname() :
- localeStrings.RESERVATION_SHELF) + ":"
- ));
- div.appendChild(document.createTextNode(
- localeStrings.NEEDS_ROUTED_TO + " "
- ));
- div.appendChild(strong);
- return div;
-};
-CaptureDisplay.prototype._generate_patron_info = function(payload) {
- var p = document.createElement("p");
- p.innerHTML = "<strong>" + localeStrings.RESERVED + "</strong> " +
- formal_name(payload.reservation.usr()) + "<br />" +
- localeStrings.BARCODE + ": " +
- payload.reservation.usr().card().barcode();
- return p;
-};
-CaptureDisplay.prototype._generate_resv_info = function(payload) {
- var p = document.createElement("p");
- p.innerHTML = localeStrings.REQUEST + ": " +
- humanize_timestamp_string(payload.reservation.request_time()) +
- "<br />" +
- localeStrings.DURATION + ": " +
- humanize_timestamp_string(payload.reservation.start_time()) +
- " - " +
- humanize_timestamp_string(payload.reservation.end_time());
- return p;
-};
-CaptureDisplay.prototype._generate_meta_info = function(result) {
- var p = document.createElement("p");
- p.innerHTML = localeStrings.SLIP_DATE + ": " + result.servertime +
- "<br />" + localeStrings.PRINTED_BY + " " +
- formal_name(openils.User.user) + " " + localeStrings.AT + " " +
- fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()).shortname()
- return p;
-};
-CaptureDisplay.prototype.display_with_transit_info = function(result) {
- var div = document.createElement("div");
- var span = document.createElement("span");
- span.appendChild(document.createTextNode(localeStrings.CAPTURE_INFO));
- span.setAttribute("class", "capture_info");
- this.control_holder.appendChild(span);
-
- var button = document.createElement("button");
- button.setAttribute("class", "print_slip");
- button.setAttribute("type", "button");
- button.setAttribute("accesskey", localeStrings.PRINT_ACCESSKEY);
- button.innerHTML = localeStrings.PRINT;
- button.onclick = function() {
- try { dojo.byId("printing_iframe").contentWindow.print(); }
- catch (E) { alert(E); } /* XXX */
- return false;
- };
- this.control_holder.appendChild(button);
-
- div.appendChild(this._generate_transit_notice(result.payload));
-
- var p = document.createElement("p");
- p.appendChild(this._generate_route_line(result.payload));
- p.appendChild(this._generate_barcode_line(result.payload));
- p.appendChild(this._generate_title_line(result.payload));
- p.appendChild(this._generate_author_line(result.payload));
- div.appendChild(p);
-
- div.appendChild(this._generate_patron_info(result.payload));
- div.appendChild(this._generate_resv_info(result.payload));
- div.appendChild(this._generate_meta_info(result));
-
- this._create_iframe(div);
-};
-CaptureDisplay.prototype._create_iframe = function(contents) {
- var iframe = document.createElement("iframe");
- iframe.setAttribute("name", "printing_iframe");
- iframe.setAttribute("id", "printing_iframe");
- iframe.setAttribute("src", "");
- iframe.setAttribute("width", "100%");
- iframe.setAttribute("height", "400"); /* hardcode 400px? really? */
-
- this.data_holder.appendChild(iframe);
-
- var w = dojo.byId("printing_iframe").contentWindow;
- w.document.open();
- w.document.write(
- "<html><head><link rel='stylesheet' type='text/css' href='" +
- dojo.byId("booking_stylesheet_link").href +
- "' /><body></body></html>"
- );
- w.document.close();
- w.document.body.appendChild(contents);
- /* FIXME if (determine_autoprint_setting_somehow()) w.print(); */
-};
-CaptureDisplay.prototype.clear = function() {
- this.control_holder.innerHTML = "";
- this.data_holder.innerHTML = "";
-};
-CaptureDisplay.prototype.load = function(result) {
- try {
- this.control_holder.appendChild(document.createElement("hr"));
- if (!result.payload) {
- this.no_payload();
- } else if (!result.payload.fail_cause && result.payload.captured) {
- this.display_with_transit_info(result);
- } else {
- this.dump(result.payload);
- }
- } catch (E) {
- alert(E); /* XXX */
- }
-};
-
-var capture_display;
-var last_result;
-
-function clear_for_next() {
- if (last_result == CAPTURE_SUCCESS) {
- last_result = undefined;
- document.getElementById("result_display").innerHTML = "";
- document.getElementById("resource_barcode").value = "";
- }
-}
-
-function capture() {
- var barcode = document.getElementById("resource_barcode").value;
- var result = fieldmapper.standardRequest(
- [
- "open-ils.booking",
- "open-ils.booking.resources.capture_for_reservation"
- ],
- [openils.User.authtoken, barcode]
- );
-
- if (result && result.ilsevent !== undefined) {
- if (result.payload && result.payload.captured > 0) {
- capture_display.load(result);
- return CAPTURE_SUCCESS;
- } else {
- capture_display.load(result);
- alert(my_ils_error(localeStrings.CAPTURED_NOTHING, result));
- return CAPTURE_FAILURE;
- }
- } else {
- return CAPTURE_UNKNOWN;
- }
-}
-
-function attempt_capture() {
- var rd = document.getElementById("result_display");
- capture_display.clear();
- switch(last_result = capture()) {
- case CAPTURE_FAILURE:
- rd.setAttribute("class", "capture_failure");
- rd.innerHTML = localeStrings.FAILURE;
- break;
- case CAPTURE_SUCCESS:
- rd.setAttribute("class", "capture_success");
- rd.innerHTML = localeStrings.SUCCESS;
- break;
- default:
- alert(localeStrings.UNKNOWN_PROBLEM);
- break;
- }
-}
-
-function my_init() {
- init_auto_l10n(dojo.byId("auto_l10n_start_here"));
- capture_display = new CaptureDisplay(
- dojo.byId("capture_info_top"),
- dojo.byId("capture_info_bottom")
- );
-}
+require([
+ "openils/User",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(openils_User,
+ openils_widget_OrgUnitFilteringSelect){
+ dojo.requireLocalization("openils.booking", "capture");
+
+ const CAPTURE_FAILURE = 0;
+ const CAPTURE_SUCCESS = 1;
+ const CAPTURE_UNKNOWN = 2;
+
+ var localeStrings = dojo.i18n.getLocalization("openils.booking", "capture");
+
+ function CaptureDisplay(control_holder, data_holder) {
+ this.control_holder = control_holder;
+ this.data_holder = data_holder;
+ }
+ CaptureDisplay.prototype.no_payload = function() {
+ this.data_holder.appendChild(
+ document.createTextNode(localeStrings.NO_PAYLOAD)
+ );
+ };
+ CaptureDisplay.prototype.dump = function(payload) {
+ var div = document.createElement("div");
+ div.appendChild(document.createTextNode(localeStrings.HERES_WHAT_WE_KNOW));
+ this.data_holder.appendChild(div);
+
+ var ul = document.createElement("ul");
+ for (var k in payload) {
+ var li = document.createElement("li");
+ li.appendChild(document.createTextNode(k + ": " + payload[k]));
+ ul.appendChild(li);
+ }
+ this.data_holder.appendChild(ul);
+ };
+ CaptureDisplay.prototype._generate_barcode_line = function(payload) {
+ var div = document.createElement("div");
+ div.appendChild(document.createTextNode(
+ localeStrings.BARCODE + ": " + payload.resource.barcode()
+ ));
+ return div;
+ };
+ CaptureDisplay.prototype._generate_title_line = function(payload) {
+ var div = document.createElement("div");
+ div.appendChild(document.createTextNode(
+ localeStrings.TITLE + ": " +
+ (payload.mvr ? payload.mvr.title() : payload.type.name())
+ ));
+ return div;
+ };
+ CaptureDisplay.prototype._generate_author_line = function(payload) {
+ var div = document.createElement("div");
+ if (payload.mvr) {
+ div.appendChild(document.createTextNode(
+ localeStrings.AUTHOR + ": " + payload.mvr.author()
+ ));
+ }
+ return div;
+ };
+ CaptureDisplay.prototype._generate_transit_notice = function(payload) {
+ var div = document.createElement("div");
+ if (payload.transit) {
+ div.setAttribute("class", "transit_notice");
+ div.appendChild(document.createTextNode(localeStrings.TRANSIT));
+ }
+ return div;
+ };
+ CaptureDisplay.prototype._generate_route_line = function(payload) {
+ var div = document.createElement("div");
+ var strong = document.createElement("strong");
+ strong.appendChild(document.createTextNode(
+ (payload.transit ?
+ fieldmapper.aou.findOrgUnit(payload.transit.dest()).shortname() :
+ localeStrings.RESERVATION_SHELF) + ":"
+ ));
+ div.appendChild(document.createTextNode(
+ localeStrings.NEEDS_ROUTED_TO + " "
+ ));
+ div.appendChild(strong);
+ return div;
+ };
+ CaptureDisplay.prototype._generate_patron_info = function(payload) {
+ var p = document.createElement("p");
+ p.innerHTML = "<strong>" + localeStrings.RESERVED + "</strong> " +
+ formal_name(payload.reservation.usr()) + "<br />" +
+ localeStrings.BARCODE + ": " +
+ payload.reservation.usr().card().barcode();
+ return p;
+ };
+ CaptureDisplay.prototype._generate_resv_info = function(payload) {
+ var p = document.createElement("p");
+ p.innerHTML = localeStrings.REQUEST + ": " +
+ humanize_timestamp_string(payload.reservation.request_time()) +
+ "<br />" +
+ localeStrings.DURATION + ": " +
+ humanize_timestamp_string(payload.reservation.start_time()) +
+ " - " +
+ humanize_timestamp_string(payload.reservation.end_time());
+ return p;
+ };
+ CaptureDisplay.prototype._generate_meta_info = function(result) {
+ var p = document.createElement("p");
+ p.innerHTML = localeStrings.SLIP_DATE + ": " + result.servertime +
+ "<br />" + localeStrings.PRINTED_BY + " " +
+ formal_name(openils_User.user) + " " + localeStrings.AT + " " +
+ fieldmapper.aou.findOrgUnit(openils_User.user.ws_ou()).shortname()
+ return p;
+ };
+ CaptureDisplay.prototype.display_with_transit_info = function(result) {
+ var div = document.createElement("div");
+ var span = document.createElement("span");
+ span.appendChild(document.createTextNode(localeStrings.CAPTURE_INFO));
+ span.setAttribute("class", "capture_info");
+ this.control_holder.appendChild(span);
+
+ var button = document.createElement("button");
+ button.setAttribute("class", "print_slip");
+ button.setAttribute("type", "button");
+ button.setAttribute("accesskey", localeStrings.PRINT_ACCESSKEY);
+ button.innerHTML = localeStrings.PRINT;
+ button.onclick = function() {
+ try { dojo.byId("printing_iframe").contentWindow.print(); }
+ catch (E) { alert(E); } /* XXX */
+ return false;
+ };
+ this.control_holder.appendChild(button);
+
+ div.appendChild(this._generate_transit_notice(result.payload));
+
+ var p = document.createElement("p");
+ p.appendChild(this._generate_route_line(result.payload));
+ p.appendChild(this._generate_barcode_line(result.payload));
+ p.appendChild(this._generate_title_line(result.payload));
+ p.appendChild(this._generate_author_line(result.payload));
+ div.appendChild(p);
+
+ div.appendChild(this._generate_patron_info(result.payload));
+ div.appendChild(this._generate_resv_info(result.payload));
+ div.appendChild(this._generate_meta_info(result));
+
+ this._create_iframe(div);
+ };
+ CaptureDisplay.prototype._create_iframe = function(contents) {
+ var iframe = document.createElement("iframe");
+ iframe.setAttribute("name", "printing_iframe");
+ iframe.setAttribute("id", "printing_iframe");
+ iframe.setAttribute("src", "");
+ iframe.setAttribute("width", "100%");
+ iframe.setAttribute("height", "400"); /* hardcode 400px? really? */
+
+ this.data_holder.appendChild(iframe);
+
+ var w = dojo.byId("printing_iframe").contentWindow;
+ w.document.open();
+ w.document.write(
+ "<html><head><link rel='stylesheet' type='text/css' href='" +
+ dojo.byId("booking_stylesheet_link").href +
+ "' /><body></body></html>"
+ );
+ w.document.close();
+ w.document.body.appendChild(contents);
+ /* FIXME if (determine_autoprint_setting_somehow()) w.print(); */
+ };
+ CaptureDisplay.prototype.clear = function() {
+ this.control_holder.innerHTML = "";
+ this.data_holder.innerHTML = "";
+ };
+ CaptureDisplay.prototype.load = function(result) {
+ try {
+ this.control_holder.appendChild(document.createElement("hr"));
+ if (!result.payload) {
+ this.no_payload();
+ } else if (!result.payload.fail_cause && result.payload.captured) {
+ this.display_with_transit_info(result);
+ } else {
+ this.dump(result.payload);
+ }
+ } catch (E) {
+ alert(E); /* XXX */
+ }
+ };
+
+ var capture_display;
+ var last_result;
+
+ function clear_for_next() {
+ if (last_result == CAPTURE_SUCCESS) {
+ last_result = undefined;
+ document.getElementById("result_display").innerHTML = "";
+ document.getElementById("resource_barcode").value = "";
+ }
+ }
+
+ function capture() {
+ var barcode = document.getElementById("resource_barcode").value;
+ var result = fieldmapper.standardRequest(
+ [
+ "open-ils.booking",
+ "open-ils.booking.resources.capture_for_reservation"
+ ],
+ [openils_User.authtoken, barcode]
+ );
+
+ if (result && result.ilsevent !== undefined) {
+ if (result.payload && result.payload.captured > 0) {
+ capture_display.load(result);
+ return CAPTURE_SUCCESS;
+ } else {
+ capture_display.load(result);
+ alert(my_ils_error(localeStrings.CAPTURED_NOTHING, result));
+ return CAPTURE_FAILURE;
+ }
+ } else {
+ return CAPTURE_UNKNOWN;
+ }
+ }
+
+ function attempt_capture() {
+ var rd = document.getElementById("result_display");
+ capture_display.clear();
+ switch(last_result = capture()) {
+ case CAPTURE_FAILURE:
+ rd.setAttribute("class", "capture_failure");
+ rd.innerHTML = localeStrings.FAILURE;
+ break;
+ case CAPTURE_SUCCESS:
+ rd.setAttribute("class", "capture_success");
+ rd.innerHTML = localeStrings.SUCCESS;
+ break;
+ default:
+ alert(localeStrings.UNKNOWN_PROBLEM);
+ break;
+ }
+ }
+
+ function my_init() {
+ init_auto_l10n(dojo.byId("auto_l10n_start_here"));
+ capture_display = new CaptureDisplay(
+ dojo.byId("capture_info_top"),
+ dojo.byId("capture_info_bottom")
+ );
+ }
+
+
+});
\ No newline at end of file
-dojo.require("dijit.form.Button");
+require([
+ "dijit/form/Button"
+ ],
+function(dijit_form_Button){
+
+ /* Quick and dirty way to localize some strings; not recommended for reuse.
+ * I'm sure dojo provides a better mechanism for this, but at the moment
+ * this is faster to implement anew than figuring out the Right way to do
+ * the same thing w/ dojo.
+ */
+ function init_auto_l10n(el) {
+ function do_it(myel, cls) {
+ if (cls) {
+ var clss = cls.split(" ");
+ for (var k in clss) {
+ var parts = clss[k].match(/^AUTO_ATTR_([A-Z]+)_.+$/);
+ if (parts && localeStrings[clss[k]]) {
+ myel.setAttribute(
+ parts[1].toLowerCase(), localeStrings[clss[k]]
+ );
+ } else if (clss[k].match(/^AUTO_/) && localeStrings[clss[k]]) {
+ myel.innerHTML = localeStrings[clss[k]];
+ }
+ }
+ }
+ }
+
+ for (var i in el.attributes) {
+ if (el.attributes[i].nodeName == "class") {
+ do_it(el, el.attributes[i].value);
+ break;
+ }
+ }
+ for (var i in el.childNodes) {
+ if (el.childNodes[i].nodeType == 1) { // element node?
+ init_auto_l10n(el.childNodes[i]); // recurse!
+ }
+ }
+ }
+
+ function get_keys(L) { var K = []; for (var k in L) K.push(k); return K; }
+ function hide_dom_element(e) { e.style.display = "none"; };
+ function reveal_dom_element(e) { e.style.display = ""; };
+ function formal_name(u) {
+ var name = u.family_name() + ", " + u.first_given_name();
+ if (u.second_given_name())
+ name += (" " + u.second_given_name());
+ return name;
+ }
+ function humanize_timestamp_string(ts) {
+ /* For now, this discards time zones. */
+ var parts = ts.split("T");
+ var timeparts = parts[1].split("-")[0].split(":");
+ return parts[0] + " " + timeparts[0] + ":" + timeparts[1];
+ }
+ function humanize_timestamp_string2(ts) {
+ /* For now, this discards time zones, too. */
+ var parts = ts.split(" ");
+ parts[1] = parts[1].replace(/[\-\+]\d+$/, "");
+ var timeparts = parts[1].split("-")[0].split(":");
+ return parts[0] + " " + timeparts[0] + ":" + timeparts[1];
+ }
+ function is_ils_event(e) { return (e.ilsevent != undefined); }
+ function is_ils_actor_card_error(e) {
+ return (e.textcode == "ACTOR_CARD_NOT_FOUND");
+ }
+ function my_ils_error(leader, e) {
+ var s = leader + "\n";
+ var keys = [
+ "ilsevent", "desc", "textcode", "servertime", "pid", "stacktrace"
+ ];
+ for (var i in keys) {
+ if (e[keys[i]]) s += ("\t" + keys[i] + ": " + e[keys[i]] + "\n");
+ }
+ return s;
+ }
+ function set_datagrid_empty_store(grid, flattener) {
+ grid.setStore(
+ new dojo.data.ItemFileReadStore(
+ {"data": flattener([])}
+ )
+ );
+ }
+
-/* Quick and dirty way to localize some strings; not recommended for reuse.
- * I'm sure dojo provides a better mechanism for this, but at the moment
- * this is faster to implement anew than figuring out the Right way to do
- * the same thing w/ dojo.
- */
-function init_auto_l10n(el) {
- function do_it(myel, cls) {
- if (cls) {
- var clss = cls.split(" ");
- for (var k in clss) {
- var parts = clss[k].match(/^AUTO_ATTR_([A-Z]+)_.+$/);
- if (parts && localeStrings[clss[k]]) {
- myel.setAttribute(
- parts[1].toLowerCase(), localeStrings[clss[k]]
- );
- } else if (clss[k].match(/^AUTO_/) && localeStrings[clss[k]]) {
- myel.innerHTML = localeStrings[clss[k]];
- }
- }
- }
- }
-
- for (var i in el.attributes) {
- if (el.attributes[i].nodeName == "class") {
- do_it(el, el.attributes[i].value);
- break;
- }
- }
- for (var i in el.childNodes) {
- if (el.childNodes[i].nodeType == 1) { // element node?
- init_auto_l10n(el.childNodes[i]); // recurse!
- }
- }
-}
-
-function get_keys(L) { var K = []; for (var k in L) K.push(k); return K; }
-function hide_dom_element(e) { e.style.display = "none"; };
-function reveal_dom_element(e) { e.style.display = ""; };
-function formal_name(u) {
- var name = u.family_name() + ", " + u.first_given_name();
- if (u.second_given_name())
- name += (" " + u.second_given_name());
- return name;
-}
-function humanize_timestamp_string(ts) {
- /* For now, this discards time zones. */
- var parts = ts.split("T");
- var timeparts = parts[1].split("-")[0].split(":");
- return parts[0] + " " + timeparts[0] + ":" + timeparts[1];
-}
-function humanize_timestamp_string2(ts) {
- /* For now, this discards time zones, too. */
- var parts = ts.split(" ");
- parts[1] = parts[1].replace(/[\-\+]\d+$/, "");
- var timeparts = parts[1].split("-")[0].split(":");
- return parts[0] + " " + timeparts[0] + ":" + timeparts[1];
-}
-function is_ils_event(e) { return (e.ilsevent != undefined); }
-function is_ils_actor_card_error(e) {
- return (e.textcode == "ACTOR_CARD_NOT_FOUND");
-}
-function my_ils_error(leader, e) {
- var s = leader + "\n";
- var keys = [
- "ilsevent", "desc", "textcode", "servertime", "pid", "stacktrace"
- ];
- for (var i in keys) {
- if (e[keys[i]]) s += ("\t" + keys[i] + ": " + e[keys[i]] + "\n");
- }
- return s;
-}
-function set_datagrid_empty_store(grid, flattener) {
- grid.setStore(
- new dojo.data.ItemFileReadStore(
- {"data": flattener([])}
- )
- );
-}
+});
\ No newline at end of file
-/* This module depends on common.js being loaded, as well as the
- * localization (Dojo/nls) for pickup and return . */
+require([
+ "dojo/data/ItemFileReadStore",
+ "dojo/date/locale",
+ "openils/PermaCrud",
+ "dojo/string"
+ ],
+function(dojo_data_ItemFileReadStore,
+ dojo_date_locale,
+ openils_PermaCrud,
+ dojo_string){
+ /* This module depends on common.js being loaded, as well as the
+ * localization (Dojo/nls) for pickup and return . */
+
+
+ function Populator(widgets, primary_input) {
+ this.widgets = widgets;
+
+ this.all = [];
+ for (var k in widgets) this.all.push(k);
+
+ if (primary_input) this.primary_input = primary_input;
+
+ this.prepare_cache();
+ this.prepare_empty_stores();
+ this.reset();
+ }
+ Populator.prototype.prepare_cache = function(data) {
+ this.cache = {};
+ for (var k in this.all) this.cache[this.all[k]] = {};
+ };
+ Populator.prototype.prepare_empty_stores = function(data) {
+ this.empty_stores = {};
+
+ for (var i in this.all) {
+ var name = this.all[i];
+
+ if (this.widgets[name] && this["flatten_" + name]) {
+ this.empty_stores[name] =
+ new dojo_data_ItemFileReadStore({
+ "data": this["flatten_" + name]([])
+ });
+ this.widgets[name].setStore(this.empty_stores[name]);
+ }
+ }
+ };
+ Populator.prototype.flatten_ready = function(data) {
+ return {
+ "label": "id",
+ "identifier": "id",
+ "items": data.map(function(o) {
+ return {
+ "id": o.id(),
+ "type": o.target_resource_type().name(),
+ "resource": o.current_resource().barcode(),
+ "start_time": humanize_timestamp_string(o.start_time()),
+ "end_time": humanize_timestamp_string(o.end_time())
+ };
+ })
+ };
+ };
+ Populator.prototype.flatten_out = function(data) {
+ return {
+ "label": "id",
+ "identifier": "id",
+ "items": data.map(function(o) {
+ return {
+ "id": o.id(),
+ "type": o.target_resource_type().name(),
+ "resource": o.current_resource().barcode(),
+ "pickup_time": humanize_timestamp_string(o.pickup_time()),
+ "end_time": humanize_timestamp_string(o.end_time())
+ };
+ })
+ };
+ };
+ Populator.prototype.flatten_in = function(data) {
+ return {
+ "label": "id",
+ "identifier": "id",
+ "items": data.map(function(o) {
+ return {
+ "id": o.id(),
+ "type": o.target_resource_type().name(),
+ "resource": o.current_resource().barcode(),
+ "due_time": humanize_timestamp_string(o.end_time()),
+ "return_time": humanize_timestamp_string(o.return_time())
+ };
+ })
+ };
+ };
+ Populator.prototype.reveal_container = function(widget) {
+ var el = document.getElementById("contains_" + widget.id);
+ if (el) reveal_dom_element(el);
+ };
+ Populator.prototype.hide_container = function(widget) {
+ var el = document.getElementById("contains_" + widget.id);
+ if (el) hide_dom_element(el);
+ };
+ Populator.prototype.populate_ready = function(data) {
+ return this._populate_any_resv_grid(data, "ready");
+ };
+ Populator.prototype.populate_out = function(data) {
+ return this._populate_any_resv_grid(data, "out");
+ };
+ Populator.prototype.populate_in = function(data) {
+ return this._populate_any_resv_grid(data, "in");
+ };
+ Populator.prototype._populate_any_resv_grid = function(data, which) {
+ var flattener = this["flatten_" + which];
+ var widget = this.widgets[which];
+ var cache = this.cache[which];
+ var empty_store = this.empty_stores[which];
+
+ this.reveal_container(widget);
+
+ if (!data || !data.length) {
+ widget.setStore(empty_store);
+ this.toggle_anyness(false, which);
+ } else {
+ for (var i in data) cache[data[i].id()] = data[i];
+
+ widget.setStore(
+ new dojo_data_ItemFileReadStore({"data": flattener(data)})
+ );
+
+ this.toggle_anyness(true, which);
+
+ /* Arrrgh! Horrid but necessary: */
+ setTimeout(function() { widget.sort(); }, 100);
+ }
+ };
+ Populator.prototype.populate_patron = function(data) {
+ var h2 = document.createElement("h2");
+ h2.setAttribute("class", "booking");
+ h2.appendChild(document.createTextNode(formal_name(data)));
+
+ this.widgets.patron.innerHTML = "";
+ this.widgets.patron.appendChild(h2);
+
+ this.reveal_container(this.widgets.patron);
+ /* Maybe add patron's home OU or something here later... */
+ };
+ Populator.prototype.return_by_resource = function(barcode, override) {
+ /* XXX instead of talking to the server every time we do this, we could
+ * also check the "out" cache, iff we have one. */
+ var r = fieldmapper.standardRequest(
+ ["open-ils.booking",
+ "open-ils.booking.reservations.by_returnable_resource_barcode"],
+ [openils.User.authtoken, barcode]
+ );
+ if (!r || r.length < 1) {
+ alert(localeStrings.NO_SUCH_RETURNABLE_RESOURCE);
+ } else if (is_ils_event(r)) {
+ alert(my_ils_error(localeStrings.RETURNABLE_RESOURCE_ERROR, r));
+ } else {
+ try {
+ var new_barcode = r.usr().card().barcode();
+ } catch (E) {
+ alert(localeStrings.RETURN_ERROR + "\nr: " + js2JSON(r) + "\n" + E);
+ return;
+ }
+ if (this.patron_barcode && this.patron_barcode != new_barcode) {
+ /* XXX make this more subtle, i.e. flash something in background */
+ alert(localeStrings.NOTICE_CHANGE_OF_PATRON);
+ }
+ this.patron_barcode = new_barcode;
+ var ret = this.return(r, override);
+ if (!ret) {
+ alert(localeStrings.RETURN_NO_RESPONSE);
+ } else if (is_ils_event(ret) && ret.textcode != "SUCCESS") {
+ if (ret.textcode == "ROUTE_ITEM") {
+ display_transit_slip(ret);
+ } else if (ret.textcode == "COPY_ALERT_MESSAGE") {
+ if (
+ confirm(
+ dojo_string.substitute(
+ localeStrings.COPY_ALERT, [ret.desc, ret.payload]
+ )
+ )
+ ) {
+ this.return_by_resource(barcode, true /*override*/);
+ return;
+ }
+ } else {
+ alert(my_ils_error(localeStrings.RETURN_ERROR, ret));
+ }
+ } else {
+ /* XXX speedbump should go, but something has to happen else
+ * there's no indication to staff that anything happened when
+ * starting from a fresh (blank) return interface.
+ */
+ alert(localeStrings.RETURN_SUCCESS);
+ }
+ this.populate(); /* Won't recurse with no args. All is well. */
+ }
+ };
+ Populator.prototype.populate = function(barcode, which) {
+ if (barcode) {
+ if (barcode.patron) {
+ this.patron_barcode = barcode.patron;
+ }
+ else if (barcode.resource) { /* resource OR patron, not both */
+ if (!this.return_by_resource(barcode.resource))
+ return;
+ }
+ }
+ if (!this.patron_barcode) {
+ alert(localeStrings.NO_PATRON_BARCODE);
+ return;
+ }
+
+ if (!which) which = this.all;
+
+ var result = fieldmapper.standardRequest(
+ ["open-ils.booking", "open-ils.booking.reservations.get_captured"],
+ [openils.User.authtoken, this.patron_barcode, which]
+ );
+
+ if (!result) {
+ this.patron_barcode = undefined;
+ alert(localeStrings.RESERVATIONS_NO_RESPONSE);
+ } else if (is_ils_event(result)) {
+ this.patron_barcode = undefined;
+ alert(my_ils_error(localeStrings.RESERVATIONS_ERROR, result));
+ } else {
+ for (var k in result)
+ this["populate_" + k](result[k]);
+ }
+ };
+ Populator.prototype.toggle_anyness = function(any, which) {
+ var widget = this.widgets[which].domNode;
+ var empty_alternate = document.getElementById("no_" + widget.id);
+ var controls = document.getElementById("controls_" + widget.id);
+ if (any) {
+ reveal_dom_element(widget);
+ if (empty_alternate) hide_dom_element(empty_alternate);
+ if (controls) reveal_dom_element(controls);
+ } else {
+ hide_dom_element(widget);
+ if (empty_alternate) reveal_dom_element(empty_alternate);
+ if (controls) hide_dom_element(controls);
+ }
+ };
+ Populator.prototype.pickup = function(reservation) {
+ return fieldmapper.standardRequest(
+ ["open-ils.circ", "open-ils.circ.reservation.pickup"],
+ [openils.User.authtoken, {
+ "patron_barcode": this.patron_barcode,
+ "reservation": reservation
+ }]
+ );
+ };
+ Populator.prototype.return = function(reservation, override) {
+ var method = "open-ils.circ.reservation.return";
+ if (override) method += ".override";
+ return fieldmapper.standardRequest(
+ ["open-ils.circ", method],
+ [openils.User.authtoken, {
+ "patron_barcode": this.patron_barcode,
+ "reservation": reservation.id()
+ /* yeah just id here ------^; lack of parallelism */
+ }]
+ );
+ };
+ Populator.prototype.act_on_selected = function(how, which) {
+ var widget = this.widgets[which];
+ var cache = this.cache[which];
+ var no_response_msg = localeStrings[how.toUpperCase() + "_NO_RESPONSE"];
+ var error_msg = localeStrings[how.toUpperCase() + "_ERROR"];
+
+ var selected_id_list =
+ widget.selection.getSelected().map(function(o) { return o.id[0]; });
+
+ if (!selected_id_list || !selected_id_list.length) {
+ alert(localeStrings.SELECT_SOMETHING);
+ return;
+ }
+
+ var reservations = selected_id_list.map(function(o) { return cache[o]; });
+
+ /* Do we have to process these one at a time? I think so... */
+ var self = this;
+ function looper(reservation, override) {
+ if (looper._done) return;
+ var result = self[how](reservation, override);
+ if (!result) {
+ alert(no_response_msg);
+ } else if (is_ils_event(result) && result.textcode != "SUCCESS") {
+ if (result.textcode == "ROUTE_ITEM") {
+ display_transit_slip(result);
+ } else if (result.textcode == "COPY_ALERT_MESSAGE") {
+ if (confirm(
+ dojo_string.substitute(
+ localeStrings.COPY_ALERT, [result.desc, result.payload]
+ )
+ )) {
+ looper(reservation, true);
+ }
+ return; // continues processing other resvs
+ } else {
+ alert(my_ils_error(error_msg, result));
+ }
+ } else {
+ return;
+ }
+ looper._done = true;
+ }
+ dojo.forEach(reservations, looper);
+
+ this.populate();
+ };
+ Populator.prototype.reset = function() {
+ for (var k in this.widgets) {
+ this.hide_container(this.widgets[k]);
+ }
+ this.patron_barcode = undefined;
+
+ if (typeof(this._extra_resetting) == "function")
+ this._extra_resetting();
+
+ if (this.primary_input) {
+ this.primary_input.value = "";
+ this.primary_input.focus();
+ }
+ };
+
+ /* XXX needs to be combined with the code that shows transit slips in the
+ * booking capture interface. */
+ function display_transit_slip(e) {
+ var ou = fieldmapper.aou.findOrgUnit(e.org, /* slim_ok */false);
+ var ma = (new openils_PermaCrud()).retrieve("aoa", ou.mailing_address());
+ var mas = ma ?
+ dojo_string.substitute(
+ localeStrings.ADDRESS,
+ [ma.street1(),ma.street2(),ma.city(),ma.state(),ma.post_code()].map(
+ function(o) { return o ? o : ""; }
+ )
+ ).replace("\n\n", "\n").replace("\n", "<br />") : "[Unknown address]";
+ /* XXX i18n and/or template */
+ try {
+ var win = window.open(
+ "","","resizeable,width=600,height=400,scrollbars=1"
+ );
+ win.document.body.innerHTML =
+ "<h1>Transit Slip</h1>\n" +
+ //"<img src='/xul/server/skin/media/images/turtle.gif' />\n" +
+ "<p>Destination: <strong>" + ou.name() + "</strong></p>\n" +
+ "<p>" + mas + "</p>\n" +
+ "<p>Barcode: " + e.payload.copy.barcode() + "<br />\n" +
+ "Title: <span id='title'></span><br />\n" +
+ "Author: <span id='author'></span><br />\n" +
+ "Slip Date: " +
+ dojo_date_locale.format(new Date(), {"formatLength": "short"}) +
+ "</p>";
+ fieldmapper.standardRequest(
+ ["open-ils.search", "open-ils.search.biblio.mods_from_copy"], {
+ "params": [e.payload.copy.id()],
+ "async": true,
+ "onresponse": function(r) {
+ var mvr = openils.Util.readResponse(r);
+ dojo.byId("title", win.document).innerHTML = mvr.title();
+ dojo.byId("author", win.document).innerHTML = mvr.author();
+ },
+ "oncomplete": function() {
+ win[confirm("Print transit slip?") ? "print" : "close"]();
+ }
+ }
+ );
+ } catch (E) {
+ alert("exception rendering transit slip: " + E); // XXX
+ }
+ }
+
-dojo.require("dojo.data.ItemFileReadStore");
-dojo.require("dojo.date.locale");
-dojo.require("openils.PermaCrud");
-dojo.require("dojo.string");
-
-function Populator(widgets, primary_input) {
- this.widgets = widgets;
-
- this.all = [];
- for (var k in widgets) this.all.push(k);
-
- if (primary_input) this.primary_input = primary_input;
-
- this.prepare_cache();
- this.prepare_empty_stores();
- this.reset();
-}
-Populator.prototype.prepare_cache = function(data) {
- this.cache = {};
- for (var k in this.all) this.cache[this.all[k]] = {};
-};
-Populator.prototype.prepare_empty_stores = function(data) {
- this.empty_stores = {};
-
- for (var i in this.all) {
- var name = this.all[i];
-
- if (this.widgets[name] && this["flatten_" + name]) {
- this.empty_stores[name] =
- new dojo.data.ItemFileReadStore({
- "data": this["flatten_" + name]([])
- });
- this.widgets[name].setStore(this.empty_stores[name]);
- }
- }
-};
-Populator.prototype.flatten_ready = function(data) {
- return {
- "label": "id",
- "identifier": "id",
- "items": data.map(function(o) {
- return {
- "id": o.id(),
- "type": o.target_resource_type().name(),
- "resource": o.current_resource().barcode(),
- "start_time": humanize_timestamp_string(o.start_time()),
- "end_time": humanize_timestamp_string(o.end_time())
- };
- })
- };
-};
-Populator.prototype.flatten_out = function(data) {
- return {
- "label": "id",
- "identifier": "id",
- "items": data.map(function(o) {
- return {
- "id": o.id(),
- "type": o.target_resource_type().name(),
- "resource": o.current_resource().barcode(),
- "pickup_time": humanize_timestamp_string(o.pickup_time()),
- "end_time": humanize_timestamp_string(o.end_time())
- };
- })
- };
-};
-Populator.prototype.flatten_in = function(data) {
- return {
- "label": "id",
- "identifier": "id",
- "items": data.map(function(o) {
- return {
- "id": o.id(),
- "type": o.target_resource_type().name(),
- "resource": o.current_resource().barcode(),
- "due_time": humanize_timestamp_string(o.end_time()),
- "return_time": humanize_timestamp_string(o.return_time())
- };
- })
- };
-};
-Populator.prototype.reveal_container = function(widget) {
- var el = document.getElementById("contains_" + widget.id);
- if (el) reveal_dom_element(el);
-};
-Populator.prototype.hide_container = function(widget) {
- var el = document.getElementById("contains_" + widget.id);
- if (el) hide_dom_element(el);
-};
-Populator.prototype.populate_ready = function(data) {
- return this._populate_any_resv_grid(data, "ready");
-};
-Populator.prototype.populate_out = function(data) {
- return this._populate_any_resv_grid(data, "out");
-};
-Populator.prototype.populate_in = function(data) {
- return this._populate_any_resv_grid(data, "in");
-};
-Populator.prototype._populate_any_resv_grid = function(data, which) {
- var flattener = this["flatten_" + which];
- var widget = this.widgets[which];
- var cache = this.cache[which];
- var empty_store = this.empty_stores[which];
-
- this.reveal_container(widget);
-
- if (!data || !data.length) {
- widget.setStore(empty_store);
- this.toggle_anyness(false, which);
- } else {
- for (var i in data) cache[data[i].id()] = data[i];
-
- widget.setStore(
- new dojo.data.ItemFileReadStore({"data": flattener(data)})
- );
-
- this.toggle_anyness(true, which);
-
- /* Arrrgh! Horrid but necessary: */
- setTimeout(function() { widget.sort(); }, 100);
- }
-};
-Populator.prototype.populate_patron = function(data) {
- var h2 = document.createElement("h2");
- h2.setAttribute("class", "booking");
- h2.appendChild(document.createTextNode(formal_name(data)));
-
- this.widgets.patron.innerHTML = "";
- this.widgets.patron.appendChild(h2);
-
- this.reveal_container(this.widgets.patron);
- /* Maybe add patron's home OU or something here later... */
-};
-Populator.prototype.return_by_resource = function(barcode, override) {
- /* XXX instead of talking to the server every time we do this, we could
- * also check the "out" cache, iff we have one. */
- var r = fieldmapper.standardRequest(
- ["open-ils.booking",
- "open-ils.booking.reservations.by_returnable_resource_barcode"],
- [openils.User.authtoken, barcode]
- );
- if (!r || r.length < 1) {
- alert(localeStrings.NO_SUCH_RETURNABLE_RESOURCE);
- } else if (is_ils_event(r)) {
- alert(my_ils_error(localeStrings.RETURNABLE_RESOURCE_ERROR, r));
- } else {
- try {
- var new_barcode = r.usr().card().barcode();
- } catch (E) {
- alert(localeStrings.RETURN_ERROR + "\nr: " + js2JSON(r) + "\n" + E);
- return;
- }
- if (this.patron_barcode && this.patron_barcode != new_barcode) {
- /* XXX make this more subtle, i.e. flash something in background */
- alert(localeStrings.NOTICE_CHANGE_OF_PATRON);
- }
- this.patron_barcode = new_barcode;
- var ret = this.return(r, override);
- if (!ret) {
- alert(localeStrings.RETURN_NO_RESPONSE);
- } else if (is_ils_event(ret) && ret.textcode != "SUCCESS") {
- if (ret.textcode == "ROUTE_ITEM") {
- display_transit_slip(ret);
- } else if (ret.textcode == "COPY_ALERT_MESSAGE") {
- if (
- confirm(
- dojo.string.substitute(
- localeStrings.COPY_ALERT, [ret.desc, ret.payload]
- )
- )
- ) {
- this.return_by_resource(barcode, true /*override*/);
- return;
- }
- } else {
- alert(my_ils_error(localeStrings.RETURN_ERROR, ret));
- }
- } else {
- /* XXX speedbump should go, but something has to happen else
- * there's no indication to staff that anything happened when
- * starting from a fresh (blank) return interface.
- */
- alert(localeStrings.RETURN_SUCCESS);
- }
- this.populate(); /* Won't recurse with no args. All is well. */
- }
-};
-Populator.prototype.populate = function(barcode, which) {
- if (barcode) {
- if (barcode.patron) {
- this.patron_barcode = barcode.patron;
- }
- else if (barcode.resource) { /* resource OR patron, not both */
- if (!this.return_by_resource(barcode.resource))
- return;
- }
- }
- if (!this.patron_barcode) {
- alert(localeStrings.NO_PATRON_BARCODE);
- return;
- }
-
- if (!which) which = this.all;
-
- var result = fieldmapper.standardRequest(
- ["open-ils.booking", "open-ils.booking.reservations.get_captured"],
- [openils.User.authtoken, this.patron_barcode, which]
- );
-
- if (!result) {
- this.patron_barcode = undefined;
- alert(localeStrings.RESERVATIONS_NO_RESPONSE);
- } else if (is_ils_event(result)) {
- this.patron_barcode = undefined;
- alert(my_ils_error(localeStrings.RESERVATIONS_ERROR, result));
- } else {
- for (var k in result)
- this["populate_" + k](result[k]);
- }
-};
-Populator.prototype.toggle_anyness = function(any, which) {
- var widget = this.widgets[which].domNode;
- var empty_alternate = document.getElementById("no_" + widget.id);
- var controls = document.getElementById("controls_" + widget.id);
- if (any) {
- reveal_dom_element(widget);
- if (empty_alternate) hide_dom_element(empty_alternate);
- if (controls) reveal_dom_element(controls);
- } else {
- hide_dom_element(widget);
- if (empty_alternate) reveal_dom_element(empty_alternate);
- if (controls) hide_dom_element(controls);
- }
-};
-Populator.prototype.pickup = function(reservation) {
- return fieldmapper.standardRequest(
- ["open-ils.circ", "open-ils.circ.reservation.pickup"],
- [openils.User.authtoken, {
- "patron_barcode": this.patron_barcode,
- "reservation": reservation
- }]
- );
-};
-Populator.prototype.return = function(reservation, override) {
- var method = "open-ils.circ.reservation.return";
- if (override) method += ".override";
- return fieldmapper.standardRequest(
- ["open-ils.circ", method],
- [openils.User.authtoken, {
- "patron_barcode": this.patron_barcode,
- "reservation": reservation.id()
- /* yeah just id here ------^; lack of parallelism */
- }]
- );
-};
-Populator.prototype.act_on_selected = function(how, which) {
- var widget = this.widgets[which];
- var cache = this.cache[which];
- var no_response_msg = localeStrings[how.toUpperCase() + "_NO_RESPONSE"];
- var error_msg = localeStrings[how.toUpperCase() + "_ERROR"];
-
- var selected_id_list =
- widget.selection.getSelected().map(function(o) { return o.id[0]; });
-
- if (!selected_id_list || !selected_id_list.length) {
- alert(localeStrings.SELECT_SOMETHING);
- return;
- }
-
- var reservations = selected_id_list.map(function(o) { return cache[o]; });
-
- /* Do we have to process these one at a time? I think so... */
- var self = this;
- function looper(reservation, override) {
- if (looper._done) return;
- var result = self[how](reservation, override);
- if (!result) {
- alert(no_response_msg);
- } else if (is_ils_event(result) && result.textcode != "SUCCESS") {
- if (result.textcode == "ROUTE_ITEM") {
- display_transit_slip(result);
- } else if (result.textcode == "COPY_ALERT_MESSAGE") {
- if (confirm(
- dojo.string.substitute(
- localeStrings.COPY_ALERT, [result.desc, result.payload]
- )
- )) {
- looper(reservation, true);
- }
- return; // continues processing other resvs
- } else {
- alert(my_ils_error(error_msg, result));
- }
- } else {
- return;
- }
- looper._done = true;
- }
- dojo.forEach(reservations, looper);
-
- this.populate();
-};
-Populator.prototype.reset = function() {
- for (var k in this.widgets) {
- this.hide_container(this.widgets[k]);
- }
- this.patron_barcode = undefined;
-
- if (typeof(this._extra_resetting) == "function")
- this._extra_resetting();
-
- if (this.primary_input) {
- this.primary_input.value = "";
- this.primary_input.focus();
- }
-};
-
-/* XXX needs to be combined with the code that shows transit slips in the
- * booking capture interface. */
-function display_transit_slip(e) {
- var ou = fieldmapper.aou.findOrgUnit(e.org, /* slim_ok */false);
- var ma = (new openils.PermaCrud()).retrieve("aoa", ou.mailing_address());
- var mas = ma ?
- dojo.string.substitute(
- localeStrings.ADDRESS,
- [ma.street1(),ma.street2(),ma.city(),ma.state(),ma.post_code()].map(
- function(o) { return o ? o : ""; }
- )
- ).replace("\n\n", "\n").replace("\n", "<br />") : "[Unknown address]";
- /* XXX i18n and/or template */
- try {
- var win = window.open(
- "","","resizeable,width=600,height=400,scrollbars=1"
- );
- win.document.body.innerHTML =
- "<h1>Transit Slip</h1>\n" +
- //"<img src='/xul/server/skin/media/images/turtle.gif' />\n" +
- "<p>Destination: <strong>" + ou.name() + "</strong></p>\n" +
- "<p>" + mas + "</p>\n" +
- "<p>Barcode: " + e.payload.copy.barcode() + "<br />\n" +
- "Title: <span id='title'></span><br />\n" +
- "Author: <span id='author'></span><br />\n" +
- "Slip Date: " +
- dojo.date.locale.format(new Date(), {"formatLength": "short"}) +
- "</p>";
- fieldmapper.standardRequest(
- ["open-ils.search", "open-ils.search.biblio.mods_from_copy"], {
- "params": [e.payload.copy.id()],
- "async": true,
- "onresponse": function(r) {
- var mvr = openils.Util.readResponse(r);
- dojo.byId("title", win.document).innerHTML = mvr.title();
- dojo.byId("author", win.document).innerHTML = mvr.author();
- },
- "oncomplete": function() {
- win[confirm("Print transit slip?") ? "print" : "close"]();
- }
- }
- );
- } catch (E) {
- alert("exception rendering transit slip: " + E); // XXX
- }
-}
+});
\ No newline at end of file
-dojo.require("openils.User");
-dojo.require("openils.PermaCrud");
-dojo.require("fieldmapper.OrgUtils");
-dojo.require("openils.widget.OrgUnitFilteringSelect");
-dojo.requireLocalization("openils.booking", "pull_list");
-
-var localeStrings = dojo.i18n.getLocalization("openils.booking", "pull_list");
-var pcrud = new openils.PermaCrud();
-
-var owning_lib_selected;
-var acp_cache = {};
-
-function init_owning_lib_selector() {
- var User = new openils.User();
- User.buildPermOrgSelector(
- "RETRIEVE_RESERVATION_PULL_LIST", owning_lib_selector, null,
- function() {
- owning_lib_selected = owning_lib_selector.getValue();
- dojo.connect(owning_lib_selector, "onChange",
- function() { owning_lib_selected = this.getValue(); }
- )
- }
- );
-}
-
-function retrieve_pull_list(ivl_in_days) {
- var secs = Number(ivl_in_days) * 86400;
-
- if (isNaN(secs) || secs < 1)
- throw new Error("Invalid interval");
-
- return fieldmapper.standardRequest(
- ["open-ils.booking", "open-ils.booking.reservations.get_pull_list"],
- [openils.User.authtoken, null, secs, owning_lib_selected]
- );
-}
-
-function dom_table_rowid(resource_id) {
- return "pull_list_resource_" + resource_id;
-}
-
-function generate_result_row(one) {
- function cell(id, content) {
- var td = document.createElement("td");
- if (id != undefined) td.setAttribute("id", id);
- td.appendChild(document.createTextNode(content));
- return td;
- }
-
- function render_pickup_lib(pickup_lib) {
- var span = document.createElement("span");
- if (pickup_lib != owning_lib_selected)
- span.setAttribute("class", "pull_list_will_transit");
- span.innerHTML = localeStrings.AT + " " +
- fieldmapper.aou.findOrgUnit(pickup_lib).shortname();
- return span;
- }
-
- function reservation_info_cell(one) {
- var td = document.createElement("td");
- for (var i in one.reservations) {
- var one_resv = one.reservations[i];
- var div = document.createElement("div");
- div.setAttribute("class", "pull_list_resv_detail");
- var content = [
- document.createTextNode(
- humanize_timestamp_string(one_resv.start_time()) +
- " - " + humanize_timestamp_string(one_resv.end_time())
- ),
- document.createElement("br"),
- render_pickup_lib(one_resv.pickup_lib()),
- document.createTextNode(
- " " + localeStrings.FOR + " " + formal_name(one_resv.usr())
- )
- ];
- for (var k in content) { div.appendChild(content[k]); }
- td.appendChild(div);
- }
- return td;
- }
-
- var baseid = dom_table_rowid(one.current_resource.id());
-
- var cells = [];
- cells.push(cell(undefined, one.target_resource_type.name()));
- cells.push(cell(undefined, one.current_resource.barcode()));
- cells.push(cell(baseid + "_call_number", "-"));
- cells.push(cell(baseid + "_copy_location", "-"));
- cells.push(reservation_info_cell(one));
-
- var row = document.createElement("tr");
- row.setAttribute("id", baseid);
-
- for (var i in cells) row.appendChild(cells[i]);
- return row;
-}
-
-function render_pull_list_fundamentals(list) {
- var rows = [];
-
- for (var i in list)
- rows.push(generate_result_row(list[i]));
-
- document.getElementById("the_table_body").innerHTML = "";
-
- for (var i in rows)
- document.getElementById("the_table_body").appendChild(rows[i]);
-}
-
-function get_all_relevant_acp(list) {
- var barcodes = [];
- for (var i in list) {
- if (list[i].target_resource_type.catalog_item()) {
- /* There shouldn't be any duplicates. No need to worry bout that */
- barcodes.push(list[i].current_resource.barcode());
- }
- }
- if (barcodes.length > 0) {
- var results = fieldmapper.standardRequest(
- [
- "open-ils.booking",
- "open-ils.booking.asset.get_copy_fleshed_just_right"
- ],
- [openils.User.authtoken, barcodes]
- );
-
- if (!results) {
- alert(localeStrings.COPY_LOOKUP_NO_RESPONSE);
- return null;
- } else if (is_ils_event(results)) {
- alert(my_ils_error(localeStrings.COPY_LOOKUP_ERROR, results));
- return null;
- } else {
- return results;
- }
- }
- return null;
-}
-
-function fill_in_pull_list_details(list, acp_cache) {
- for (var i in list) {
- var one = list[i];
- if (one.target_resource_type.catalog_item() == "t") {
- /* FIXME: This block could stand to be a lot more elegant. */
- var call_number_el = document.getElementById(
- dom_table_rowid(one.current_resource.id()) + "_call_number"
- );
- var copy_location_el = document.getElementById(
- dom_table_rowid(one.current_resource.id()) + "_copy_location"
- );
- var bc = one.current_resource.barcode();
-
- if (acp_cache[bc]) {
- if (call_number_el && acp_cache[bc].call_number()) {
- var value = acp_cache[bc].call_number().label();
- if (value) call_number_el.innerHTML = value;
- }
- if (copy_location_el && acp_cache[bc].location()) {
- var value = acp_cache[bc].location().name();
- if (value) copy_location_el.innerHTML = value;
- }
- } else {
- alert(localeStrings.COPY_MISSING + bc);
- }
- }
- }
-}
-
-function populate_pull_list(form) {
- /* Step 1: get the pull list from the server. */
- try {
- var results = retrieve_pull_list(form.interval_in_days.value);
- } catch (E) {
- alert(localeStrings.PULL_LIST_ERROR + E);
- return;
- }
- if (results == null) {
- alert(localeStrings.PULL_LIST_NO_RESPONSE);
- return;
- } else if (is_ils_event(results)) {
- alert(my_ils_error(localeStrings.PULL_LIST_ERROR, results));
- return;
- }
-
- if (results.length) {
- reveal_dom_element(document.getElementById("table_goes_here"));
- hide_dom_element(document.getElementById("no_results"));
-
- /* Step 2: render the table with the pull list */
- render_pull_list_fundamentals(results);
-
- /* Step 3: asynchronously fill in the copy details we're missing */
- setTimeout(function() {
- var acp_cache = {};
- if ((acp_cache = get_all_relevant_acp(results)))
- fill_in_pull_list_details(results, acp_cache);
- }, 0);
- } else {
- hide_dom_element(document.getElementById("table_goes_here"));
- reveal_dom_element(document.getElementById("no_results"));
- }
-
-}
-
-function my_init() {
- hide_dom_element(document.getElementById("table_goes_here"));
- hide_dom_element(document.getElementById("no_results"));
- init_owning_lib_selector();
- init_auto_l10n(document.getElementById("auto_l10n_start_here"));
-}
+require([
+ "openils/User",
+ "openils/PermaCrud",
+ "fieldmapper/OrgUtils",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(openils_User,
+ openils_PermaCrud,
+ fieldmapper_OrgUtils,
+ openils_widget_OrgUnitFilteringSelect){
+ dojo.requireLocalization("openils.booking", "pull_list");
+
+ var localeStrings = dojo.i18n.getLocalization("openils.booking", "pull_list");
+ var pcrud = new openils_PermaCrud();
+
+ var owning_lib_selected;
+ var acp_cache = {};
+
+ function init_owning_lib_selector() {
+ var User = new openils_User();
+ User.buildPermOrgSelector(
+ "RETRIEVE_RESERVATION_PULL_LIST", owning_lib_selector, null,
+ function() {
+ owning_lib_selected = owning_lib_selector.getValue();
+ dojo.connect(owning_lib_selector, "onChange",
+ function() { owning_lib_selected = this.getValue(); }
+ )
+ }
+ );
+ }
+
+ function retrieve_pull_list(ivl_in_days) {
+ var secs = Number(ivl_in_days) * 86400;
+
+ if (isNaN(secs) || secs < 1)
+ throw new Error("Invalid interval");
+
+ return fieldmapper.standardRequest(
+ ["open-ils.booking", "open-ils.booking.reservations.get_pull_list"],
+ [openils_User.authtoken, null, secs, owning_lib_selected]
+ );
+ }
+
+ function dom_table_rowid(resource_id) {
+ return "pull_list_resource_" + resource_id;
+ }
+
+ function generate_result_row(one) {
+ function cell(id, content) {
+ var td = document.createElement("td");
+ if (id != undefined) td.setAttribute("id", id);
+ td.appendChild(document.createTextNode(content));
+ return td;
+ }
+
+ function render_pickup_lib(pickup_lib) {
+ var span = document.createElement("span");
+ if (pickup_lib != owning_lib_selected)
+ span.setAttribute("class", "pull_list_will_transit");
+ span.innerHTML = localeStrings.AT + " " +
+ fieldmapper.aou.findOrgUnit(pickup_lib).shortname();
+ return span;
+ }
+
+ function reservation_info_cell(one) {
+ var td = document.createElement("td");
+ for (var i in one.reservations) {
+ var one_resv = one.reservations[i];
+ var div = document.createElement("div");
+ div.setAttribute("class", "pull_list_resv_detail");
+ var content = [
+ document.createTextNode(
+ humanize_timestamp_string(one_resv.start_time()) +
+ " - " + humanize_timestamp_string(one_resv.end_time())
+ ),
+ document.createElement("br"),
+ render_pickup_lib(one_resv.pickup_lib()),
+ document.createTextNode(
+ " " + localeStrings.FOR + " " + formal_name(one_resv.usr())
+ )
+ ];
+ for (var k in content) { div.appendChild(content[k]); }
+ td.appendChild(div);
+ }
+ return td;
+ }
+
+ var baseid = dom_table_rowid(one.current_resource.id());
+
+ var cells = [];
+ cells.push(cell(undefined, one.target_resource_type.name()));
+ cells.push(cell(undefined, one.current_resource.barcode()));
+ cells.push(cell(baseid + "_call_number", "-"));
+ cells.push(cell(baseid + "_copy_location", "-"));
+ cells.push(reservation_info_cell(one));
+
+ var row = document.createElement("tr");
+ row.setAttribute("id", baseid);
+
+ for (var i in cells) row.appendChild(cells[i]);
+ return row;
+ }
+
+ function render_pull_list_fundamentals(list) {
+ var rows = [];
+
+ for (var i in list)
+ rows.push(generate_result_row(list[i]));
+
+ document.getElementById("the_table_body").innerHTML = "";
+
+ for (var i in rows)
+ document.getElementById("the_table_body").appendChild(rows[i]);
+ }
+
+ function get_all_relevant_acp(list) {
+ var barcodes = [];
+ for (var i in list) {
+ if (list[i].target_resource_type.catalog_item()) {
+ /* There shouldn't be any duplicates. No need to worry bout that */
+ barcodes.push(list[i].current_resource.barcode());
+ }
+ }
+ if (barcodes.length > 0) {
+ var results = fieldmapper.standardRequest(
+ [
+ "open-ils.booking",
+ "open-ils.booking.asset.get_copy_fleshed_just_right"
+ ],
+ [openils_User.authtoken, barcodes]
+ );
+
+ if (!results) {
+ alert(localeStrings.COPY_LOOKUP_NO_RESPONSE);
+ return null;
+ } else if (is_ils_event(results)) {
+ alert(my_ils_error(localeStrings.COPY_LOOKUP_ERROR, results));
+ return null;
+ } else {
+ return results;
+ }
+ }
+ return null;
+ }
+
+ function fill_in_pull_list_details(list, acp_cache) {
+ for (var i in list) {
+ var one = list[i];
+ if (one.target_resource_type.catalog_item() == "t") {
+ /* FIXME: This block could stand to be a lot more elegant. */
+ var call_number_el = document.getElementById(
+ dom_table_rowid(one.current_resource.id()) + "_call_number"
+ );
+ var copy_location_el = document.getElementById(
+ dom_table_rowid(one.current_resource.id()) + "_copy_location"
+ );
+ var bc = one.current_resource.barcode();
+
+ if (acp_cache[bc]) {
+ if (call_number_el && acp_cache[bc].call_number()) {
+ var value = acp_cache[bc].call_number().label();
+ if (value) call_number_el.innerHTML = value;
+ }
+ if (copy_location_el && acp_cache[bc].location()) {
+ var value = acp_cache[bc].location().name();
+ if (value) copy_location_el.innerHTML = value;
+ }
+ } else {
+ alert(localeStrings.COPY_MISSING + bc);
+ }
+ }
+ }
+ }
+
+ function populate_pull_list(form) {
+ /* Step 1: get the pull list from the server. */
+ try {
+ var results = retrieve_pull_list(form.interval_in_days.value);
+ } catch (E) {
+ alert(localeStrings.PULL_LIST_ERROR + E);
+ return;
+ }
+ if (results == null) {
+ alert(localeStrings.PULL_LIST_NO_RESPONSE);
+ return;
+ } else if (is_ils_event(results)) {
+ alert(my_ils_error(localeStrings.PULL_LIST_ERROR, results));
+ return;
+ }
+
+ if (results.length) {
+ reveal_dom_element(document.getElementById("table_goes_here"));
+ hide_dom_element(document.getElementById("no_results"));
+
+ /* Step 2: render the table with the pull list */
+ render_pull_list_fundamentals(results);
+
+ /* Step 3: asynchronously fill in the copy details we're missing */
+ setTimeout(function() {
+ var acp_cache = {};
+ if ((acp_cache = get_all_relevant_acp(results)))
+ fill_in_pull_list_details(results, acp_cache);
+ }, 0);
+ } else {
+ hide_dom_element(document.getElementById("table_goes_here"));
+ reveal_dom_element(document.getElementById("no_results"));
+ }
+
+ }
+
+ function my_init() {
+ hide_dom_element(document.getElementById("table_goes_here"));
+ hide_dom_element(document.getElementById("no_results"));
+ init_owning_lib_selector();
+ init_auto_l10n(document.getElementById("auto_l10n_start_here"));
+ }
+
+
+});
\ No newline at end of file
-/*
- * Details, details...
- */
-dojo.require("fieldmapper.OrgUtils");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.User");
-dojo.require("openils.widget.OrgUnitFilteringSelect");
-dojo.require("dojo.data.ItemFileReadStore");
-dojo.require("dijit.form.DateTextBox");
-dojo.require("dijit.form.TimeTextBox");
-dojo.require("dojo.date.stamp");
-dojo.requireLocalization("openils.booking", "reservation");
-
-/*
- * Globals; prototypes and their instances
- */
-var localeStrings = dojo.i18n.getLocalization("openils.booking", "reservation");
-var pcrud = new openils.PermaCrud();
-var opts;
-var our_brt;
-var pickup_lib_selected;
-var brt_list = [];
-var brsrc_index = {};
-var bresv_index = {};
-var just_reserved_now = {};
-var aous_cache = {};
-
-function AttrValueTable() { this.t = {}; }
-AttrValueTable.prototype.set = function(attr, value) { this.t[attr] = value; };
-AttrValueTable.prototype.update_from_selector = function(selector) {
- var attr = selector.name.match(/_(\d+)$/)[1];
- var value = selector.options[selector.selectedIndex].value;
- if (attr)
- attr_value_table.set(attr, value);
-};
-AttrValueTable.prototype.get_all_values = function() {
- var values = [];
- for (var k in this.t) {
- if (this.t[k] != undefined && this.t[k] != "")
- values.push(this.t[k]);
- }
- return values;
-};
-var attr_value_table = new AttrValueTable();
-
-function TimestampRange() {
- this.start = new Date();
- this.end = new Date();
-
- this.validity = {"start": false, "end": false};
- this.nodes = {
- "start": {"date": undefined, "time": undefined},
- "end": {"date": undefined, "time": undefined}
- };
- this.saved_style_properties = {};
- this.invalid_style_properties = {
- "backgroundColor": "#ffcccc",
- "color": "#990000",
- "borderColor": "#990000",
- "fontWeight": "bold"
- };
-}
-TimestampRange.prototype.get_timestamp = function(when) {
- return dojo.date.stamp.toISOString(this[when]).
- replace("T", " ").substr(0, 19);
-};
-TimestampRange.prototype.get_range = function() {
- return this.is_backwards() ?
- [this.get_timestamp("end"), this.get_timestamp("start")] :
- [this.get_timestamp("start"), this.get_timestamp("end")];
-};
-TimestampRange.prototype.update_from_widget = function(widget) {
- var when = widget.name.match(/(start|end)/)[1];
- var which = widget.name.match(/(date|time)/)[1];
-
- if (this.nodes[when][which] == undefined)
- this.nodes[when][which] = widget.domNode; /* We'll need this later */
-
- if (when && which) {
- this.update_timestamp(when, which, widget.attr("value"));
- }
-
- this.compute_validity();
- this.paint_validity();
-};
-TimestampRange.prototype.compute_validity = function() {
- if (Math.abs(this.start - this.end) < 1000) {
- this.validity.end = false;
- } else {
- if (this.start < this.current_minimum())
- this.validity.start = false;
- else
- this.validity.start = true;
-
- if (this.end < this.current_minimum())
- this.validity.end = false;
- else
- this.validity.end = true;
- }
-};
-/* This method provides the minimum timestamp that is considered valid. For
- * now it's arbitrarily "now + 15 minutes", meaning that all reservations
- * must be made at least 15 minutes in the future.
- *
- * For reasons of keeping the middle layer happy, this should always return
- * a time that is at least somewhat in the future. The ML isn't able to target
- * any resources for a reservation with a start date that isn't in the future.
- */
-TimestampRange.prototype.current_minimum = function() {
- /* XXX This is going to be a problem with local clocks that are off. */
- var n = new Date();
- n.setTime(n.getTime() + 1000 * 900); /* XXX 15 minutes; stop hardcoding! */
- return n;
-};
-TimestampRange.prototype.update_timestamp = function(when, which, value) {
- if (which == "date") {
- this[when].setFullYear(value.getFullYear());
- /* month and date MUST be done together */
- this[when].setMonth(value.getMonth(), value.getDate());
- } else { /* "time" */
- this[when].setHours(value.getHours());
- this[when].setMinutes(value.getMinutes());
- this[when].setSeconds(0);
- }
-};
-TimestampRange.prototype.is_backwards = function() {
- return (this.start > this.end);
-};
-TimestampRange.prototype.paint_validity = function() {
- for (var when in this.validity) {
- if (this.validity[when]) {
- this.paint_valid_node(this.nodes[when].date);
- this.paint_valid_node(this.nodes[when].time);
- } else {
- this.paint_invalid_node(this.nodes[when].date);
- this.paint_invalid_node(this.nodes[when].time);
- }
- }
-};
-TimestampRange.prototype.paint_invalid_node = function(node) {
- if (node) {
- /* Just toggling the class of something would be better than
- * manually setting style here, but I haven't been able to get that
- * to play nicely with dojo's styling of the date/time textboxen.
- */
- if (this.saved_style_properties.backgroundColor == undefined) {
- for (var k in this.invalid_style_properties) {
- this.saved_style_properties[k] = node.style[k];
- }
- }
- for (var k in this.invalid_style_properties) {
- node.style[k] = this.invalid_style_properties[k];
- }
- }
-};
-TimestampRange.prototype.paint_valid_node = function(node) {
- if (node) {
- for (var k in this.saved_style_properties) {
- node.style[k] = this.saved_style_properties[k];
- }
- }
-};
-TimestampRange.prototype.is_valid = function() {
- return (this.validity.start && this.validity.end);
-};
-var reserve_timestamp_range = new TimestampRange();
-
-function SelectorMemory(selector) {
- this.selector = selector;
- this.memory = {};
-}
-SelectorMemory.prototype.save = function() {
- for (var i = 0; i < this.selector.options.length; i++) {
- if (this.selector.options[i].selected) {
- this.memory[this.selector.options[i].value] = true;
- }
- }
-};
-SelectorMemory.prototype.restore = function() {
- for (var i = 0; i < this.selector.options.length; i++) {
- if (this.memory[this.selector.options[i].value]) {
- if (!this.selector.options[i].disabled)
- this.selector.options[i].selected = true;
- }
- }
-};
-
-/*
- * These functions communicate with the middle layer.
- */
-function get_all_noncat_brt() {
- return pcrud.search("brt",
- {"id": {"!=": null}, "catalog_item": "f"},
- {"order_by": {"brt":"name"}}
- );
-}
-
-function get_brt_by_id(id) {
- return pcrud.retrieve("brt", id);
-}
-
-function get_brsrc_id_list() {
- var options = {"type": our_brt.id(), "pickup_lib": pickup_lib_selected};
-
- /* This mechanism for avoiding the passing of an empty 'attribute_values'
- * option is essential because if you pass such an option to the
- * middle layer API at all, it won't return any IDs for brsrcs that
- * don't have at least one attribute of some kind.
- */
- var attribute_values = attr_value_table.get_all_values();
- if (attribute_values.length > 0)
- options.attribute_values = attribute_values;
-
- options.available = reserve_timestamp_range.get_range();
-
- return fieldmapper.standardRequest(
- ["open-ils.booking", "open-ils.booking.resources.filtered_id_list"],
- [openils.User.authtoken, options]
- );
-}
-
-/* FIXME: We need failure checking after pcrud.retrieve() */
-function add_brsrc_to_index_if_needed(list, further) {
- for (var i in list) {
- if (!brsrc_index[list[i]]) {
- brsrc_index[list[i]] = pcrud.retrieve("brsrc", list[i]);
- }
- if (further)
- further(brsrc_index[list[i]]);
- }
-}
-
-function sync_brsrc_index_from_ids(available_list, additional_list) {
- /* Default states for everything in the index. Read the further comments. */
- for (var i in brsrc_index) {
- brsrc_index[i].isdeleted(true);
- brsrc_index[i].ischanged(false);
- }
-
- /* Populate the cache with anything that's missing and tag everything
- * in the "available" list as *not* deleted, and tag everything in the
- * additional list as "changed." See below. */
- add_brsrc_to_index_if_needed(
- available_list, function(o) { o.isdeleted(false); }
- );
- add_brsrc_to_index_if_needed(
- additional_list,
- function(o) {
- if (!(o.id() in just_reserved_now)) o.ischanged(true);
- }
- );
- /* NOTE: We lightly abuse the isdeleted() and ischanged() magic fieldmapper
- * attributes of the brsrcs in our cache. Because we're not going to
- * pass back any brsrcs to the middle layer, it doesn't really matter
- * what we set this attribute to. What we're using it for is to indicate
- * in our little brsrc cache how a given brsrc should be displayed in this
- * UI's current state (based on whether the brsrc matches timestamp range
- * availability (isdeleted(false)) and whether the brsrc has been forced
- * into the list because it was selected in a previous interface (like
- * the catalog) (ischanged(true))).
- */
-}
-
-function check_bresv_targeting(results) {
- var missing = 0;
- var due_dates = [];
- for (var i in results) {
- var targ = results[i].targeting;
- if (!(targ && targ.current_resource)) {
- missing++;
- if (targ) {
- if (targ.error == "NO_COPIES" && targ.conflicts) {
- for (var k in targ.conflicts) {
- /* Could potentially get more circ information from
- * targ.conflicts for display in the future. */
- due_dates.push(humanize_timestamp_string2(targ.conflicts[k].due_date()));
- }
- }
- }
- } else {
- just_reserved_now[results[i].targeting.current_resource] = true;
- }
- }
- return {"missing": missing, "due_dates": due_dates};
-}
-
-function create_bresv(resource_list) {
- var barcode = document.getElementById("patron_barcode").value;
- if (barcode == "") {
- alert(localeStrings.WHERES_THE_BARCODE);
- return;
- } else if (!reserve_timestamp_range.is_valid()) {
- alert(localeStrings.INVALID_TS_RANGE);
- return;
- }
- var email_notify = document.getElementById("email_notify").checked ? true : false;
- var results;
- try {
- results = fieldmapper.standardRequest(
- ["open-ils.booking", "open-ils.booking.reservations.create"],
- [
- openils.User.authtoken,
- barcode,
- reserve_timestamp_range.get_range(),
- pickup_lib_selected,
- our_brt.id(),
- resource_list,
- attr_value_table.get_all_values(),
- email_notify
- ]
- );
- } catch (E) {
- alert(localeStrings.CREATE_BRESV_LOCAL_ERROR + E);
- }
- if (results) {
- if (is_ils_event(results)) {
- if (is_ils_actor_card_error(results)) {
- alert(localeStrings.ACTOR_CARD_NOT_FOUND);
- } else {
- alert(my_ils_error(
- localeStrings.CREATE_BRESV_SERVER_ERROR, results
- ));
- }
- } else {
- var targeting = check_bresv_targeting(results);
- if (targeting.missing) {
- if (aous_cache["booking.require_successful_targeting"]) {
- alert(
- dojo.string.substitute(
- localeStrings.CREATE_BRESV_OK_MISSING_TARGET,
- [results.length, targeting.missing]
- ) + "\n\n" +
- dojo.string.substitute(
- localeStrings.CREATE_BRESV_OK_MISSING_TARGET_BLOCKED_BY_CIRC,
- [targeting.due_dates]
- ) + "\n\n" +
- localeStrings.CREATE_BRESV_OK_MISSING_TARGET_WILL_CANCEL
- );
- cancel_reservations(
- results.map(
- function(o) { return o.bresv; },
- true /* skip_update */
- )
- );
- } else {
- alert(
- dojo.string.substitute(
- localeStrings.CREATE_BRESV_OK_MISSING_TARGET,
- [results.length, targeting.missing]
- ) + "\n\n" +
- dojo.string.substitute(
- localeStrings.CREATE_BRESV_OK_MISSING_TARGET_BLOCKED_BY_CIRC,
- [targeting.due_dates]
- )
- );
- }
- } else {
- alert(
- dojo.string.substitute(
- localeStrings.CREATE_BRESV_OK, [results.length]
- )
- );
- }
- update_brsrc_list();
- update_bresv_grid();
- }
- } else {
- alert(localeStrings.CREATE_BRESV_SERVER_NO_RESPONSE);
- }
-}
-
-function flatten_to_dojo_data(obj_list) {
- return {
- "label": "id",
- "identifier": "id",
- "items": obj_list.map(function(o) {
- var new_obj = {
- "id": o.id(),
- "type": o.target_resource_type().name(),
- "start_time": humanize_timestamp_string(o.start_time()),
- "end_time": humanize_timestamp_string(o.end_time())
- };
-
- if (o.current_resource())
- new_obj["resource"] = o.current_resource().barcode();
- else if (o.target_resource())
- new_obj["resource"] = "* " + o.target_resource().barcode();
- else
- new_obj["resource"] = "* " + localeStrings.UNTARGETED + " *";
- return new_obj;
- })
- };
-}
-
-function create_bresv_on_brsrc() {
- var selector = document.getElementById("brsrc_list");
- var selected_values = [];
- for (var i in selector.options) {
- if (selector.options[i] && selector.options[i].selected)
- selected_values.push(selector.options[i].value);
- }
- if (selected_values.length > 0)
- create_bresv(selected_values);
- else
- alert(localeStrings.SELECT_A_BRSRC_THEN);
-}
-
-function create_bresv_on_brt() {
- if (any_usable_brsrc())
- create_bresv();
- else
- alert(localeStrings.NO_USABLE_BRSRC);
-}
-
-function get_actor_by_barcode(barcode) {
- var usr = fieldmapper.standardRequest(
- ["open-ils.actor", "open-ils.actor.user.fleshed.retrieve_by_barcode"],
- [openils.User.authtoken, barcode]
- );
- if (usr == null) {
- alert(localeStrings.GET_PATRON_NO_RESULT);
- } else if (is_ils_event(usr)) {
- return null; /* XXX inelegant: this function is quiet about errors
- here because to report them would be redundant with
- another function that gets called right after this one.
- */
- } else {
- return usr;
- }
-}
-
-function init_bresv_grid(barcode) {
- var result = fieldmapper.standardRequest(
- ["open-ils.booking",
- "open-ils.booking.reservations.filtered_id_list"
- ],
- [openils.User.authtoken, {
- "user_barcode": barcode,
- "fields": {
- "pickup_time": null,
- "cancel_time": null,
- "return_time": null
- }
- }, /* whole_obj */ true]
- );
- if (result == null) {
- set_datagrid_empty_store(bresvGrid, flatten_to_dojo_data);
- alert(localeStrings.GET_BRESV_LIST_NO_RESULT);
- } else if (is_ils_event(result)) {
- set_datagrid_empty_store(bresvGrid, flatten_to_dojo_data);
- if (is_ils_actor_card_error(result)) {
- alert(localeStrings.ACTOR_CARD_NOT_FOUND);
- } else {
- alert(my_ils_error(localeStrings.GET_BRESV_LIST_ERR, result));
- }
- } else {
- if (result.length < 1) {
- document.getElementById("bresv_grid_alt_explanation").innerHTML =
- localeStrings.NO_EXISTING_BRESV;
- hide_dom_element(document.getElementById("bresv_grid"));
- reveal_dom_element(document.getElementById("reserve_under"));
- } else {
- document.getElementById("bresv_grid_alt_explanation").innerHTML =
- "";
- reveal_dom_element(document.getElementById("bresv_grid"));
- reveal_dom_element(document.getElementById("reserve_under"));
- }
- /* May as well do the following in either case... */
- bresvGrid.setStore(
- new dojo.data.ItemFileReadStore(
- {"data": flatten_to_dojo_data(result)}
- )
- );
- bresv_index = {};
- for (var i in result) {
- bresv_index[result[i].id()] = result[i];
- }
- }
-}
-
-function cancel_reservations(bresv_id_list, skip_update) {
- try {
- var result = fieldmapper.standardRequest(
- ["open-ils.booking", "open-ils.booking.reservations.cancel"],
- [openils.User.authtoken, bresv_id_list]
- );
- } catch (E) {
- alert(localeStrings.CXL_BRESV_FAILURE2 + E);
- return;
- }
- if (!skip_update) setTimeout(update_bresv_grid, 0);
- if (!result) {
- alert(localeStrings.CXL_BRESV_FAILURE);
- } else if (is_ils_event(result)) {
- alert(my_ils_error(localeStrings.CXL_BRESV_FAILURE2, result));
- } else {
- alert(
- dojo.string.substitute(
- localeStrings.CXL_BRESV_SUCCESS, [result.length]
- )
- );
- }
-}
-
-function munge_specific_resource(barcode) {
- try {
- var copy_list = pcrud.search(
- "acp", {"barcode": barcode, "deleted": "f"}
- );
- if (copy_list && copy_list.length > 0) {
- var r = fieldmapper.standardRequest(
- ["open-ils.booking",
- "open-ils.booking.resources.create_from_copies"],
- [openils.User.authtoken,
- copy_list.map(function(o) { return o.id(); })]
- );
-
- if (!r) {
- alert(localeStrings.ON_FLY_NO_RESPONSE);
- } else if (is_ils_event(r)) {
- alert(my_ils_error(localeStrings.ON_FLY_ERROR, r));
- } else {
- if (!(our_brt = get_brt_by_id(r.brt[0][0]))) {
- alert(localeStrings.COULD_NOT_RETRIEVE_BRT_PASSED_IN);
- } else {
- opts.booking_results = r;
- init_reservation_interface();
- }
- }
- } else {
- alert(localeStrings.BRSRC_NOT_FOUND);
- }
- } catch (E) {
- alert(localeStrings.BRSRC_RETRIEVE_ERROR + E);
- }
-}
-
-/*
- * These functions deal with interface tricks (populating widgets,
- * changing the page, etc.).
- */
-function init_pickup_lib_selector() {
- var User = new openils.User();
- User.buildPermOrgSelector(
- "ADMIN_BOOKING_RESERVATION", pickup_lib_selector, null,
- function() {
- pickup_lib_selected = pickup_lib_selector.getValue();
- dojo.connect(pickup_lib_selector, "onChange",
- function() {
- pickup_lib_selected = this.getValue();
- update_brsrc_list();
- }
- )
- }
- );
-}
-
-function provide_brt_selector(targ_div) {
- if (!targ_div) {
- alert(localeStrings.NO_TARG_DIV);
- } else {
- brt_list = get_all_noncat_brt();
- if (!brt_list || brt_list.length < 1) {
- document.getElementById("select_noncat_brt_block").
- style.display = "none";
- } else {
- var selector = document.createElement("select");
- selector.setAttribute("id", "brt_selector");
- selector.setAttribute("name", "brt_selector");
- /* I'm reluctantly hardcoding this "size" attribute as 8
- * because you can't accomplish this with CSS anyway.
- */
- selector.setAttribute("size", 8);
- for (var i in brt_list) {
- var option = document.createElement("option");
- option.setAttribute("value", brt_list[i].id());
- option.appendChild(document.createTextNode(brt_list[i].name()));
- selector.appendChild(option);
- }
- targ_div.innerHTML = "";
- targ_div.appendChild(selector);
- }
- }
-}
-
-function init_resv_iface_arb() {
- init_reservation_interface(document.getElementById("arbitrary_resource"));
-}
-
-function init_resv_iface_sel() {
- init_reservation_interface(document.getElementById("brt_selector"));
-}
-
-function init_reservation_interface(widget) {
- /* Show or hide the email notification checkbox depending on org unit setting. */
- if (!aous_cache["booking.allow_email_notify"]) {
- hide_dom_element(document.getElementById("contain_email_notify"));
- }
- /* Save a global reference to the brt we're going to reserve */
- if (widget && (widget.selectedIndex != undefined)) {
- our_brt = brt_list[widget.selectedIndex];
- } else if (widget != undefined) {
- if (!munge_specific_resource(widget.value))
- return;
- }
-
- /* Hide and reveal relevant divs. */
- var search_block = document.getElementById("brt_search_block");
- var reserve_block = document.getElementById("brt_reserve_block");
- hide_dom_element(search_block);
- reveal_dom_element(reserve_block);
-
- /* Get a list of attributes that can apply to that brt. */
- var bra_list = pcrud.search("bra", {"resource_type": our_brt.id()});
- if (!bra_list) {
- alert(localeString.NO_BRA_LIST);
- return;
- }
-
- /* Get a table of values that can apply to the above attributes. */
- var brav_by_bra = {};
- bra_list.map(function(o) {
- brav_by_bra[o.id()] = pcrud.search("brav", {"attr": o.id()});
- });
-
- /* Hide the label over the attributes widgets if we have nothing to show. */
- var domf = (bra_list.length < 1) ? hide_dom_element : reveal_dom_element;
- domf(document.getElementById("bra_and_brav_header"));
-
- /* Create DOM widgets to represent each attribute/values set. */
- for (var i in bra_list) {
- var bra_div = document.createElement("div");
- bra_div.setAttribute("class", "nice_vertical_padding");
-
- var bra_select = document.createElement("select");
- bra_select.setAttribute("name", "bra_" + bra_list[i].id());
- bra_select.setAttribute(
- "onchange",
- "attr_value_table.update_from_selector(this); update_brsrc_list();"
- );
-
- var bra_opt_any = document.createElement("option");
- bra_opt_any.appendChild(document.createTextNode(localeStrings.ANY));
- bra_opt_any.setAttribute("value", "");
-
- bra_select.appendChild(bra_opt_any);
-
- var bra_label = document.createElement("label");
- bra_label.setAttribute("class", "bra");
- bra_label.appendChild(document.createTextNode(bra_list[i].name()));
-
- var j = bra_list[i].id();
- for (var k in brav_by_bra[j]) {
- var bra_opt = document.createElement("option");
- bra_opt.setAttribute("value", brav_by_bra[j][k].id());
- bra_opt.appendChild(
- document.createTextNode(brav_by_bra[j][k].valid_value())
- );
- bra_select.appendChild(bra_opt);
- }
-
- bra_div.appendChild(bra_label);
- bra_div.appendChild(bra_select);
- document.getElementById("bra_and_brav").appendChild(bra_div);
- }
- /* Add a prominent label reminding the user what resource type they're
- * asking about. */
- document.getElementById("brsrc_list_header").innerHTML = our_brt.name();
- init_pickup_lib_selector();
- update_brsrc_list();
-}
-
-function update_brsrc_list() {
- var brsrc_id_list = get_brsrc_id_list();
- var force_list = (opts.booking_results && opts.booking_results.brsrc) ?
- opts.booking_results.brsrc.map(function(o) { return o[0]; }) : [];
-
- sync_brsrc_index_from_ids(brsrc_id_list, force_list);
-
- var target_selector = document.getElementById("brsrc_list");
- var selector_memory = new SelectorMemory(target_selector);
- selector_memory.save();
- target_selector.innerHTML = "";
-
- for (var i in brsrc_index) {
- if (brsrc_index[i].isdeleted() && (!brsrc_index[i].ischanged()))
- continue;
-
- var opt = document.createElement("option");
- opt.setAttribute("value", brsrc_index[i].id());
- opt.appendChild(document.createTextNode(brsrc_index[i].barcode()));
-
- if (brsrc_index[i].isdeleted() && (brsrc_index[i].ischanged())) {
- opt.setAttribute("class", "forced_unavailable");
- opt.setAttribute("disabled", "disabled");
- }
-
- target_selector.appendChild(opt);
- }
-
- selector_memory.restore();
-}
-
-function any_usable_brsrc() {
- for (var i in brsrc_index) {
- if (!brsrc_index[i].isdeleted())
- return true;
- }
- return false;
-}
-
-function update_bresv_grid() {
- var widg = document.getElementById("patron_barcode");
- if (widg.value != "") {
- setTimeout(function() {
- var target = document.getElementById(
- "existing_reservation_patron_line"
- );
- var patron = get_actor_by_barcode(widg.value);
- if (patron) {
- target.innerHTML = (
- localeStrings.HERE_ARE_EXISTING_BRESV + " " +
- formal_name(patron) + ": "
- );
- } else {
- target.innerHTML = "";
- }
- }, 0);
- setTimeout(function() { init_bresv_grid(widg.value); }, 0);
- }
-}
-
-function init_timestamp_widgets() {
- var when = ["start", "end"];
- for (var i in when) {
- reserve_timestamp_range.update_from_widget(
- new dijit.form.TimeTextBox({
- name: "reserve_time_" + when[i],
- value: new Date(),
- constraints: {
- timePattern: "HH:mm",
- clickableIncrement: "T00:15:00",
- visibleIncrement: "T00:15:00",
- visibleRange: "T01:30:00"
- },
- onChange: function() {
- reserve_timestamp_range.update_from_widget(this);
- update_brsrc_list();
- }
- }, "reserve_time_" + when[i])
- );
- reserve_timestamp_range.update_from_widget(
- new dijit.form.DateTextBox({
- name: "reserve_date_" + when[i],
- value: new Date(),
- onChange: function() {
- reserve_timestamp_range.update_from_widget(this);
- update_brsrc_list();
- }
- }, "reserve_date_" + when[i])
- );
- }
-}
-
-function cancel_selected_bresv(bresv_dojo_items) {
- if (bresv_dojo_items && bresv_dojo_items.length > 0 &&
- (bresv_dojo_items[0].length == undefined ||
- bresv_dojo_items[0].length > 0)) {
- cancel_reservations(
- bresv_dojo_items.map(function(o) { return o.id[0]; })
- );
- /* After some delay to allow the cancellations a chance to get
- * committed, refresh the brsrc list as it might reflect newly
- * available resources now. */
- if (our_brt) setTimeout(update_brsrc_list, 2000);
- } else {
- alert(localeStrings.CXL_BRESV_SELECT_SOMETHING);
- }
-}
-
-/* The following function should return true if the reservation interface
- * should start normally (show a list of brt to choose from) or false if
- * it should not (because we've "started" it some other way by setting up
- * and displaying other widgets).
- */
-function early_action_passthru() {
- if (opts.booking_results) {
- if (opts.booking_results.brt.length != 1) {
- alert(localeStrings.NEED_EXACTLY_ONE_BRT_PASSED_IN);
- return true;
- } else if (!(our_brt = get_brt_by_id(opts.booking_results.brt[0][0]))) {
- alert(localeStrings.COULD_NOT_RETRIEVE_BRT_PASSED_IN);
- return true;
- }
-
- init_reservation_interface();
- return false;
- }
-
- if (opts.patron_barcode) {
- document.getElementById("contain_patron_barcode").style.display="none";
- document.getElementById("patron_barcode").value = opts.patron_barcode;
- update_bresv_grid();
- }
-
- return true;
-}
-
-function init_aous_cache() {
- /* The following method call could be given a longer
- * list of OU settings to fetch in the future if needed. */
- var results = fieldmapper.aou.fetchOrgSettingBatch(
- openils.User.user.ws_ou(), ["booking.require_successful_targeting", "booking.allow_email_notify"]
- );
- if (results && !is_ils_event(results)) {
- for (var k in results) {
- if (results[k] != undefined)
- aous_cache[k] = results[k].value;
- }
- } else if (results) {
- alert(my_ils_error(localeStrings.ERROR_FETCHING_AOUS, results));
- } else {
- alert(localeStrings.ERROR_FETCHING_AOUS);
- }
-}
-
-/*
- * my_init
- */
-function my_init() {
- hide_dom_element(document.getElementById("brt_reserve_block"));
- reveal_dom_element(document.getElementById("brt_search_block"));
- hide_dom_element(document.getElementById("reserve_under"));
- init_auto_l10n(document.getElementById("auto_l10n_start_here"));
- init_aous_cache();
- init_timestamp_widgets();
-
- if (!(opts = xulG.bresv_interface_opts)) opts = {};
- if (early_action_passthru())
- provide_brt_selector(document.getElementById("brt_selector_here"));
-}
+require([
+ "fieldmapper/OrgUtils",
+ "openils/PermaCrud",
+ "openils/User",
+ "openils/widget/OrgUnitFilteringSelect",
+ "dojo/data/ItemFileReadStore",
+ "dijit/form/DateTextBox",
+ "dijit/form/TimeTextBox",
+ "dojo/date/stamp"
+ ],
+function(fieldmapper_OrgUtils,
+ openils_PermaCrud,
+ openils_User,
+ openils_widget_OrgUnitFilteringSelect,
+ dojo_data_ItemFileReadStore,
+ dijit_form_DateTextBox,
+ dijit_form_TimeTextBox,
+ dojo_date_stamp){
+ /*
+ * Details, details...
+ */
+ dojo.requireLocalization("openils.booking", "reservation");
+
+ /*
+ * Globals; prototypes and their instances
+ */
+ var localeStrings = dojo.i18n.getLocalization("openils.booking", "reservation");
+ var pcrud = new openils_PermaCrud();
+ var opts;
+ var our_brt;
+ var pickup_lib_selected;
+ var brt_list = [];
+ var brsrc_index = {};
+ var bresv_index = {};
+ var just_reserved_now = {};
+ var aous_cache = {};
+
+ function AttrValueTable() { this.t = {}; }
+ AttrValueTable.prototype.set = function(attr, value) { this.t[attr] = value; };
+ AttrValueTable.prototype.update_from_selector = function(selector) {
+ var attr = selector.name.match(/_(\d+)$/)[1];
+ var value = selector.options[selector.selectedIndex].value;
+ if (attr)
+ attr_value_table.set(attr, value);
+ };
+ AttrValueTable.prototype.get_all_values = function() {
+ var values = [];
+ for (var k in this.t) {
+ if (this.t[k] != undefined && this.t[k] != "")
+ values.push(this.t[k]);
+ }
+ return values;
+ };
+ var attr_value_table = new AttrValueTable();
+
+ function TimestampRange() {
+ this.start = new Date();
+ this.end = new Date();
+
+ this.validity = {"start": false, "end": false};
+ this.nodes = {
+ "start": {"date": undefined, "time": undefined},
+ "end": {"date": undefined, "time": undefined}
+ };
+ this.saved_style_properties = {};
+ this.invalid_style_properties = {
+ "backgroundColor": "#ffcccc",
+ "color": "#990000",
+ "borderColor": "#990000",
+ "fontWeight": "bold"
+ };
+ }
+ TimestampRange.prototype.get_timestamp = function(when) {
+ return dojo_date_stamp.toISOString(this[when]).
+ replace("T", " ").substr(0, 19);
+ };
+ TimestampRange.prototype.get_range = function() {
+ return this.is_backwards() ?
+ [this.get_timestamp("end"), this.get_timestamp("start")] :
+ [this.get_timestamp("start"), this.get_timestamp("end")];
+ };
+ TimestampRange.prototype.update_from_widget = function(widget) {
+ var when = widget.name.match(/(start|end)/)[1];
+ var which = widget.name.match(/(date|time)/)[1];
+
+ if (this.nodes[when][which] == undefined)
+ this.nodes[when][which] = widget.domNode; /* We'll need this later */
+
+ if (when && which) {
+ this.update_timestamp(when, which, widget.attr("value"));
+ }
+
+ this.compute_validity();
+ this.paint_validity();
+ };
+ TimestampRange.prototype.compute_validity = function() {
+ if (Math.abs(this.start - this.end) < 1000) {
+ this.validity.end = false;
+ } else {
+ if (this.start < this.current_minimum())
+ this.validity.start = false;
+ else
+ this.validity.start = true;
+
+ if (this.end < this.current_minimum())
+ this.validity.end = false;
+ else
+ this.validity.end = true;
+ }
+ };
+ /* This method provides the minimum timestamp that is considered valid. For
+ * now it's arbitrarily "now + 15 minutes", meaning that all reservations
+ * must be made at least 15 minutes in the future.
+ *
+ * For reasons of keeping the middle layer happy, this should always return
+ * a time that is at least somewhat in the future. The ML isn't able to target
+ * any resources for a reservation with a start date that isn't in the future.
+ */
+ TimestampRange.prototype.current_minimum = function() {
+ /* XXX This is going to be a problem with local clocks that are off. */
+ var n = new Date();
+ n.setTime(n.getTime() + 1000 * 900); /* XXX 15 minutes; stop hardcoding! */
+ return n;
+ };
+ TimestampRange.prototype.update_timestamp = function(when, which, value) {
+ if (which == "date") {
+ this[when].setFullYear(value.getFullYear());
+ /* month and date MUST be done together */
+ this[when].setMonth(value.getMonth(), value.getDate());
+ } else { /* "time" */
+ this[when].setHours(value.getHours());
+ this[when].setMinutes(value.getMinutes());
+ this[when].setSeconds(0);
+ }
+ };
+ TimestampRange.prototype.is_backwards = function() {
+ return (this.start > this.end);
+ };
+ TimestampRange.prototype.paint_validity = function() {
+ for (var when in this.validity) {
+ if (this.validity[when]) {
+ this.paint_valid_node(this.nodes[when].date);
+ this.paint_valid_node(this.nodes[when].time);
+ } else {
+ this.paint_invalid_node(this.nodes[when].date);
+ this.paint_invalid_node(this.nodes[when].time);
+ }
+ }
+ };
+ TimestampRange.prototype.paint_invalid_node = function(node) {
+ if (node) {
+ /* Just toggling the class of something would be better than
+ * manually setting style here, but I haven't been able to get that
+ * to play nicely with dojo's styling of the date/time textboxen.
+ */
+ if (this.saved_style_properties.backgroundColor == undefined) {
+ for (var k in this.invalid_style_properties) {
+ this.saved_style_properties[k] = node.style[k];
+ }
+ }
+ for (var k in this.invalid_style_properties) {
+ node.style[k] = this.invalid_style_properties[k];
+ }
+ }
+ };
+ TimestampRange.prototype.paint_valid_node = function(node) {
+ if (node) {
+ for (var k in this.saved_style_properties) {
+ node.style[k] = this.saved_style_properties[k];
+ }
+ }
+ };
+ TimestampRange.prototype.is_valid = function() {
+ return (this.validity.start && this.validity.end);
+ };
+ var reserve_timestamp_range = new TimestampRange();
+
+ function SelectorMemory(selector) {
+ this.selector = selector;
+ this.memory = {};
+ }
+ SelectorMemory.prototype.save = function() {
+ for (var i = 0; i < this.selector.options.length; i++) {
+ if (this.selector.options[i].selected) {
+ this.memory[this.selector.options[i].value] = true;
+ }
+ }
+ };
+ SelectorMemory.prototype.restore = function() {
+ for (var i = 0; i < this.selector.options.length; i++) {
+ if (this.memory[this.selector.options[i].value]) {
+ if (!this.selector.options[i].disabled)
+ this.selector.options[i].selected = true;
+ }
+ }
+ };
+
+ /*
+ * These functions communicate with the middle layer.
+ */
+ function get_all_noncat_brt() {
+ return pcrud.search("brt",
+ {"id": {"!=": null}, "catalog_item": "f"},
+ {"order_by": {"brt":"name"}}
+ );
+ }
+
+ function get_brt_by_id(id) {
+ return pcrud.retrieve("brt", id);
+ }
+
+ function get_brsrc_id_list() {
+ var options = {"type": our_brt.id(), "pickup_lib": pickup_lib_selected};
+
+ /* This mechanism for avoiding the passing of an empty 'attribute_values'
+ * option is essential because if you pass such an option to the
+ * middle layer API at all, it won't return any IDs for brsrcs that
+ * don't have at least one attribute of some kind.
+ */
+ var attribute_values = attr_value_table.get_all_values();
+ if (attribute_values.length > 0)
+ options.attribute_values = attribute_values;
+
+ options.available = reserve_timestamp_range.get_range();
+
+ return fieldmapper.standardRequest(
+ ["open-ils.booking", "open-ils.booking.resources.filtered_id_list"],
+ [openils_User.authtoken, options]
+ );
+ }
+
+ /* FIXME: We need failure checking after pcrud.retrieve() */
+ function add_brsrc_to_index_if_needed(list, further) {
+ for (var i in list) {
+ if (!brsrc_index[list[i]]) {
+ brsrc_index[list[i]] = pcrud.retrieve("brsrc", list[i]);
+ }
+ if (further)
+ further(brsrc_index[list[i]]);
+ }
+ }
+
+ function sync_brsrc_index_from_ids(available_list, additional_list) {
+ /* Default states for everything in the index. Read the further comments. */
+ for (var i in brsrc_index) {
+ brsrc_index[i].isdeleted(true);
+ brsrc_index[i].ischanged(false);
+ }
+
+ /* Populate the cache with anything that's missing and tag everything
+ * in the "available" list as *not* deleted, and tag everything in the
+ * additional list as "changed." See below. */
+ add_brsrc_to_index_if_needed(
+ available_list, function(o) { o.isdeleted(false); }
+ );
+ add_brsrc_to_index_if_needed(
+ additional_list,
+ function(o) {
+ if (!(o.id() in just_reserved_now)) o.ischanged(true);
+ }
+ );
+ /* NOTE: We lightly abuse the isdeleted() and ischanged() magic fieldmapper
+ * attributes of the brsrcs in our cache. Because we're not going to
+ * pass back any brsrcs to the middle layer, it doesn't really matter
+ * what we set this attribute to. What we're using it for is to indicate
+ * in our little brsrc cache how a given brsrc should be displayed in this
+ * UI's current state (based on whether the brsrc matches timestamp range
+ * availability (isdeleted(false)) and whether the brsrc has been forced
+ * into the list because it was selected in a previous interface (like
+ * the catalog) (ischanged(true))).
+ */
+ }
+
+ function check_bresv_targeting(results) {
+ var missing = 0;
+ var due_dates = [];
+ for (var i in results) {
+ var targ = results[i].targeting;
+ if (!(targ && targ.current_resource)) {
+ missing++;
+ if (targ) {
+ if (targ.error == "NO_COPIES" && targ.conflicts) {
+ for (var k in targ.conflicts) {
+ /* Could potentially get more circ information from
+ * targ.conflicts for display in the future. */
+ due_dates.push(humanize_timestamp_string2(targ.conflicts[k].due_date()));
+ }
+ }
+ }
+ } else {
+ just_reserved_now[results[i].targeting.current_resource] = true;
+ }
+ }
+ return {"missing": missing, "due_dates": due_dates};
+ }
+
+ function create_bresv(resource_list) {
+ var barcode = document.getElementById("patron_barcode").value;
+ if (barcode == "") {
+ alert(localeStrings.WHERES_THE_BARCODE);
+ return;
+ } else if (!reserve_timestamp_range.is_valid()) {
+ alert(localeStrings.INVALID_TS_RANGE);
+ return;
+ }
+ var email_notify = document.getElementById("email_notify").checked ? true : false;
+ var results;
+ try {
+ results = fieldmapper.standardRequest(
+ ["open-ils.booking", "open-ils.booking.reservations.create"],
+ [
+ openils_User.authtoken,
+ barcode,
+ reserve_timestamp_range.get_range(),
+ pickup_lib_selected,
+ our_brt.id(),
+ resource_list,
+ attr_value_table.get_all_values(),
+ email_notify
+ ]
+ );
+ } catch (E) {
+ alert(localeStrings.CREATE_BRESV_LOCAL_ERROR + E);
+ }
+ if (results) {
+ if (is_ils_event(results)) {
+ if (is_ils_actor_card_error(results)) {
+ alert(localeStrings.ACTOR_CARD_NOT_FOUND);
+ } else {
+ alert(my_ils_error(
+ localeStrings.CREATE_BRESV_SERVER_ERROR, results
+ ));
+ }
+ } else {
+ var targeting = check_bresv_targeting(results);
+ if (targeting.missing) {
+ if (aous_cache["booking.require_successful_targeting"]) {
+ alert(
+ dojo.string.substitute(
+ localeStrings.CREATE_BRESV_OK_MISSING_TARGET,
+ [results.length, targeting.missing]
+ ) + "\n\n" +
+ dojo.string.substitute(
+ localeStrings.CREATE_BRESV_OK_MISSING_TARGET_BLOCKED_BY_CIRC,
+ [targeting.due_dates]
+ ) + "\n\n" +
+ localeStrings.CREATE_BRESV_OK_MISSING_TARGET_WILL_CANCEL
+ );
+ cancel_reservations(
+ results.map(
+ function(o) { return o.bresv; },
+ true /* skip_update */
+ )
+ );
+ } else {
+ alert(
+ dojo.string.substitute(
+ localeStrings.CREATE_BRESV_OK_MISSING_TARGET,
+ [results.length, targeting.missing]
+ ) + "\n\n" +
+ dojo.string.substitute(
+ localeStrings.CREATE_BRESV_OK_MISSING_TARGET_BLOCKED_BY_CIRC,
+ [targeting.due_dates]
+ )
+ );
+ }
+ } else {
+ alert(
+ dojo.string.substitute(
+ localeStrings.CREATE_BRESV_OK, [results.length]
+ )
+ );
+ }
+ update_brsrc_list();
+ update_bresv_grid();
+ }
+ } else {
+ alert(localeStrings.CREATE_BRESV_SERVER_NO_RESPONSE);
+ }
+ }
+
+ function flatten_to_dojo_data(obj_list) {
+ return {
+ "label": "id",
+ "identifier": "id",
+ "items": obj_list.map(function(o) {
+ var new_obj = {
+ "id": o.id(),
+ "type": o.target_resource_type().name(),
+ "start_time": humanize_timestamp_string(o.start_time()),
+ "end_time": humanize_timestamp_string(o.end_time())
+ };
+
+ if (o.current_resource())
+ new_obj["resource"] = o.current_resource().barcode();
+ else if (o.target_resource())
+ new_obj["resource"] = "* " + o.target_resource().barcode();
+ else
+ new_obj["resource"] = "* " + localeStrings.UNTARGETED + " *";
+ return new_obj;
+ })
+ };
+ }
+
+ function create_bresv_on_brsrc() {
+ var selector = document.getElementById("brsrc_list");
+ var selected_values = [];
+ for (var i in selector.options) {
+ if (selector.options[i] && selector.options[i].selected)
+ selected_values.push(selector.options[i].value);
+ }
+ if (selected_values.length > 0)
+ create_bresv(selected_values);
+ else
+ alert(localeStrings.SELECT_A_BRSRC_THEN);
+ }
+
+ function create_bresv_on_brt() {
+ if (any_usable_brsrc())
+ create_bresv();
+ else
+ alert(localeStrings.NO_USABLE_BRSRC);
+ }
+
+ function get_actor_by_barcode(barcode) {
+ var usr = fieldmapper.standardRequest(
+ ["open-ils.actor", "open-ils.actor.user.fleshed.retrieve_by_barcode"],
+ [openils_User.authtoken, barcode]
+ );
+ if (usr == null) {
+ alert(localeStrings.GET_PATRON_NO_RESULT);
+ } else if (is_ils_event(usr)) {
+ return null; /* XXX inelegant: this function is quiet about errors
+ here because to report them would be redundant with
+ another function that gets called right after this one.
+ */
+ } else {
+ return usr;
+ }
+ }
+
+ function init_bresv_grid(barcode) {
+ var result = fieldmapper.standardRequest(
+ ["open-ils.booking",
+ "open-ils.booking.reservations.filtered_id_list"
+ ],
+ [openils_User.authtoken, {
+ "user_barcode": barcode,
+ "fields": {
+ "pickup_time": null,
+ "cancel_time": null,
+ "return_time": null
+ }
+ }, /* whole_obj */ true]
+ );
+ if (result == null) {
+ set_datagrid_empty_store(bresvGrid, flatten_to_dojo_data);
+ alert(localeStrings.GET_BRESV_LIST_NO_RESULT);
+ } else if (is_ils_event(result)) {
+ set_datagrid_empty_store(bresvGrid, flatten_to_dojo_data);
+ if (is_ils_actor_card_error(result)) {
+ alert(localeStrings.ACTOR_CARD_NOT_FOUND);
+ } else {
+ alert(my_ils_error(localeStrings.GET_BRESV_LIST_ERR, result));
+ }
+ } else {
+ if (result.length < 1) {
+ document.getElementById("bresv_grid_alt_explanation").innerHTML =
+ localeStrings.NO_EXISTING_BRESV;
+ hide_dom_element(document.getElementById("bresv_grid"));
+ reveal_dom_element(document.getElementById("reserve_under"));
+ } else {
+ document.getElementById("bresv_grid_alt_explanation").innerHTML =
+ "";
+ reveal_dom_element(document.getElementById("bresv_grid"));
+ reveal_dom_element(document.getElementById("reserve_under"));
+ }
+ /* May as well do the following in either case... */
+ bresvGrid.setStore(
+ new dojo_data_ItemFileReadStore(
+ {"data": flatten_to_dojo_data(result)}
+ )
+ );
+ bresv_index = {};
+ for (var i in result) {
+ bresv_index[result[i].id()] = result[i];
+ }
+ }
+ }
+
+ function cancel_reservations(bresv_id_list, skip_update) {
+ try {
+ var result = fieldmapper.standardRequest(
+ ["open-ils.booking", "open-ils.booking.reservations.cancel"],
+ [openils_User.authtoken, bresv_id_list]
+ );
+ } catch (E) {
+ alert(localeStrings.CXL_BRESV_FAILURE2 + E);
+ return;
+ }
+ if (!skip_update) setTimeout(update_bresv_grid, 0);
+ if (!result) {
+ alert(localeStrings.CXL_BRESV_FAILURE);
+ } else if (is_ils_event(result)) {
+ alert(my_ils_error(localeStrings.CXL_BRESV_FAILURE2, result));
+ } else {
+ alert(
+ dojo.string.substitute(
+ localeStrings.CXL_BRESV_SUCCESS, [result.length]
+ )
+ );
+ }
+ }
+
+ function munge_specific_resource(barcode) {
+ try {
+ var copy_list = pcrud.search(
+ "acp", {"barcode": barcode, "deleted": "f"}
+ );
+ if (copy_list && copy_list.length > 0) {
+ var r = fieldmapper.standardRequest(
+ ["open-ils.booking",
+ "open-ils.booking.resources.create_from_copies"],
+ [openils_User.authtoken,
+ copy_list.map(function(o) { return o.id(); })]
+ );
+
+ if (!r) {
+ alert(localeStrings.ON_FLY_NO_RESPONSE);
+ } else if (is_ils_event(r)) {
+ alert(my_ils_error(localeStrings.ON_FLY_ERROR, r));
+ } else {
+ if (!(our_brt = get_brt_by_id(r.brt[0][0]))) {
+ alert(localeStrings.COULD_NOT_RETRIEVE_BRT_PASSED_IN);
+ } else {
+ opts.booking_results = r;
+ init_reservation_interface();
+ }
+ }
+ } else {
+ alert(localeStrings.BRSRC_NOT_FOUND);
+ }
+ } catch (E) {
+ alert(localeStrings.BRSRC_RETRIEVE_ERROR + E);
+ }
+ }
+
+ /*
+ * These functions deal with interface tricks (populating widgets,
+ * changing the page, etc.).
+ */
+ function init_pickup_lib_selector() {
+ var User = new openils_User();
+ User.buildPermOrgSelector(
+ "ADMIN_BOOKING_RESERVATION", pickup_lib_selector, null,
+ function() {
+ pickup_lib_selected = pickup_lib_selector.getValue();
+ dojo.connect(pickup_lib_selector, "onChange",
+ function() {
+ pickup_lib_selected = this.getValue();
+ update_brsrc_list();
+ }
+ )
+ }
+ );
+ }
+
+ function provide_brt_selector(targ_div) {
+ if (!targ_div) {
+ alert(localeStrings.NO_TARG_DIV);
+ } else {
+ brt_list = get_all_noncat_brt();
+ if (!brt_list || brt_list.length < 1) {
+ document.getElementById("select_noncat_brt_block").
+ style.display = "none";
+ } else {
+ var selector = document.createElement("select");
+ selector.setAttribute("id", "brt_selector");
+ selector.setAttribute("name", "brt_selector");
+ /* I'm reluctantly hardcoding this "size" attribute as 8
+ * because you can't accomplish this with CSS anyway.
+ */
+ selector.setAttribute("size", 8);
+ for (var i in brt_list) {
+ var option = document.createElement("option");
+ option.setAttribute("value", brt_list[i].id());
+ option.appendChild(document.createTextNode(brt_list[i].name()));
+ selector.appendChild(option);
+ }
+ targ_div.innerHTML = "";
+ targ_div.appendChild(selector);
+ }
+ }
+ }
+
+ function init_resv_iface_arb() {
+ init_reservation_interface(document.getElementById("arbitrary_resource"));
+ }
+
+ function init_resv_iface_sel() {
+ init_reservation_interface(document.getElementById("brt_selector"));
+ }
+
+ function init_reservation_interface(widget) {
+ /* Show or hide the email notification checkbox depending on org unit setting. */
+ if (!aous_cache["booking.allow_email_notify"]) {
+ hide_dom_element(document.getElementById("contain_email_notify"));
+ }
+ /* Save a global reference to the brt we're going to reserve */
+ if (widget && (widget.selectedIndex != undefined)) {
+ our_brt = brt_list[widget.selectedIndex];
+ } else if (widget != undefined) {
+ if (!munge_specific_resource(widget.value))
+ return;
+ }
+
+ /* Hide and reveal relevant divs. */
+ var search_block = document.getElementById("brt_search_block");
+ var reserve_block = document.getElementById("brt_reserve_block");
+ hide_dom_element(search_block);
+ reveal_dom_element(reserve_block);
+
+ /* Get a list of attributes that can apply to that brt. */
+ var bra_list = pcrud.search("bra", {"resource_type": our_brt.id()});
+ if (!bra_list) {
+ alert(localeString.NO_BRA_LIST);
+ return;
+ }
+
+ /* Get a table of values that can apply to the above attributes. */
+ var brav_by_bra = {};
+ bra_list.map(function(o) {
+ brav_by_bra[o.id()] = pcrud.search("brav", {"attr": o.id()});
+ });
+
+ /* Hide the label over the attributes widgets if we have nothing to show. */
+ var domf = (bra_list.length < 1) ? hide_dom_element : reveal_dom_element;
+ domf(document.getElementById("bra_and_brav_header"));
+
+ /* Create DOM widgets to represent each attribute/values set. */
+ for (var i in bra_list) {
+ var bra_div = document.createElement("div");
+ bra_div.setAttribute("class", "nice_vertical_padding");
+
+ var bra_select = document.createElement("select");
+ bra_select.setAttribute("name", "bra_" + bra_list[i].id());
+ bra_select.setAttribute(
+ "onchange",
+ "attr_value_table.update_from_selector(this); update_brsrc_list();"
+ );
+
+ var bra_opt_any = document.createElement("option");
+ bra_opt_any.appendChild(document.createTextNode(localeStrings.ANY));
+ bra_opt_any.setAttribute("value", "");
+
+ bra_select.appendChild(bra_opt_any);
+
+ var bra_label = document.createElement("label");
+ bra_label.setAttribute("class", "bra");
+ bra_label.appendChild(document.createTextNode(bra_list[i].name()));
+
+ var j = bra_list[i].id();
+ for (var k in brav_by_bra[j]) {
+ var bra_opt = document.createElement("option");
+ bra_opt.setAttribute("value", brav_by_bra[j][k].id());
+ bra_opt.appendChild(
+ document.createTextNode(brav_by_bra[j][k].valid_value())
+ );
+ bra_select.appendChild(bra_opt);
+ }
+
+ bra_div.appendChild(bra_label);
+ bra_div.appendChild(bra_select);
+ document.getElementById("bra_and_brav").appendChild(bra_div);
+ }
+ /* Add a prominent label reminding the user what resource type they're
+ * asking about. */
+ document.getElementById("brsrc_list_header").innerHTML = our_brt.name();
+ init_pickup_lib_selector();
+ update_brsrc_list();
+ }
+
+ function update_brsrc_list() {
+ var brsrc_id_list = get_brsrc_id_list();
+ var force_list = (opts.booking_results && opts.booking_results.brsrc) ?
+ opts.booking_results.brsrc.map(function(o) { return o[0]; }) : [];
+
+ sync_brsrc_index_from_ids(brsrc_id_list, force_list);
+
+ var target_selector = document.getElementById("brsrc_list");
+ var selector_memory = new SelectorMemory(target_selector);
+ selector_memory.save();
+ target_selector.innerHTML = "";
+
+ for (var i in brsrc_index) {
+ if (brsrc_index[i].isdeleted() && (!brsrc_index[i].ischanged()))
+ continue;
+
+ var opt = document.createElement("option");
+ opt.setAttribute("value", brsrc_index[i].id());
+ opt.appendChild(document.createTextNode(brsrc_index[i].barcode()));
+
+ if (brsrc_index[i].isdeleted() && (brsrc_index[i].ischanged())) {
+ opt.setAttribute("class", "forced_unavailable");
+ opt.setAttribute("disabled", "disabled");
+ }
+
+ target_selector.appendChild(opt);
+ }
+
+ selector_memory.restore();
+ }
+
+ function any_usable_brsrc() {
+ for (var i in brsrc_index) {
+ if (!brsrc_index[i].isdeleted())
+ return true;
+ }
+ return false;
+ }
+
+ function update_bresv_grid() {
+ var widg = document.getElementById("patron_barcode");
+ if (widg.value != "") {
+ setTimeout(function() {
+ var target = document.getElementById(
+ "existing_reservation_patron_line"
+ );
+ var patron = get_actor_by_barcode(widg.value);
+ if (patron) {
+ target.innerHTML = (
+ localeStrings.HERE_ARE_EXISTING_BRESV + " " +
+ formal_name(patron) + ": "
+ );
+ } else {
+ target.innerHTML = "";
+ }
+ }, 0);
+ setTimeout(function() { init_bresv_grid(widg.value); }, 0);
+ }
+ }
+
+ function init_timestamp_widgets() {
+ var when = ["start", "end"];
+ for (var i in when) {
+ reserve_timestamp_range.update_from_widget(
+ new dijit_form_TimeTextBox({
+ name: "reserve_time_" + when[i],
+ value: new Date(),
+ constraints: {
+ timePattern: "HH:mm",
+ clickableIncrement: "T00:15:00",
+ visibleIncrement: "T00:15:00",
+ visibleRange: "T01:30:00"
+ },
+ onChange: function() {
+ reserve_timestamp_range.update_from_widget(this);
+ update_brsrc_list();
+ }
+ }, "reserve_time_" + when[i])
+ );
+ reserve_timestamp_range.update_from_widget(
+ new dijit_form_DateTextBox({
+ name: "reserve_date_" + when[i],
+ value: new Date(),
+ onChange: function() {
+ reserve_timestamp_range.update_from_widget(this);
+ update_brsrc_list();
+ }
+ }, "reserve_date_" + when[i])
+ );
+ }
+ }
+
+ function cancel_selected_bresv(bresv_dojo_items) {
+ if (bresv_dojo_items && bresv_dojo_items.length > 0 &&
+ (bresv_dojo_items[0].length == undefined ||
+ bresv_dojo_items[0].length > 0)) {
+ cancel_reservations(
+ bresv_dojo_items.map(function(o) { return o.id[0]; })
+ );
+ /* After some delay to allow the cancellations a chance to get
+ * committed, refresh the brsrc list as it might reflect newly
+ * available resources now. */
+ if (our_brt) setTimeout(update_brsrc_list, 2000);
+ } else {
+ alert(localeStrings.CXL_BRESV_SELECT_SOMETHING);
+ }
+ }
+
+ /* The following function should return true if the reservation interface
+ * should start normally (show a list of brt to choose from) or false if
+ * it should not (because we've "started" it some other way by setting up
+ * and displaying other widgets).
+ */
+ function early_action_passthru() {
+ if (opts.booking_results) {
+ if (opts.booking_results.brt.length != 1) {
+ alert(localeStrings.NEED_EXACTLY_ONE_BRT_PASSED_IN);
+ return true;
+ } else if (!(our_brt = get_brt_by_id(opts.booking_results.brt[0][0]))) {
+ alert(localeStrings.COULD_NOT_RETRIEVE_BRT_PASSED_IN);
+ return true;
+ }
+
+ init_reservation_interface();
+ return false;
+ }
+
+ if (opts.patron_barcode) {
+ document.getElementById("contain_patron_barcode").style.display="none";
+ document.getElementById("patron_barcode").value = opts.patron_barcode;
+ update_bresv_grid();
+ }
+
+ return true;
+ }
+
+ function init_aous_cache() {
+ /* The following method call could be given a longer
+ * list of OU settings to fetch in the future if needed. */
+ var results = fieldmapper.aou.fetchOrgSettingBatch(
+ openils_User.user.ws_ou(), ["booking.require_successful_targeting", "booking.allow_email_notify"]
+ );
+ if (results && !is_ils_event(results)) {
+ for (var k in results) {
+ if (results[k] != undefined)
+ aous_cache[k] = results[k].value;
+ }
+ } else if (results) {
+ alert(my_ils_error(localeStrings.ERROR_FETCHING_AOUS, results));
+ } else {
+ alert(localeStrings.ERROR_FETCHING_AOUS);
+ }
+ }
+
+ /*
+ * my_init
+ */
+ function my_init() {
+ hide_dom_element(document.getElementById("brt_reserve_block"));
+ reveal_dom_element(document.getElementById("brt_search_block"));
+ hide_dom_element(document.getElementById("reserve_under"));
+ init_auto_l10n(document.getElementById("auto_l10n_start_here"));
+ init_aous_cache();
+ init_timestamp_widgets();
+
+ if (!(opts = xulG.bresv_interface_opts)) opts = {};
+ if (early_action_passthru())
+ provide_brt_selector(document.getElementById("brt_selector_here"));
+ }
+
+
+});
\ No newline at end of file
-dojo.require('dijit.Dialog');
-dojo.require('dijit.form.Button');
-dojo.require('dijit.form.DropDownButton');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.form.Form');
-dojo.require('dijit.form.NumberSpinner');
-dojo.require('dijit.form.TextBox');
-dojo.require("dijit.Menu");
-dojo.require("dijit.MenuItem");
-dojo.require('dojox.xml.parser');
-dojo.require('DojoSRF');
-dojo.require("fieldmapper.Fieldmapper");
-dojo.require('openils.CGI');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.XUL');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require("openils.widget.PCrudAutocompleteBox");
-dojo.requireLocalization("openils.authority", "authority");
-var auth_strings = dojo.i18n.getLocalization("openils.authority", "authority");
-
-var cgi = new openils.CGI();
-
-/*
-// OrgUnits do not currently affect the retrieval of authority records,
-// but this is how to display them if they become OrgUnit-aware
-function authOUListInit() {
- new openils.User().buildPermOrgSelector(
- "STAFF_LOGIN", // anywhere you can log in
- dijit.byId("authOU"),
- null, // pre-selected org
- null
- );
-}
-dojo.addOnLoad(authOUListInit);
-*/
-function displayAuthorities(data) {
-
- var idArr = [];
- // Grab each record from the returned authority records
- dojo.query("record", data).forEach(function(node) {
- var auth = {};
- auth.text = '';
- auth.id = 0;
-
- // Grab each authority record field from the authority record
- dojo.query("datafield[tag^='1']", node).forEach(function(dfNode) {
- auth.text += dojox.xml.parser.textContent(dfNode);
- auth.name = dojo.attr(dfNode, 'tag');
- auth.ind1 = dojo.attr(dfNode, 'ind1');
- auth.ind2 = dojo.attr(dfNode, 'ind2');
- });
-
-
- // Grab the ID of the authority record
- dojo.query("datafield[tag='901'] subfield[code='c']", node).forEach(function(dfNode) {
- auth.id = dojox.xml.parser.textContent(dfNode);
- });
-
- idArr.push(parseInt(auth.id));
-
- // Create the authority record listing entry
- dojo.place('<div class="authEntry" id="auth' + auth.id + '"><span class="text" id="authLabel' + auth.id + '">' + auth.text + '</span></div>', "authlist-div", "last");
-
- // Add the menu of new/edit/delete/mark-for-merge options
- var auth_menu = new dijit.Menu({});
-
- // "Edit" menu item
- new dijit.MenuItem({"id": "edit_" + auth.id, "onClick": function(){
- var pcrud = new openils.PermaCrud();
- var auth_rec = pcrud.retrieve("are", auth.id);
- if (auth_rec) {
- loadMarcEditor(pcrud, auth_rec);
- }
- }, "label":auth_strings.MENU_EDIT}).placeAt(auth_menu, "first");
-
- // "Merge" menu item
- new dijit.MenuItem({"id": "merge_" + auth.id, "onClick":function(){
- auth.text = '';
- dojo.query('#auth' + auth.id + ' span.text').forEach(function(node) {
- auth.text += dojox.xml.parser.textContent(node);
- });
-
- // If there is a toMerge item already, this is a target record
- var mergeRole = '<td style="border: 1px solid black; padding-left: 0.5em; padding-right: 1em;">';
- var isTarget = dojo.query('.toMerge').length;
- if (isTarget) {
- mergeRole += auth_strings.TARGET_RECORD + '</td>';
- } else {
- mergeRole += auth_strings.MASTER_RECORD + '</td>';
- }
-
- dojo.place('<tr class="toMerge" id="toMerge_' + auth.id + '"><td>' + mergeRole + '</td><td style="border: 1px solid black;" id="mergeMeta_' + auth.id + '"></td><td style="border: 1px solid black; padding-left: 1em; padding-right: 1em;" >' + auth.text + '</td></tr>', 'mergebox-tbody', 'last');
- dojo.place('<span class="authmeta" style="font-family: monospace;">' + auth.name + ' ' + auth.ind1 + auth.ind2 + '</span>', 'mergeMeta_' + auth.id, 'last');
- dojo.removeClass('mergebox-div', 'hidden');
- }, "label":auth_strings.MENU_MERGE}).placeAt(auth_menu, "last");
-
- // "Delete" menu item
- new dijit.MenuItem({
- "id": "delete_" + auth.id,
- "onClick":function(){
- auth.text = '';
-
- var pcrud = new openils.PermaCrud();
- var auth_rec = pcrud.retrieve("are", auth.id);
-
- // Bit of a hack to get the linked bib count until an explicit ID
- var linkedBibs = dojox.xml.parser.textContent(
- dojo.query("#authLabel" + auth.id)[0].previousSibling
- );
-
- var delDlg = dijit.byId("delDialog_" + auth.id);
-
- dojo.query('#auth' + auth.id + ' span.text').forEach(function(node) {
- auth.text += dojo.trim(dojox.xml.parser.textContent(node));
- });
-
- if (!delDlg) {
- var content = '<div>' + dojo.string.substitute(auth_strings.CONFIRM_DELETE_TITLE, [auth.text]) + '</div>';
- if (parseInt(linkedBibs) > 0) {
- content = "<div id='delAuthSum_" + auth.id + "'>"
- + dojo.string.substitute(auth_strings.LINKED_BIBS, [linkedBibs])
- + "</div>";
- }
- content += "<div id='authMARC" + auth.id + "' style='width: 100%; display:none;'>";
- content += "<hr style='width: 100%;' />";
- content += marcToHTML(auth_rec.marc());
- content += "</div><hr style='width: 100%;' /><div>";
- content += "<input type='button' dojoType='dijit.form.Button' label='" + auth_strings.CANCEL + "' onClick='cancelDelete(" + auth.id + ")'/>";
- content += "<input type='button' dojoType='dijit.form.Button' label='" + auth_strings.DELETE + "' onClick='confirmDelete(" + auth.id + ")'/>";
- content += "<input id='viewMARC" + auth.id + "' type='button' "
- + "style='float:right;' dojoType='dijit.form.Button' "
- + "label='" + auth_strings.VIEW_MARC + "' onClick='viewMARC(" + auth.id + ")'/>";
- content += "<input id='hideMARC" + auth.id + "' type='button' "
- + "style='display: none; float:right;' dojoType='dijit.form.Button' "
- + "label='" + auth_strings.HIDE_MARC + "' onClick='hideMARC(" + auth.id + ")'/>";
- content += "</div>";
- delDlg = new dijit.Dialog({
- "id":"delDialog_" + auth.id,
- "title": dojo.string.substitute(auth_strings.CONFIRM_DELETE_PROMPT, [auth.id]),
- "content": content
- });
- }
- delDlg.show();
-
- }, "label":auth_strings.DELETE}).placeAt(auth_menu, "last");
-
- auth_mb = new dijit.form.DropDownButton({dropDown: auth_menu, label: auth_strings.ACTIONS, id:"menu" + auth.id});
- auth_mb.placeAt("auth" + auth.id, "first");
- auth_menu.startup();
- });
-
- showBibCount(idArr);
-}
-
-function viewMARC(recId) {
- dojo.style(dojo.byId("authMARC" + recId), 'display', 'block');
- dojo.style(dijit.byId("viewMARC" + recId).domNode, 'display', 'none');
- dojo.style(dijit.byId("hideMARC" + recId).domNode, 'display', 'block');
-}
-
-function hideMARC(recId) {
- dojo.style(dojo.byId("authMARC" + recId), 'display', 'none');
- dojo.style(dijit.byId("hideMARC" + recId).domNode, 'display', 'none');
- dojo.style(dijit.byId("viewMARC" + recId).domNode, 'display', 'block');
-}
-
-function marcToHTML(marc) {
- var html = '<table><tbody>';
- marc = dojox.xml.parser.parse(marc);
- dojo.query('leader', marc).forEach(function(node) {
- html += '<tr><td>LDR</td><td> </td><td> </td><td>' + dojox.xml.parser.textContent(node) + '</td></tr>';
- });
- dojo.query('controlfield', marc).forEach(function(node) {
- html += '<tr><td>' + dojo.attr(node, "tag") + '</td><td> </td><td> </td><td>' + dojox.xml.parser.textContent(node) + '</td></tr>';
- });
- dojo.query('datafield', marc).forEach(function(node) {
- var cnt = 0;
- html += '<tr><td>' + dojo.attr(node, "tag") + '</td><td>' + dojo.attr(node, "ind1") + '</td><td>' + dojo.attr(node, "ind2") + '</td>';
- dojo.query('subfield', node).forEach(function(sf) {
- if (cnt == 0) {
- html += '<td>$' + dojo.attr(sf, "code") + ' ' + dojox.xml.parser.textContent(sf) + '</td></tr>';
- cnt = 1;
- } else {
- html += '<tr><td colspan="3"></td><td>$' + dojo.attr(sf, "code") + ' ' + dojox.xml.parser.textContent(sf) + '</td></tr>';
- }
- });
- });
- html += '</tbody></table>';
- return html;
-}
-
-function cancelDelete(recId) {
- dijit.byId("delDialog_" + recId).hide();
-}
-
-function confirmDelete(recId) {
- var pcrud = new openils.PermaCrud();
- var auth_rec = pcrud.retrieve("are", recId);
- if (auth_rec) {
- pcrud.eliminate(auth_rec);
- dijit.byId("delDialog_" + recId).attr("content", dojo.string.substitute(auth_strings.CONFIRM_DELETE_RESULT, [recId]));
- setTimeout(function() {
- dijit.byId("delDialog_" + recId).hide();
- }, 3000);
- }
-}
-
-function showBibCount(authIds) {
- /* Decorate the list with # of bibs linked to each authority record */
- var ses = new OpenSRF.ClientSession('open-ils.cat');
- var req = ses.request('open-ils.cat.authority.records.count_linked_bibs', authIds);
- var linkedIds = [];
- req.oncomplete = function(r) {
- var msg = r.recv().content();
- dojo.forEach(msg, function(auth) {
- linkedIds.push(auth.authority);
- dojo.place('<span class="bibcount">' + auth.bibs + '</span>', 'authLabel' + auth.authority, 'before');
- }
- );
-
- /* Assign counts of 0 for every non-linked authority */
- dojo.forEach(authIds, function (id) {
- var found = false;
- dojo.forEach(linkedIds, function (lid) {
- if (id == lid) {
- found = true;
- }
- });
- if (!found) {
- dojo.place('<span class="bibcount">0</span>', 'authLabel' + id, 'before');
- }
- });
- }
- req.send();
-}
-
-function loadMarcEditor(pcrud, rec) {
- /*
- To run in Firefox directly, must set signed.applets.codebase_principal_support
- to true in about:config
- */
- netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
- win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?
-
- win.xulG = {
- "record": {"marc": rec.marc(), "rtype": "are"},
- "save": {
- "label": auth_strings.SAVE,
- "func": function(xmlString) {
- rec.marc(xmlString);
- rec.edit_date('now');
- rec.ischanged(true);
- pcrud.update(rec);
- alert(auth_strings.SAVE_RESULT_SUCCESS);
- win.close();
- }
- },
- 'lock_tab' : typeof xulG != 'undefined' ? (typeof xulG['lock_tab'] != 'undefined' ? xulG.lock_tab : undefined) : undefined,
- 'unlock_tab' : typeof xulG != 'undefined' ? (typeof xulG['unlock_tab'] != 'undefined' ? xulG.unlock_tab : undefined) : undefined
- };
-}
-
-function authListInit() {
- var term = cgi.param('authTerm') || '';
- var page = cgi.param('authPage') || 0;
- var axis = cgi.param('authAxis') || 'authority.author';
- if (axis) {
- dijit.byId('authAxis').attr('value', axis);
- }
- if (page) {
- dijit.byId('authPage').attr('value', page);
- }
- if (term) {
- dijit.byId('authTerm').attr('value', term);
- displayRecords();
- }
-
- dojo.connect(dijit.byId('authAxis'), 'onKeyPress', function(evt) {
- if (evt.keyCode == dojo.keys.ENTER) {
- dijit.byId('authPage').attr('value', 0);
- displayRecords();
- }
- });
-
- dojo.connect(dijit.byId('authPage'), 'onKeyPress', function(evt) {
- if (evt.keyCode == dojo.keys.ENTER) {
- dijit.byId('authPage').attr('value', 0);
- displayRecords();
- }
- });
-
- dojo.connect(dijit.byId('authTerm'), 'onKeyPress', function(evt) {
- if (evt.keyCode == dojo.keys.ENTER) {
- dijit.byId('authPage').attr('value', 0);
- displayRecords();
- }
- });
-
- dijit.byId('authTerm').focus();
-
-}
-dojo.addOnLoad(authListInit);
-
-function displayRecords(parms) {
-
- if (parms && parms.page) {
- if (parms.page == 'next') {
- page = dijit.byId('authPage').attr('value');
- dijit.byId('authPage').attr('value', page + 1);
- } else if (parms.page == 'prev') {
- page = dijit.byId('authPage').attr('value');
- dijit.byId('authPage').attr('value', page - 1);
- } else {
- dijit.byId('authPage').attr('value', parms.page);
- }
- }
-
- /* Protect against null input */
- if (!dijit.byId('authTerm').attr('value')) {
- return;
- }
-
- /* Clear out the current contents of the page */
- var widgets = dijit.findWidgets(dojo.byId('authlist-div'));
- dojo.forEach(widgets, function(w) { w.destroyRecursive(true); });
-
- dojo.query("#authlist-div div").orphan();
-
- var url = '/opac/extras/browse/marcxml/authority.'
- + dijit.byId('authAxis').attr('value')
- // + '/' + dijit.byId('authOU').attr('value')
- + '/1' // replace with preceding line if OUs gain some meaning
- + '/' + dijit.byId('authTerm').attr('value')
- + '/' + dijit.byId('authPage').attr('value')
- + '/' + '20' // 20 results per page
- ;
- dojo.xhrGet({"url":url, "handleAs":"xml", "content":{"format":"marcxml"}, "preventCache": true, "load":displayAuthorities });
-}
-
-function clearMergeRecords() {
- var records = dojo.query('.toMerge').orphan();
- dojo.addClass('mergebox-div', 'hidden');
-}
-
-function mergeRecords() {
- var records = dojo.query('.toMerge').attr('id');
- dojo.forEach(records, function(item, idx) {
- records[idx] = parseInt(item.slice(item.lastIndexOf('_') + 1));
- });
-
- /* Take the first record in the list and use that as the master */
- fieldmapper.standardRequest(
- ['open-ils.cat', 'open-ils.cat.authority.records.merge'],
- { async: false,
- params: [openils.User.authtoken, records.shift(), records],
- oncomplete : function(r) {
- alert(auth_strings.MERGE_RESULT_SUCCESS);
- clearMergeRecords();
- displayRecords();
- }
- }
- );
-}
+require([
+ "dijit/Dialog",
+ "dijit/form/Button",
+ "dijit/form/DropDownButton",
+ "dijit/form/FilteringSelect",
+ "dijit/form/Form",
+ "dijit/form/NumberSpinner",
+ "dijit/form/TextBox",
+ "dijit/Menu",
+ "dijit/MenuItem",
+ "dojox/xml/parser",
+ "DojoSRF",
+ "fieldmapper/Fieldmapper",
+ "openils/CGI",
+ "openils/PermaCrud",
+ "openils/XUL",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/widget/PCrudAutocompleteBox"
+ ],
+function(dijit_Dialog,
+ dijit_form_Button,
+ dijit_form_DropDownButton,
+ dijit_form_FilteringSelect,
+ dijit_form_Form,
+ dijit_form_NumberSpinner,
+ dijit_form_TextBox,
+ dijit_Menu,
+ dijit_MenuItem,
+ dojox_xml_parser,
+ DojoSRF,
+ fieldmapper_Fieldmapper,
+ openils_CGI,
+ openils_PermaCrud,
+ openils_XUL,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_widget_PCrudAutocompleteBox){
+ dojo.requireLocalization("openils.authority", "authority");
+ var auth_strings = dojo.i18n.getLocalization("openils.authority", "authority");
+
+ var cgi = new openils_CGI();
+
+ /*
+ // OrgUnits do not currently affect the retrieval of authority records,
+ // but this is how to display them if they become OrgUnit-aware
+ function authOUListInit() {
+ new openils.User().buildPermOrgSelector(
+ "STAFF_LOGIN", // anywhere you can log in
+ dijit.byId("authOU"),
+ null, // pre-selected org
+ null
+ );
+ }
+ dojo.addOnLoad(authOUListInit);
+ */
+ function displayAuthorities(data) {
+
+ var idArr = [];
+ // Grab each record from the returned authority records
+ dojo.query("record", data).forEach(function(node) {
+ var auth = {};
+ auth.text = '';
+ auth.id = 0;
+
+ // Grab each authority record field from the authority record
+ dojo.query("datafield[tag^='1']", node).forEach(function(dfNode) {
+ auth.text += dojox_xml_parser.textContent(dfNode);
+ auth.name = dojo.attr(dfNode, 'tag');
+ auth.ind1 = dojo.attr(dfNode, 'ind1');
+ auth.ind2 = dojo.attr(dfNode, 'ind2');
+ });
+
+
+ // Grab the ID of the authority record
+ dojo.query("datafield[tag='901'] subfield[code='c']", node).forEach(function(dfNode) {
+ auth.id = dojox_xml_parser.textContent(dfNode);
+ });
+
+ idArr.push(parseInt(auth.id));
+
+ // Create the authority record listing entry
+ dojo.place('<div class="authEntry" id="auth' + auth.id + '"><span class="text" id="authLabel' + auth.id + '">' + auth.text + '</span></div>', "authlist-div", "last");
+
+ // Add the menu of new/edit/delete/mark-for-merge options
+ var auth_menu = new dijit_Menu({});
+
+ // "Edit" menu item
+ new dijit_MenuItem({"id": "edit_" + auth.id, "onClick": function(){
+ var pcrud = new openils_PermaCrud();
+ var auth_rec = pcrud.retrieve("are", auth.id);
+ if (auth_rec) {
+ loadMarcEditor(pcrud, auth_rec);
+ }
+ }, "label":auth_strings.MENU_EDIT}).placeAt(auth_menu, "first");
+
+ // "Merge" menu item
+ new dijit_MenuItem({"id": "merge_" + auth.id, "onClick":function(){
+ auth.text = '';
+ dojo.query('#auth' + auth.id + ' span.text').forEach(function(node) {
+ auth.text += dojox_xml_parser.textContent(node);
+ });
+
+ // If there is a toMerge item already, this is a target record
+ var mergeRole = '<td style="border: 1px solid black; padding-left: 0.5em; padding-right: 1em;">';
+ var isTarget = dojo.query('.toMerge').length;
+ if (isTarget) {
+ mergeRole += auth_strings.TARGET_RECORD + '</td>';
+ } else {
+ mergeRole += auth_strings.MASTER_RECORD + '</td>';
+ }
+
+ dojo.place('<tr class="toMerge" id="toMerge_' + auth.id + '"><td>' + mergeRole + '</td><td style="border: 1px solid black;" id="mergeMeta_' + auth.id + '"></td><td style="border: 1px solid black; padding-left: 1em; padding-right: 1em;" >' + auth.text + '</td></tr>', 'mergebox-tbody', 'last');
+ dojo.place('<span class="authmeta" style="font-family: monospace;">' + auth.name + ' ' + auth.ind1 + auth.ind2 + '</span>', 'mergeMeta_' + auth.id, 'last');
+ dojo.removeClass('mergebox-div', 'hidden');
+ }, "label":auth_strings.MENU_MERGE}).placeAt(auth_menu, "last");
+
+ // "Delete" menu item
+ new dijit_MenuItem({
+ "id": "delete_" + auth.id,
+ "onClick":function(){
+ auth.text = '';
+
+ var pcrud = new openils_PermaCrud();
+ var auth_rec = pcrud.retrieve("are", auth.id);
+
+ // Bit of a hack to get the linked bib count until an explicit ID
+ var linkedBibs = dojox_xml_parser.textContent(
+ dojo.query("#authLabel" + auth.id)[0].previousSibling
+ );
+
+ var delDlg = dijit.byId("delDialog_" + auth.id);
+
+ dojo.query('#auth' + auth.id + ' span.text').forEach(function(node) {
+ auth.text += dojo.trim(dojox_xml_parser.textContent(node));
+ });
+
+ if (!delDlg) {
+ var content = '<div>' + dojo.string.substitute(auth_strings.CONFIRM_DELETE_TITLE, [auth.text]) + '</div>';
+ if (parseInt(linkedBibs) > 0) {
+ content = "<div id='delAuthSum_" + auth.id + "'>"
+ + dojo.string.substitute(auth_strings.LINKED_BIBS, [linkedBibs])
+ + "</div>";
+ }
+ content += "<div id='authMARC" + auth.id + "' style='width: 100%; display:none;'>";
+ content += "<hr style='width: 100%;' />";
+ content += marcToHTML(auth_rec.marc());
+ content += "</div><hr style='width: 100%;' /><div>";
+ content += "<input type='button' dojoType='dijit_form_Button' label='" + auth_strings.CANCEL + "' onClick='cancelDelete(" + auth.id + ")'/>";
+ content += "<input type='button' dojoType='dijit_form_Button' label='" + auth_strings.DELETE + "' onClick='confirmDelete(" + auth.id + ")'/>";
+ content += "<input id='viewMARC" + auth.id + "' type='button' "
+ + "style='float:right;' dojoType='dijit_form_Button' "
+ + "label='" + auth_strings.VIEW_MARC + "' onClick='viewMARC(" + auth.id + ")'/>";
+ content += "<input id='hideMARC" + auth.id + "' type='button' "
+ + "style='display: none; float:right;' dojoType='dijit_form_Button' "
+ + "label='" + auth_strings.HIDE_MARC + "' onClick='hideMARC(" + auth.id + ")'/>";
+ content += "</div>";
+ delDlg = new dijit_Dialog({
+ "id":"delDialog_" + auth.id,
+ "title": dojo.string.substitute(auth_strings.CONFIRM_DELETE_PROMPT, [auth.id]),
+ "content": content
+ });
+ }
+ delDlg.show();
+
+ }, "label":auth_strings.DELETE}).placeAt(auth_menu, "last");
+
+ auth_mb = new dijit_form_DropDownButton({dropDown: auth_menu, label: auth_strings.ACTIONS, id:"menu" + auth.id});
+ auth_mb.placeAt("auth" + auth.id, "first");
+ auth_menu.startup();
+ });
+
+ showBibCount(idArr);
+ }
+
+ function viewMARC(recId) {
+ dojo.style(dojo.byId("authMARC" + recId), 'display', 'block');
+ dojo.style(dijit.byId("viewMARC" + recId).domNode, 'display', 'none');
+ dojo.style(dijit.byId("hideMARC" + recId).domNode, 'display', 'block');
+ }
+
+ function hideMARC(recId) {
+ dojo.style(dojo.byId("authMARC" + recId), 'display', 'none');
+ dojo.style(dijit.byId("hideMARC" + recId).domNode, 'display', 'none');
+ dojo.style(dijit.byId("viewMARC" + recId).domNode, 'display', 'block');
+ }
+
+ function marcToHTML(marc) {
+ var html = '<table><tbody>';
+ marc = dojox_xml_parser.parse(marc);
+ dojo.query('leader', marc).forEach(function(node) {
+ html += '<tr><td>LDR</td><td> </td><td> </td><td>' + dojox_xml_parser.textContent(node) + '</td></tr>';
+ });
+ dojo.query('controlfield', marc).forEach(function(node) {
+ html += '<tr><td>' + dojo.attr(node, "tag") + '</td><td> </td><td> </td><td>' + dojox_xml_parser.textContent(node) + '</td></tr>';
+ });
+ dojo.query('datafield', marc).forEach(function(node) {
+ var cnt = 0;
+ html += '<tr><td>' + dojo.attr(node, "tag") + '</td><td>' + dojo.attr(node, "ind1") + '</td><td>' + dojo.attr(node, "ind2") + '</td>';
+ dojo.query('subfield', node).forEach(function(sf) {
+ if (cnt == 0) {
+ html += '<td>$' + dojo.attr(sf, "code") + ' ' + dojox_xml_parser.textContent(sf) + '</td></tr>';
+ cnt = 1;
+ } else {
+ html += '<tr><td colspan="3"></td><td>$' + dojo.attr(sf, "code") + ' ' + dojox_xml_parser.textContent(sf) + '</td></tr>';
+ }
+ });
+ });
+ html += '</tbody></table>';
+ return html;
+ }
+
+ function cancelDelete(recId) {
+ dijit.byId("delDialog_" + recId).hide();
+ }
+
+ function confirmDelete(recId) {
+ var pcrud = new openils_PermaCrud();
+ var auth_rec = pcrud.retrieve("are", recId);
+ if (auth_rec) {
+ pcrud.eliminate(auth_rec);
+ dijit.byId("delDialog_" + recId).attr("content", dojo.string.substitute(auth_strings.CONFIRM_DELETE_RESULT, [recId]));
+ setTimeout(function() {
+ dijit.byId("delDialog_" + recId).hide();
+ }, 3000);
+ }
+ }
+
+ function showBibCount(authIds) {
+ /* Decorate the list with # of bibs linked to each authority record */
+ var ses = new OpenSRF.ClientSession('open-ils.cat');
+ var req = ses.request('open-ils.cat.authority.records.count_linked_bibs', authIds);
+ var linkedIds = [];
+ req.oncomplete = function(r) {
+ var msg = r.recv().content();
+ dojo.forEach(msg, function(auth) {
+ linkedIds.push(auth.authority);
+ dojo.place('<span class="bibcount">' + auth.bibs + '</span>', 'authLabel' + auth.authority, 'before');
+ }
+ );
+
+ /* Assign counts of 0 for every non-linked authority */
+ dojo.forEach(authIds, function (id) {
+ var found = false;
+ dojo.forEach(linkedIds, function (lid) {
+ if (id == lid) {
+ found = true;
+ }
+ });
+ if (!found) {
+ dojo.place('<span class="bibcount">0</span>', 'authLabel' + id, 'before');
+ }
+ });
+ }
+ req.send();
+ }
+
+ function loadMarcEditor(pcrud, rec) {
+ /*
+ To run in Firefox directly, must set signed.applets.codebase_principal_support
+ to true in about:config
+ */
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+ win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?
+
+ win.xulG = {
+ "record": {"marc": rec.marc(), "rtype": "are"},
+ "save": {
+ "label": auth_strings.SAVE,
+ "func": function(xmlString) {
+ rec.marc(xmlString);
+ rec.edit_date('now');
+ rec.ischanged(true);
+ pcrud.update(rec);
+ alert(auth_strings.SAVE_RESULT_SUCCESS);
+ win.close();
+ }
+ },
+ 'lock_tab' : typeof xulG != 'undefined' ? (typeof xulG['lock_tab'] != 'undefined' ? xulG.lock_tab : undefined) : undefined,
+ 'unlock_tab' : typeof xulG != 'undefined' ? (typeof xulG['unlock_tab'] != 'undefined' ? xulG.unlock_tab : undefined) : undefined
+ };
+ }
+
+ function authListInit() {
+ var term = cgi.param('authTerm') || '';
+ var page = cgi.param('authPage') || 0;
+ var axis = cgi.param('authAxis') || 'authority.author';
+ if (axis) {
+ dijit.byId('authAxis').attr('value', axis);
+ }
+ if (page) {
+ dijit.byId('authPage').attr('value', page);
+ }
+ if (term) {
+ dijit.byId('authTerm').attr('value', term);
+ displayRecords();
+ }
+
+ dojo.connect(dijit.byId('authAxis'), 'onKeyPress', function(evt) {
+ if (evt.keyCode == dojo.keys.ENTER) {
+ dijit.byId('authPage').attr('value', 0);
+ displayRecords();
+ }
+ });
+
+ dojo.connect(dijit.byId('authPage'), 'onKeyPress', function(evt) {
+ if (evt.keyCode == dojo.keys.ENTER) {
+ dijit.byId('authPage').attr('value', 0);
+ displayRecords();
+ }
+ });
+
+ dojo.connect(dijit.byId('authTerm'), 'onKeyPress', function(evt) {
+ if (evt.keyCode == dojo.keys.ENTER) {
+ dijit.byId('authPage').attr('value', 0);
+ displayRecords();
+ }
+ });
+
+ dijit.byId('authTerm').focus();
+
+ }
+ dojo.addOnLoad(authListInit);
+
+ function displayRecords(parms) {
+
+ if (parms && parms.page) {
+ if (parms.page == 'next') {
+ page = dijit.byId('authPage').attr('value');
+ dijit.byId('authPage').attr('value', page + 1);
+ } else if (parms.page == 'prev') {
+ page = dijit.byId('authPage').attr('value');
+ dijit.byId('authPage').attr('value', page - 1);
+ } else {
+ dijit.byId('authPage').attr('value', parms.page);
+ }
+ }
+
+ /* Protect against null input */
+ if (!dijit.byId('authTerm').attr('value')) {
+ return;
+ }
+
+ /* Clear out the current contents of the page */
+ var widgets = dijit.findWidgets(dojo.byId('authlist-div'));
+ dojo.forEach(widgets, function(w) { w.destroyRecursive(true); });
+
+ dojo.query("#authlist-div div").orphan();
+
+ var url = '/opac/extras/browse/marcxml/authority.'
+ + dijit.byId('authAxis').attr('value')
+ // + '/' + dijit.byId('authOU').attr('value')
+ + '/1' // replace with preceding line if OUs gain some meaning
+ + '/' + dijit.byId('authTerm').attr('value')
+ + '/' + dijit.byId('authPage').attr('value')
+ + '/' + '20' // 20 results per page
+ ;
+ dojo.xhrGet({"url":url, "handleAs":"xml", "content":{"format":"marcxml"}, "preventCache": true, "load":displayAuthorities });
+ }
+
+ function clearMergeRecords() {
+ var records = dojo.query('.toMerge').orphan();
+ dojo.addClass('mergebox-div', 'hidden');
+ }
+
+ function mergeRecords() {
+ var records = dojo.query('.toMerge').attr('id');
+ dojo.forEach(records, function(item, idx) {
+ records[idx] = parseInt(item.slice(item.lastIndexOf('_') + 1));
+ });
+
+ /* Take the first record in the list and use that as the master */
+ fieldmapper.standardRequest(
+ ['open-ils.cat', 'open-ils.cat.authority.records.merge'],
+ { async: false,
+ params: [openils.User.authtoken, records.shift(), records],
+ oncomplete : function(r) {
+ alert(auth_strings.MERGE_RESULT_SUCCESS);
+ clearMergeRecords();
+ displayRecords();
+ }
+ }
+ );
+ }
+
+
+});
\ No newline at end of file
-dojo.require('dojo.date.locale');
-dojo.require('dojo.cookie');
-dojo.require('dojo.date.stamp');
-dojo.require('dijit.form.CheckBox');
-dojo.require('dijit.form.NumberSpinner');
-dojo.require('openils.CGI');
-dojo.require('openils.Util');
-dojo.require('openils.User');
-dojo.require('openils.Event');
-dojo.require('openils.widget.ProgressDialog');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-
-
-dojo.requireLocalization('openils.circ', 'selfcheck');
-var localeStrings = dojo.i18n.getLocalization('openils.circ', 'selfcheck');
-
-
-const SET_BARCODE_REGEX = 'opac.barcode_regex';
-const SET_PATRON_TIMEOUT = 'circ.selfcheck.patron_login_timeout';
-const SET_AUTO_OVERRIDE_EVENTS = 'circ.selfcheck.auto_override_checkout_events';
-const SET_PATRON_PASSWORD_REQUIRED = 'circ.selfcheck.patron_password_required';
-const SET_AUTO_RENEW_INTERVAL = 'circ.checkout_auto_renew_age';
-const SET_WORKSTATION_REQUIRED = 'circ.selfcheck.workstation_required';
-const SET_ALERT_POPUP = 'circ.selfcheck.alert.popup';
-const SET_ALERT_SOUND = 'circ.selfcheck.alert.sound';
-const SET_CC_PAYMENT_ALLOWED = 'credit.payments.allow';
-// This setting only comes into play if COPY_NOT_AVAILABLE is in the SET_AUTO_OVERRIDE_EVENTS list
-const SET_BLOCK_CHECKOUT_ON_COPY_STATUS = 'circ.selfcheck.block_checkout_on_copy_status';
-
-// set before the login dialog is rendered
-openils.User.default_login_agent = 'selfcheck';
-
-function SelfCheckManager() {
-
- this.cgi = new openils.CGI();
- this.staff = null;
- this.workstation = null;
- this.authtoken = null;
-
- this.patron = null;
- this.patronBarcodeRegex = null;
-
- this.checkouts = [];
- this.itemsOut = [];
-
- // During renewals, keep track of the ID of the previous circulation.
- // Previous circ is used for tracking failed renewals (for receipts).
- this.prevCirc = null;
-
- // current item barcode
- this.itemBarcode = null;
-
- // are we currently performing a renewal?
- this.isRenewal = false;
-
- // dict of org unit settings for "here"
- this.orgSettings = {};
-
- // Construct a mock checkout for debugging purposes
- if(this.mockCheckouts = this.cgi.param('mock-circ')) {
-
- this.mockCheckout = {
- payload : {
- record : new fieldmapper.mvr(),
- copy : new fieldmapper.acp(),
- circ : new fieldmapper.circ()
- }
- };
-
- this.mockCheckout.payload.record.title('Jazz improvisation for guitar');
- this.mockCheckout.payload.record.author('Wise, Les');
- this.mockCheckout.payload.record.isbn('0634033565');
- this.mockCheckout.payload.copy.barcode('123456789');
- this.mockCheckout.payload.circ.renewal_remaining(1);
- this.mockCheckout.payload.circ.parent_circ(1);
- this.mockCheckout.payload.circ.due_date('2012-12-21');
- }
-
- this.initPrinter();
-}
-
-SelfCheckManager.prototype.setupStaffLogin = function(verify) {
-
- if(verify) oilsSetupUser();
- this.staff = openils.User.user;
- this.workstation = openils.User.workstation;
- this.authtoken = openils.User.authtoken;
-}
-
-
-
-/**
- * Fetch the org-unit settings, initialize the display, etc.
- */
-SelfCheckManager.prototype.init = function() {
-
- this.setupStaffLogin();
- this.loadOrgSettings();
-
- this.circTbody = dojo.byId('oils-selfck-circ-tbody');
- this.itemsOutTbody = dojo.byId('oils-selfck-circ-out-tbody');
-
- // workstation is required but none provided
- if(this.orgSettings[SET_WORKSTATION_REQUIRED] && !this.workstation) {
- if(confirm(dojo.string.substitute(localeStrings.WORKSTATION_REQUIRED))) {
- this.registerWorkstation();
- }
- return;
- }
-
- var self = this;
- // connect onclick handlers to the various navigation links
- var linkHandlers = {
- 'oils-selfck-hold-details-link' : function() { self.drawHoldsPage(); },
- 'oils-selfck-view-fines-link' : function() { self.drawFinesPage(); },
- 'oils-selfck-pay-fines-link' : function() {
- self.goToTab("payment");
- self.drawPayFinesPage(
- self.patron,
- self.getSelectedFinesTotal(),
- self.getSelectedFineTransactions(),
- function(resp) {
- var evt = openils.Event.parse(resp);
- if(evt) {
- var message = evt + '';
- if(evt.textcode == 'CREDIT_PROCESSOR_DECLINED_TRANSACTION' && evt.payload)
- message += '\n' + evt.payload.error_message;
- if(evt.textcode == 'INVALID_USER_XACT_ID')
- message += '\n' + localeStrings.PAYMENT_INVALID_USER_XACT_ID;
- self.handleAlert(message, true, 'payment-failure');
- return;
- }
-
- self.patron.last_xact_id(resp.last_xact_id); // update to match latest from server
- self.printPaymentReceipt(
- resp,
- function() {
- self.updateFinesSummary();
- self.drawFinesPage();
- }
- );
- }
- );
- },
- 'oils-selfck-nav-home' : function() { self.drawCircPage(); },
- 'oils-selfck-nav-logout' : function() { self.logoutPatron(); },
- 'oils-selfck-nav-logout-print' : function() { self.logoutPatron(true); },
- 'oils-selfck-items-out-details-link' : function() { self.drawItemsOutPage(); },
- 'oils-selfck-print-list-link' : function() { self.printList(); }
- }
-
- for(var id in linkHandlers)
- dojo.connect(dojo.byId(id), 'onclick', linkHandlers[id]);
-
-
- if(this.cgi.param('patron')) {
-
- // Patron barcode via cgi param. Mainly used for debugging and
- // only works if password is not required by policy
- this.loginPatron(this.cgi.param('patron'));
-
- } else {
- this.drawLoginPage();
- }
-
- /**
- * To test printing, pass a URL param of 'testprint'. The value for the param
- * should be a JSON string like so: [{circ:<circ_id>}, ...]
- */
- var testPrint = this.cgi.param('testprint');
- if(testPrint) {
- this.checkouts = JSON2js(testPrint);
- this.printSessionReceipt();
- this.checkouts = [];
- }
-}
-
-
-SelfCheckManager.prototype.getSelectedFinesTotal = function() {
- var total = 0;
- dojo.forEach(
- dojo.query("[name=selector]", this.finesTbody),
- function(input) {
- if(input.checked)
- total += Number(input.getAttribute("balance_owed"));
- }
- );
- return total.toFixed(2);
-};
-
-SelfCheckManager.prototype.getSelectedFineTransactions = function() {
- return dojo.query("[name=selector]", this.finesTbody).
- filter(function (o) { return o.checked }).
- map(
- function (o) {
- return [
- o.getAttribute("xact"),
- Number(o.getAttribute("balance_owed")).toFixed(2)
- ];
- }
- );
-};
-
-/**
- * Registers a new workstion
- */
-SelfCheckManager.prototype.registerWorkstation = function() {
-
- oilsSelfckWsDialog.show();
-
- new openils.User().buildPermOrgSelector(
- 'REGISTER_WORKSTATION',
- oilsSelfckWsLocSelector,
- this.staff.home_ou()
- );
-
-
- var self = this;
- dojo.connect(oilsSelfckWsSubmit, 'onClick',
-
- function() {
- oilsSelfckWsDialog.hide();
- var name = oilsSelfckWsLocSelector.attr('displayedValue') + '-' + oilsSelfckWsName.attr('value');
-
- var res = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.workstation.register'],
- { params : [
- self.authtoken, name, oilsSelfckWsLocSelector.attr('value')
- ]
- }
- );
-
- if(evt = openils.Event.parse(res)) {
- if(evt.textcode == 'WORKSTATION_NAME_EXISTS') {
- if(confirm(localeStrings.WORKSTATION_EXISTS)) {
- location.href = location.href.replace(/\?.*/, '') + '?ws=' + name;
- } else {
- self.registerWorkstation();
- }
- return;
- } else {
- alert(evt);
- }
- } else {
- location.href = location.href.replace(/\?.*/, '') + '?ws=' + name;
- }
- }
- );
-}
-
-/**
- * Loads the org unit settings
- */
-SelfCheckManager.prototype.loadOrgSettings = function() {
-
- var settings = fieldmapper.aou.fetchOrgSettingBatch(
- this.staff.ws_ou(), [
- SET_BARCODE_REGEX,
- SET_PATRON_TIMEOUT,
- SET_ALERT_POPUP,
- SET_ALERT_SOUND,
- SET_AUTO_OVERRIDE_EVENTS,
- SET_BLOCK_CHECKOUT_ON_COPY_STATUS,
- SET_PATRON_PASSWORD_REQUIRED,
- SET_AUTO_RENEW_INTERVAL,
- SET_WORKSTATION_REQUIRED,
- SET_CC_PAYMENT_ALLOWED
- ]
- );
-
- for(k in settings) {
- if(settings[k])
- this.orgSettings[k] = settings[k].value;
- }
-
- if(settings[SET_BARCODE_REGEX])
- this.patronBarcodeRegex = new RegExp(settings[SET_BARCODE_REGEX].value);
-}
-
-SelfCheckManager.prototype.drawLoginPage = function() {
- var self = this;
-
- var bcHandler = function(barcode_or_usrname) {
- // handle patron barcode/usrname entry
-
- if(self.orgSettings[SET_PATRON_PASSWORD_REQUIRED]) {
-
- // password is required. wire up the scan box to read it
- self.updateScanBox({
- msg : 'Please enter your password', // TODO i18n
- handler : function(pw) { self.loginPatron(barcode_or_usrname, pw); },
- password : true
- });
-
- } else {
- // password is not required, go ahead and login
- self.loginPatron(barcode_or_usrname);
- }
- };
-
- this.updateScanBox({
- msg : 'Please log in with your username or library barcode.', // TODO
- handler : bcHandler
- });
-}
-
-/**
- * Login the patron.
- */
-SelfCheckManager.prototype.loginPatron = function(barcode_or_usrname, passwd) {
-
- this.setupStaffLogin(true); // verify still valid
-
- var barcode = null;
- var usrname = null;
- console.log('testing ' + barcode_or_usrname);
- if (barcode_or_usrname.match(this.patronBarcodeRegex)) {
- console.log('barcode');
- barcode = barcode_or_usrname;
- } else {
- console.log('usrname');
- usrname = barcode_or_usrname;
- }
-
- if(this.orgSettings[SET_PATRON_PASSWORD_REQUIRED]) {
-
- if(!passwd) {
- // would only happen in dev/debug mode when using the patron= param
- alert('password required by org setting. remove patron= from URL');
- return;
- }
-
- // patron password is required. Verify it.
-
- var self = this;
- new openils.User().auth_verify(
- { username : usrname, barcode : barcode,
- type : 'opac', passwd : passwd, agent : 'selfcheck' },
- function(OK) {
- if (OK) {
- self.fetchPatron(barcode, usrname);
-
- } else {
- // auth verify failed
- self.handleAlert(
- dojo.string.substitute(localeStrings.LOGIN_FAILED, [barcode_or_usrname]),
- false, 'login-failure'
- );
- self.drawLoginPage();
- }
- }
- );
-
- } else {
- this.fetchPatron(barcode, usrname);
- }
-};
-
-SelfCheckManager.prototype.fetchPatron = function(barcode, usrname) {
-
- var patron_id = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.retrieve_id_by_barcode_or_username'],
- {params : [this.authtoken, barcode, usrname]}
- );
-
- // retrieve the fleshed user by id
- this.patron = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.fleshed.retrieve.authoritative'],
- {params : [this.authtoken, patron_id]}
- );
-
- var evt = openils.Event.parse(this.patron);
-
- // verify validity of the card used to log in
- var inactiveCard = false;
- if(!evt) {
- var card;
- if (barcode) {
- card = this.patron.cards().filter(
- function(c) { return (c.barcode() == barcode); })[0];
- } else {
- card = this.patron.card();
- }
- inactiveCard = !openils.Util.isTrue(card.active());
- }
-
- if(evt || inactiveCard) {
- this.handleAlert(
- dojo.string.substitute(localeStrings.LOGIN_FAILED, [barcode || usrname]),
- false, 'login-failure'
- );
- this.drawLoginPage();
-
- } else {
-
- this.handleAlert('', false, 'login-success');
- dojo.byId('oils-selfck-user-banner').innerHTML =
- dojo.string.substitute(localeStrings.WELCOME_BANNER, [this.patron.first_given_name()]);
- this.drawCircPage();
- }
-}
-
-
-SelfCheckManager.prototype.handleAlert = function(message, shouldPopup, sound) {
-
- console.log("Handling alert " + message);
-
- dojo.byId('oils-selfck-status-div').innerHTML = message;
-
- if(shouldPopup)
- openils.Util.addCSSClass( dojo.byId('oils-selfck-status-div'), 'checkout_failure' );
- else
- openils.Util.removeCSSClass( dojo.byId('oils-selfck-status-div'), 'checkout_failure' );
-
- if(shouldPopup && this.orgSettings[SET_ALERT_POPUP])
- alert(message);
-
- if(sound && this.orgSettings[SET_ALERT_SOUND])
- openils.Util.playAudioUrl(SelfCheckManager.audioConfig[sound]);
-}
-
-
-/**
- * Manages the main input box
- * @param msg The context message to display with the box
- * @param clearOnly Don't update the context message, just clear the value and re-focus
- * @param handler Optional "on-enter" handler.
- */
-SelfCheckManager.prototype.updateScanBox = function(args) {
- args = args || {};
-
- if(args.select) {
- selfckScanBox.domNode.select();
- } else {
- selfckScanBox.attr('value', '');
- }
-
- if(args.password) {
- selfckScanBox.domNode.setAttribute('type', 'password');
- } else {
- selfckScanBox.domNode.setAttribute('type', '');
- }
-
- if(args.value)
- selfckScanBox.attr('value', args.value);
-
- if(args.msg)
- dojo.byId('oils-selfck-scan-text').innerHTML = args.msg;
-
- if(selfckScanBox._lastHandler && (args.handler || args.clearHandler)) {
- dojo.disconnect(selfckScanBox._lastHandler);
- }
-
- if(args.handler) {
- selfckScanBox._lastHandler = dojo.connect(
- selfckScanBox,
- 'onKeyDown',
- function(e) {
- if(e.keyCode != dojo.keys.ENTER)
- return;
- args.handler(selfckScanBox.attr('value'));
- }
- );
- }
-
- selfckScanBox.focus();
-}
-
-/**
- * Sets up the checkout/renewal interface
- */
-SelfCheckManager.prototype.drawCircPage = function() {
-
- openils.Util.show('oils-selfck-circ-tbody', 'table-row-group');
- this.goToTab('checkout');
-
- while(this.itemsOutTbody.childNodes[0])
- this.itemsOutTbody.removeChild(this.itemsOutTbody.childNodes[0]);
-
- var self = this;
- this.updateScanBox({
- msg : 'Please enter an item barcode', // TODO i18n
- handler : function(barcode) { self.checkout(barcode); }
- });
-
- if(!this.circTemplate)
- this.circTemplate = this.circTbody.removeChild(dojo.byId('oils-selfck-circ-row'));
-
- // fines summary
- this.updateFinesSummary();
-
- // holds summary
- this.updateHoldsSummary();
-
- // items out summary
- this.updateCircSummary();
-
- // render mock checkouts for debugging?
- if(this.mockCheckouts) {
- for(var i in [1,2,3])
- this.displayCheckout(this.mockCheckout, 'checkout');
- }
-}
-
-
-SelfCheckManager.prototype.updateFinesSummary = function() {
- var self = this;
-
- // fines summary
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.fines.summary'],
- { async : true,
- params : [this.authtoken, this.patron.id()],
- oncomplete : function(r) {
-
- var summary = openils.Util.readResponse(r);
-
- dojo.byId('oils-selfck-fines-total').innerHTML =
- dojo.string.substitute(
- localeStrings.TOTAL_FINES_ACCOUNT,
- [summary.balance_owed()]
- );
-
- self.creditPayableBalance = summary.balance_owed();
- }
- }
- );
-}
-
-
-SelfCheckManager.prototype.drawItemsOutPage = function() {
- openils.Util.hide('oils-selfck-circ-tbody');
-
- this.goToTab('items_out');
-
- while(this.itemsOutTbody.childNodes[0])
- this.itemsOutTbody.removeChild(this.itemsOutTbody.childNodes[0]);
-
- progressDialog.show(true);
-
- var self = this;
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.actor.user.checked_out.atomic'],
- {
- async : true,
- params : [this.authtoken, this.patron.id()],
- oncomplete : function(r) {
-
- var resp = openils.Util.readResponse(r);
-
- var circs = resp.sort(
- function(a, b) {
- if(a.circ.due_date() > b.circ.due_date())
- return -1;
- return 1;
- }
- );
-
- progressDialog.hide();
-
- self.itemsOut = [];
- dojo.forEach(circs,
- function(circ) {
- self.itemsOut.push(circ.circ.id());
- self.displayCheckout(
- {payload : circ},
- (circ.circ.parent_circ()) ? 'renew' : 'checkout',
- true
- );
- }
- );
- }
- }
- );
-}
-
-
-SelfCheckManager.prototype.goToTab = function(name) {
- this.tabName = name;
-
- openils.Util.hide('oils-selfck-fines-page');
- openils.Util.hide('oils-selfck-payment-page');
- openils.Util.hide('oils-selfck-holds-page');
- openils.Util.hide('oils-selfck-circ-page');
- openils.Util.hide('oils-selfck-pay-fines-link');
-
- switch(name) {
- case 'checkout':
- openils.Util.show('oils-selfck-circ-page');
- break;
- case 'items_out':
- openils.Util.show('oils-selfck-circ-page');
- break;
- case 'holds':
- openils.Util.show('oils-selfck-holds-page');
- break;
- case 'fines':
- openils.Util.show('oils-selfck-fines-page');
- break;
- case 'payment':
- openils.Util.show('oils-selfck-payment-page');
- break;
- }
-}
-
-
-SelfCheckManager.prototype.printList = function() {
- switch(this.tabName) {
- case 'checkout':
- this.printSessionReceipt();
- break;
- case 'items_out':
- this.printItemsOutReceipt();
- break;
- case 'holds':
- this.printHoldsReceipt();
- break;
- case 'fines':
- this.printFinesReceipt();
- break;
- }
-}
-
-SelfCheckManager.prototype.updateHoldsSummary = function() {
-
- if(!this.holdsSummary) {
- var summary = fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.holds.user_summary'],
- {params : [this.authtoken, this.patron.id()]}
- );
-
- this.holdsSummary = {};
- this.holdsSummary.ready = Number(summary['4']);
- this.holdsSummary.total = 0;
-
- for(var i in summary)
- this.holdsSummary.total += Number(summary[i]);
- }
-
- dojo.byId('oils-selfck-holds-total').innerHTML =
- dojo.string.substitute(
- localeStrings.TOTAL_HOLDS,
- [this.holdsSummary.total]
- );
-
- dojo.byId('oils-selfck-holds-ready').innerHTML =
- dojo.string.substitute(
- localeStrings.HOLDS_READY_FOR_PICKUP,
- [this.holdsSummary.ready]
- );
-}
-
-
-SelfCheckManager.prototype.updateCircSummary = function(increment) {
-
- if(!this.circSummary) {
-
- var summary = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.checked_out.count'],
- {params : [this.authtoken, this.patron.id()]}
- );
-
- this.circSummary = {
- total : Number(summary.out) + Number(summary.overdue),
- overdue : Number(summary.overdue),
- session : 0
- };
- }
-
- if(increment) {
- // local checkout occurred. Add to the total and the session.
- this.circSummary.total += 1;
- this.circSummary.session += 1;
- }
-
- dojo.byId('oils-selfck-circ-account-total').innerHTML =
- dojo.string.substitute(
- localeStrings.TOTAL_ITEMS_ACCOUNT,
- [this.circSummary.total]
- );
-
- dojo.byId('oils-selfck-circ-session-total').innerHTML =
- dojo.string.substitute(
- localeStrings.TOTAL_ITEMS_SESSION,
- [this.circSummary.session]
- );
-}
-
-
-SelfCheckManager.prototype.drawHoldsPage = function() {
-
- // TODO add option to hid scanBox
- // this.updateScanBox(...)
-
- this.goToTab('holds');
-
- this.holdTbody = dojo.byId('oils-selfck-hold-tbody');
- if(!this.holdTemplate)
- this.holdTemplate = this.holdTbody.removeChild(dojo.byId('oils-selfck-hold-row'));
- while(this.holdTbody.childNodes[0])
- this.holdTbody.removeChild(this.holdTbody.childNodes[0]);
-
- progressDialog.show(true);
-
- var self = this;
- fieldmapper.standardRequest( // fetch the hold IDs
-
- ['open-ils.circ', 'open-ils.circ.holds.id_list.retrieve'],
- { async : true,
- params : [this.authtoken, this.patron.id()],
-
- oncomplete : function(r) {
- var ids = openils.Util.readResponse(r);
- if(!ids || ids.length == 0) {
- progressDialog.hide();
- return;
- }
-
- fieldmapper.standardRequest( // fetch the hold objects with fleshed details
- ['open-ils.circ', 'open-ils.circ.hold.details.batch.retrieve'],
- { async : true,
- params : [self.authtoken, ids],
- onresponse : function(rr) {
- progressDialog.hide();
- self.insertHold(openils.Util.readResponse(rr));
- }
- }
- );
- }
- }
- );
-}
-
-SelfCheckManager.prototype.insertHold = function(data) {
- var row = this.holdTemplate.cloneNode(true);
-
- if(data.mvr.isbn()) {
- this.byName(row, 'jacket').setAttribute('src', '/opac/extras/ac/jacket/small/' + data.mvr.isbn());
- }
-
- this.byName(row, 'title').innerHTML = data.mvr.title();
- this.byName(row, 'author').innerHTML = data.mvr.author();
-
- if(data.status == 4) {
-
- // hold is ready for pickup
- this.byName(row, 'status').innerHTML = localeStrings.HOLD_STATUS_READY;
-
- } else {
-
- // hold is still pending
- this.byName(row, 'status').innerHTML =
- dojo.string.substitute(
- localeStrings.HOLD_STATUS_WAITING,
- [data.queue_position, data.potential_copies]
- );
- }
-
- // find the correct place the table to slot in the hold based on queue position
-
- var position = (data.status == 4) ? 0 : data.queue_position;
- row.setAttribute('position', position);
-
- for(var i = 0; i < this.holdTbody.childNodes.length; i++) {
- var node = this.holdTbody.childNodes[i];
- if(Number(node.getAttribute('position')) >= position) {
- this.holdTbody.insertBefore(row, node);
- return;
- }
- }
-
- this.holdTbody.appendChild(row);
-}
-
-
-SelfCheckManager.prototype.drawFinesPage = function() {
-
- // TODO add option to hid scanBox
- // this.updateScanBox(...)
-
- this.goToTab('fines');
- progressDialog.show(true);
-
- if(this.creditPayableBalance > 0 && this.orgSettings[SET_CC_PAYMENT_ALLOWED]) {
- openils.Util.show('oils-selfck-pay-fines-link', 'inline');
- }
-
- this.finesTbody = dojo.byId('oils-selfck-fines-tbody');
- if(!this.finesTemplate)
- this.finesTemplate = this.finesTbody.removeChild(dojo.byId('oils-selfck-fines-row'));
- while(this.finesTbody.childNodes[0])
- this.finesTbody.removeChild(this.finesTbody.childNodes[0]);
-
- // when user clicks on a selector checkbox, update the total owed
- var updateSelected = function() {
- var total = 0;
- dojo.forEach(
- dojo.query('[name=selector]', this.finesTbody),
- function(input) {
- if(input.checked)
- total += Number(input.getAttribute('balance_owed'));
- }
- );
-
- total = total.toFixed(2);
- dojo.byId('oils-selfck-selected-total').innerHTML =
- dojo.string.substitute(localeStrings.TOTAL_FINES_SELECTED, [total]);
- }
-
- // wire up the batch on/off selector
- var sel = dojo.byId('oils-selfck-fines-selector');
- sel.onchange = function() {
- dojo.forEach(
- dojo.query('[name=selector]', this.finesTbody),
- function(input) {
- input.checked = sel.checked;
- }
- );
- };
-
- var self = this;
- var handler = function(dataList) {
-
- self.finesCount = dataList.length;
- self.finesData = dataList;
-
- for(var i in dataList) {
-
- var data = dataList[i];
- var row = self.finesTemplate.cloneNode(true);
- var type = data.transaction.xact_type();
-
- if(type == 'circulation') {
- self.byName(row, 'type').innerHTML = type;
- self.byName(row, 'details').innerHTML = data.record.title();
-
- } else if(type == 'grocery') {
- self.byName(row, 'type').innerHTML = 'Miscellaneous'; // Go ahead and head off any confusion around "grocery". TODO i18n
- self.byName(row, 'details').innerHTML = data.transaction.last_billing_type();
- }
-
- self.byName(row, 'total_owed').innerHTML = data.transaction.total_owed();
- self.byName(row, 'total_paid').innerHTML = data.transaction.total_paid();
- self.byName(row, 'balance').innerHTML = data.transaction.balance_owed();
-
- // row selector
- var selector = self.byName(row, 'selector')
- selector.onchange = updateSelected;
- selector.setAttribute('xact', data.transaction.id());
- selector.setAttribute('balance_owed', data.transaction.balance_owed());
- selector.checked = true;
-
- self.finesTbody.appendChild(row);
- }
-
- updateSelected();
- }
-
-
- fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.transactions.have_balance.fleshed'],
- { async : true,
- params : [this.authtoken, this.patron.id()],
- oncomplete : function(r) {
- progressDialog.hide();
- handler(openils.Util.readResponse(r));
- }
- }
- );
-}
-
-SelfCheckManager.prototype.checkin = function(barcode, abortTransit) {
-
- var resp = fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.transit.abort'],
- {params : [this.authtoken, {barcode : barcode}]}
- );
-
- // resp == 1 on success
- if(openils.Event.parse(resp))
- return false;
-
- var resp = fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.checkin.override'],
- {params : [
- this.authtoken, {
- patron_id : this.patron.id(),
- copy_barcode : barcode,
- noop : true
- }
- ]}
- );
-
- if(!resp.length) resp = [resp];
- for(var i = 0; i < resp.length; i++) {
- var tc = openils.Event.parse(resp[i]).textcode;
- if(tc == 'SUCCESS' || tc == 'NO_CHANGE') {
- continue;
- } else {
- return false;
- }
- }
-
- return true;
-}
-
-/**
- * Check out a single item. If the item is already checked
- * out to the patron, redirect to renew()
- */
-SelfCheckManager.prototype.checkout = function(barcode, override) {
-
- this.prevCirc = null;
-
- if(!barcode) {
- this.updateScanbox(null, true);
- return;
- }
-
- if(this.mockCheckouts) {
- // if we're in mock-checkout mode, just insert another
- // fake circ into the table and get out of here.
- this.displayCheckout(this.mockCheckout, 'checkout');
- return;
- }
-
- // TODO see if it's a patron barcode
- // TODO see if this item has already been checked out in this session
-
- var method = 'open-ils.circ.checkout.full';
- if(override) method += '.override';
-
- console.log("Checkout out item " + barcode + " with method " + method);
-
- var result = fieldmapper.standardRequest(
- ['open-ils.circ', method],
- {params: [
- this.authtoken, {
- patron_id : this.patron.id(),
- copy_barcode : barcode
- }
- ]}
- );
-
- var stat = this.handleXactResult('checkout', barcode, result);
-
- if(stat.override) {
- this.checkout(barcode, true);
- } else if(stat.doOver) {
- this.checkout(barcode);
- } else if(stat.renew) {
- this.renew(barcode);
- }
-}
-
-SelfCheckManager.prototype.failPartMessage = function(result) {
- if (result.payload && result.payload.fail_part) {
- var stringKey = "FAIL_PART_" +
- result.payload.fail_part.replace(/\./g, "_");
- return localeStrings[stringKey];
- } else {
- return null;
- }
-}
-
-SelfCheckManager.prototype.handleXactResult = function(action, item, result) {
-
- var displayText = '';
-
- // If true, the display message is important enough to pop up. Whether or not
- // an alert() actually occurs, depends on org unit settings
- var popup = false;
- var sound = ''; // sound file reference
- var payload = result.payload || {};
- var overrideEvents = this.orgSettings[SET_AUTO_OVERRIDE_EVENTS];
- var blockStatuses = this.orgSettings[SET_BLOCK_CHECKOUT_ON_COPY_STATUS];
-
- if(result.textcode == 'NO_SESSION') {
-
- return this.logoutStaff();
-
- } else if(result.textcode == 'SUCCESS') {
-
- if(action == 'checkout') {
-
- displayText = dojo.string.substitute(localeStrings.CHECKOUT_SUCCESS, [item]);
- this.displayCheckout(result, 'checkout');
-
- if(payload.holds_fulfilled && payload.holds_fulfilled.length) {
- // A hold was fulfilled, update the hold numbers in the circ summary
- console.log("fulfilled hold " + payload.holds_fulfilled + " during checkout");
- this.holdsSummary = null;
- this.updateHoldsSummary();
- }
-
- this.updateCircSummary(true);
-
- } else if(action == 'renew') {
-
- displayText = dojo.string.substitute(localeStrings.RENEW_SUCCESS, [item]);
- this.displayCheckout(result, 'renew');
- }
-
- this.checkouts.push({circ : result.payload.circ.id()});
- sound = 'checkout-success';
- this.updateScanBox();
-
- } else if(result.textcode == 'OPEN_CIRCULATION_EXISTS' && action == 'checkout') {
-
- // Server says the item is already checked out. If it's checked out to the
- // current user, we may need to renew it.
-
- if(payload.old_circ) {
-
- /*
- old_circ refers to the previous checkout IFF it's for the same user.
- If no auto-renew interval is not defined, assume we should renew it
- If an auto-renew interval is defined and the payload comes back with
- auto_renew set to true, do the renewal. Otherwise, let the patron know
- the item is already checked out to them. */
-
- if( !this.orgSettings[SET_AUTO_RENEW_INTERVAL] ||
- (this.orgSettings[SET_AUTO_RENEW_INTERVAL] && payload.auto_renew) ) {
- this.prevCirc = payload.old_circ.id();
- return { renew : true };
- }
-
- popup = true;
- sound = 'checkout-failure';
- displayText = dojo.string.substitute(localeStrings.ALREADY_OUT, [item]);
-
- } else {
-
- if( // copy is marked lost. if configured to do so, check it in and try again.
- result.payload.copy &&
- result.payload.copy.status() == /* LOST */ 3 &&
- overrideEvents && overrideEvents.length &&
- overrideEvents.indexOf('COPY_STATUS_LOST') != -1) {
-
- if(this.checkin(item)) {
- return { doOver : true };
- }
- }
-
-
- // item is checked out to some other user
- popup = true;
- sound = 'checkout-failure';
- displayText = dojo.string.substitute(localeStrings.OPEN_CIRCULATION_EXISTS, [item]);
- }
-
- this.updateScanBox({select:true});
-
- } else {
-
-
- if(overrideEvents && overrideEvents.length) {
-
- // see if the events we received are all in the list of
- // events to override
-
- if(!result.length) result = [result];
-
- var override = true;
- for(var i = 0; i < result.length; i++) {
-
- var match = overrideEvents.filter(function(e) { return (e == result[i].textcode); })[0];
-
- if(!match) {
- override = false;
- break;
- }
-
- if(result[i].textcode == 'COPY_NOT_AVAILABLE' && blockStatuses && blockStatuses.length) {
-
- var stat = result[i].payload.status(); // copy status
- if(typeof stat == 'object') stat = stat.id();
-
- var match2 = blockStatuses.filter(function(e) { return (e == stat); })[0];
-
- if(match2) { // copy is in a blocked status
- override = false;
- break;
- }
- }
-
- if(result[i].textcode == 'COPY_IN_TRANSIT') {
- // to override a transit, we have to abort the transit and check it in first
- if(this.checkin(item, true)) {
- return { doOver : true };
- } else {
- override = false;
- }
- }
- }
-
- if(override)
- return { override : true };
- }
-
- this.updateScanBox({select : true});
- popup = true;
- sound = 'checkout-failure';
-
- if(action == 'renew')
- this.checkouts.push({circ : this.prevCirc, renewal_failure : true});
-
- if(result.length)
- result = result[0];
-
- switch(result.textcode) {
-
- // TODO custom handler for blocking penalties
-
- case 'MAX_RENEWALS_REACHED' :
- displayText = dojo.string.substitute(
- localeStrings.MAX_RENEWALS, [item]);
- break;
-
- case 'ITEM_NOT_CATALOGED' :
- displayText = dojo.string.substitute(
- localeStrings.ITEM_NOT_CATALOGED, [item]);
- break;
-
- case 'OPEN_CIRCULATION_EXISTS' :
- displayText = dojo.string.substitute(
- localeStrings.OPEN_CIRCULATION_EXISTS, [item]);
-
- break;
-
- default:
- console.error('Unhandled event ' + result.textcode);
-
- if (!(displayText = this.failPartMessage(result))) {
- if (action == 'checkout' || action == 'renew') {
- displayText = dojo.string.substitute(
- localeStrings.GENERIC_CIRC_FAILURE, [item]);
- } else {
- displayText = dojo.string.substitute(
- localeStrings.UNKNOWN_ERROR, [result.textcode]);
- }
- }
- }
- }
-
- this.handleAlert(displayText, popup, sound);
- return {};
-}
-
-
-/**
- * Renew an item
- */
-SelfCheckManager.prototype.renew = function(barcode, override) {
-
- var method = 'open-ils.circ.renew';
- if(override) method += '.override';
-
- console.log("Renewing item " + barcode + " with method " + method);
-
- var result = fieldmapper.standardRequest(
- ['open-ils.circ', method],
- {params: [
- this.authtoken, {
- patron_id : this.patron.id(),
- copy_barcode : barcode
- }
- ]}
- );
-
- console.log(js2JSON(result));
-
- var stat = this.handleXactResult('renew', barcode, result);
-
- if(stat.override)
- this.renew(barcode, true);
-}
-
-/**
- * Display the result of a checkout or renewal in the items out table
- */
-SelfCheckManager.prototype.displayCheckout = function(evt, type, itemsOut) {
-
- var copy = evt.payload.copy;
- var record = evt.payload.record;
- var circ = evt.payload.circ;
- var row = this.circTemplate.cloneNode(true);
-
- if(record.isbn()) {
- this.byName(row, 'jacket').setAttribute('src', '/opac/extras/ac/jacket/small/' + record.isbn());
- }
-
- this.byName(row, 'barcode').innerHTML = copy.barcode();
- this.byName(row, 'title').innerHTML = record.title();
- this.byName(row, 'author').innerHTML = record.author();
- this.byName(row, 'remaining').innerHTML = circ.renewal_remaining();
- openils.Util.show(this.byName(row, type));
-
- var date = dojo.date.stamp.fromISOString(circ.due_date());
- this.byName(row, 'due_date').innerHTML =
- dojo.date.locale.format(date, {selector : 'date'});
-
- // put new circs at the top of the list
- var tbody = this.circTbody;
- if(itemsOut) tbody = this.itemsOutTbody;
- tbody.insertBefore(row, tbody.getElementsByTagName('tr')[0]);
-}
-
-
-SelfCheckManager.prototype.byName = function(node, name) {
- return dojo.query('[name=' + name+']', node)[0];
-}
-
-
-SelfCheckManager.prototype.initPrinter = function() {
- try { // Mozilla only
- netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
- netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
- netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesRead');
- netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesWrite');
- var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
- if (pref)
- pref.setBoolPref('print.always_print_silent', true);
- } catch(E) {
- console.log("Unable to initialize auto-printing");
- }
-}
-
-/**
- * Print a receipt for this session's checkouts
- */
-SelfCheckManager.prototype.printSessionReceipt = function(callback) {
-
- var circIds = [];
- var circCtx = []; // circ context data. in this case, renewal_failure info
-
- // collect the circs and failure info
- dojo.forEach(
- this.checkouts,
- function(blob) {
- circIds.push(blob.circ);
- circCtx.push({renewal_failure:blob.renewal_failure});
- }
- );
-
- var params = [
- this.authtoken,
- this.staff.ws_ou(),
- null,
- 'format.selfcheck.checkout',
- 'print-on-demand',
- circIds,
- circCtx
- ];
-
- var self = this;
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.fire_circ_trigger_events'],
- {
- async : true,
- params : params,
- oncomplete : function(r) {
- var resp = openils.Util.readResponse(r);
- var output = resp.template_output();
- if(output) {
- self.printData(output.data(), self.checkouts.length, callback);
- } else {
- var error = resp.error_output();
- if(error) {
- throw new Error("Error creating receipt: " + error.data());
- } else {
- throw new Error("No receipt data returned from server");
- }
- }
- }
- }
- );
-}
-
-SelfCheckManager.prototype.printData = function(data, numItems, callback) {
-
- var win = window.open('', '', 'resizable,width=700,height=500,scrollbars=1');
- win.document.body.innerHTML = data;
- win.print();
-
- /*
- * There is no way to know when the browser is done printing.
- * Make a best guess at when to close the print window by basing
- * the setTimeout wait on the number of items to be printed plus
- * a small buffer
- */
- var sleepTime = 1000;
- if(numItems > 0)
- sleepTime += (numItems / 2) * 1000;
-
- setTimeout(
- function() {
- win.close(); // close the print window
- if(callback)
- callback(); // fire optional post-print callback
- },
- sleepTime
- );
-}
-
-
-/**
- * Print a receipt for this user's items out
- */
-SelfCheckManager.prototype.printItemsOutReceipt = function(callback) {
-
- if(!this.itemsOut.length) return;
-
- progressDialog.show(true);
-
- var params = [
- this.authtoken,
- this.staff.ws_ou(),
- null,
- 'format.selfcheck.items_out',
- 'print-on-demand',
- this.itemsOut
- ];
-
- var self = this;
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.fire_circ_trigger_events'],
- {
- async : true,
- params : params,
- oncomplete : function(r) {
- progressDialog.hide();
- var resp = openils.Util.readResponse(r);
- var output = resp.template_output();
- if(output) {
- self.printData(output.data(), self.itemsOut.length, callback);
- } else {
- var error = resp.error_output();
- if(error) {
- throw new Error("Error creating receipt: " + error.data());
- } else {
- throw new Error("No receipt data returned from server");
- }
- }
- }
- }
- );
-}
-
-/**
- * Print a receipt for this user's items out
- */
-SelfCheckManager.prototype.printHoldsReceipt = function(callback) {
-
- if(!this.holds.length) return;
-
- progressDialog.show(true);
-
- var holdIds = [];
- var holdData = [];
-
- dojo.forEach(this.holds,
- function(data) {
- holdIds.push(data.hold.id());
- if(data.status == 4) {
- holdData.push({ready : true});
- } else {
- holdData.push({
- queue_position : data.queue_position,
- potential_copies : data.potential_copies
- });
- }
- }
- );
-
- var params = [
- this.authtoken,
- this.staff.ws_ou(),
- null,
- 'format.selfcheck.holds',
- 'print-on-demand',
- holdIds,
- holdData
- ];
-
- var self = this;
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.fire_hold_trigger_events'],
- {
- async : true,
- params : params,
- oncomplete : function(r) {
- progressDialog.hide();
- var resp = openils.Util.readResponse(r);
- var output = resp.template_output();
- if(output) {
- self.printData(output.data(), self.holds.length, callback);
- } else {
- var error = resp.error_output();
- if(error) {
- throw new Error("Error creating receipt: " + error.data());
- } else {
- throw new Error("No receipt data returned from server");
- }
- }
- }
- }
- );
-}
-
-
-SelfCheckManager.prototype.printPaymentReceipt = function(response, callback) {
-
- var self = this;
- progressDialog.show(true);
-
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.money.payment_receipt.print'],
- {
- async : true,
- params : [this.authtoken, response.payments],
- oncomplete : function(r) {
- var resp = openils.Util.readResponse(r);
- var output = resp.template_output();
- progressDialog.hide();
- if(output) {
- self.printData(output.data(), 1, callback);
- } else {
- var error = resp.error_output();
- if(error) {
- throw new Error("Error creating receipt: " + error.data());
- } else {
- throw new Error("No receipt data returned from server");
- }
- }
- }
- }
- );
-}
-
-/**
- * Print a receipt for this user's items out
- */
-SelfCheckManager.prototype.printFinesReceipt = function(callback) {
-
- progressDialog.show(true);
-
- var params = [
- this.authtoken,
- this.staff.ws_ou(),
- null,
- 'format.selfcheck.fines',
- 'print-on-demand',
- [this.patron.id()]
- ];
-
- var self = this;
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.fire_user_trigger_events'],
- {
- async : true,
- params : params,
- oncomplete : function(r) {
- progressDialog.hide();
- var resp = openils.Util.readResponse(r);
- var output = resp.template_output();
- if(output) {
- self.printData(output.data(), self.finesCount, callback);
- } else {
- var error = resp.error_output();
- if(error) {
- throw new Error("Error creating receipt: " + error.data());
- } else {
- throw new Error("No receipt data returned from server");
- }
- }
- }
- }
- );
-}
-
-
-
-
-/**
- * Logout the patron and return to the login page
- */
-SelfCheckManager.prototype.logoutPatron = function(print) {
- progressDialog.show(true); // prevent patron from clicking logout link twice
- if(print && this.checkouts.length) {
- this.printSessionReceipt(
- function() {
- location.href = location.href;
- }
- );
- } else {
- location.href = location.href;
- }
-}
-
-
-/**
- * Fire up the manager on page load
- */
-openils.Util.addOnLoad(
- function() {
- new SelfCheckManager().init();
- }
-);
+require([
+ "dojo/date/locale",
+ "dojo/cookie",
+ "dojo/date/stamp",
+ "dijit/form/CheckBox",
+ "dijit/form/NumberSpinner",
+ "openils/CGI",
+ "openils/Util",
+ "openils/User",
+ "openils/Event",
+ "openils/widget/ProgressDialog",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(dojo_date_locale,
+ dojo_cookie,
+ dojo_date_stamp,
+ dijit_form_CheckBox,
+ dijit_form_NumberSpinner,
+ openils_CGI,
+ openils_Util,
+ openils_User,
+ openils_Event,
+ openils_widget_ProgressDialog,
+ openils_widget_OrgUnitFilteringSelect){
+
+
+ dojo.requireLocalization('openils.circ', 'selfcheck');
+ var localeStrings = dojo.i18n.getLocalization('openils.circ', 'selfcheck');
+
+
+ const SET_BARCODE_REGEX = 'opac.barcode_regex';
+ const SET_PATRON_TIMEOUT = 'circ.selfcheck.patron_login_timeout';
+ const SET_AUTO_OVERRIDE_EVENTS = 'circ.selfcheck.auto_override_checkout_events';
+ const SET_PATRON_PASSWORD_REQUIRED = 'circ.selfcheck.patron_password_required';
+ const SET_AUTO_RENEW_INTERVAL = 'circ.checkout_auto_renew_age';
+ const SET_WORKSTATION_REQUIRED = 'circ.selfcheck.workstation_required';
+ const SET_ALERT_POPUP = 'circ.selfcheck.alert.popup';
+ const SET_ALERT_SOUND = 'circ.selfcheck.alert.sound';
+ const SET_CC_PAYMENT_ALLOWED = 'credit.payments.allow';
+ // This setting only comes into play if COPY_NOT_AVAILABLE is in the SET_AUTO_OVERRIDE_EVENTS list
+ const SET_BLOCK_CHECKOUT_ON_COPY_STATUS = 'circ.selfcheck.block_checkout_on_copy_status';
+
+ // set before the login dialog is rendered
+ openils_User.default_login_agent = 'selfcheck';
+
+ function SelfCheckManager() {
+
+ this.cgi = new openils_CGI();
+ this.staff = null;
+ this.workstation = null;
+ this.authtoken = null;
+
+ this.patron = null;
+ this.patronBarcodeRegex = null;
+
+ this.checkouts = [];
+ this.itemsOut = [];
+
+ // During renewals, keep track of the ID of the previous circulation.
+ // Previous circ is used for tracking failed renewals (for receipts).
+ this.prevCirc = null;
+
+ // current item barcode
+ this.itemBarcode = null;
+
+ // are we currently performing a renewal?
+ this.isRenewal = false;
+
+ // dict of org unit settings for "here"
+ this.orgSettings = {};
+
+ // Construct a mock checkout for debugging purposes
+ if(this.mockCheckouts = this.cgi.param('mock-circ')) {
+
+ this.mockCheckout = {
+ payload : {
+ record : new fieldmapper.mvr(),
+ copy : new fieldmapper.acp(),
+ circ : new fieldmapper.circ()
+ }
+ };
+
+ this.mockCheckout.payload.record.title('Jazz improvisation for guitar');
+ this.mockCheckout.payload.record.author('Wise, Les');
+ this.mockCheckout.payload.record.isbn('0634033565');
+ this.mockCheckout.payload.copy.barcode('123456789');
+ this.mockCheckout.payload.circ.renewal_remaining(1);
+ this.mockCheckout.payload.circ.parent_circ(1);
+ this.mockCheckout.payload.circ.due_date('2012-12-21');
+ }
+
+ this.initPrinter();
+ }
+
+ SelfCheckManager.prototype.setupStaffLogin = function(verify) {
+
+ if(verify) oilsSetupUser();
+ this.staff = openils_User.user;
+ this.workstation = openils_User.workstation;
+ this.authtoken = openils_User.authtoken;
+ }
+
+
+
+ /**
+ * Fetch the org-unit settings, initialize the display, etc.
+ */
+ SelfCheckManager.prototype.init = function() {
+
+ this.setupStaffLogin();
+ this.loadOrgSettings();
+
+ this.circTbody = dojo.byId('oils-selfck-circ-tbody');
+ this.itemsOutTbody = dojo.byId('oils-selfck-circ-out-tbody');
+
+ // workstation is required but none provided
+ if(this.orgSettings[SET_WORKSTATION_REQUIRED] && !this.workstation) {
+ if(confirm(dojo.string.substitute(localeStrings.WORKSTATION_REQUIRED))) {
+ this.registerWorkstation();
+ }
+ return;
+ }
+
+ var self = this;
+ // connect onclick handlers to the various navigation links
+ var linkHandlers = {
+ 'oils-selfck-hold-details-link' : function() { self.drawHoldsPage(); },
+ 'oils-selfck-view-fines-link' : function() { self.drawFinesPage(); },
+ 'oils-selfck-pay-fines-link' : function() {
+ self.goToTab("payment");
+ self.drawPayFinesPage(
+ self.patron,
+ self.getSelectedFinesTotal(),
+ self.getSelectedFineTransactions(),
+ function(resp) {
+ var evt = openils_Event.parse(resp);
+ if(evt) {
+ var message = evt + '';
+ if(evt.textcode == 'CREDIT_PROCESSOR_DECLINED_TRANSACTION' && evt.payload)
+ message += '\n' + evt.payload.error_message;
+ if(evt.textcode == 'INVALID_USER_XACT_ID')
+ message += '\n' + localeStrings.PAYMENT_INVALID_USER_XACT_ID;
+ self.handleAlert(message, true, 'payment-failure');
+ return;
+ }
+
+ self.patron.last_xact_id(resp.last_xact_id); // update to match latest from server
+ self.printPaymentReceipt(
+ resp,
+ function() {
+ self.updateFinesSummary();
+ self.drawFinesPage();
+ }
+ );
+ }
+ );
+ },
+ 'oils-selfck-nav-home' : function() { self.drawCircPage(); },
+ 'oils-selfck-nav-logout' : function() { self.logoutPatron(); },
+ 'oils-selfck-nav-logout-print' : function() { self.logoutPatron(true); },
+ 'oils-selfck-items-out-details-link' : function() { self.drawItemsOutPage(); },
+ 'oils-selfck-print-list-link' : function() { self.printList(); }
+ }
+
+ for(var id in linkHandlers)
+ dojo.connect(dojo.byId(id), 'onclick', linkHandlers[id]);
+
+
+ if(this.cgi.param('patron')) {
+
+ // Patron barcode via cgi param. Mainly used for debugging and
+ // only works if password is not required by policy
+ this.loginPatron(this.cgi.param('patron'));
+
+ } else {
+ this.drawLoginPage();
+ }
+
+ /**
+ * To test printing, pass a URL param of 'testprint'. The value for the param
+ * should be a JSON string like so: [{circ:<circ_id>}, ...]
+ */
+ var testPrint = this.cgi.param('testprint');
+ if(testPrint) {
+ this.checkouts = JSON2js(testPrint);
+ this.printSessionReceipt();
+ this.checkouts = [];
+ }
+ }
+
+
+ SelfCheckManager.prototype.getSelectedFinesTotal = function() {
+ var total = 0;
+ dojo.forEach(
+ dojo.query("[name=selector]", this.finesTbody),
+ function(input) {
+ if(input.checked)
+ total += Number(input.getAttribute("balance_owed"));
+ }
+ );
+ return total.toFixed(2);
+ };
+
+ SelfCheckManager.prototype.getSelectedFineTransactions = function() {
+ return dojo.query("[name=selector]", this.finesTbody).
+ filter(function (o) { return o.checked }).
+ map(
+ function (o) {
+ return [
+ o.getAttribute("xact"),
+ Number(o.getAttribute("balance_owed")).toFixed(2)
+ ];
+ }
+ );
+ };
+
+ /**
+ * Registers a new workstion
+ */
+ SelfCheckManager.prototype.registerWorkstation = function() {
+
+ oilsSelfckWsDialog.show();
+
+ new openils_User().buildPermOrgSelector(
+ 'REGISTER_WORKSTATION',
+ oilsSelfckWsLocSelector,
+ this.staff.home_ou()
+ );
+
+
+ var self = this;
+ dojo.connect(oilsSelfckWsSubmit, 'onClick',
+
+ function() {
+ oilsSelfckWsDialog.hide();
+ var name = oilsSelfckWsLocSelector.attr('displayedValue') + '-' + oilsSelfckWsName.attr('value');
+
+ var res = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.workstation.register'],
+ { params : [
+ self.authtoken, name, oilsSelfckWsLocSelector.attr('value')
+ ]
+ }
+ );
+
+ if(evt = openils_Event.parse(res)) {
+ if(evt.textcode == 'WORKSTATION_NAME_EXISTS') {
+ if(confirm(localeStrings.WORKSTATION_EXISTS)) {
+ location.href = location.href.replace(/\?.*/, '') + '?ws=' + name;
+ } else {
+ self.registerWorkstation();
+ }
+ return;
+ } else {
+ alert(evt);
+ }
+ } else {
+ location.href = location.href.replace(/\?.*/, '') + '?ws=' + name;
+ }
+ }
+ );
+ }
+
+ /**
+ * Loads the org unit settings
+ */
+ SelfCheckManager.prototype.loadOrgSettings = function() {
+
+ var settings = fieldmapper.aou.fetchOrgSettingBatch(
+ this.staff.ws_ou(), [
+ SET_BARCODE_REGEX,
+ SET_PATRON_TIMEOUT,
+ SET_ALERT_POPUP,
+ SET_ALERT_SOUND,
+ SET_AUTO_OVERRIDE_EVENTS,
+ SET_BLOCK_CHECKOUT_ON_COPY_STATUS,
+ SET_PATRON_PASSWORD_REQUIRED,
+ SET_AUTO_RENEW_INTERVAL,
+ SET_WORKSTATION_REQUIRED,
+ SET_CC_PAYMENT_ALLOWED
+ ]
+ );
+
+ for(k in settings) {
+ if(settings[k])
+ this.orgSettings[k] = settings[k].value;
+ }
+
+ if(settings[SET_BARCODE_REGEX])
+ this.patronBarcodeRegex = new RegExp(settings[SET_BARCODE_REGEX].value);
+ }
+
+ SelfCheckManager.prototype.drawLoginPage = function() {
+ var self = this;
+
+ var bcHandler = function(barcode_or_usrname) {
+ // handle patron barcode/usrname entry
+
+ if(self.orgSettings[SET_PATRON_PASSWORD_REQUIRED]) {
+
+ // password is required. wire up the scan box to read it
+ self.updateScanBox({
+ msg : 'Please enter your password', // TODO i18n
+ handler : function(pw) { self.loginPatron(barcode_or_usrname, pw); },
+ password : true
+ });
+
+ } else {
+ // password is not required, go ahead and login
+ self.loginPatron(barcode_or_usrname);
+ }
+ };
+
+ this.updateScanBox({
+ msg : 'Please log in with your username or library barcode.', // TODO
+ handler : bcHandler
+ });
+ }
+
+ /**
+ * Login the patron.
+ */
+ SelfCheckManager.prototype.loginPatron = function(barcode_or_usrname, passwd) {
+
+ this.setupStaffLogin(true); // verify still valid
+
+ var barcode = null;
+ var usrname = null;
+ console.log('testing ' + barcode_or_usrname);
+ if (barcode_or_usrname.match(this.patronBarcodeRegex)) {
+ console.log('barcode');
+ barcode = barcode_or_usrname;
+ } else {
+ console.log('usrname');
+ usrname = barcode_or_usrname;
+ }
+
+ if(this.orgSettings[SET_PATRON_PASSWORD_REQUIRED]) {
+
+ if(!passwd) {
+ // would only happen in dev/debug mode when using the patron= param
+ alert('password required by org setting. remove patron= from URL');
+ return;
+ }
+
+ // patron password is required. Verify it.
+
+ var self = this;
+ new openils_User().auth_verify(
+ { username : usrname, barcode : barcode,
+ type : 'opac', passwd : passwd, agent : 'selfcheck' },
+ function(OK) {
+ if (OK) {
+ self.fetchPatron(barcode, usrname);
+
+ } else {
+ // auth verify failed
+ self.handleAlert(
+ dojo.string.substitute(localeStrings.LOGIN_FAILED, [barcode_or_usrname]),
+ false, 'login-failure'
+ );
+ self.drawLoginPage();
+ }
+ }
+ );
+
+ } else {
+ this.fetchPatron(barcode, usrname);
+ }
+ };
+
+ SelfCheckManager.prototype.fetchPatron = function(barcode, usrname) {
+
+ var patron_id = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.retrieve_id_by_barcode_or_username'],
+ {params : [this.authtoken, barcode, usrname]}
+ );
+
+ // retrieve the fleshed user by id
+ this.patron = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.fleshed.retrieve.authoritative'],
+ {params : [this.authtoken, patron_id]}
+ );
+
+ var evt = openils_Event.parse(this.patron);
+
+ // verify validity of the card used to log in
+ var inactiveCard = false;
+ if(!evt) {
+ var card;
+ if (barcode) {
+ card = this.patron.cards().filter(
+ function(c) { return (c.barcode() == barcode); })[0];
+ } else {
+ card = this.patron.card();
+ }
+ inactiveCard = !openils_Util.isTrue(card.active());
+ }
+
+ if(evt || inactiveCard) {
+ this.handleAlert(
+ dojo.string.substitute(localeStrings.LOGIN_FAILED, [barcode || usrname]),
+ false, 'login-failure'
+ );
+ this.drawLoginPage();
+
+ } else {
+
+ this.handleAlert('', false, 'login-success');
+ dojo.byId('oils-selfck-user-banner').innerHTML =
+ dojo.string.substitute(localeStrings.WELCOME_BANNER, [this.patron.first_given_name()]);
+ this.drawCircPage();
+ }
+ }
+
+
+ SelfCheckManager.prototype.handleAlert = function(message, shouldPopup, sound) {
+
+ console.log("Handling alert " + message);
+
+ dojo.byId('oils-selfck-status-div').innerHTML = message;
+
+ if(shouldPopup)
+ openils_Util.addCSSClass( dojo.byId('oils-selfck-status-div'), 'checkout_failure' );
+ else
+ openils_Util.removeCSSClass( dojo.byId('oils-selfck-status-div'), 'checkout_failure' );
+
+ if(shouldPopup && this.orgSettings[SET_ALERT_POPUP])
+ alert(message);
+
+ if(sound && this.orgSettings[SET_ALERT_SOUND])
+ openils_Util.playAudioUrl(SelfCheckManager.audioConfig[sound]);
+ }
+
+
+ /**
+ * Manages the main input box
+ * @param msg The context message to display with the box
+ * @param clearOnly Don't update the context message, just clear the value and re-focus
+ * @param handler Optional "on-enter" handler.
+ */
+ SelfCheckManager.prototype.updateScanBox = function(args) {
+ args = args || {};
+
+ if(args.select) {
+ selfckScanBox.domNode.select();
+ } else {
+ selfckScanBox.attr('value', '');
+ }
+
+ if(args.password) {
+ selfckScanBox.domNode.setAttribute('type', 'password');
+ } else {
+ selfckScanBox.domNode.setAttribute('type', '');
+ }
+
+ if(args.value)
+ selfckScanBox.attr('value', args.value);
+
+ if(args.msg)
+ dojo.byId('oils-selfck-scan-text').innerHTML = args.msg;
+
+ if(selfckScanBox._lastHandler && (args.handler || args.clearHandler)) {
+ dojo.disconnect(selfckScanBox._lastHandler);
+ }
+
+ if(args.handler) {
+ selfckScanBox._lastHandler = dojo.connect(
+ selfckScanBox,
+ 'onKeyDown',
+ function(e) {
+ if(e.keyCode != dojo.keys.ENTER)
+ return;
+ args.handler(selfckScanBox.attr('value'));
+ }
+ );
+ }
+
+ selfckScanBox.focus();
+ }
+
+ /**
+ * Sets up the checkout/renewal interface
+ */
+ SelfCheckManager.prototype.drawCircPage = function() {
+
+ openils_Util.show('oils-selfck-circ-tbody', 'table-row-group');
+ this.goToTab('checkout');
+
+ while(this.itemsOutTbody.childNodes[0])
+ this.itemsOutTbody.removeChild(this.itemsOutTbody.childNodes[0]);
+
+ var self = this;
+ this.updateScanBox({
+ msg : 'Please enter an item barcode', // TODO i18n
+ handler : function(barcode) { self.checkout(barcode); }
+ });
+
+ if(!this.circTemplate)
+ this.circTemplate = this.circTbody.removeChild(dojo.byId('oils-selfck-circ-row'));
+
+ // fines summary
+ this.updateFinesSummary();
+
+ // holds summary
+ this.updateHoldsSummary();
+
+ // items out summary
+ this.updateCircSummary();
+
+ // render mock checkouts for debugging?
+ if(this.mockCheckouts) {
+ for(var i in [1,2,3])
+ this.displayCheckout(this.mockCheckout, 'checkout');
+ }
+ }
+
+
+ SelfCheckManager.prototype.updateFinesSummary = function() {
+ var self = this;
+
+ // fines summary
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.fines.summary'],
+ { async : true,
+ params : [this.authtoken, this.patron.id()],
+ oncomplete : function(r) {
+
+ var summary = openils_Util.readResponse(r);
+
+ dojo.byId('oils-selfck-fines-total').innerHTML =
+ dojo.string.substitute(
+ localeStrings.TOTAL_FINES_ACCOUNT,
+ [summary.balance_owed()]
+ );
+
+ self.creditPayableBalance = summary.balance_owed();
+ }
+ }
+ );
+ }
+
+
+ SelfCheckManager.prototype.drawItemsOutPage = function() {
+ openils_Util.hide('oils-selfck-circ-tbody');
+
+ this.goToTab('items_out');
+
+ while(this.itemsOutTbody.childNodes[0])
+ this.itemsOutTbody.removeChild(this.itemsOutTbody.childNodes[0]);
+
+ progressDialog.show(true);
+
+ var self = this;
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.actor.user.checked_out.atomic'],
+ {
+ async : true,
+ params : [this.authtoken, this.patron.id()],
+ oncomplete : function(r) {
+
+ var resp = openils_Util.readResponse(r);
+
+ var circs = resp.sort(
+ function(a, b) {
+ if(a.circ.due_date() > b.circ.due_date())
+ return -1;
+ return 1;
+ }
+ );
+
+ progressDialog.hide();
+
+ self.itemsOut = [];
+ dojo.forEach(circs,
+ function(circ) {
+ self.itemsOut.push(circ.circ.id());
+ self.displayCheckout(
+ {payload : circ},
+ (circ.circ.parent_circ()) ? 'renew' : 'checkout',
+ true
+ );
+ }
+ );
+ }
+ }
+ );
+ }
+
+
+ SelfCheckManager.prototype.goToTab = function(name) {
+ this.tabName = name;
+
+ openils_Util.hide('oils-selfck-fines-page');
+ openils_Util.hide('oils-selfck-payment-page');
+ openils_Util.hide('oils-selfck-holds-page');
+ openils_Util.hide('oils-selfck-circ-page');
+ openils_Util.hide('oils-selfck-pay-fines-link');
+
+ switch(name) {
+ case 'checkout':
+ openils_Util.show('oils-selfck-circ-page');
+ break;
+ case 'items_out':
+ openils_Util.show('oils-selfck-circ-page');
+ break;
+ case 'holds':
+ openils_Util.show('oils-selfck-holds-page');
+ break;
+ case 'fines':
+ openils_Util.show('oils-selfck-fines-page');
+ break;
+ case 'payment':
+ openils_Util.show('oils-selfck-payment-page');
+ break;
+ }
+ }
+
+
+ SelfCheckManager.prototype.printList = function() {
+ switch(this.tabName) {
+ case 'checkout':
+ this.printSessionReceipt();
+ break;
+ case 'items_out':
+ this.printItemsOutReceipt();
+ break;
+ case 'holds':
+ this.printHoldsReceipt();
+ break;
+ case 'fines':
+ this.printFinesReceipt();
+ break;
+ }
+ }
+
+ SelfCheckManager.prototype.updateHoldsSummary = function() {
+
+ if(!this.holdsSummary) {
+ var summary = fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.holds.user_summary'],
+ {params : [this.authtoken, this.patron.id()]}
+ );
+
+ this.holdsSummary = {};
+ this.holdsSummary.ready = Number(summary['4']);
+ this.holdsSummary.total = 0;
+
+ for(var i in summary)
+ this.holdsSummary.total += Number(summary[i]);
+ }
+
+ dojo.byId('oils-selfck-holds-total').innerHTML =
+ dojo.string.substitute(
+ localeStrings.TOTAL_HOLDS,
+ [this.holdsSummary.total]
+ );
+
+ dojo.byId('oils-selfck-holds-ready').innerHTML =
+ dojo.string.substitute(
+ localeStrings.HOLDS_READY_FOR_PICKUP,
+ [this.holdsSummary.ready]
+ );
+ }
+
+
+ SelfCheckManager.prototype.updateCircSummary = function(increment) {
+
+ if(!this.circSummary) {
+
+ var summary = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.checked_out.count'],
+ {params : [this.authtoken, this.patron.id()]}
+ );
+
+ this.circSummary = {
+ total : Number(summary.out) + Number(summary.overdue),
+ overdue : Number(summary.overdue),
+ session : 0
+ };
+ }
+
+ if(increment) {
+ // local checkout occurred. Add to the total and the session.
+ this.circSummary.total += 1;
+ this.circSummary.session += 1;
+ }
+
+ dojo.byId('oils-selfck-circ-account-total').innerHTML =
+ dojo.string.substitute(
+ localeStrings.TOTAL_ITEMS_ACCOUNT,
+ [this.circSummary.total]
+ );
+
+ dojo.byId('oils-selfck-circ-session-total').innerHTML =
+ dojo.string.substitute(
+ localeStrings.TOTAL_ITEMS_SESSION,
+ [this.circSummary.session]
+ );
+ }
+
+
+ SelfCheckManager.prototype.drawHoldsPage = function() {
+
+ // TODO add option to hid scanBox
+ // this.updateScanBox(...)
+
+ this.goToTab('holds');
+
+ this.holdTbody = dojo.byId('oils-selfck-hold-tbody');
+ if(!this.holdTemplate)
+ this.holdTemplate = this.holdTbody.removeChild(dojo.byId('oils-selfck-hold-row'));
+ while(this.holdTbody.childNodes[0])
+ this.holdTbody.removeChild(this.holdTbody.childNodes[0]);
+
+ progressDialog.show(true);
+
+ var self = this;
+ fieldmapper.standardRequest( // fetch the hold IDs
+
+ ['open-ils.circ', 'open-ils.circ.holds.id_list.retrieve'],
+ { async : true,
+ params : [this.authtoken, this.patron.id()],
+
+ oncomplete : function(r) {
+ var ids = openils_Util.readResponse(r);
+ if(!ids || ids.length == 0) {
+ progressDialog.hide();
+ return;
+ }
+
+ fieldmapper.standardRequest( // fetch the hold objects with fleshed details
+ ['open-ils.circ', 'open-ils.circ.hold.details.batch.retrieve'],
+ { async : true,
+ params : [self.authtoken, ids],
+ onresponse : function(rr) {
+ progressDialog.hide();
+ self.insertHold(openils_Util.readResponse(rr));
+ }
+ }
+ );
+ }
+ }
+ );
+ }
+
+ SelfCheckManager.prototype.insertHold = function(data) {
+ var row = this.holdTemplate.cloneNode(true);
+
+ if(data.mvr.isbn()) {
+ this.byName(row, 'jacket').setAttribute('src', '/opac/extras/ac/jacket/small/' + data.mvr.isbn());
+ }
+
+ this.byName(row, 'title').innerHTML = data.mvr.title();
+ this.byName(row, 'author').innerHTML = data.mvr.author();
+
+ if(data.status == 4) {
+
+ // hold is ready for pickup
+ this.byName(row, 'status').innerHTML = localeStrings.HOLD_STATUS_READY;
+
+ } else {
+
+ // hold is still pending
+ this.byName(row, 'status').innerHTML =
+ dojo.string.substitute(
+ localeStrings.HOLD_STATUS_WAITING,
+ [data.queue_position, data.potential_copies]
+ );
+ }
+
+ // find the correct place the table to slot in the hold based on queue position
+
+ var position = (data.status == 4) ? 0 : data.queue_position;
+ row.setAttribute('position', position);
+
+ for(var i = 0; i < this.holdTbody.childNodes.length; i++) {
+ var node = this.holdTbody.childNodes[i];
+ if(Number(node.getAttribute('position')) >= position) {
+ this.holdTbody.insertBefore(row, node);
+ return;
+ }
+ }
+
+ this.holdTbody.appendChild(row);
+ }
+
+
+ SelfCheckManager.prototype.drawFinesPage = function() {
+
+ // TODO add option to hid scanBox
+ // this.updateScanBox(...)
+
+ this.goToTab('fines');
+ progressDialog.show(true);
+
+ if(this.creditPayableBalance > 0 && this.orgSettings[SET_CC_PAYMENT_ALLOWED]) {
+ openils_Util.show('oils-selfck-pay-fines-link', 'inline');
+ }
+
+ this.finesTbody = dojo.byId('oils-selfck-fines-tbody');
+ if(!this.finesTemplate)
+ this.finesTemplate = this.finesTbody.removeChild(dojo.byId('oils-selfck-fines-row'));
+ while(this.finesTbody.childNodes[0])
+ this.finesTbody.removeChild(this.finesTbody.childNodes[0]);
+
+ // when user clicks on a selector checkbox, update the total owed
+ var updateSelected = function() {
+ var total = 0;
+ dojo.forEach(
+ dojo.query('[name=selector]', this.finesTbody),
+ function(input) {
+ if(input.checked)
+ total += Number(input.getAttribute('balance_owed'));
+ }
+ );
+
+ total = total.toFixed(2);
+ dojo.byId('oils-selfck-selected-total').innerHTML =
+ dojo.string.substitute(localeStrings.TOTAL_FINES_SELECTED, [total]);
+ }
+
+ // wire up the batch on/off selector
+ var sel = dojo.byId('oils-selfck-fines-selector');
+ sel.onchange = function() {
+ dojo.forEach(
+ dojo.query('[name=selector]', this.finesTbody),
+ function(input) {
+ input.checked = sel.checked;
+ }
+ );
+ };
+
+ var self = this;
+ var handler = function(dataList) {
+
+ self.finesCount = dataList.length;
+ self.finesData = dataList;
+
+ for(var i in dataList) {
+
+ var data = dataList[i];
+ var row = self.finesTemplate.cloneNode(true);
+ var type = data.transaction.xact_type();
+
+ if(type == 'circulation') {
+ self.byName(row, 'type').innerHTML = type;
+ self.byName(row, 'details').innerHTML = data.record.title();
+
+ } else if(type == 'grocery') {
+ self.byName(row, 'type').innerHTML = 'Miscellaneous'; // Go ahead and head off any confusion around "grocery". TODO i18n
+ self.byName(row, 'details').innerHTML = data.transaction.last_billing_type();
+ }
+
+ self.byName(row, 'total_owed').innerHTML = data.transaction.total_owed();
+ self.byName(row, 'total_paid').innerHTML = data.transaction.total_paid();
+ self.byName(row, 'balance').innerHTML = data.transaction.balance_owed();
+
+ // row selector
+ var selector = self.byName(row, 'selector')
+ selector.onchange = updateSelected;
+ selector.setAttribute('xact', data.transaction.id());
+ selector.setAttribute('balance_owed', data.transaction.balance_owed());
+ selector.checked = true;
+
+ self.finesTbody.appendChild(row);
+ }
+
+ updateSelected();
+ }
+
+
+ fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.transactions.have_balance.fleshed'],
+ { async : true,
+ params : [this.authtoken, this.patron.id()],
+ oncomplete : function(r) {
+ progressDialog.hide();
+ handler(openils_Util.readResponse(r));
+ }
+ }
+ );
+ }
+
+ SelfCheckManager.prototype.checkin = function(barcode, abortTransit) {
+
+ var resp = fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.transit.abort'],
+ {params : [this.authtoken, {barcode : barcode}]}
+ );
+
+ // resp == 1 on success
+ if(openils_Event.parse(resp))
+ return false;
+
+ var resp = fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.checkin.override'],
+ {params : [
+ this.authtoken, {
+ patron_id : this.patron.id(),
+ copy_barcode : barcode,
+ noop : true
+ }
+ ]}
+ );
+
+ if(!resp.length) resp = [resp];
+ for(var i = 0; i < resp.length; i++) {
+ var tc = openils_Event.parse(resp[i]).textcode;
+ if(tc == 'SUCCESS' || tc == 'NO_CHANGE') {
+ continue;
+ } else {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Check out a single item. If the item is already checked
+ * out to the patron, redirect to renew()
+ */
+ SelfCheckManager.prototype.checkout = function(barcode, override) {
+
+ this.prevCirc = null;
+
+ if(!barcode) {
+ this.updateScanbox(null, true);
+ return;
+ }
+
+ if(this.mockCheckouts) {
+ // if we're in mock-checkout mode, just insert another
+ // fake circ into the table and get out of here.
+ this.displayCheckout(this.mockCheckout, 'checkout');
+ return;
+ }
+
+ // TODO see if it's a patron barcode
+ // TODO see if this item has already been checked out in this session
+
+ var method = 'open-ils.circ.checkout.full';
+ if(override) method += '.override';
+
+ console.log("Checkout out item " + barcode + " with method " + method);
+
+ var result = fieldmapper.standardRequest(
+ ['open-ils.circ', method],
+ {params: [
+ this.authtoken, {
+ patron_id : this.patron.id(),
+ copy_barcode : barcode
+ }
+ ]}
+ );
+
+ var stat = this.handleXactResult('checkout', barcode, result);
+
+ if(stat.override) {
+ this.checkout(barcode, true);
+ } else if(stat.doOver) {
+ this.checkout(barcode);
+ } else if(stat.renew) {
+ this.renew(barcode);
+ }
+ }
+
+ SelfCheckManager.prototype.failPartMessage = function(result) {
+ if (result.payload && result.payload.fail_part) {
+ var stringKey = "FAIL_PART_" +
+ result.payload.fail_part.replace(/\./g, "_");
+ return localeStrings[stringKey];
+ } else {
+ return null;
+ }
+ }
+
+ SelfCheckManager.prototype.handleXactResult = function(action, item, result) {
+
+ var displayText = '';
+
+ // If true, the display message is important enough to pop up. Whether or not
+ // an alert() actually occurs, depends on org unit settings
+ var popup = false;
+ var sound = ''; // sound file reference
+ var payload = result.payload || {};
+ var overrideEvents = this.orgSettings[SET_AUTO_OVERRIDE_EVENTS];
+ var blockStatuses = this.orgSettings[SET_BLOCK_CHECKOUT_ON_COPY_STATUS];
+
+ if(result.textcode == 'NO_SESSION') {
+
+ return this.logoutStaff();
+
+ } else if(result.textcode == 'SUCCESS') {
+
+ if(action == 'checkout') {
+
+ displayText = dojo.string.substitute(localeStrings.CHECKOUT_SUCCESS, [item]);
+ this.displayCheckout(result, 'checkout');
+
+ if(payload.holds_fulfilled && payload.holds_fulfilled.length) {
+ // A hold was fulfilled, update the hold numbers in the circ summary
+ console.log("fulfilled hold " + payload.holds_fulfilled + " during checkout");
+ this.holdsSummary = null;
+ this.updateHoldsSummary();
+ }
+
+ this.updateCircSummary(true);
+
+ } else if(action == 'renew') {
+
+ displayText = dojo.string.substitute(localeStrings.RENEW_SUCCESS, [item]);
+ this.displayCheckout(result, 'renew');
+ }
+
+ this.checkouts.push({circ : result.payload.circ.id()});
+ sound = 'checkout-success';
+ this.updateScanBox();
+
+ } else if(result.textcode == 'OPEN_CIRCULATION_EXISTS' && action == 'checkout') {
+
+ // Server says the item is already checked out. If it's checked out to the
+ // current user, we may need to renew it.
+
+ if(payload.old_circ) {
+
+ /*
+ old_circ refers to the previous checkout IFF it's for the same user.
+ If no auto-renew interval is not defined, assume we should renew it
+ If an auto-renew interval is defined and the payload comes back with
+ auto_renew set to true, do the renewal. Otherwise, let the patron know
+ the item is already checked out to them. */
+
+ if( !this.orgSettings[SET_AUTO_RENEW_INTERVAL] ||
+ (this.orgSettings[SET_AUTO_RENEW_INTERVAL] && payload.auto_renew) ) {
+ this.prevCirc = payload.old_circ.id();
+ return { renew : true };
+ }
+
+ popup = true;
+ sound = 'checkout-failure';
+ displayText = dojo.string.substitute(localeStrings.ALREADY_OUT, [item]);
+
+ } else {
+
+ if( // copy is marked lost. if configured to do so, check it in and try again.
+ result.payload.copy &&
+ result.payload.copy.status() == /* LOST */ 3 &&
+ overrideEvents && overrideEvents.length &&
+ overrideEvents.indexOf('COPY_STATUS_LOST') != -1) {
+
+ if(this.checkin(item)) {
+ return { doOver : true };
+ }
+ }
+
+
+ // item is checked out to some other user
+ popup = true;
+ sound = 'checkout-failure';
+ displayText = dojo.string.substitute(localeStrings.OPEN_CIRCULATION_EXISTS, [item]);
+ }
+
+ this.updateScanBox({select:true});
+
+ } else {
+
+
+ if(overrideEvents && overrideEvents.length) {
+
+ // see if the events we received are all in the list of
+ // events to override
+
+ if(!result.length) result = [result];
+
+ var override = true;
+ for(var i = 0; i < result.length; i++) {
+
+ var match = overrideEvents.filter(function(e) { return (e == result[i].textcode); })[0];
+
+ if(!match) {
+ override = false;
+ break;
+ }
+
+ if(result[i].textcode == 'COPY_NOT_AVAILABLE' && blockStatuses && blockStatuses.length) {
+
+ var stat = result[i].payload.status(); // copy status
+ if(typeof stat == 'object') stat = stat.id();
+
+ var match2 = blockStatuses.filter(function(e) { return (e == stat); })[0];
+
+ if(match2) { // copy is in a blocked status
+ override = false;
+ break;
+ }
+ }
+
+ if(result[i].textcode == 'COPY_IN_TRANSIT') {
+ // to override a transit, we have to abort the transit and check it in first
+ if(this.checkin(item, true)) {
+ return { doOver : true };
+ } else {
+ override = false;
+ }
+ }
+ }
+
+ if(override)
+ return { override : true };
+ }
+
+ this.updateScanBox({select : true});
+ popup = true;
+ sound = 'checkout-failure';
+
+ if(action == 'renew')
+ this.checkouts.push({circ : this.prevCirc, renewal_failure : true});
+
+ if(result.length)
+ result = result[0];
+
+ switch(result.textcode) {
+
+ // TODO custom handler for blocking penalties
+
+ case 'MAX_RENEWALS_REACHED' :
+ displayText = dojo.string.substitute(
+ localeStrings.MAX_RENEWALS, [item]);
+ break;
+
+ case 'ITEM_NOT_CATALOGED' :
+ displayText = dojo.string.substitute(
+ localeStrings.ITEM_NOT_CATALOGED, [item]);
+ break;
+
+ case 'OPEN_CIRCULATION_EXISTS' :
+ displayText = dojo.string.substitute(
+ localeStrings.OPEN_CIRCULATION_EXISTS, [item]);
+
+ break;
+
+ default:
+ console.error('Unhandled event ' + result.textcode);
+
+ if (!(displayText = this.failPartMessage(result))) {
+ if (action == 'checkout' || action == 'renew') {
+ displayText = dojo.string.substitute(
+ localeStrings.GENERIC_CIRC_FAILURE, [item]);
+ } else {
+ displayText = dojo.string.substitute(
+ localeStrings.UNKNOWN_ERROR, [result.textcode]);
+ }
+ }
+ }
+ }
+
+ this.handleAlert(displayText, popup, sound);
+ return {};
+ }
+
+
+ /**
+ * Renew an item
+ */
+ SelfCheckManager.prototype.renew = function(barcode, override) {
+
+ var method = 'open-ils.circ.renew';
+ if(override) method += '.override';
+
+ console.log("Renewing item " + barcode + " with method " + method);
+
+ var result = fieldmapper.standardRequest(
+ ['open-ils.circ', method],
+ {params: [
+ this.authtoken, {
+ patron_id : this.patron.id(),
+ copy_barcode : barcode
+ }
+ ]}
+ );
+
+ console.log(js2JSON(result));
+
+ var stat = this.handleXactResult('renew', barcode, result);
+
+ if(stat.override)
+ this.renew(barcode, true);
+ }
+
+ /**
+ * Display the result of a checkout or renewal in the items out table
+ */
+ SelfCheckManager.prototype.displayCheckout = function(evt, type, itemsOut) {
+
+ var copy = evt.payload.copy;
+ var record = evt.payload.record;
+ var circ = evt.payload.circ;
+ var row = this.circTemplate.cloneNode(true);
+
+ if(record.isbn()) {
+ this.byName(row, 'jacket').setAttribute('src', '/opac/extras/ac/jacket/small/' + record.isbn());
+ }
+
+ this.byName(row, 'barcode').innerHTML = copy.barcode();
+ this.byName(row, 'title').innerHTML = record.title();
+ this.byName(row, 'author').innerHTML = record.author();
+ this.byName(row, 'remaining').innerHTML = circ.renewal_remaining();
+ openils_Util.show(this.byName(row, type));
+
+ var date = dojo_date_stamp.fromISOString(circ.due_date());
+ this.byName(row, 'due_date').innerHTML =
+ dojo_date_locale.format(date, {selector : 'date'});
+
+ // put new circs at the top of the list
+ var tbody = this.circTbody;
+ if(itemsOut) tbody = this.itemsOutTbody;
+ tbody.insertBefore(row, tbody.getElementsByTagName('tr')[0]);
+ }
+
+
+ SelfCheckManager.prototype.byName = function(node, name) {
+ return dojo.query('[name=' + name+']', node)[0];
+ }
+
+
+ SelfCheckManager.prototype.initPrinter = function() {
+ try { // Mozilla only
+ netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesRead');
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalPreferencesWrite');
+ var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+ if (pref)
+ pref.setBoolPref('print.always_print_silent', true);
+ } catch(E) {
+ console.log("Unable to initialize auto-printing");
+ }
+ }
+
+ /**
+ * Print a receipt for this session's checkouts
+ */
+ SelfCheckManager.prototype.printSessionReceipt = function(callback) {
+
+ var circIds = [];
+ var circCtx = []; // circ context data. in this case, renewal_failure info
+
+ // collect the circs and failure info
+ dojo.forEach(
+ this.checkouts,
+ function(blob) {
+ circIds.push(blob.circ);
+ circCtx.push({renewal_failure:blob.renewal_failure});
+ }
+ );
+
+ var params = [
+ this.authtoken,
+ this.staff.ws_ou(),
+ null,
+ 'format.selfcheck.checkout',
+ 'print-on-demand',
+ circIds,
+ circCtx
+ ];
+
+ var self = this;
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.fire_circ_trigger_events'],
+ {
+ async : true,
+ params : params,
+ oncomplete : function(r) {
+ var resp = openils_Util.readResponse(r);
+ var output = resp.template_output();
+ if(output) {
+ self.printData(output.data(), self.checkouts.length, callback);
+ } else {
+ var error = resp.error_output();
+ if(error) {
+ throw new Error("Error creating receipt: " + error.data());
+ } else {
+ throw new Error("No receipt data returned from server");
+ }
+ }
+ }
+ }
+ );
+ }
+
+ SelfCheckManager.prototype.printData = function(data, numItems, callback) {
+
+ var win = window.open('', '', 'resizable,width=700,height=500,scrollbars=1');
+ win.document.body.innerHTML = data;
+ win.print();
+
+ /*
+ * There is no way to know when the browser is done printing.
+ * Make a best guess at when to close the print window by basing
+ * the setTimeout wait on the number of items to be printed plus
+ * a small buffer
+ */
+ var sleepTime = 1000;
+ if(numItems > 0)
+ sleepTime += (numItems / 2) * 1000;
+
+ setTimeout(
+ function() {
+ win.close(); // close the print window
+ if(callback)
+ callback(); // fire optional post-print callback
+ },
+ sleepTime
+ );
+ }
+
+
+ /**
+ * Print a receipt for this user's items out
+ */
+ SelfCheckManager.prototype.printItemsOutReceipt = function(callback) {
+
+ if(!this.itemsOut.length) return;
+
+ progressDialog.show(true);
+
+ var params = [
+ this.authtoken,
+ this.staff.ws_ou(),
+ null,
+ 'format.selfcheck.items_out',
+ 'print-on-demand',
+ this.itemsOut
+ ];
+
+ var self = this;
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.fire_circ_trigger_events'],
+ {
+ async : true,
+ params : params,
+ oncomplete : function(r) {
+ progressDialog.hide();
+ var resp = openils_Util.readResponse(r);
+ var output = resp.template_output();
+ if(output) {
+ self.printData(output.data(), self.itemsOut.length, callback);
+ } else {
+ var error = resp.error_output();
+ if(error) {
+ throw new Error("Error creating receipt: " + error.data());
+ } else {
+ throw new Error("No receipt data returned from server");
+ }
+ }
+ }
+ }
+ );
+ }
+
+ /**
+ * Print a receipt for this user's items out
+ */
+ SelfCheckManager.prototype.printHoldsReceipt = function(callback) {
+
+ if(!this.holds.length) return;
+
+ progressDialog.show(true);
+
+ var holdIds = [];
+ var holdData = [];
+
+ dojo.forEach(this.holds,
+ function(data) {
+ holdIds.push(data.hold.id());
+ if(data.status == 4) {
+ holdData.push({ready : true});
+ } else {
+ holdData.push({
+ queue_position : data.queue_position,
+ potential_copies : data.potential_copies
+ });
+ }
+ }
+ );
+
+ var params = [
+ this.authtoken,
+ this.staff.ws_ou(),
+ null,
+ 'format.selfcheck.holds',
+ 'print-on-demand',
+ holdIds,
+ holdData
+ ];
+
+ var self = this;
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.fire_hold_trigger_events'],
+ {
+ async : true,
+ params : params,
+ oncomplete : function(r) {
+ progressDialog.hide();
+ var resp = openils_Util.readResponse(r);
+ var output = resp.template_output();
+ if(output) {
+ self.printData(output.data(), self.holds.length, callback);
+ } else {
+ var error = resp.error_output();
+ if(error) {
+ throw new Error("Error creating receipt: " + error.data());
+ } else {
+ throw new Error("No receipt data returned from server");
+ }
+ }
+ }
+ }
+ );
+ }
+
+
+ SelfCheckManager.prototype.printPaymentReceipt = function(response, callback) {
+
+ var self = this;
+ progressDialog.show(true);
+
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.money.payment_receipt.print'],
+ {
+ async : true,
+ params : [this.authtoken, response.payments],
+ oncomplete : function(r) {
+ var resp = openils_Util.readResponse(r);
+ var output = resp.template_output();
+ progressDialog.hide();
+ if(output) {
+ self.printData(output.data(), 1, callback);
+ } else {
+ var error = resp.error_output();
+ if(error) {
+ throw new Error("Error creating receipt: " + error.data());
+ } else {
+ throw new Error("No receipt data returned from server");
+ }
+ }
+ }
+ }
+ );
+ }
+
+ /**
+ * Print a receipt for this user's items out
+ */
+ SelfCheckManager.prototype.printFinesReceipt = function(callback) {
+
+ progressDialog.show(true);
+
+ var params = [
+ this.authtoken,
+ this.staff.ws_ou(),
+ null,
+ 'format.selfcheck.fines',
+ 'print-on-demand',
+ [this.patron.id()]
+ ];
+
+ var self = this;
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.fire_user_trigger_events'],
+ {
+ async : true,
+ params : params,
+ oncomplete : function(r) {
+ progressDialog.hide();
+ var resp = openils_Util.readResponse(r);
+ var output = resp.template_output();
+ if(output) {
+ self.printData(output.data(), self.finesCount, callback);
+ } else {
+ var error = resp.error_output();
+ if(error) {
+ throw new Error("Error creating receipt: " + error.data());
+ } else {
+ throw new Error("No receipt data returned from server");
+ }
+ }
+ }
+ }
+ );
+ }
+
+
+
+
+ /**
+ * Logout the patron and return to the login page
+ */
+ SelfCheckManager.prototype.logoutPatron = function(print) {
+ progressDialog.show(true); // prevent patron from clicking logout link twice
+ if(print && this.checkouts.length) {
+ this.printSessionReceipt(
+ function() {
+ location.href = location.href;
+ }
+ );
+ } else {
+ location.href = location.href;
+ }
+ }
+
+
+ /**
+ * Fire up the manager on page load
+ */
+ openils_Util.addOnLoad(
+ function() {
+ new SelfCheckManager().init();
+ }
+ );
+
+
+});
\ No newline at end of file
-dojo.require('openils.Util');
-dojo.require('openils.User');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-
-var contextOrg;
-
-function setup() {
- buildGrid();
-
- var connect = function() {
- dojo.connect(contextOrgSelector, 'onChange',
- function() {
- contextOrg = this.attr('value');
- crGrid.resetStore();
- buildGrid();
- }
- );
- };
-
- new openils.User().buildPermOrgSelector(
- 'ADMIN_ACQ_CANCEL_CAUSE', contextOrgSelector, null, connect);
-}
-
-function buildGrid() {
-
- if(contextOrg == null)
- contextOrg = openils.User.user.ws_ou();
-
- crGrid.loadAll(
- {order_by : {acqcr : 'label'}},
- {org_unit : fieldmapper.aou.fullPath(contextOrg, true)}
- );
-}
-
-openils.Util.addOnLoad(setup);
-
-
+require([
+ "openils/Util",
+ "openils/User",
+ "openils/widget/AutoGrid",
+ "fieldmapper/OrgUtils",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(openils_Util,
+ openils_User,
+ openils_widget_AutoGrid,
+ fieldmapper_OrgUtils,
+ openils_widget_OrgUnitFilteringSelect){
+
+ var contextOrg;
+
+ function setup() {
+ buildGrid();
+
+ var connect = function() {
+ dojo.connect(contextOrgSelector, 'onChange',
+ function() {
+ contextOrg = this.attr('value');
+ crGrid.resetStore();
+ buildGrid();
+ }
+ );
+ };
+
+ new openils_User().buildPermOrgSelector(
+ 'ADMIN_ACQ_CANCEL_CAUSE', contextOrgSelector, null, connect);
+ }
+
+ function buildGrid() {
+
+ if(contextOrg == null)
+ contextOrg = openils_User.user.ws_ou();
+
+ crGrid.loadAll(
+ {order_by : {acqcr : 'label'}},
+ {org_unit : fieldmapper.aou.fullPath(contextOrg, true)}
+ );
+ }
+
+ openils_Util.addOnLoad(setup);
+
+
+
+
+});
\ No newline at end of file
-dojo.require("openils.widget.AutoGrid");
-dojo.require("openils.widget.OrgUnitFilteringSelect");
+require([
+ "openils/widget/AutoGrid",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(openils_widget_AutoGrid,
+ openils_widget_OrgUnitFilteringSelect){
+
+ var owner;
+
+ function prepareOwnerSelector(perm) {
+ new openils.User().buildPermOrgSelector(
+ perm,
+ ownerSelect,
+ null,
+ function() {
+ dojo.connect(
+ ownerSelect,
+ "onChange",
+ function() {
+ owner = fieldmapper.aou.findOrgUnit(this.attr("value"));
+ grid.resetStore();
+ populateGrid();
+ }
+ );
+ }
+ );
+ }
+
+ function populateGrid(id) {
+ var search = typeof(ownerSelect) == "undefined" ? {"id": {"!=": null}} : {
+ "org_unit": fieldmapper.aou.orgNodeTrail(
+ owner || fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()),
+ true /* asId */
+ )
+ };
+ if (id) search.id = id;
+
+ grid.loadAll(null, search);
+ }
+
-var owner;
-
-function prepareOwnerSelector(perm) {
- new openils.User().buildPermOrgSelector(
- perm,
- ownerSelect,
- null,
- function() {
- dojo.connect(
- ownerSelect,
- "onChange",
- function() {
- owner = fieldmapper.aou.findOrgUnit(this.attr("value"));
- grid.resetStore();
- populateGrid();
- }
- );
- }
- );
-}
-
-function populateGrid(id) {
- var search = typeof(ownerSelect) == "undefined" ? {"id": {"!=": null}} : {
- "org_unit": fieldmapper.aou.orgNodeTrail(
- owner || fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou()),
- true /* asId */
- )
- };
- if (id) search.id = id;
-
- grid.loadAll(null, search);
-}
+});
\ No newline at end of file
-dojo.require("dojo.dnd.Container");
-dojo.require("dojo.dnd.Source");
-dojo.require('openils.widget.AutoGrid');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.requireLocalization('openils.conify', 'conify');
-var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
-
-
-var formCache = {};
-var formula, entryTbody, entryTemplate, dndSource;
-var virtualId = -1;
-var pcrud;
-
-
-function gridDataLoader() {
- fListGrid.resetStore();
- fListGrid.showLoadProgressIndicator();
- fieldmapper.standardRequest(
- ["open-ils.acq", "open-ils.acq.distribution_formula.ranged.retrieve"], {
- "async": true,
- "params": [
- openils.User.authtoken,
- fListGrid.displayOffset,
- fListGrid.displayLimit
- ],
- "onresponse": function(r) {
- var form = openils.Util.readResponse(r);
- formCache[form.id()] = form;
- fListGrid.store.newItem(form.toStoreItem());
- },
- "oncomplete": function() {
- fListGrid.hideLoadProgressIndicator();
- }
- }
- );
-}
-
-function draw() {
-
- pcrud = new openils.PermaCrud();
-
- if(formulaId) {
- openils.Util.hide('formula-list-div');
- drawFormulaSummary();
- } else {
-
- openils.Util.hide('formula-entry-div');
- fListGrid.onPostCreate = function(fmObject) {
- location.href = location.href + '/' + fmObject.id();
- }
-
- fListGrid.dataLoader = gridDataLoader;
- gridDataLoader();
- }
-}
-
-function cloneSelectedFormula() {
- var item = fListGrid.getSelectedItems()[0];
- if(!item) return;
- var formula = new fieldmapper.acqf().fromStoreItem(item);
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.distribution_formula.clone'],
- {
- asnyc : true,
- params : [
- openils.User.authtoken,
- formula.id(),
- dojo.string.substitute(localeStrings.ACQ_DISTRIB_FORMULA_NAME_CLONE, [formula.name()])
- ],
- oncomplete : function(r) {
- if(r = openils.Util.readResponse(r)) {
- location.href = oilsBasePath + '/conify/global/acq/distribution_formula/' + r;
- }
- }
- }
- );
-}
-
-openils.Util.addOnLoad(draw);
-
-function getItemCount(rowIndex, item) {
- if(!item) return '';
- var form = formCache[this.grid.store.getValue(item, "id")];
- if(!form) return 0;
- var count = 0;
- dojo.forEach(form.entries(), function(e) { count = count + e.item_count(); });
- return count;
-}
-
-function byName(node, name) {
- return dojo.query('[name='+name+']', node)[0];
-}
-
-function drawFormulaSummary() {
- openils.Util.show('formula-entry-div');
-
- var entries = pcrud.search('acqdfe', {formula: formulaId}, {order_by:{acqdfe : 'position'}});
- formula = pcrud.retrieve('acqdf', formulaId);
- formula.entries(entries);
-
- dojo.byId('formula_head').innerHTML = formula.name();
- dojo.byId('formula_head').onclick = function() {
- var name = prompt(localeStrings.ACQ_DISTRIB_FORMULA_NAME_PROMPT, formula.name());
- if(name && name != formula.name()) {
- formula.name(name);
- pcrud = new openils.PermaCrud();
- pcrud.update(formula);
- dojo.byId('formula_head').innerHTML = name;
- }
- }
-
- dojo.forEach(entries, function(entry) { addEntry(entry); } );
-}
-
-function addEntry(entry) {
-
- if(!entryTbody) {
- entryTbody = dojo.byId('formula-entry-tbody');
- entryTemplate = entryTbody.removeChild(dojo.byId('formula-entry-tempate'));
- dndSource = new dojo.dnd.Source(entryTbody);
- dndSource.selectAll();
- dndSource.deleteSelectedNodes();
- dndSource.clearItems();
- }
-
- if(!entry) {
- entry = new fieldmapper.acqdfe();
- entry.formula(formulaId);
- entry.item_count(1);
- entry.owning_lib(openils.User.user.ws_ou());
- entry.id(virtualId--);
- entry.isnew(true);
- formula.entries().push(entry);
- }
-
- var row = entryTbody.appendChild(entryTemplate.cloneNode(true));
- row.setAttribute('entry', entry.id());
- dndSource.insertNodes(false, [row]);
- byName(row, 'delete').onclick = function() {
- entry.isdeleted(true);
- entryTbody.removeChild(row);
- dndSource.sync();
- };
-
- dojo.forEach(
- ['owning_lib', 'location', 'item_count'],
- function(field) {
- new openils.widget.AutoFieldWidget({
- forceSync : true,
- fmField : field,
- fmObject : entry,
- fmClass : 'acqdfe',
- parentNode : byName(row, field),
- orgDefaultsToWs : true,
- orgLimitPerms : ['ADMIN_ACQ_DISTRIB_FORMULA'],
- widgetClass : (field == 'item_count') ? 'dijit.form.NumberSpinner' : null,
- dijitArgs : (field == 'item_count') ? {min:1, places:0} : null
- }).build(
- function(w, ww) {
- dojo.connect(w, 'onChange',
- function(newVal) {
- entry[field]( newVal );
- entry.ischanged(true);
- }
- )
- }
- );
- }
- );
-}
-
-function saveFormula() {
- var pos = 1;
- var updatedEntries = [];
- var deletedEntries = [];
-
- // remove deleted entries from consideration for collision protection
- for(var i = 0; i < formula.entries().length; i++) {
- if(formula.entries()[i].isdeleted())
- deletedEntries.push(formula.entries().splice(i--, 1)[0])
- }
-
- // update entry positions and create temporary collision avoidance entries
- dojo.forEach(
- dndSource.getAllNodes(),
- function(node) {
-
- var entryId = node.getAttribute('entry');
- var entry = formula.entries().filter(function(e) {return (e.id() == entryId)})[0];
-
- if(entry.position() != pos) {
-
- // update the position
- var changedEntry = entry.clone();
- changedEntry.position(pos);
- changedEntry.ischanged(true);
- updatedEntries.push(changedEntry);
-
- // clear the virtual ID
- if(changedEntry.isnew())
- changedEntry.id(null);
-
- var oldEntry = formula.entries().filter(function(e) {return (e.position() == pos)})[0];
-
- if(oldEntry) {
- // move the entry currently in that spot temporarily into negative territory
- var moveMe = oldEntry.clone();
- moveMe.ischanged(true);
- moveMe.position(moveMe.position() * -1);
- updatedEntries.unshift(moveMe);
- }
- }
- pos++;
- }
- );
-
- // finally, for every entry that changed w/o changing position
- // throw it on the list for update
- dojo.forEach(
- formula.entries(),
- function(entry) {
- if(entry.ischanged() && !entry.isdeleted() && !entry.isnew()) {
- if(updatedEntries.filter(function(e) { return (e.id() == entry.id()) }).length == 0)
- updatedEntries.push(entry);
- }
- }
- );
-
- updatedEntries = deletedEntries.concat(updatedEntries);
- if(updatedEntries.length) {
- pcrud = new openils.PermaCrud();
- try {
- pcrud.apply(updatedEntries);
- } catch(E) {
- alert('error updating: ' + E);
- return;
- }
- location.href = location.href;
- }
-}
-
-
+require([
+ "dojo/dnd/Container",
+ "dojo/dnd/Source",
+ "openils/widget/AutoGrid",
+ "dijit/form/FilteringSelect",
+ "openils/PermaCrud",
+ "openils/widget/AutoFieldWidget"
+ ],
+function(dojo_dnd_Container,
+ dojo_dnd_Source,
+ openils_widget_AutoGrid,
+ dijit_form_FilteringSelect,
+ openils_PermaCrud,
+ openils_widget_AutoFieldWidget){
+ dojo.requireLocalization('openils.conify', 'conify');
+ var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
+
+
+ var formCache = {};
+ var formula, entryTbody, entryTemplate, dndSource;
+ var virtualId = -1;
+ var pcrud;
+
+
+ function gridDataLoader() {
+ fListGrid.resetStore();
+ fListGrid.showLoadProgressIndicator();
+ fieldmapper.standardRequest(
+ ["open-ils.acq", "open-ils.acq.distribution_formula.ranged.retrieve"], {
+ "async": true,
+ "params": [
+ openils.User.authtoken,
+ fListGrid.displayOffset,
+ fListGrid.displayLimit
+ ],
+ "onresponse": function(r) {
+ var form = openils.Util.readResponse(r);
+ formCache[form.id()] = form;
+ fListGrid.store.newItem(form.toStoreItem());
+ },
+ "oncomplete": function() {
+ fListGrid.hideLoadProgressIndicator();
+ }
+ }
+ );
+ }
+
+ function draw() {
+
+ pcrud = new openils_PermaCrud();
+
+ if(formulaId) {
+ openils.Util.hide('formula-list-div');
+ drawFormulaSummary();
+ } else {
+
+ openils.Util.hide('formula-entry-div');
+ fListGrid.onPostCreate = function(fmObject) {
+ location.href = location.href + '/' + fmObject.id();
+ }
+
+ fListGrid.dataLoader = gridDataLoader;
+ gridDataLoader();
+ }
+ }
+
+ function cloneSelectedFormula() {
+ var item = fListGrid.getSelectedItems()[0];
+ if(!item) return;
+ var formula = new fieldmapper.acqf().fromStoreItem(item);
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.distribution_formula.clone'],
+ {
+ asnyc : true,
+ params : [
+ openils.User.authtoken,
+ formula.id(),
+ dojo.string.substitute(localeStrings.ACQ_DISTRIB_FORMULA_NAME_CLONE, [formula.name()])
+ ],
+ oncomplete : function(r) {
+ if(r = openils.Util.readResponse(r)) {
+ location.href = oilsBasePath + '/conify/global/acq/distribution_formula/' + r;
+ }
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(draw);
+
+ function getItemCount(rowIndex, item) {
+ if(!item) return '';
+ var form = formCache[this.grid.store.getValue(item, "id")];
+ if(!form) return 0;
+ var count = 0;
+ dojo.forEach(form.entries(), function(e) { count = count + e.item_count(); });
+ return count;
+ }
+
+ function byName(node, name) {
+ return dojo.query('[name='+name+']', node)[0];
+ }
+
+ function drawFormulaSummary() {
+ openils.Util.show('formula-entry-div');
+
+ var entries = pcrud.search('acqdfe', {formula: formulaId}, {order_by:{acqdfe : 'position'}});
+ formula = pcrud.retrieve('acqdf', formulaId);
+ formula.entries(entries);
+
+ dojo.byId('formula_head').innerHTML = formula.name();
+ dojo.byId('formula_head').onclick = function() {
+ var name = prompt(localeStrings.ACQ_DISTRIB_FORMULA_NAME_PROMPT, formula.name());
+ if(name && name != formula.name()) {
+ formula.name(name);
+ pcrud = new openils_PermaCrud();
+ pcrud.update(formula);
+ dojo.byId('formula_head').innerHTML = name;
+ }
+ }
+
+ dojo.forEach(entries, function(entry) { addEntry(entry); } );
+ }
+
+ function addEntry(entry) {
+
+ if(!entryTbody) {
+ entryTbody = dojo.byId('formula-entry-tbody');
+ entryTemplate = entryTbody.removeChild(dojo.byId('formula-entry-tempate'));
+ dndSource = new dojo_dnd_Source(entryTbody);
+ dndSource.selectAll();
+ dndSource.deleteSelectedNodes();
+ dndSource.clearItems();
+ }
+
+ if(!entry) {
+ entry = new fieldmapper.acqdfe();
+ entry.formula(formulaId);
+ entry.item_count(1);
+ entry.owning_lib(openils.User.user.ws_ou());
+ entry.id(virtualId--);
+ entry.isnew(true);
+ formula.entries().push(entry);
+ }
+
+ var row = entryTbody.appendChild(entryTemplate.cloneNode(true));
+ row.setAttribute('entry', entry.id());
+ dndSource.insertNodes(false, [row]);
+ byName(row, 'delete').onclick = function() {
+ entry.isdeleted(true);
+ entryTbody.removeChild(row);
+ dndSource.sync();
+ };
+
+ dojo.forEach(
+ ['owning_lib', 'location', 'item_count'],
+ function(field) {
+ new openils_widget_AutoFieldWidget({
+ forceSync : true,
+ fmField : field,
+ fmObject : entry,
+ fmClass : 'acqdfe',
+ parentNode : byName(row, field),
+ orgDefaultsToWs : true,
+ orgLimitPerms : ['ADMIN_ACQ_DISTRIB_FORMULA'],
+ widgetClass : (field == 'item_count') ? 'dijit.form.NumberSpinner' : null,
+ dijitArgs : (field == 'item_count') ? {min:1, places:0} : null
+ }).build(
+ function(w, ww) {
+ dojo.connect(w, 'onChange',
+ function(newVal) {
+ entry[field]( newVal );
+ entry.ischanged(true);
+ }
+ )
+ }
+ );
+ }
+ );
+ }
+
+ function saveFormula() {
+ var pos = 1;
+ var updatedEntries = [];
+ var deletedEntries = [];
+
+ // remove deleted entries from consideration for collision protection
+ for(var i = 0; i < formula.entries().length; i++) {
+ if(formula.entries()[i].isdeleted())
+ deletedEntries.push(formula.entries().splice(i--, 1)[0])
+ }
+
+ // update entry positions and create temporary collision avoidance entries
+ dojo.forEach(
+ dndSource.getAllNodes(),
+ function(node) {
+
+ var entryId = node.getAttribute('entry');
+ var entry = formula.entries().filter(function(e) {return (e.id() == entryId)})[0];
+
+ if(entry.position() != pos) {
+
+ // update the position
+ var changedEntry = entry.clone();
+ changedEntry.position(pos);
+ changedEntry.ischanged(true);
+ updatedEntries.push(changedEntry);
+
+ // clear the virtual ID
+ if(changedEntry.isnew())
+ changedEntry.id(null);
+
+ var oldEntry = formula.entries().filter(function(e) {return (e.position() == pos)})[0];
+
+ if(oldEntry) {
+ // move the entry currently in that spot temporarily into negative territory
+ var moveMe = oldEntry.clone();
+ moveMe.ischanged(true);
+ moveMe.position(moveMe.position() * -1);
+ updatedEntries.unshift(moveMe);
+ }
+ }
+ pos++;
+ }
+ );
+
+ // finally, for every entry that changed w/o changing position
+ // throw it on the list for update
+ dojo.forEach(
+ formula.entries(),
+ function(entry) {
+ if(entry.ischanged() && !entry.isdeleted() && !entry.isnew()) {
+ if(updatedEntries.filter(function(e) { return (e.id() == entry.id()) }).length == 0)
+ updatedEntries.push(entry);
+ }
+ }
+ );
+
+ updatedEntries = deletedEntries.concat(updatedEntries);
+ if(updatedEntries.length) {
+ pcrud = new openils_PermaCrud();
+ try {
+ pcrud.apply(updatedEntries);
+ } catch(E) {
+ alert('error updating: ' + E);
+ return;
+ }
+ location.href = location.href;
+ }
+ }
+
+
+
+
+});
\ No newline at end of file
-dojo.require('openils.widget.AutoGrid');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('openils.PermaCrud');
-
-function draw() {
- if (! targetId) {
- pListGrid.loadAll({order_by:{acqedi : "id"}});
- // The following code does no good ...
-// pListGrid.onPostCreate = function(fmObject) {
-// location.href = location.href + '/' + fmObject.id();
-// };
- return;
- }
-
- var pcrud = new openils.PermaCrud();
- pcrud.retrieve('acqedi', targetId, {
- // ... because this code here does nothing yet
- oncomplete : function(r) {
- console.log('edi_account is' + js2JSON(openils.Util.readResponse(r)));
- }
- });
-}
-
-openils.Util.addOnLoad(draw);
+require([
+ "openils/widget/AutoGrid",
+ "dijit/form/FilteringSelect",
+ "openils/PermaCrud"
+ ],
+function(openils_widget_AutoGrid,
+ dijit_form_FilteringSelect,
+ openils_PermaCrud){
+
+ function draw() {
+ if (! targetId) {
+ pListGrid.loadAll({order_by:{acqedi : "id"}});
+ // The following code does no good ...
+ // pListGrid.onPostCreate = function(fmObject) {
+ // location.href = location.href + '/' + fmObject.id();
+ // };
+ return;
+ }
+
+ var pcrud = new openils_PermaCrud();
+ pcrud.retrieve('acqedi', targetId, {
+ // ... because this code here does nothing yet
+ oncomplete : function(r) {
+ console.log('edi_account is' + js2JSON(openils.Util.readResponse(r)));
+ }
+ });
+ }
+
+ openils.Util.addOnLoad(draw);
+
+
+});
\ No newline at end of file
-dojo.require("dojo.data.ItemFileWriteStore");
-dojo.require("dojox.grid.DataGrid");
-dojo.require("dojox.grid.cells.dijit");
-dojo.require("dojox.widget.PlaceholderMenuItem");
-dojo.require("dijit.form.CurrencyTextBox");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("openils.widget.AutoGrid");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.widget.OrgUnitFilteringSelect");
+require([
+ "dojo/data/ItemFileWriteStore",
+ "dojox/grid/DataGrid",
+ "dojox/grid/cells/dijit",
+ "dojox/widget/PlaceholderMenuItem",
+ "dijit/form/CurrencyTextBox",
+ "dijit/form/FilteringSelect",
+ "openils/widget/AutoGrid",
+ "openils/PermaCrud",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(dojo_data_ItemFileWriteStore,
+ dojox_grid_DataGrid,
+ dojox_grid_cells_dijit,
+ dojox_widget_PlaceholderMenuItem,
+ dijit_form_CurrencyTextBox,
+ dijit_form_FilteringSelect,
+ openils_widget_AutoGrid,
+ openils_PermaCrud,
+ openils_widget_OrgUnitFilteringSelect){
+
+ var pcrud;
+ var ftOwner;
+ var ftList;
+
+ function ftInit() {
+ pcrud = new openils_PermaCrud();
+
+ new openils.User().buildPermOrgSelector(
+ "ADMIN_ACQ_FUND_TAG",
+ ftOwnerSelect,
+ null,
+ function() {
+ dojo.connect(
+ ftOwnerSelect,
+ "onChange",
+ function() {
+ ftOwner = fieldmapper.aou.findOrgUnit(this.attr("value"));
+ ftGrid.resetStore();
+ buildFtGrid();
+ }
+ );
+ buildFtGrid();
+ }
+ );
+ }
+
+ function buildFtGrid() {
+ if (!ftOwner)
+ ftOwner = fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou());
+
+ pcrud.search(
+ "acqft",
+ {"owner": fieldmapper.aou.orgNodeTrail(ftOwner, true /* asId */)},
+ {
+ "async": true,
+ "onresponse": function(r) {
+ if ((ftList = openils.Util.readResponse(r))) {
+ ftList = openils.Util.objectSort(ftList);
+ ftList.forEach(
+ function(o) {
+ ftGrid.store.newItem(acqft.toStoreItem(o));
+ }
+ );
+ }
+ },
+ "oncomplete": function() {
+ ftGrid.hideLoadProgressIndicator();
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(ftInit);
+
-var pcrud;
-var ftOwner;
-var ftList;
-
-function ftInit() {
- pcrud = new openils.PermaCrud();
-
- new openils.User().buildPermOrgSelector(
- "ADMIN_ACQ_FUND_TAG",
- ftOwnerSelect,
- null,
- function() {
- dojo.connect(
- ftOwnerSelect,
- "onChange",
- function() {
- ftOwner = fieldmapper.aou.findOrgUnit(this.attr("value"));
- ftGrid.resetStore();
- buildFtGrid();
- }
- );
- buildFtGrid();
- }
- );
-}
-
-function buildFtGrid() {
- if (!ftOwner)
- ftOwner = fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou());
-
- pcrud.search(
- "acqft",
- {"owner": fieldmapper.aou.orgNodeTrail(ftOwner, true /* asId */)},
- {
- "async": true,
- "onresponse": function(r) {
- if ((ftList = openils.Util.readResponse(r))) {
- ftList = openils.Util.objectSort(ftList);
- ftList.forEach(
- function(o) {
- ftGrid.store.newItem(acqft.toStoreItem(o));
- }
- );
- }
- },
- "oncomplete": function() {
- ftGrid.hideLoadProgressIndicator();
- }
- }
- );
-}
-
-openils.Util.addOnLoad(ftInit);
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dijit.form.CurrencyTextBox');
-dojo.require('dijit.Dialog');
-dojo.require('dojox.widget.PlaceholderMenuItem');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-
-var alertContextOrg;
-var alertList;
-
-function alertInit() {
-
- buildAlertGrid();
- var connect = function() {
- dojo.connect(alertContextOrgSelect, 'onChange',
- function() {
- alertContextOrg = this.getValue();
- alertGrid.resetStore();
- buildAlertGrid();
- }
- );
- };
- new openils.User().buildPermOrgSelector('ADMIN_ACQ_LINEITEM_ALERT_TEXT', alertContextOrgSelect, null, connect);
-}
-
-function buildAlertGrid() {
- if(alertContextOrg == null)
- alertContextOrg = openils.User.user.ws_ou();
- fieldmapper.standardRequest(
- ['open-ils.acq', 'open-ils.acq.line_item_alert_text.ranged.retrieve.all'],
- { async: true,
- params: [openils.User.authtoken, alertContextOrg, fieldmapper.aou.findOrgDepth(alertContextOrg)],
- oncomplete: function(r) {
- if(alertList = openils.Util.readResponse(r)) {
- alertList = openils.Util.objectSort(alertList);
- dojo.forEach(alertList,
- function(e) {
- alertGrid.store.newItem(acqliat.toStoreItem(e));
- }
- );
- }
- }
- }
- );
-}
-
-openils.Util.addOnLoad(alertInit);
-
+require([
+ "dojox/grid/DataGrid",
+ "openils/widget/AutoGrid",
+ "dojox/grid/cells/dijit",
+ "dojo/data/ItemFileWriteStore",
+ "dijit/form/CurrencyTextBox",
+ "dijit/Dialog",
+ "dojox/widget/PlaceholderMenuItem",
+ "fieldmapper/OrgUtils",
+ "dijit/form/FilteringSelect",
+ "openils/PermaCrud",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(dojox_grid_DataGrid,
+ openils_widget_AutoGrid,
+ dojox_grid_cells_dijit,
+ dojo_data_ItemFileWriteStore,
+ dijit_form_CurrencyTextBox,
+ dijit_Dialog,
+ dojox_widget_PlaceholderMenuItem,
+ fieldmapper_OrgUtils,
+ dijit_form_FilteringSelect,
+ openils_PermaCrud,
+ openils_widget_OrgUnitFilteringSelect){
+
+ var alertContextOrg;
+ var alertList;
+
+ function alertInit() {
+
+ buildAlertGrid();
+ var connect = function() {
+ dojo.connect(alertContextOrgSelect, 'onChange',
+ function() {
+ alertContextOrg = this.getValue();
+ alertGrid.resetStore();
+ buildAlertGrid();
+ }
+ );
+ };
+ new openils.User().buildPermOrgSelector('ADMIN_ACQ_LINEITEM_ALERT_TEXT', alertContextOrgSelect, null, connect);
+ }
+
+ function buildAlertGrid() {
+ if(alertContextOrg == null)
+ alertContextOrg = openils.User.user.ws_ou();
+ fieldmapper.standardRequest(
+ ['open-ils.acq', 'open-ils.acq.line_item_alert_text.ranged.retrieve.all'],
+ { async: true,
+ params: [openils.User.authtoken, alertContextOrg, fieldmapper.aou.findOrgDepth(alertContextOrg)],
+ oncomplete: function(r) {
+ if(alertList = openils.Util.readResponse(r)) {
+ alertList = openils.Util.objectSort(alertList);
+ dojo.forEach(alertList,
+ function(e) {
+ alertGrid.store.newItem(acqliat.toStoreItem(e));
+ }
+ );
+ }
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(alertInit);
+
+
+
+});
\ No newline at end of file
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.Util');
-dojo.require('openils.User');
-dojo.require('openils.MarcXPathParser');
+require([
+ "openils/widget/AutoGrid",
+ "openils/PermaCrud",
+ "openils/Util",
+ "openils/User",
+ "openils/MarcXPathParser"
+ ],
+function(openils_widget_AutoGrid,
+ openils_PermaCrud,
+ openils_Util,
+ openils_User,
+ openils_MarcXPathParser){
+
+ var xpathParser = new openils_MarcXPathParser();
+
+ function init() {
+ attrGrid.loadAll({order_by : {acqlimad : 'code'}});
+ }
+
+ function attrGridGetTag(rowIdx, item) {
+ return item && xpathParser.parse(this.grid.store.getValue(item, 'xpath')).tags;
+ }
+
+ function attrGridGetSubfield(rowIdx, item) {
+ return item && xpathParser.parse(this.grid.store.getValue(item, 'xpath')).subfields;
+ }
+
+ openils_Util.addOnLoad(init);
+
-var xpathParser = new openils.MarcXPathParser();
-
-function init() {
- attrGrid.loadAll({order_by : {acqlimad : 'code'}});
-}
-
-function attrGridGetTag(rowIdx, item) {
- return item && xpathParser.parse(this.grid.store.getValue(item, 'xpath')).tags;
-}
-
-function attrGridGetSubfield(rowIdx, item) {
- return item && xpathParser.parse(this.grid.store.getValue(item, 'xpath')).subfields;
-}
-
-openils.Util.addOnLoad(init);
+});
\ No newline at end of file
-dojo.require('dijit.layout.TabContainer');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.MarcXPathParser');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-
-
-var provider;
-var xpathParser = new openils.MarcXPathParser();
-var subFields= [];
-var adminPermOrgs = [];
-var viewPermOrgs = [];
-var user;
-var viewPerms = [
- 'ADMIN_PROVIDER',
- 'MANAGE_PROVIDER',
- 'VIEW_PROVIDER'
-];
-
-
-function draw() {
-
- user = new openils.User();
-
- if(providerId) {
- drawOneProvider();
- return;
- }
-
- openils.Util.hide('provider-details-div');
-
- // after a provider is created, load the provider page
- pListGrid.onPostCreate = function(fmObject) {
- location.href = location.href + '/' + fmObject.id();
- }
-
- user.buildPermOrgSelector(
- viewPerms,
- contextOrgSelector, null,
-
- function() {
- if (!contextOrgSelector.attr('value')) return
-
- dojo.connect(contextOrgSelector, 'onChange', drawProviderGrid);
-
- // fetch the admin org units
- user.getPermOrgList(
- 'ADMIN_PROVIDER',
-
- function(list) {
- adminPermOrgs = list;
-
- // fetch the view org units
- user.getPermOrgList(
- viewPerms,
- function(list2) {
- viewPermOrgs = list2
- drawProviderGrid();
- },
- true, true
- );
- },
- true, true
- );
- }
- );
-}
-
-
-function drawOneProvider() {
- openils.Util.hide('provider-list-div');
-
- var pcrud = new openils.PermaCrud();
- pcrud.retrieve('acqpro', providerId, {
- oncomplete : function(r) {
- provider = openils.Util.readResponse(r);
- console.log('provider is' + js2JSON(provider));
- var pane = new openils.widget.EditPane({fmObject:provider, paneStackCount:2}, dojo.byId('provider-summary-pane'));
- pane.startup();
- console.log("pane started");
- dojo.connect(providerTabs, 'selectChild', drawProviderSummary);
- }
- });
-
- drawProviderSummary();
-}
-
-
-function drawProviderGrid() {
- pListGrid.resetStore();
-
- // view providers for here plus children
- var list = fieldmapper.aou.descendantNodeList(
- contextOrgSelector.attr('value'), true, true);
-
- pListGrid.loadAll(
- {order_by : [ // sort providers I can edit to the front
- { 'class' : 'acqpro',
- field : 'owner',
- compare : {'in' : adminPermOrgs},
- direction : 'desc'
- },
- { 'class' : 'acqpro',
- field : 'name'
- }
- ]},
- {'owner' : list}
- );
-}
-
-function drawProviderSummary(child) {
- var loadedTabs = {'provider-address' : true};
- if(child){
- if(loadedTabs[child.id]) return;
- loadedTabs[child.id] = true;
- switch(child.id) {
- case 'tab-pro-contact':
- pcListGrid.overrideEditWidgets.provider = new
- dijit.form.TextBox({disabled: 'true', value: providerId});
- pcListGrid.resetStore();
- pcListGrid.loadAll({
- oncomplete:function(r) {
- var count = 0;
- pcListGrid.store.fetch( {
- onComplete:function(list) {
- count = list.length
- if (count>=1) {
- var contactIds = [];
- dojo.forEach(list, function(item) {
- contactIds.push(pcListGrid.store.getValue(item, 'id'));
- });
-
- pcaListGrid.overrideEditWidgets.contact = new
- dijit.form.FilteringSelect({store: pcListGrid.store});
- pcaListGrid.resetStore();
- pcaListGrid.loadAll({order_by:{acqpca : 'contact'}}, {contact: contactIds});
-
- } else {
- return;
- }
- }
- });
- }
- }, {provider : providerId});
-
- break;
-
- case 'tab-attr':
- padListGrid.overrideEditWidgets.provider = new
- dijit.form.TextBox({disabled: 'true', value: providerId});
- padListGrid.resetStore();
- padListGrid.loadAll({order_by:{acqlipad : 'code'}}, {provider : providerId});
- break;
-
- case 'tab-hold':
- phsListGrid.overrideEditWidgets.provider = new
- dijit.form.TextBox({disabled: 'true', value: providerId});
- phsListGrid.resetStore();
- phsListGrid.loadAll({order_by:{acqphsm : 'name'}}, {provider : providerId});
- break;
-
- case "tab-invoice":
- invListGrid.resetStore();
- invListGrid.loadAll(
- {"order_by": {"acqinv": "recv_date DESC"}},
- {"provider": providerId}
- );
- break;
-
- default:
- paListGrid.overrideEditWidgets.provider = new
- dijit.form.TextBox({disabled: 'true', value: providerId});
- paListGrid.resetStore();
- paListGrid.loadAll({order_by:{acqpa:'provider'}}, {provider: providerId});
- }
-
- } else {
- paListGrid.overrideEditWidgets.provider = new
- dijit.form.TextBox({disabled: 'true', value: providerId});
- paListGrid.resetStore();
- paListGrid.loadAll({order_by:{acqpa:'provider'}}, {provider: providerId});
- }
-}
-
-
-function getParsedTag(rowIndex, item) {
- return item && xpathParser.parse(padListGrid.store.getValue(item, 'xpath')).tags;
-}
-
-
-function getParsedSubf(rowIndex, item) {
- if(item) {
- var subfields = xpathParser.parse(padListGrid.store.getValue(item, 'xpath')).subfields;
- return subfields.join(',');
- }
- return'';
-}
-
-
-openils.Util.addOnLoad(draw);
+require([
+ "dijit/layout/TabContainer",
+ "openils/widget/AutoGrid",
+ "dijit/form/FilteringSelect",
+ "openils/PermaCrud",
+ "openils/MarcXPathParser",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(dijit_layout_TabContainer,
+ openils_widget_AutoGrid,
+ dijit_form_FilteringSelect,
+ openils_PermaCrud,
+ openils_MarcXPathParser,
+ openils_widget_OrgUnitFilteringSelect){
+
+
+ var provider;
+ var xpathParser = new openils_MarcXPathParser();
+ var subFields= [];
+ var adminPermOrgs = [];
+ var viewPermOrgs = [];
+ var user;
+ var viewPerms = [
+ 'ADMIN_PROVIDER',
+ 'MANAGE_PROVIDER',
+ 'VIEW_PROVIDER'
+ ];
+
+
+ function draw() {
+
+ user = new openils.User();
+
+ if(providerId) {
+ drawOneProvider();
+ return;
+ }
+
+ openils.Util.hide('provider-details-div');
+
+ // after a provider is created, load the provider page
+ pListGrid.onPostCreate = function(fmObject) {
+ location.href = location.href + '/' + fmObject.id();
+ }
+
+ user.buildPermOrgSelector(
+ viewPerms,
+ contextOrgSelector, null,
+
+ function() {
+ if (!contextOrgSelector.attr('value')) return
+
+ dojo.connect(contextOrgSelector, 'onChange', drawProviderGrid);
+
+ // fetch the admin org units
+ user.getPermOrgList(
+ 'ADMIN_PROVIDER',
+
+ function(list) {
+ adminPermOrgs = list;
+
+ // fetch the view org units
+ user.getPermOrgList(
+ viewPerms,
+ function(list2) {
+ viewPermOrgs = list2
+ drawProviderGrid();
+ },
+ true, true
+ );
+ },
+ true, true
+ );
+ }
+ );
+ }
+
+
+ function drawOneProvider() {
+ openils.Util.hide('provider-list-div');
+
+ var pcrud = new openils_PermaCrud();
+ pcrud.retrieve('acqpro', providerId, {
+ oncomplete : function(r) {
+ provider = openils.Util.readResponse(r);
+ console.log('provider is' + js2JSON(provider));
+ var pane = new openils.widget.EditPane({fmObject:provider, paneStackCount:2}, dojo.byId('provider-summary-pane'));
+ pane.startup();
+ console.log("pane started");
+ dojo.connect(providerTabs, 'selectChild', drawProviderSummary);
+ }
+ });
+
+ drawProviderSummary();
+ }
+
+
+ function drawProviderGrid() {
+ pListGrid.resetStore();
+
+ // view providers for here plus children
+ var list = fieldmapper.aou.descendantNodeList(
+ contextOrgSelector.attr('value'), true, true);
+
+ pListGrid.loadAll(
+ {order_by : [ // sort providers I can edit to the front
+ { 'class' : 'acqpro',
+ field : 'owner',
+ compare : {'in' : adminPermOrgs},
+ direction : 'desc'
+ },
+ { 'class' : 'acqpro',
+ field : 'name'
+ }
+ ]},
+ {'owner' : list}
+ );
+ }
+
+ function drawProviderSummary(child) {
+ var loadedTabs = {'provider-address' : true};
+ if(child){
+ if(loadedTabs[child.id]) return;
+ loadedTabs[child.id] = true;
+ switch(child.id) {
+ case 'tab-pro-contact':
+ pcListGrid.overrideEditWidgets.provider = new
+ dijit.form.TextBox({disabled: 'true', value: providerId});
+ pcListGrid.resetStore();
+ pcListGrid.loadAll({
+ oncomplete:function(r) {
+ var count = 0;
+ pcListGrid.store.fetch( {
+ onComplete:function(list) {
+ count = list.length
+ if (count>=1) {
+ var contactIds = [];
+ dojo.forEach(list, function(item) {
+ contactIds.push(pcListGrid.store.getValue(item, 'id'));
+ });
+
+ pcaListGrid.overrideEditWidgets.contact = new
+ dijit_form_FilteringSelect({store: pcListGrid.store});
+ pcaListGrid.resetStore();
+ pcaListGrid.loadAll({order_by:{acqpca : 'contact'}}, {contact: contactIds});
+
+ } else {
+ return;
+ }
+ }
+ });
+ }
+ }, {provider : providerId});
+
+ break;
+
+ case 'tab-attr':
+ padListGrid.overrideEditWidgets.provider = new
+ dijit.form.TextBox({disabled: 'true', value: providerId});
+ padListGrid.resetStore();
+ padListGrid.loadAll({order_by:{acqlipad : 'code'}}, {provider : providerId});
+ break;
+
+ case 'tab-hold':
+ phsListGrid.overrideEditWidgets.provider = new
+ dijit.form.TextBox({disabled: 'true', value: providerId});
+ phsListGrid.resetStore();
+ phsListGrid.loadAll({order_by:{acqphsm : 'name'}}, {provider : providerId});
+ break;
+
+ case "tab-invoice":
+ invListGrid.resetStore();
+ invListGrid.loadAll(
+ {"order_by": {"acqinv": "recv_date DESC"}},
+ {"provider": providerId}
+ );
+ break;
+
+ default:
+ paListGrid.overrideEditWidgets.provider = new
+ dijit.form.TextBox({disabled: 'true', value: providerId});
+ paListGrid.resetStore();
+ paListGrid.loadAll({order_by:{acqpa:'provider'}}, {provider: providerId});
+ }
+
+ } else {
+ paListGrid.overrideEditWidgets.provider = new
+ dijit.form.TextBox({disabled: 'true', value: providerId});
+ paListGrid.resetStore();
+ paListGrid.loadAll({order_by:{acqpa:'provider'}}, {provider: providerId});
+ }
+ }
+
+
+ function getParsedTag(rowIndex, item) {
+ return item && xpathParser.parse(padListGrid.store.getValue(item, 'xpath')).tags;
+ }
+
+
+ function getParsedSubf(rowIndex, item) {
+ if(item) {
+ var subfields = xpathParser.parse(padListGrid.store.getValue(item, 'xpath')).subfields;
+ return subfields.join(',');
+ }
+ return'';
+ }
+
+
+ openils.Util.addOnLoad(draw);
+
+
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dijit.form.TextBox');
-dojo.require('dijit.form.CurrencyTextBox');
-dojo.require('dijit.Dialog');
-dojo.require('openils.DojoPatch');
-dojo.require('dojox.widget.PlaceholderMenuItem');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('openils.PermaCrud');
-
-var svCache = {};
-var surveyMap;
-var svId;
-var questionId;
-
-
-/** really need to put this in a shared location... */
-function getOrgInfo(rowIndex, item) {
- if(!item) return '';
- var orgId = svGrid.store.getValue(item, this.field);
- return fieldmapper.aou.findOrgUnit(orgId).shortname();
-}
-
-function getDateTimeField(rowIndex, item) {
- if(!item) return '';
- var data = svGrid.store.getValue(item, this.field);
- var date = dojo.date.stamp.fromISOString(data);
- return dojo.date.locale.format(date, {formatLength:'short'});
-}
-
-function formatBool(inDatum) {
- switch (inDatum) {
- case 't':
- return "<span style='color:green;'>✓</span>";
- case 'f':
- return "<span style='color:red;'>✗</span>";
- default:
- return'';
- }
-}
-
-function endSurvey() {
- _endSurvey(svGrid.selection.getSelected(), 0);
-}
-
-function _endSurvey(list, idx) {
- if(idx >= list.length) // we've made it through the list
- return;
-
- var item = list[idx];
- var svId = svGrid.store.getValue(item, 'id');
- var pcrud = new openils.PermaCrud();
- var survey = pcrud.retrieve('asv', svId);
- var today = new Date();
- var date = dojo.date.stamp.toISOString(today);
- survey.end_date(date);
- survey.ischanged(true);
- pcrud.update(survey);
- _endSurvey(list, ++idx);
-
-}
-
-function buildSVGrid() {
- var store = new dojo.data.ItemFileWriteStore({data:asv.initStoreData('id', {identifier:'id'})});
- svGrid.setStore(store);
- svGrid.render();
- var user = new openils.User();
- var pcrud = new openils.PermaCrud();
- var retrieveSurveys = function(orgList) {
- pcrud.search('asv',
- {owner : orgList},
- {
- async : true,
- streaming : true,
- onresponse : function(r) {
- var survey = openils.Util.readResponse(r);
- if(!survey) return'';
- svCache[survey.id()] = survey;
- store.newItem(survey.toStoreItem());
- }
- }
- );
- }
- user.getPermOrgList('ADMIN_SURVEY', retrieveSurveys, true, true);
-
-}
-
-function svPage() {
- var pcrud = new openils.PermaCrud();
- var survey = pcrud.retrieve('asv', surveyId);
- dojo.byId("name").innerHTML = survey.name();
- dojo.byId("description").innerHTML = survey.description();
- dojo.byId("start_date").innerHTML = survey.start_date();
- dojo.byId("end_date").innerHTML = survey.end_date();
- dojo.byId("opac").innerHTML = survey.opac();
- dojo.byId("poll").innerHTML = survey.poll();
- dojo.byId("required").innerHTML = survey.required();
- dojo.byId("usr_summary").innerHTML = survey.usr_summary();
- dojo.byId("svQuestion").innerHTML = survey.question();
- dojo.byId("svAnswer").innerHTML = survey.answer();
-
-}
-
-function svNewSurvey() {
- new openils.User().buildPermOrgSelector('ADMIN_SURVEY', asvOwningOrg);
- svSurveyDialog.show();
-
-}
-
-function svCreate(args) {
-
- var sv = new asv();
- sv.name(args.svName);
- sv.owner(args.svOwner);
- sv.description(args.svDescription);
- sv.start_date(args.svStart_date);
- sv.end_date(args.svEnd_date);
- if(args.svPoll == 'on')
- sv.poll('t')
- else
- sv.poll('f');
-
- if(args.svPoll == 'on')
- sv.poll('t')
- else
- sv.poll('f');
-
- if(args.svOpac == 'on')
- sv.opac('t')
- else
- sv.opac('f');
-
- if(args.svRequired == 'on')
- sv.required('t')
- else
- sv.required('f');
-
- if(args.svUsr_summary == 'on')
- sv.usr_summary('t')
- else
- sv.usr_summary('f');
-
- var pcrud = new openils.PermaCrud();
- pcrud.create(sv,
- {
- oncomplete: function(r, objs) {
- var obj = objs[0];
- if(!obj) return '';
- svGrid.store.newItem(asv.toStoreItem(obj));
- svSurveyDialog.hide();
- svId = obj.id();
- document.location.href = oilsBasePath + "/conify/global/action/survey/edit/"+svId;
- }
- }
- );
-}
-
-function redirect(svId) {
-
-}
-
-
-function deleteFromGrid() {
- _deleteFromGrid(svGrid.selection.getSelected(), 0);
-}
-
-function _deleteFromGrid(list, idx) {
- if(idx >= list.length) // we've made it through the list
- return;
-
- var item = list[idx];
- var code = svGrid.store.getValue(item, 'id');
-
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.survey.delete.cascade'],
- { async: true,
- streaming: true,
- params: [openils.User.authtoken, code],
- onresponse: function(r) {
- if(stat = openils.Util.readResponse(r)) {
- console.log(stat);
- svGrid.store.deleteItem(item);
- }
- _deleteFromGrid(list, ++idx);
-
- }
- }
- );
-}
-openils.Util.addOnLoad(buildSVGrid);
-
-
+require([
+ "dojox/grid/DataGrid",
+ "dojox/grid/cells/dijit",
+ "dojo/data/ItemFileWriteStore",
+ "dijit/form/TextBox",
+ "dijit/form/CurrencyTextBox",
+ "dijit/Dialog",
+ "openils/DojoPatch",
+ "dojox/widget/PlaceholderMenuItem",
+ "fieldmapper/OrgUtils",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/PermaCrud"
+ ],
+function(dojox_grid_DataGrid,
+ dojox_grid_cells_dijit,
+ dojo_data_ItemFileWriteStore,
+ dijit_form_TextBox,
+ dijit_form_CurrencyTextBox,
+ dijit_Dialog,
+ openils_DojoPatch,
+ dojox_widget_PlaceholderMenuItem,
+ fieldmapper_OrgUtils,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_PermaCrud){
+
+ var svCache = {};
+ var surveyMap;
+ var svId;
+ var questionId;
+
+
+ /** really need to put this in a shared location... */
+ function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var orgId = svGrid.store.getValue(item, this.field);
+ return fieldmapper.aou.findOrgUnit(orgId).shortname();
+ }
+
+ function getDateTimeField(rowIndex, item) {
+ if(!item) return '';
+ var data = svGrid.store.getValue(item, this.field);
+ var date = dojo.date.stamp.fromISOString(data);
+ return dojo.date.locale.format(date, {formatLength:'short'});
+ }
+
+ function formatBool(inDatum) {
+ switch (inDatum) {
+ case 't':
+ return "<span style='color:green;'>✓</span>";
+ case 'f':
+ return "<span style='color:red;'>✗</span>";
+ default:
+ return'';
+ }
+ }
+
+ function endSurvey() {
+ _endSurvey(svGrid.selection.getSelected(), 0);
+ }
+
+ function _endSurvey(list, idx) {
+ if(idx >= list.length) // we've made it through the list
+ return;
+
+ var item = list[idx];
+ var svId = svGrid.store.getValue(item, 'id');
+ var pcrud = new openils_PermaCrud();
+ var survey = pcrud.retrieve('asv', svId);
+ var today = new Date();
+ var date = dojo.date.stamp.toISOString(today);
+ survey.end_date(date);
+ survey.ischanged(true);
+ pcrud.update(survey);
+ _endSurvey(list, ++idx);
+
+ }
+
+ function buildSVGrid() {
+ var store = new dojo_data_ItemFileWriteStore({data:asv.initStoreData('id', {identifier:'id'})});
+ svGrid.setStore(store);
+ svGrid.render();
+ var user = new openils.User();
+ var pcrud = new openils_PermaCrud();
+ var retrieveSurveys = function(orgList) {
+ pcrud.search('asv',
+ {owner : orgList},
+ {
+ async : true,
+ streaming : true,
+ onresponse : function(r) {
+ var survey = openils.Util.readResponse(r);
+ if(!survey) return'';
+ svCache[survey.id()] = survey;
+ store.newItem(survey.toStoreItem());
+ }
+ }
+ );
+ }
+ user.getPermOrgList('ADMIN_SURVEY', retrieveSurveys, true, true);
+
+ }
+
+ function svPage() {
+ var pcrud = new openils_PermaCrud();
+ var survey = pcrud.retrieve('asv', surveyId);
+ dojo.byId("name").innerHTML = survey.name();
+ dojo.byId("description").innerHTML = survey.description();
+ dojo.byId("start_date").innerHTML = survey.start_date();
+ dojo.byId("end_date").innerHTML = survey.end_date();
+ dojo.byId("opac").innerHTML = survey.opac();
+ dojo.byId("poll").innerHTML = survey.poll();
+ dojo.byId("required").innerHTML = survey.required();
+ dojo.byId("usr_summary").innerHTML = survey.usr_summary();
+ dojo.byId("svQuestion").innerHTML = survey.question();
+ dojo.byId("svAnswer").innerHTML = survey.answer();
+
+ }
+
+ function svNewSurvey() {
+ new openils.User().buildPermOrgSelector('ADMIN_SURVEY', asvOwningOrg);
+ svSurveyDialog.show();
+
+ }
+
+ function svCreate(args) {
+
+ var sv = new asv();
+ sv.name(args.svName);
+ sv.owner(args.svOwner);
+ sv.description(args.svDescription);
+ sv.start_date(args.svStart_date);
+ sv.end_date(args.svEnd_date);
+ if(args.svPoll == 'on')
+ sv.poll('t')
+ else
+ sv.poll('f');
+
+ if(args.svPoll == 'on')
+ sv.poll('t')
+ else
+ sv.poll('f');
+
+ if(args.svOpac == 'on')
+ sv.opac('t')
+ else
+ sv.opac('f');
+
+ if(args.svRequired == 'on')
+ sv.required('t')
+ else
+ sv.required('f');
+
+ if(args.svUsr_summary == 'on')
+ sv.usr_summary('t')
+ else
+ sv.usr_summary('f');
+
+ var pcrud = new openils_PermaCrud();
+ pcrud.create(sv,
+ {
+ oncomplete: function(r, objs) {
+ var obj = objs[0];
+ if(!obj) return '';
+ svGrid.store.newItem(asv.toStoreItem(obj));
+ svSurveyDialog.hide();
+ svId = obj.id();
+ document.location.href = oilsBasePath + "/conify/global/action/survey/edit/"+svId;
+ }
+ }
+ );
+ }
+
+ function redirect(svId) {
+
+ }
+
+
+ function deleteFromGrid() {
+ _deleteFromGrid(svGrid.selection.getSelected(), 0);
+ }
+
+ function _deleteFromGrid(list, idx) {
+ if(idx >= list.length) // we've made it through the list
+ return;
+
+ var item = list[idx];
+ var code = svGrid.store.getValue(item, 'id');
+
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.survey.delete.cascade'],
+ { async: true,
+ streaming: true,
+ params: [openils.User.authtoken, code],
+ onresponse: function(r) {
+ if(stat = openils.Util.readResponse(r)) {
+ console.log(stat);
+ svGrid.store.deleteItem(item);
+ }
+ _deleteFromGrid(list, ++idx);
+
+ }
+ }
+ );
+ }
+ openils.Util.addOnLoad(buildSVGrid);
+
+
+
+
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dojo.date.stamp');
-dojo.require('dijit.form.TextBox');
-dojo.require('dijit.form.Button');
-dojo.require('dijit.Dialog');
-dojo.require('dojox.widget.PlaceholderMenuItem');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.GridColumnPicker');
-dojo.require('openils.widget.EditPane');
-dojo.requireLocalization('openils.conify', 'conify');
-
-var surveyId;
-var startDate;
-var endDate;
-var today;
-var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
-
-function drawSurvey(svyId) {
- today = new Date();
- var surveyTable = dojo.byId('edit-pane');
- var surveyHead = dojo.create('thead', {id: "survey_head"}, surveyTable);
- var headRow = dojo.create('tr', null, surveyHead);
- var headCell = dojo.create('td', {id: "head_cell", innerHTML: "<h2>" +dojo.string.substitute(localeStrings.SURVEY_ID, [svyId])+"</h2>" }, headRow);
- var pcrud = new openils.PermaCrud();
- var survey = pcrud.retrieve('asv', svyId);
- startDate = dojo.date.stamp.fromISOString(survey.start_date());
- endDate = dojo.date.stamp.fromISOString(survey.end_date());
- var pane = new openils.widget.EditPane({fmObject : survey, hideActionButtons:false}, dojo.byId('edit-pane'));
-
- if ( endDate > today) {
- var buttonBody = dojo.create( 'td', null, surveyHead);
- var endButton = new dijit.form.Button({label: localeStrings.END_SURVEY, onClick:function() {endSurvey(survey.id())} }, buttonBody);
- }
-
- pane.fieldOrder = ['id', 'name', 'description', 'owner', 'start_date', 'end_date'];
- pane.onCancel = cancelEdit;
- pane.startup();
-
- var surveyFoot = dojo.create('tfoot', { id: "survey_foot"}, surveyTable);
- var footRow = dojo.create('tr', {id: "foot_row"}, surveyFoot);
- var footLabel = dojo.create('td', {id: "foot_label", innerHTML: "<h3>"+localeStrings.SURVEY_FOOT_LABEL+"</h3>"}, footRow);
- var footCell = dojo.create('td', {innerHTML: "<hr>", id: "foot_cell"}, footRow);
- getQuestions(svyId, survey);
-
-}
-
-function cancelEdit(){
- document.location.href = oilsBasePath + "/conify/global/action/survey";
-}
-
-function endSurvey(svyId) {
- var pcrud = new openils.PermaCrud();
- var survey = pcrud.retrieve('asv', svyId);
- var today = new Date();
- var date = dojo.date.stamp.toISOString(today);
- survey.end_date(date);
- survey.ischanged(true);
- return pcrud.update(survey);
-
-}
-
-// all functions for question manipulation
-
-function getQuestions(svyId, survey) {
-
- surveyId = svyId;
-
- var pcrud = new openils.PermaCrud();
- var questions = pcrud.search('asvq', {survey:svyId});
-
- for(var i in questions) {
- questionId = questions[i].id();
- var answers = pcrud.search('asva', {question:questionId});
- if (answers)
- drawQuestionBody(questions[i], answers, survey);
- }
- if ( startDate > today) newQuestionBody(surveyId);
-}
-
-function newQuestionBody(svyId) {
- var surveyTable = dojo.byId("survey_table");
- var surveyBody = dojo.create('tbody', {style: "background-color: #d9e8f9"}, surveyTable);
- var questionRow = dojo.create('tr', null, surveyBody);
- var questionLabel = dojo.create('td',{ innerHTML: localeStrings.SURVEY_QUESTION}, questionRow, "first");
- var questionTextbox = dojo.create('td', null, questionRow, "second");
- var qInput = new dijit.form.TextBox(null, questionTextbox);
- var questionButton = dojo.create('td', null , questionRow);
- var qButton = new dijit.form.Button({ label: localeStrings.SURVEY_SAVE_ADD, onClick:function() {newQuestion(svyId, qInput.getValue(), questionRow)} }, questionButton);
-
-}
-
-function drawQuestionBody(question, answers, survey){
-
- var surveyTable = dojo.byId('survey_table');
- var surveyBody = dojo.create( 'tbody', {quid:question.id(), id:("q" + question.id()), style: "background-color: #d9e8f9"}, surveyTable);
- var questionRow = dojo.create('tr', {quid:question.id()}, surveyBody);
- var questionLabel = dojo.create('td', {quid:question.id(), innerHTML: localeStrings.SURVEY_QUESTION}, questionRow, "first");
- var questionTextbox = dojo.create('td', {quid: question.id() }, questionRow, "second");
- var qInput = new dijit.form.TextBox(null, questionTextbox);
- qInput.attr('value', question.question());
- if (startDate > today){
- var questionButton = dojo.create('td', {quid: question.id()}, questionRow);
- var qButton = new dijit.form.Button({label: localeStrings.SURVEY_DELETE_QUESTION, onClick:function() {deleteQuestion(question.id(), surveyBody) }}, questionButton);
- var qChangesButton = dojo.create('td', {quid: question.id()}, questionRow);
- var qcButton = new dijit.form.Button({label: localeStrings.SURVEY_SAVE_CHANGES, onClick:function() {changeQuestion(question.id(), qInput.attr('value')) }}, qChangesButton);
-
- }
- for (var i in answers) {
- if(!answers) return'';
- drawAnswer(answers[i], question.id(), surveyBody, survey);
- }
- drawNewAnswerRow(question.id(), surveyBody);
-}
-
-function newQuestion(svyId, questionText, questionRow) {
- var pcrud = new openils.PermaCrud();
- var question = new asvq();
- question.survey(svyId);
- question.question(questionText);
- question.isnew(true);
- pcrud.create(question,
- {oncomplete: function(r, qs)
- { var q = qs[0];
- questionRow.parentNode.removeChild(questionRow);
- drawQuestionBody(q, null);
- newQuestionBody(svyId);
- }
- }
- );
-}
-
-function changeQuestion(quesId, questionText) {
- var pcrud = new openils.PermaCrud();
- var question = pcrud.retrieve('asvq', quesId);
- question.question(questionText);
- question.ischanged(true);
- return pcrud.update(question);
-}
-
-function deleteQuestion(quesId, surveyBody) {
- var pcrud = new openils.PermaCrud();
- var delQuestion = new asvq();
- var answers = pcrud.search('asva', {question:quesId});
- for(var i in answers){
- var ansId = answers[i].id();
- deleteAnswer(ansId);
- }
- delQuestion.id(quesId);
- delQuestion.isdeleted(true);
- surveyBody.parentNode.removeChild(surveyBody);
- return pcrud.eliminate(delQuestion);
-
-}
-
-// all functions for answer manipulation
-
-function drawAnswer(answer, qid, surveyBody, survey) {
- var surveyBody = dojo.byId(("q" + qid));
- var answerRow = dojo.create('tr', {anid: answer.id(), style: "background-color: #FFF"}, surveyBody);
- var answerSpacer = dojo.create('td', {anid: answer.id()}, answerRow, "first");
- var answerLabel = dojo.create('td', {anid: answer.id(), style: "float: right", innerHTML: localeStrings.SURVEY_ANSWER }, answerRow, "second");
- var answerTextbox = dojo.create('td', {anid: answer.id() }, answerRow, "third");
- var input = new dijit.form.TextBox(null, answerTextbox);
- input.attr('value', answer.answer());
- if (startDate > today){
- var answerSpacer = dojo.create('td', {anid: answer.id()}, answerRow);
- var delanswerButton = dojo.create('td', {anid: answer.id()}, answerRow);
- var aid = answer.id();
- var aButton = new dijit.form.Button({label: localeStrings.SURVEY_DELETE_ANSWER, onClick:function(){deleteAnswer(aid);answerRow.parentNode.removeChild(answerRow)} }, delanswerButton);
- var aChangesButton = dojo.create('td', {anid: qid}, answerRow);
- var acButton = new dijit.form.Button({label: localeStrings.SURVEY_SAVE_CHANGES, onClick:function() {changeAnswer(answer.id(), input.attr('value')) }}, aChangesButton);
- }
-}
-
-function drawNewAnswerRow(qid, surveyBody) {
- var answerRow = dojo.create('tr', {quid: qid, style: "background-color: #FFF"}, surveyBody);
- var answerSpacer = dojo.create('td', {quid: qid}, answerRow, "first");
- var answerLabel = dojo.create('td', {quid: qid, innerHTML: localeStrings.SURVEY_ANSWER, style: "float:right" }, answerRow, "second");
- var answerTextbox = dojo.create('td', {quid: qid }, answerRow, "third");
- var input = new dijit.form.TextBox(null, answerTextbox);
- var answerButton = dojo.create('td', {anid: qid}, answerRow);
- var aButton = new dijit.form.Button({label: localeStrings.SURVEY_ADD_ANSWER, onClick:function() {newAnswer(qid, input.attr('value'), answerRow, surveyBody)} }, answerButton);
-
-}
-
-
-function deleteAnswer(ansId) {
- var pcrud = new openils.PermaCrud();
- var delAnswer = new asva();
- delAnswer.id(ansId);
- delAnswer.isdeleted(true);
- return pcrud.eliminate(delAnswer);
-
-}
-function newAnswer(quesId, answerText, answerRow, surveyBody) {
- var pcrud = new openils.PermaCrud();
- var answer = new asva();
- answer.question(quesId);
- answer.answer(answerText);
- answer.isnew(true);
- answerRow.parentNode.removeChild(answerRow);
- drawAnswer(answer, answer.question());
- drawNewAnswerRow(quesId, surveyBody);
- return pcrud.create(answer);
-}
-
-
-function changeAnswer(ansId, answerText) {
- var pcrud = new openils.PermaCrud();
- var answer = pcrud.retrieve('asva', ansId);
- answer.answer(answerText);
- answer.ischanged(true);
- return pcrud.update(answer);
-}
-
+require([
+ "dojox/grid/DataGrid",
+ "dojox/grid/cells/dijit",
+ "dojo/data/ItemFileWriteStore",
+ "dojo/date/stamp",
+ "dijit/form/TextBox",
+ "dijit/form/Button",
+ "dijit/Dialog",
+ "dojox/widget/PlaceholderMenuItem",
+ "fieldmapper/OrgUtils",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/PermaCrud",
+ "openils/widget/GridColumnPicker",
+ "openils/widget/EditPane"
+ ],
+function(dojox_grid_DataGrid,
+ dojox_grid_cells_dijit,
+ dojo_data_ItemFileWriteStore,
+ dojo_date_stamp,
+ dijit_form_TextBox,
+ dijit_form_Button,
+ dijit_Dialog,
+ dojox_widget_PlaceholderMenuItem,
+ fieldmapper_OrgUtils,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_PermaCrud,
+ openils_widget_GridColumnPicker,
+ openils_widget_EditPane){
+ dojo.requireLocalization('openils.conify', 'conify');
+
+ var surveyId;
+ var startDate;
+ var endDate;
+ var today;
+ var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
+
+ function drawSurvey(svyId) {
+ today = new Date();
+ var surveyTable = dojo.byId('edit-pane');
+ var surveyHead = dojo.create('thead', {id: "survey_head"}, surveyTable);
+ var headRow = dojo.create('tr', null, surveyHead);
+ var headCell = dojo.create('td', {id: "head_cell", innerHTML: "<h2>" +dojo.string.substitute(localeStrings.SURVEY_ID, [svyId])+"</h2>" }, headRow);
+ var pcrud = new openils_PermaCrud();
+ var survey = pcrud.retrieve('asv', svyId);
+ startDate = dojo_date_stamp.fromISOString(survey.start_date());
+ endDate = dojo_date_stamp.fromISOString(survey.end_date());
+ var pane = new openils_widget_EditPane({fmObject : survey, hideActionButtons:false}, dojo.byId('edit-pane'));
+
+ if ( endDate > today) {
+ var buttonBody = dojo.create( 'td', null, surveyHead);
+ var endButton = new dijit_form_Button({label: localeStrings.END_SURVEY, onClick:function() {endSurvey(survey.id())} }, buttonBody);
+ }
+
+ pane.fieldOrder = ['id', 'name', 'description', 'owner', 'start_date', 'end_date'];
+ pane.onCancel = cancelEdit;
+ pane.startup();
+
+ var surveyFoot = dojo.create('tfoot', { id: "survey_foot"}, surveyTable);
+ var footRow = dojo.create('tr', {id: "foot_row"}, surveyFoot);
+ var footLabel = dojo.create('td', {id: "foot_label", innerHTML: "<h3>"+localeStrings.SURVEY_FOOT_LABEL+"</h3>"}, footRow);
+ var footCell = dojo.create('td', {innerHTML: "<hr>", id: "foot_cell"}, footRow);
+ getQuestions(svyId, survey);
+
+ }
+
+ function cancelEdit(){
+ document.location.href = oilsBasePath + "/conify/global/action/survey";
+ }
+
+ function endSurvey(svyId) {
+ var pcrud = new openils_PermaCrud();
+ var survey = pcrud.retrieve('asv', svyId);
+ var today = new Date();
+ var date = dojo_date_stamp.toISOString(today);
+ survey.end_date(date);
+ survey.ischanged(true);
+ return pcrud.update(survey);
+
+ }
+
+ // all functions for question manipulation
+
+ function getQuestions(svyId, survey) {
+
+ surveyId = svyId;
+
+ var pcrud = new openils_PermaCrud();
+ var questions = pcrud.search('asvq', {survey:svyId});
+
+ for(var i in questions) {
+ questionId = questions[i].id();
+ var answers = pcrud.search('asva', {question:questionId});
+ if (answers)
+ drawQuestionBody(questions[i], answers, survey);
+ }
+ if ( startDate > today) newQuestionBody(surveyId);
+ }
+
+ function newQuestionBody(svyId) {
+ var surveyTable = dojo.byId("survey_table");
+ var surveyBody = dojo.create('tbody', {style: "background-color: #d9e8f9"}, surveyTable);
+ var questionRow = dojo.create('tr', null, surveyBody);
+ var questionLabel = dojo.create('td',{ innerHTML: localeStrings.SURVEY_QUESTION}, questionRow, "first");
+ var questionTextbox = dojo.create('td', null, questionRow, "second");
+ var qInput = new dijit_form_TextBox(null, questionTextbox);
+ var questionButton = dojo.create('td', null , questionRow);
+ var qButton = new dijit_form_Button({ label: localeStrings.SURVEY_SAVE_ADD, onClick:function() {newQuestion(svyId, qInput.getValue(), questionRow)} }, questionButton);
+
+ }
+
+ function drawQuestionBody(question, answers, survey){
+
+ var surveyTable = dojo.byId('survey_table');
+ var surveyBody = dojo.create( 'tbody', {quid:question.id(), id:("q" + question.id()), style: "background-color: #d9e8f9"}, surveyTable);
+ var questionRow = dojo.create('tr', {quid:question.id()}, surveyBody);
+ var questionLabel = dojo.create('td', {quid:question.id(), innerHTML: localeStrings.SURVEY_QUESTION}, questionRow, "first");
+ var questionTextbox = dojo.create('td', {quid: question.id() }, questionRow, "second");
+ var qInput = new dijit_form_TextBox(null, questionTextbox);
+ qInput.attr('value', question.question());
+ if (startDate > today){
+ var questionButton = dojo.create('td', {quid: question.id()}, questionRow);
+ var qButton = new dijit_form_Button({label: localeStrings.SURVEY_DELETE_QUESTION, onClick:function() {deleteQuestion(question.id(), surveyBody) }}, questionButton);
+ var qChangesButton = dojo.create('td', {quid: question.id()}, questionRow);
+ var qcButton = new dijit_form_Button({label: localeStrings.SURVEY_SAVE_CHANGES, onClick:function() {changeQuestion(question.id(), qInput.attr('value')) }}, qChangesButton);
+
+ }
+ for (var i in answers) {
+ if(!answers) return'';
+ drawAnswer(answers[i], question.id(), surveyBody, survey);
+ }
+ drawNewAnswerRow(question.id(), surveyBody);
+ }
+
+ function newQuestion(svyId, questionText, questionRow) {
+ var pcrud = new openils_PermaCrud();
+ var question = new asvq();
+ question.survey(svyId);
+ question.question(questionText);
+ question.isnew(true);
+ pcrud.create(question,
+ {oncomplete: function(r, qs)
+ { var q = qs[0];
+ questionRow.parentNode.removeChild(questionRow);
+ drawQuestionBody(q, null);
+ newQuestionBody(svyId);
+ }
+ }
+ );
+ }
+
+ function changeQuestion(quesId, questionText) {
+ var pcrud = new openils_PermaCrud();
+ var question = pcrud.retrieve('asvq', quesId);
+ question.question(questionText);
+ question.ischanged(true);
+ return pcrud.update(question);
+ }
+
+ function deleteQuestion(quesId, surveyBody) {
+ var pcrud = new openils_PermaCrud();
+ var delQuestion = new asvq();
+ var answers = pcrud.search('asva', {question:quesId});
+ for(var i in answers){
+ var ansId = answers[i].id();
+ deleteAnswer(ansId);
+ }
+ delQuestion.id(quesId);
+ delQuestion.isdeleted(true);
+ surveyBody.parentNode.removeChild(surveyBody);
+ return pcrud.eliminate(delQuestion);
+
+ }
+
+ // all functions for answer manipulation
+
+ function drawAnswer(answer, qid, surveyBody, survey) {
+ var surveyBody = dojo.byId(("q" + qid));
+ var answerRow = dojo.create('tr', {anid: answer.id(), style: "background-color: #FFF"}, surveyBody);
+ var answerSpacer = dojo.create('td', {anid: answer.id()}, answerRow, "first");
+ var answerLabel = dojo.create('td', {anid: answer.id(), style: "float: right", innerHTML: localeStrings.SURVEY_ANSWER }, answerRow, "second");
+ var answerTextbox = dojo.create('td', {anid: answer.id() }, answerRow, "third");
+ var input = new dijit_form_TextBox(null, answerTextbox);
+ input.attr('value', answer.answer());
+ if (startDate > today){
+ var answerSpacer = dojo.create('td', {anid: answer.id()}, answerRow);
+ var delanswerButton = dojo.create('td', {anid: answer.id()}, answerRow);
+ var aid = answer.id();
+ var aButton = new dijit_form_Button({label: localeStrings.SURVEY_DELETE_ANSWER, onClick:function(){deleteAnswer(aid);answerRow.parentNode.removeChild(answerRow)} }, delanswerButton);
+ var aChangesButton = dojo.create('td', {anid: qid}, answerRow);
+ var acButton = new dijit_form_Button({label: localeStrings.SURVEY_SAVE_CHANGES, onClick:function() {changeAnswer(answer.id(), input.attr('value')) }}, aChangesButton);
+ }
+ }
+
+ function drawNewAnswerRow(qid, surveyBody) {
+ var answerRow = dojo.create('tr', {quid: qid, style: "background-color: #FFF"}, surveyBody);
+ var answerSpacer = dojo.create('td', {quid: qid}, answerRow, "first");
+ var answerLabel = dojo.create('td', {quid: qid, innerHTML: localeStrings.SURVEY_ANSWER, style: "float:right" }, answerRow, "second");
+ var answerTextbox = dojo.create('td', {quid: qid }, answerRow, "third");
+ var input = new dijit_form_TextBox(null, answerTextbox);
+ var answerButton = dojo.create('td', {anid: qid}, answerRow);
+ var aButton = new dijit_form_Button({label: localeStrings.SURVEY_ADD_ANSWER, onClick:function() {newAnswer(qid, input.attr('value'), answerRow, surveyBody)} }, answerButton);
+
+ }
+
+
+ function deleteAnswer(ansId) {
+ var pcrud = new openils_PermaCrud();
+ var delAnswer = new asva();
+ delAnswer.id(ansId);
+ delAnswer.isdeleted(true);
+ return pcrud.eliminate(delAnswer);
+
+ }
+ function newAnswer(quesId, answerText, answerRow, surveyBody) {
+ var pcrud = new openils_PermaCrud();
+ var answer = new asva();
+ answer.question(quesId);
+ answer.answer(answerText);
+ answer.isnew(true);
+ answerRow.parentNode.removeChild(answerRow);
+ drawAnswer(answer, answer.question());
+ drawNewAnswerRow(quesId, surveyBody);
+ return pcrud.create(answer);
+ }
+
+
+ function changeAnswer(ansId, answerText) {
+ var pcrud = new openils_PermaCrud();
+ var answer = pcrud.retrieve('asva', ansId);
+ answer.answer(answerText);
+ answer.ischanged(true);
+ return pcrud.update(answer);
+ }
+
+
+
+});
\ No newline at end of file
-dojo.require('dijit.layout.TabContainer');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dijit.form.TextBox');
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.Util');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.Textarea');
-dojo.require('openils.widget.ProgressDialog');
-dojo.require('dojox.string.sprintf');
-dojo.requireLocalization('openils.conify', 'conify');
-
-var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
-var eventDef = null;
-
-function loadEventDef() {
- eventDefGranularity.attr('value', null);
- edGrid.overrideEditWidgets.granularity = eventDefGranularity;
- edGrid.overrideEditWidgets.granularity.shove = {"create": ""};
- edGrid.loadAll({order_by:{atevdef : 'name, owner, hook, reactor, delay'}});
- openils.widget.Textarea.width = '600px';
- openils.widget.Textarea.height = '600px';
- edGrid.overrideEditWidgetClass.template = 'openils.widget.Textarea';
- dojo.connect(eventDefTabs,'selectChild', tabLoader);
-}
-
-/**
- * After an event def is cloned, see if the user wants to also clone the event def environment
- * @param {Object} oldItem Grid store item that was cloned
- * @param {Object} newObject Newly created fieldmapper object
- */
-function cloneEventEnv(oldItem, newObject) {
- if(!confirm('Clone event definition environment as well?')) return; // TODO i18n
- progressDialog.show(true);
- var pcrud = new openils.PermaCrud();
-
- // fetch the env list for the cloned object
- var env_list = pcrud.search('atenv', {event_def : edGrid.store.getValue(oldItem, 'id')});
-
- if(env_list && env_list.length) {
-
- // clone the environment
- env_list = env_list.map(
- function(item) {
- item.id(null);
- item.event_def(newObject.id());
- return item;
- }
- );
-
- // create the cloned environment list
- pcrud.create(env_list);
- }
-
- progressDialog.hide();
-}
-
-function loadEventDefData() {
- var pcrud = new openils.PermaCrud();
- eventDef = pcrud.retrieve('atevdef', eventDefId);
- var hook = pcrud.retrieve('ath', eventDef.hook());
-
- if(hook.core_type() == 'circ') {
- openils.Util.hide('at-test-none');
- openils.Util.show('at-test-circ');
- }
-
- dojo.byId('at-event-def-name').innerHTML = eventDef.name();
- teeGrid.loadAll({order_by:{atenv : 'path'}}, {event_def : eventDefId});
- dojo.connect(eventDefTabs,'selectChild', tabLoader);
-
- teeGrid.overrideEditWidgets.event_def = new dijit.form.TextBox({value: eventDefId, disabled : true});
- tepGrid.overrideEditWidgets.event_def = new dijit.form.TextBox({value: eventDefId, disabled : true});
-}
-
-var loadedTabs = {'tab-atevdef' : true};
-function tabLoader(child) {
- if(loadedTabs[child.id]) return;
- loadedTabs[child.id] = true;
-
- switch(child.id) {
- case 'tab-atevparam':
- tepGrid.loadAll({order_by:{atevparam : 'param'}}, {event_def : eventDefId});
- break;
- case 'tab-ath':
- thGrid.loadAll({order_by:{ath : 'key'}});
- break;
- case 'tab-atreact':
- trGrid.loadAll({order_by:{atreact : 'module'}});
- break;
- case 'tab-atval':
- tvGrid.loadAll({order_by:{atval : 'module'}});
- break;
- /*
- case 'tab-test':
- loadTestTab();
- break;
- */
- }
-}
-
-function getEventDefNameLink(rowIdx, item) {
- if(!item) return
- return this.grid.store.getValue(item, 'id') + ':' + this.grid.store.getValue(item, 'name');
-}
-
-function formatEventDefNameLink(data) {
- if(!data) return;
- var parts = data.split(/:/);
- return dojox.string.sprintf(
- '<a href="%s/conify/global/action_trigger/event_definition_data/%s">%s</a>',
- oilsBasePath, parts[0], parts[1]);
-}
-
-
-function evtTestCirc() {
- var barcode = circTestBarcode.attr('value');
- if(!barcode) return;
-
- progressDialog.show();
-
- function handleResponse(r) {
- var evt = openils.Util.readResponse(r);
- progressDialog.hide();
- if(evt && evt != '0') {
- var output = evt.template_output();
- if(!output) output = evt.error_output();
- var pre = document.createElement('pre');
- pre.innerHTML = output.data();
- openils.Util.appendClear('test-event-output', pre);
- openils.Util.show('test-event-output');
- }
- }
-
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.trigger_event_by_def_and_barcode.fire'],
- { async: true,
- params: [openils.User.authtoken, eventDefId, barcode],
- oncomplete: handleResponse
- }
- );
-}
-
+require([
+ "dijit/layout/TabContainer",
+ "dijit/form/FilteringSelect",
+ "dijit/form/TextBox",
+ "dojo/data/ItemFileReadStore",
+ "openils/widget/AutoGrid",
+ "openils/Util",
+ "openils/PermaCrud",
+ "openils/widget/Textarea",
+ "openils/widget/ProgressDialog",
+ "dojox/string/sprintf"
+ ],
+function(dijit_layout_TabContainer,
+ dijit_form_FilteringSelect,
+ dijit_form_TextBox,
+ dojo_data_ItemFileReadStore,
+ openils_widget_AutoGrid,
+ openils_Util,
+ openils_PermaCrud,
+ openils_widget_Textarea,
+ openils_widget_ProgressDialog,
+ dojox_string_sprintf){
+ dojo.requireLocalization('openils.conify', 'conify');
+
+ var localeStrings = dojo.i18n.getLocalization('openils.conify', 'conify');
+ var eventDef = null;
+
+ function loadEventDef() {
+ eventDefGranularity.attr('value', null);
+ edGrid.overrideEditWidgets.granularity = eventDefGranularity;
+ edGrid.overrideEditWidgets.granularity.shove = {"create": ""};
+ edGrid.loadAll({order_by:{atevdef : 'name, owner, hook, reactor, delay'}});
+ openils_widget_Textarea.width = '600px';
+ openils_widget_Textarea.height = '600px';
+ edGrid.overrideEditWidgetClass.template = 'openils_widget_Textarea';
+ dojo.connect(eventDefTabs,'selectChild', tabLoader);
+ }
+
+ /**
+ * After an event def is cloned, see if the user wants to also clone the event def environment
+ * @param {Object} oldItem Grid store item that was cloned
+ * @param {Object} newObject Newly created fieldmapper object
+ */
+ function cloneEventEnv(oldItem, newObject) {
+ if(!confirm('Clone event definition environment as well?')) return; // TODO i18n
+ progressDialog.show(true);
+ var pcrud = new openils_PermaCrud();
+
+ // fetch the env list for the cloned object
+ var env_list = pcrud.search('atenv', {event_def : edGrid.store.getValue(oldItem, 'id')});
+
+ if(env_list && env_list.length) {
+
+ // clone the environment
+ env_list = env_list.map(
+ function(item) {
+ item.id(null);
+ item.event_def(newObject.id());
+ return item;
+ }
+ );
+
+ // create the cloned environment list
+ pcrud.create(env_list);
+ }
+
+ progressDialog.hide();
+ }
+
+ function loadEventDefData() {
+ var pcrud = new openils_PermaCrud();
+ eventDef = pcrud.retrieve('atevdef', eventDefId);
+ var hook = pcrud.retrieve('ath', eventDef.hook());
+
+ if(hook.core_type() == 'circ') {
+ openils_Util.hide('at-test-none');
+ openils_Util.show('at-test-circ');
+ }
+
+ dojo.byId('at-event-def-name').innerHTML = eventDef.name();
+ teeGrid.loadAll({order_by:{atenv : 'path'}}, {event_def : eventDefId});
+ dojo.connect(eventDefTabs,'selectChild', tabLoader);
+
+ teeGrid.overrideEditWidgets.event_def = new dijit_form_TextBox({value: eventDefId, disabled : true});
+ tepGrid.overrideEditWidgets.event_def = new dijit_form_TextBox({value: eventDefId, disabled : true});
+ }
+
+ var loadedTabs = {'tab-atevdef' : true};
+ function tabLoader(child) {
+ if(loadedTabs[child.id]) return;
+ loadedTabs[child.id] = true;
+
+ switch(child.id) {
+ case 'tab-atevparam':
+ tepGrid.loadAll({order_by:{atevparam : 'param'}}, {event_def : eventDefId});
+ break;
+ case 'tab-ath':
+ thGrid.loadAll({order_by:{ath : 'key'}});
+ break;
+ case 'tab-atreact':
+ trGrid.loadAll({order_by:{atreact : 'module'}});
+ break;
+ case 'tab-atval':
+ tvGrid.loadAll({order_by:{atval : 'module'}});
+ break;
+ /*
+ case 'tab-test':
+ loadTestTab();
+ break;
+ */
+ }
+ }
+
+ function getEventDefNameLink(rowIdx, item) {
+ if(!item) return
+ return this.grid.store.getValue(item, 'id') + ':' + this.grid.store.getValue(item, 'name');
+ }
+
+ function formatEventDefNameLink(data) {
+ if(!data) return;
+ var parts = data.split(/:/);
+ return dojox_string_sprintf(
+ '<a href="%s/conify/global/action_trigger/event_definition_data/%s">%s</a>',
+ oilsBasePath, parts[0], parts[1]);
+ }
+
+
+ function evtTestCirc() {
+ var barcode = circTestBarcode.attr('value');
+ if(!barcode) return;
+
+ progressDialog.show();
+
+ function handleResponse(r) {
+ var evt = openils_Util.readResponse(r);
+ progressDialog.hide();
+ if(evt && evt != '0') {
+ var output = evt.template_output();
+ if(!output) output = evt.error_output();
+ var pre = document.createElement('pre');
+ pre.innerHTML = output.data();
+ openils_Util.appendClear('test-event-output', pre);
+ openils_Util.show('test-event-output');
+ }
+ }
+
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.trigger_event_by_def_and_barcode.fire'],
+ { async: true,
+ params: [openils.User.authtoken, eventDefId, barcode],
+ oncomplete: handleResponse
+ }
+ );
+ }
+
+
+
+});
\ No newline at end of file
-dojo.require('dijit.layout.ContentPane');
-dojo.require('dijit.layout.BorderContainer');
-dojo.require("dojo.dnd.Container");
-dojo.require("dojo.dnd.Source");
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.User');
-dojo.require('openils.Util');
-dojo.require('openils.Event');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.widget.ProgressDialog');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('openils.widget.EditDialog');
-
-var user;
-var groups;
-var locations;
-var source;
-var locTbody;
-var locRowTemplate;
-var locMapTbody;
-var locMapRowTemplate;
-var currentGroupId;
-var currentGroupMaps;
-var currentOrg;
-
-function init() {
-
- user = new openils.User();
-
- // init the DnD environment
- source = new dojo.dnd.Source('acplg-list');
- dojo.connect(source, 'onDndDrop', updateGroupOrder);
-
- // context org selector
- user.buildPermOrgSelector(
- 'ADMIN_COPY_LOCATION_GROUP',
- contextOrgSelector,
- null,
- function() {
- dojo.connect(contextOrgSelector, 'onChange', drawPage);
- }
- );
-
- fetchCopyLocations();
-}
-
-function fetchCopyLocations() {
- // the full set of copy locations can be very large.
- // Only retrieve the set of locations owned by orgs this user
- // can use for building location groups.
- user.getPermOrgList(
- ['ADMIN_COPY_LOCATION_GROUP'],
- function(list) {
-
- var ownerOrgList = [];
- dojo.forEach(list,
- function(org) {
- // include parent orgs
- ownerOrgList = ownerOrgList.concat(org).concat(
- fieldmapper.aou.orgNodeTrail(fieldmapper.aou.findOrgUnit(org), true));
- }
- );
-
- var pcrud = new openils.PermaCrud({authtoken : user.authtoken});
- pcrud.search('acpl', // this can take some time...
- {owning_lib : ownerOrgList},
- {
- async : true,
- join : 'aou',
- oncomplete : function(r) {
- locations = openils.Util.readResponse(r);
- sortCopyLocations();
- drawPage(user.user.ws_ou());
- }
- }
- );
- },
- true,
- true
- );
-}
-
-// sort the list of copy locations according the shape of
-// the org unit tree. apply a secondary sort on name.
-function sortCopyLocations() {
- var newlist = [];
-
- function addNode(node) {
- // find locs for this org
- var locs = locations.filter(function(loc) { return loc.owning_lib() == node.id() });
- // sort on name and append to the new list
- newlist = newlist.concat(locs.sort(function(a, b) { return a.name() < b.name() ? -1 : 1 }));
- // repeat for org child nodes
- dojo.forEach(node.children(), addNode);
- }
-
- addNode(fieldmapper.aou.globalOrgTree);
- locations = newlist;
-}
-
-
-function drawPage(org) {
- currentOrg = org;
- currentGroupId = null;
- currentGroupMaps = [];
- //drawLocations();
- drawGroupList();
-}
-
-function drawGroupList(selectedGrp) {
- var pcrud = new openils.PermaCrud({authtoken : user.authtoken});
- groups = pcrud.search('acplg', {owner : currentOrg}, {order_by : {acplg : 'pos'}});
-
-
- source.selectAll();
- source.deleteSelectedNodes();
- source.clearItems();
-
- dojo.forEach(groups,
- function(group) {
- if(!group) return;
-
- var drag = dojo.byId('dnd-drag-actions').cloneNode(true);
- drag.id = '';
- var vis = openils.Util.isTrue(group.opac_visible());
- openils.Util.hide(dojo.query('[name=' + (vis ? 'invisible' : 'visible') + ']', drag)[0]);
-
-
- var node = source.insertNodes(false, [{
- data : drag.innerHTML.replace(/GRPID/g, group.id()).replace(/GRPNAME/g, group.name()),
- type : [group.id()+''] // use the type field to store the ID
- }]);
- }
- );
-
- if (groups.length == 0) {
- selectedGrp = null
- } else if (selectedGrp == null) {
- selectedGrp = groups[0].id();
- }
-
- drawGroupEntries(selectedGrp);
-}
-
-function drawLocations() {
-
- if (!locTbody) {
- locTbody = dojo.byId('acplg-loc-tbody');
- locRowTemplate = locTbody.removeChild(dojo.byId('acplg-loc-row'));
- } else {
- // clear out the previous table
- while (node = locTbody.childNodes[0])
- locTbody.removeChild(node);
- }
-
- var allMyOrgs = fieldmapper.aou.fullPath(currentOrg, true);
-
- dojo.forEach(locations,
- function(loc) {
- if (allMyOrgs.indexOf(loc.owning_lib()) == -1) return;
-
- // don't show locations contained in the current group
- if (currentGroupMaps.length) {
- var existing = currentGroupMaps.filter(
- function(map) { return (map.location() == loc.id()) });
- if (existing.length > 0) return;
- }
-
- var row = locRowTemplate.cloneNode(true);
- row.setAttribute('location', loc.id());
- dojo.query('[name=name]', row)[0].innerHTML = loc.name();
- dojo.query('[name=owning_lib]', row)[0].innerHTML = fieldmapper.aou.findOrgUnit(loc.owning_lib()).shortname();
- locTbody.appendChild(row);
- }
- );
-}
-
-function updateGroupOrder() {
- var pos = 0;
- var toUpdate = [];
-
- // find any groups that have changed position and send them off for update
- dojo.forEach(
- source.getAllNodes(),
- function(node) {
- var item = source.getItem(node.id);
- var grpId = item.type[0];
- var grp = groups.filter(function(g) { return g.id() == grpId })[0];
- if (grp.pos() != pos) {
- grp.pos(pos);
- toUpdate.push(grp);
- }
- pos++;
- }
- );
-
- if (toUpdate.length == 0) return;
-
- var pcrud = new openils.PermaCrud({authtoken : user.authtoken});
- pcrud.update(toUpdate); // run sync to prevent UI changes mid-update
-}
-
-function newGroup() {
-
- var dialog = new openils.widget.EditDialog({
- fmClass : 'acplg',
- mode : 'create',
- parentNode : dojo.byId('acplg-edit-dialog'),
- suppressFields : ['id'],
- // note: when 'pos' is suppressed, the value is not propagated.
- overrideWidgetArgs : {
- pos : {widgetValue : groups.length, dijitArgs : {disabled : true}},
- owner : {widgetValue : currentOrg, dijitArgs : {disabled : true}}
- },
- onPostSubmit : function(req, cudResults) {
- if (cudResults && cudResults.length) {
- // refresh the group display
- drawGroupList(cudResults[0].id());
- }
- }
- });
-
- dialog.startup();
- dialog.show();
-}
-
-function editGroup(grpId) {
- var grp = groups.filter(function(g) { return g.id() == grpId })[0];
-
- var dialog = new openils.widget.EditDialog({
- fmObject : grp,
- mode : 'update',
- parentNode : dojo.byId('acplg-edit-dialog'),
- suppressFields : ['id', 'pos', 'owner'],
- onPostSubmit : function(req, cudResults) {
- if (cudResults && cudResults.length) {
- // refresh the group display
- // pcrud.update returns ID only
- drawGroupList(cudResults[0]);
- }
- }
- });
-
- dialog.startup();
- dialog.show();
-}
-
-function deleteGroup(grpId) {
- // confirm and delete
- var pcrud = new openils.PermaCrud({authtoken : user.authtoken});
- var grp = groups.filter(function(g) { return g.id() == grpId })[0];
- pcrud.eliminate(grp, {oncomplete : function() { drawGroupList() }});
-}
-
-function drawGroupEntries(grpId) {
- currentGroupId = grpId;
-
- // init/reset the table of mapped copy locations
- if (!locMapTbody) {
- locMapTbody = dojo.byId('acplg-loc-map-tbody');
- locMapRowTemplate = locMapTbody.removeChild(dojo.byId('acplg-loc-map-row'));
- } else {
- // clear out the previous table
- while (node = locMapTbody.childNodes[0])
- locMapTbody.removeChild(node);
- }
-
- // update the 'selected' status
- dojo.query('[group]').forEach(
- function(node) {
- if (node.getAttribute('group') == grpId) {
- openils.Util.addCSSClass(node, 'acplg-group-selected');
- } else {
- openils.Util.removeCSSClass(node, 'acplg-group-selected');
- }
- }
- );
-
- currentGroupMaps = [];
-
- // fetch the group
- if (grpId) {
- var pcrud = new openils.PermaCrud({authtoken : user.authtoken});
- currentGroupMaps = pcrud.search('acplgm', {lgroup : grpId});
- }
-
- // update the location selector to remove the already-selected orgs
- drawLocations();
-
- // draw the mapped copy locations
- // remove any mapped locations from the location selector
- dojo.forEach(currentGroupMaps,
- function(map) {
- var row = locMapRowTemplate.cloneNode(true);
- row.setAttribute('map', map.id());
- var loc = locations.filter(
- function(loc) { return (loc.id() == map.location()) })[0];
- dojo.query('[name=name]', row)[0].innerHTML = loc.name();
- dojo.query('[name=owning_lib]', row)[0].innerHTML =
- fieldmapper.aou.findOrgUnit(loc.owning_lib()).shortname();
- locMapTbody.appendChild(row);
-
- // if the location is in the group, remove it from the location selection list
- //removeLocationRow(loc.id());
- }
- );
-}
-
-function editLocations(action) {
- var maps = [];
- var tbody = (action == 'create') ? locTbody : locMapTbody;
- dojo.forEach(tbody.getElementsByTagName('tr'),
- function(row) {
- var selector = dojo.query('[name=selector]', row)[0];
- if (selector.checked) {
- var map = new fieldmapper.acplgm();
- map.lgroup(currentGroupId);
- if (action == 'create') {
- map.location(row.getAttribute('location'));
- } else {
- map.id(row.getAttribute('map'));
- }
- maps.push(map);
- }
- }
- );
-
- if (maps.length == 0) return;
-
- // check for dupes
- var pcrud = new openils.PermaCrud({authtoken : user.authtoken});
- pcrud[action](maps, {
- oncomplete : function() {
- drawGroupEntries(currentGroupId)
- /*
- if (action != 'create') {
- drawLocations();
- }
- */
- }
- });
-}
-
-function deSelectAll(node) {
- dojo.query('[name=selector]', node).forEach(
- function(selector) {
- selector.checked = false;
- }
- );
-}
-
-/*
-function removeLocationRow(locId) {
- var row = dojo.query('[location=' + locId + ']', locTbody)[0];
- if (row) locTbody.removeChild(row);
-}
-*/
-
-openils.Util.addOnLoad(init);
+require([
+ "dijit/layout/ContentPane",
+ "dijit/layout/BorderContainer",
+ "dojo/dnd/Container",
+ "dojo/dnd/Source",
+ "fieldmapper/OrgUtils",
+ "openils/User",
+ "openils/Util",
+ "openils/Event",
+ "openils/PermaCrud",
+ "openils/widget/AutoGrid",
+ "openils/widget/ProgressDialog",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/widget/EditDialog"
+ ],
+function(dijit_layout_ContentPane,
+ dijit_layout_BorderContainer,
+ dojo_dnd_Container,
+ dojo_dnd_Source,
+ fieldmapper_OrgUtils,
+ openils_User,
+ openils_Util,
+ openils_Event,
+ openils_PermaCrud,
+ openils_widget_AutoGrid,
+ openils_widget_ProgressDialog,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_widget_EditDialog){
+
+ var user;
+ var groups;
+ var locations;
+ var source;
+ var locTbody;
+ var locRowTemplate;
+ var locMapTbody;
+ var locMapRowTemplate;
+ var currentGroupId;
+ var currentGroupMaps;
+ var currentOrg;
+
+ function init() {
+
+ user = new openils_User();
+
+ // init the DnD environment
+ source = new dojo_dnd_Source('acplg-list');
+ dojo.connect(source, 'onDndDrop', updateGroupOrder);
+
+ // context org selector
+ user.buildPermOrgSelector(
+ 'ADMIN_COPY_LOCATION_GROUP',
+ contextOrgSelector,
+ null,
+ function() {
+ dojo.connect(contextOrgSelector, 'onChange', drawPage);
+ }
+ );
+
+ fetchCopyLocations();
+ }
+
+ function fetchCopyLocations() {
+ // the full set of copy locations can be very large.
+ // Only retrieve the set of locations owned by orgs this user
+ // can use for building location groups.
+ user.getPermOrgList(
+ ['ADMIN_COPY_LOCATION_GROUP'],
+ function(list) {
+
+ var ownerOrgList = [];
+ dojo.forEach(list,
+ function(org) {
+ // include parent orgs
+ ownerOrgList = ownerOrgList.concat(org).concat(
+ fieldmapper.aou.orgNodeTrail(fieldmapper.aou.findOrgUnit(org), true));
+ }
+ );
+
+ var pcrud = new openils_PermaCrud({authtoken : user.authtoken});
+ pcrud.search('acpl', // this can take some time...
+ {owning_lib : ownerOrgList},
+ {
+ async : true,
+ join : 'aou',
+ oncomplete : function(r) {
+ locations = openils_Util.readResponse(r);
+ sortCopyLocations();
+ drawPage(user.user.ws_ou());
+ }
+ }
+ );
+ },
+ true,
+ true
+ );
+ }
+
+ // sort the list of copy locations according the shape of
+ // the org unit tree. apply a secondary sort on name.
+ function sortCopyLocations() {
+ var newlist = [];
+
+ function addNode(node) {
+ // find locs for this org
+ var locs = locations.filter(function(loc) { return loc.owning_lib() == node.id() });
+ // sort on name and append to the new list
+ newlist = newlist.concat(locs.sort(function(a, b) { return a.name() < b.name() ? -1 : 1 }));
+ // repeat for org child nodes
+ dojo.forEach(node.children(), addNode);
+ }
+
+ addNode(fieldmapper.aou.globalOrgTree);
+ locations = newlist;
+ }
+
+
+ function drawPage(org) {
+ currentOrg = org;
+ currentGroupId = null;
+ currentGroupMaps = [];
+ //drawLocations();
+ drawGroupList();
+ }
+
+ function drawGroupList(selectedGrp) {
+ var pcrud = new openils_PermaCrud({authtoken : user.authtoken});
+ groups = pcrud.search('acplg', {owner : currentOrg}, {order_by : {acplg : 'pos'}});
+
+
+ source.selectAll();
+ source.deleteSelectedNodes();
+ source.clearItems();
+
+ dojo.forEach(groups,
+ function(group) {
+ if(!group) return;
+
+ var drag = dojo.byId('dnd-drag-actions').cloneNode(true);
+ drag.id = '';
+ var vis = openils_Util.isTrue(group.opac_visible());
+ openils_Util.hide(dojo.query('[name=' + (vis ? 'invisible' : 'visible') + ']', drag)[0]);
+
+
+ var node = source.insertNodes(false, [{
+ data : drag.innerHTML.replace(/GRPID/g, group.id()).replace(/GRPNAME/g, group.name()),
+ type : [group.id()+''] // use the type field to store the ID
+ }]);
+ }
+ );
+
+ if (groups.length == 0) {
+ selectedGrp = null
+ } else if (selectedGrp == null) {
+ selectedGrp = groups[0].id();
+ }
+
+ drawGroupEntries(selectedGrp);
+ }
+
+ function drawLocations() {
+
+ if (!locTbody) {
+ locTbody = dojo.byId('acplg-loc-tbody');
+ locRowTemplate = locTbody.removeChild(dojo.byId('acplg-loc-row'));
+ } else {
+ // clear out the previous table
+ while (node = locTbody.childNodes[0])
+ locTbody.removeChild(node);
+ }
+
+ var allMyOrgs = fieldmapper.aou.fullPath(currentOrg, true);
+
+ dojo.forEach(locations,
+ function(loc) {
+ if (allMyOrgs.indexOf(loc.owning_lib()) == -1) return;
+
+ // don't show locations contained in the current group
+ if (currentGroupMaps.length) {
+ var existing = currentGroupMaps.filter(
+ function(map) { return (map.location() == loc.id()) });
+ if (existing.length > 0) return;
+ }
+
+ var row = locRowTemplate.cloneNode(true);
+ row.setAttribute('location', loc.id());
+ dojo.query('[name=name]', row)[0].innerHTML = loc.name();
+ dojo.query('[name=owning_lib]', row)[0].innerHTML = fieldmapper.aou.findOrgUnit(loc.owning_lib()).shortname();
+ locTbody.appendChild(row);
+ }
+ );
+ }
+
+ function updateGroupOrder() {
+ var pos = 0;
+ var toUpdate = [];
+
+ // find any groups that have changed position and send them off for update
+ dojo.forEach(
+ source.getAllNodes(),
+ function(node) {
+ var item = source.getItem(node.id);
+ var grpId = item.type[0];
+ var grp = groups.filter(function(g) { return g.id() == grpId })[0];
+ if (grp.pos() != pos) {
+ grp.pos(pos);
+ toUpdate.push(grp);
+ }
+ pos++;
+ }
+ );
+
+ if (toUpdate.length == 0) return;
+
+ var pcrud = new openils_PermaCrud({authtoken : user.authtoken});
+ pcrud.update(toUpdate); // run sync to prevent UI changes mid-update
+ }
+
+ function newGroup() {
+
+ var dialog = new openils_widget_EditDialog({
+ fmClass : 'acplg',
+ mode : 'create',
+ parentNode : dojo.byId('acplg-edit-dialog'),
+ suppressFields : ['id'],
+ // note: when 'pos' is suppressed, the value is not propagated.
+ overrideWidgetArgs : {
+ pos : {widgetValue : groups.length, dijitArgs : {disabled : true}},
+ owner : {widgetValue : currentOrg, dijitArgs : {disabled : true}}
+ },
+ onPostSubmit : function(req, cudResults) {
+ if (cudResults && cudResults.length) {
+ // refresh the group display
+ drawGroupList(cudResults[0].id());
+ }
+ }
+ });
+
+ dialog.startup();
+ dialog.show();
+ }
+
+ function editGroup(grpId) {
+ var grp = groups.filter(function(g) { return g.id() == grpId })[0];
+
+ var dialog = new openils_widget_EditDialog({
+ fmObject : grp,
+ mode : 'update',
+ parentNode : dojo.byId('acplg-edit-dialog'),
+ suppressFields : ['id', 'pos', 'owner'],
+ onPostSubmit : function(req, cudResults) {
+ if (cudResults && cudResults.length) {
+ // refresh the group display
+ // pcrud.update returns ID only
+ drawGroupList(cudResults[0]);
+ }
+ }
+ });
+
+ dialog.startup();
+ dialog.show();
+ }
+
+ function deleteGroup(grpId) {
+ // confirm and delete
+ var pcrud = new openils_PermaCrud({authtoken : user.authtoken});
+ var grp = groups.filter(function(g) { return g.id() == grpId })[0];
+ pcrud.eliminate(grp, {oncomplete : function() { drawGroupList() }});
+ }
+
+ function drawGroupEntries(grpId) {
+ currentGroupId = grpId;
+
+ // init/reset the table of mapped copy locations
+ if (!locMapTbody) {
+ locMapTbody = dojo.byId('acplg-loc-map-tbody');
+ locMapRowTemplate = locMapTbody.removeChild(dojo.byId('acplg-loc-map-row'));
+ } else {
+ // clear out the previous table
+ while (node = locMapTbody.childNodes[0])
+ locMapTbody.removeChild(node);
+ }
+
+ // update the 'selected' status
+ dojo.query('[group]').forEach(
+ function(node) {
+ if (node.getAttribute('group') == grpId) {
+ openils_Util.addCSSClass(node, 'acplg-group-selected');
+ } else {
+ openils_Util.removeCSSClass(node, 'acplg-group-selected');
+ }
+ }
+ );
+
+ currentGroupMaps = [];
+
+ // fetch the group
+ if (grpId) {
+ var pcrud = new openils_PermaCrud({authtoken : user.authtoken});
+ currentGroupMaps = pcrud.search('acplgm', {lgroup : grpId});
+ }
+
+ // update the location selector to remove the already-selected orgs
+ drawLocations();
+
+ // draw the mapped copy locations
+ // remove any mapped locations from the location selector
+ dojo.forEach(currentGroupMaps,
+ function(map) {
+ var row = locMapRowTemplate.cloneNode(true);
+ row.setAttribute('map', map.id());
+ var loc = locations.filter(
+ function(loc) { return (loc.id() == map.location()) })[0];
+ dojo.query('[name=name]', row)[0].innerHTML = loc.name();
+ dojo.query('[name=owning_lib]', row)[0].innerHTML =
+ fieldmapper.aou.findOrgUnit(loc.owning_lib()).shortname();
+ locMapTbody.appendChild(row);
+
+ // if the location is in the group, remove it from the location selection list
+ //removeLocationRow(loc.id());
+ }
+ );
+ }
+
+ function editLocations(action) {
+ var maps = [];
+ var tbody = (action == 'create') ? locTbody : locMapTbody;
+ dojo.forEach(tbody.getElementsByTagName('tr'),
+ function(row) {
+ var selector = dojo.query('[name=selector]', row)[0];
+ if (selector.checked) {
+ var map = new fieldmapper.acplgm();
+ map.lgroup(currentGroupId);
+ if (action == 'create') {
+ map.location(row.getAttribute('location'));
+ } else {
+ map.id(row.getAttribute('map'));
+ }
+ maps.push(map);
+ }
+ }
+ );
+
+ if (maps.length == 0) return;
+
+ // check for dupes
+ var pcrud = new openils_PermaCrud({authtoken : user.authtoken});
+ pcrud[action](maps, {
+ oncomplete : function() {
+ drawGroupEntries(currentGroupId)
+ /*
+ if (action != 'create') {
+ drawLocations();
+ }
+ */
+ }
+ });
+ }
+
+ function deSelectAll(node) {
+ dojo.query('[name=selector]', node).forEach(
+ function(selector) {
+ selector.checked = false;
+ }
+ );
+ }
+
+ /*
+ function removeLocationRow(locId) {
+ var row = dojo.query('[location=' + locId + ']', locTbody)[0];
+ if (row) locTbody.removeChild(row);
+ }
+ */
+
+ openils_Util.addOnLoad(init);
+
+
+});
\ No newline at end of file
-dojo.require('dijit.layout.ContentPane');
-dojo.require("dojo.dnd.Container");
-dojo.require("dojo.dnd.Source");
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.User');
-dojo.require('openils.Util');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.ProgressDialog');
-
-var user;
-var orders;
-var locations;
-var source;
-
-function init() {
-
- user = new openils.User();
- source = new dojo.dnd.Source('acl-ol');
-
- user.buildPermOrgSelector(
- 'ADMIN_COPY_LOCATION_ORDER',
- contextOrgSelector,
- null,
- function() {
- dojo.connect(contextOrgSelector, 'onChange', filterGrid);
- }
- );
-
- filterGrid(user.user.ws_ou());
-}
-
-function filterGrid(org) {
-
- // fetch the locations and order entries
- if(!orders) {
- var pcrud = new openils.PermaCrud({authtoken : user.authtoken});
- orders = pcrud.search('acplo', {org : org}, {order_by : {acplo : 'position'}});
- locations = pcrud.search('acpl',
- {owning_lib : fieldmapper.aou.orgNodeTrail(fieldmapper.aou.findOrgUnit(org), true)},
- {order_by : {acpl : 'name'}}
- );
- }
-
- // init the DnD environment
- source.selectAll();
- source.deleteSelectedNodes();
- source.clearItems();
-
- var locs = [];
-
- // sort and append by existing order settings
- dojo.forEach(orders,
- function(order) {
- locs.push(
- locations.filter(function(l) {return l.id() == order.location()})[0]
- );
- }
- );
-
- // append any non-sorted locations
- dojo.forEach(locations,
- function(l) {
- if(!locs.filter(function(ll) { return ll.id() == l.id() })[0])
- locs.push(l);
- }
- );
-
- // shove them into the DnD environment
- dojo.forEach(locs,
- function(loc) {
- if(!loc) return;
- var node = source.insertNodes(false, [
- {
- data : loc.name() + ' (' + fieldmapper.aou.findOrgUnit(loc.owning_lib()).shortname()+')',
- type : [loc.id()+''] // use the type field to store the ID
- }
- ]);
- }
- );
-}
-
-function applyChanges() {
- progressDialog.show();
-
- var newOrders = [];
- var contextOrg = contextOrgSelector.attr('value');
-
- // pull the locations out of the DnD environment and create order entries for them
- dojo.forEach(
- source.getAllNodes(),
- function(node) {
- var item = source.getItem(node.id);
- var o = new fieldmapper.acplo();
- o.position(newOrders.length + 1);
- o.location(item.type[0]); // location.id() is stored in DnD item type
- o.org(contextOrg);
- newOrders.push(o);
- }
- );
-
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.copy_location_order.update'],
- {
- async : true,
- params : [openils.User.authtoken, newOrders],
- onresponse : function(r) {
- if(r = openils.Util.readResponse(r)) {
- if(r.orders) {
- orders = r.order;
- progressDialog.hide();
- filterGrid(contextOrg);
- return;
- }
- progressDialog.update(r);
- }
- },
- }
- );
-}
-
-openils.Util.addOnLoad(init);
-
+require([
+ "dijit/layout/ContentPane",
+ "dojo/dnd/Container",
+ "dojo/dnd/Source",
+ "openils/widget/OrgUnitFilteringSelect",
+ "fieldmapper/OrgUtils",
+ "openils/User",
+ "openils/Util",
+ "openils/widget/AutoGrid",
+ "openils/PermaCrud",
+ "openils/widget/ProgressDialog"
+ ],
+function(dijit_layout_ContentPane,
+ dojo_dnd_Container,
+ dojo_dnd_Source,
+ openils_widget_OrgUnitFilteringSelect,
+ fieldmapper_OrgUtils,
+ openils_User,
+ openils_Util,
+ openils_widget_AutoGrid,
+ openils_PermaCrud,
+ openils_widget_ProgressDialog){
+
+ var user;
+ var orders;
+ var locations;
+ var source;
+
+ function init() {
+
+ user = new openils_User();
+ source = new dojo_dnd_Source('acl-ol');
+
+ user.buildPermOrgSelector(
+ 'ADMIN_COPY_LOCATION_ORDER',
+ contextOrgSelector,
+ null,
+ function() {
+ dojo.connect(contextOrgSelector, 'onChange', filterGrid);
+ }
+ );
+
+ filterGrid(user.user.ws_ou());
+ }
+
+ function filterGrid(org) {
+
+ // fetch the locations and order entries
+ if(!orders) {
+ var pcrud = new openils_PermaCrud({authtoken : user.authtoken});
+ orders = pcrud.search('acplo', {org : org}, {order_by : {acplo : 'position'}});
+ locations = pcrud.search('acpl',
+ {owning_lib : fieldmapper.aou.orgNodeTrail(fieldmapper.aou.findOrgUnit(org), true)},
+ {order_by : {acpl : 'name'}}
+ );
+ }
+
+ // init the DnD environment
+ source.selectAll();
+ source.deleteSelectedNodes();
+ source.clearItems();
+
+ var locs = [];
+
+ // sort and append by existing order settings
+ dojo.forEach(orders,
+ function(order) {
+ locs.push(
+ locations.filter(function(l) {return l.id() == order.location()})[0]
+ );
+ }
+ );
+
+ // append any non-sorted locations
+ dojo.forEach(locations,
+ function(l) {
+ if(!locs.filter(function(ll) { return ll.id() == l.id() })[0])
+ locs.push(l);
+ }
+ );
+
+ // shove them into the DnD environment
+ dojo.forEach(locs,
+ function(loc) {
+ if(!loc) return;
+ var node = source.insertNodes(false, [
+ {
+ data : loc.name() + ' (' + fieldmapper.aou.findOrgUnit(loc.owning_lib()).shortname()+')',
+ type : [loc.id()+''] // use the type field to store the ID
+ }
+ ]);
+ }
+ );
+ }
+
+ function applyChanges() {
+ progressDialog.show();
+
+ var newOrders = [];
+ var contextOrg = contextOrgSelector.attr('value');
+
+ // pull the locations out of the DnD environment and create order entries for them
+ dojo.forEach(
+ source.getAllNodes(),
+ function(node) {
+ var item = source.getItem(node.id);
+ var o = new fieldmapper.acplo();
+ o.position(newOrders.length + 1);
+ o.location(item.type[0]); // location.id() is stored in DnD item type
+ o.org(contextOrg);
+ newOrders.push(o);
+ }
+ );
+
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.copy_location_order.update'],
+ {
+ async : true,
+ params : [openils_User.authtoken, newOrders],
+ onresponse : function(r) {
+ if(r = openils_Util.readResponse(r)) {
+ if(r.orders) {
+ orders = r.order;
+ progressDialog.hide();
+ filterGrid(contextOrg);
+ return;
+ }
+ progressDialog.update(r);
+ }
+ },
+ }
+ );
+ }
+
+ openils_Util.addOnLoad(init);
+
+
+
+});
\ No newline at end of file
-dojo.require("dojo.data.ItemFileWriteStore");
-dojo.require("dijit.form.CurrencyTextBox");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("openils.widget.AutoGrid");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.widget.OrgUnitFilteringSelect");
+require([
+ "dojo/data/ItemFileWriteStore",
+ "dijit/form/CurrencyTextBox",
+ "dijit/form/FilteringSelect",
+ "openils/widget/AutoGrid",
+ "openils/PermaCrud",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(dojo_data_ItemFileWriteStore,
+ dijit_form_CurrencyTextBox,
+ dijit_form_FilteringSelect,
+ openils_widget_AutoGrid,
+ openils_PermaCrud,
+ openils_widget_OrgUnitFilteringSelect){
+
+ var pcrud;
+ var actOwner;
+ var actList;
+
+ function create_or_update_act(obj, opts, edit_pane) {
+ fieldmapper.standardRequest(
+ ["open-ils.cat", "open-ils.cat.asset.copy_template.create_or_update"], {
+ "params": [openils.User.authtoken, obj],
+ "async": true,
+ "oncomplete": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ if (edit_pane.onPostSubmit)
+ edit_pane.onPostSubmit(null, [r]);
+ }
+ }
+ }
+ );
+ }
+
+ function actInit() {
+ actGrid.overrideEditWidgets.fine_level = special_fine_level;
+ actGrid.overrideEditWidgets.fine_level.shove = {"create": 2};
+
+ actGrid.overrideEditWidgets.loan_duration = special_loan_duration;
+ actGrid.overrideEditWidgets.loan_duration.shove = {"create": 2};
+
+ pcrud = new openils_PermaCrud();
+
+ new openils.User().buildPermOrgSelector(
+ "ADMIN_ASSET_COPY_TEMPLATE",
+ actOwnerSelect,
+ null,
+ function() {
+ dojo.connect(
+ actOwnerSelect,
+ "onChange",
+ function() {
+ actOwner = fieldmapper.aou.findOrgUnit(this.attr("value"));
+ actGrid.resetStore();
+ buildActGrid();
+ }
+ );
+ buildActGrid();
+ }
+ );
+ }
+
+ function buildActGrid() {
+ if (!actOwner)
+ actOwner = fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou());
+
+ pcrud.search(
+ "act", {
+ "owning_lib": fieldmapper.aou.orgNodeTrail(actOwner, true /* asId */)
+ }, {
+ "async": true,
+ "onresponse": function(r) {
+ if ((actList = openils.Util.readResponse(r))) {
+ actList = openils.Util.objectSort(actList);
+ actList.forEach(
+ function(o) {
+ actGrid.store.newItem(act.toStoreItem(o));
+ }
+ );
+ }
+ },
+ "oncomplete": function() {
+ actGrid.hideLoadProgressIndicator();
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(actInit);
+
-var pcrud;
-var actOwner;
-var actList;
-
-function create_or_update_act(obj, opts, edit_pane) {
- fieldmapper.standardRequest(
- ["open-ils.cat", "open-ils.cat.asset.copy_template.create_or_update"], {
- "params": [openils.User.authtoken, obj],
- "async": true,
- "oncomplete": function(r) {
- if (r = openils.Util.readResponse(r)) {
- if (edit_pane.onPostSubmit)
- edit_pane.onPostSubmit(null, [r]);
- }
- }
- }
- );
-}
-
-function actInit() {
- actGrid.overrideEditWidgets.fine_level = special_fine_level;
- actGrid.overrideEditWidgets.fine_level.shove = {"create": 2};
-
- actGrid.overrideEditWidgets.loan_duration = special_loan_duration;
- actGrid.overrideEditWidgets.loan_duration.shove = {"create": 2};
-
- pcrud = new openils.PermaCrud();
-
- new openils.User().buildPermOrgSelector(
- "ADMIN_ASSET_COPY_TEMPLATE",
- actOwnerSelect,
- null,
- function() {
- dojo.connect(
- actOwnerSelect,
- "onChange",
- function() {
- actOwner = fieldmapper.aou.findOrgUnit(this.attr("value"));
- actGrid.resetStore();
- buildActGrid();
- }
- );
- buildActGrid();
- }
- );
-}
-
-function buildActGrid() {
- if (!actOwner)
- actOwner = fieldmapper.aou.findOrgUnit(openils.User.user.ws_ou());
-
- pcrud.search(
- "act", {
- "owning_lib": fieldmapper.aou.orgNodeTrail(actOwner, true /* asId */)
- }, {
- "async": true,
- "onresponse": function(r) {
- if ((actList = openils.Util.readResponse(r))) {
- actList = openils.Util.objectSort(actList);
- actList.forEach(
- function(o) {
- actGrid.store.newItem(act.toStoreItem(o));
- }
- );
- }
- },
- "oncomplete": function() {
- actGrid.hideLoadProgressIndicator();
- }
- }
- );
-}
-
-openils.Util.addOnLoad(actInit);
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dijit.form.CurrencyTextBox');
-dojo.require('dijit.Dialog');
-dojo.require('dojox.widget.PlaceholderMenuItem');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-
-var thingContextOrg;
-var thingList;
-
-/** really need to put this in a shared location... */
-function getOrgInfo(rowIndex, item) {
- if(!item) return '';
- var orgId = this.grid.store.getValue(item, this.field);
- return fieldmapper.aou.findOrgUnit(orgId).shortname();
-}
-
-function thingInit() {
-
- thingGrid.disableSelectorForRow = function(rowIdx) {
- var item = thingGrid.getItem(rowIdx);
- return (thingGrid.store.getValue(item, 'id') < 0);
- }
-
- buildGrid();
- var connect = function() {
- dojo.connect(thingContextOrgSelect, 'onChange',
- function() {
- thingContextOrg = this.getValue();
- thingGrid.resetStore();
- buildGrid();
- }
- );
- };
- // go ahead and let staff see everything
- new openils.User().buildPermOrgSelector('STAFF_LOGIN', thingContextOrgSelect, null, connect);
-}
-
-function buildGrid() {
- if(thingContextOrg == null)
- thingContextOrg = openils.User.user.ws_ou();
-
- fieldmapper.standardRequest(
- ['open-ils.pcrud', 'open-ils.pcrud.search.acnp.atomic'],
- { async: true,
- params: [
- openils.User.authtoken,
- {"owning_lib":fieldmapper.aou.descendantNodeList(thingContextOrg,true)},
- {"order_by":{"acnp":"label_sortkey"}}
- ],
- oncomplete: function(r) {
- if(thingList = openils.Util.readResponse(r)) {
- thingList = openils.Util.objectSort(thingList);
- dojo.forEach(thingList,
- function(e) {
- thingGrid.store.newItem(acnp.toStoreItem(e));
- }
- );
- }
- }
- }
- );
-}
-
-openils.Util.addOnLoad(thingInit);
-
+require([
+ "dojox/grid/DataGrid",
+ "openils/widget/AutoGrid",
+ "dojox/grid/cells/dijit",
+ "dojo/data/ItemFileWriteStore",
+ "dijit/form/CurrencyTextBox",
+ "dijit/Dialog",
+ "dojox/widget/PlaceholderMenuItem",
+ "fieldmapper/OrgUtils",
+ "dijit/form/FilteringSelect",
+ "openils/PermaCrud",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(dojox_grid_DataGrid,
+ openils_widget_AutoGrid,
+ dojox_grid_cells_dijit,
+ dojo_data_ItemFileWriteStore,
+ dijit_form_CurrencyTextBox,
+ dijit_Dialog,
+ dojox_widget_PlaceholderMenuItem,
+ fieldmapper_OrgUtils,
+ dijit_form_FilteringSelect,
+ openils_PermaCrud,
+ openils_widget_OrgUnitFilteringSelect){
+
+ var thingContextOrg;
+ var thingList;
+
+ /** really need to put this in a shared location... */
+ function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var orgId = this.grid.store.getValue(item, this.field);
+ return fieldmapper.aou.findOrgUnit(orgId).shortname();
+ }
+
+ function thingInit() {
+
+ thingGrid.disableSelectorForRow = function(rowIdx) {
+ var item = thingGrid.getItem(rowIdx);
+ return (thingGrid.store.getValue(item, 'id') < 0);
+ }
+
+ buildGrid();
+ var connect = function() {
+ dojo.connect(thingContextOrgSelect, 'onChange',
+ function() {
+ thingContextOrg = this.getValue();
+ thingGrid.resetStore();
+ buildGrid();
+ }
+ );
+ };
+ // go ahead and let staff see everything
+ new openils.User().buildPermOrgSelector('STAFF_LOGIN', thingContextOrgSelect, null, connect);
+ }
+
+ function buildGrid() {
+ if(thingContextOrg == null)
+ thingContextOrg = openils.User.user.ws_ou();
+
+ fieldmapper.standardRequest(
+ ['open-ils.pcrud', 'open-ils.pcrud.search.acnp.atomic'],
+ { async: true,
+ params: [
+ openils.User.authtoken,
+ {"owning_lib":fieldmapper.aou.descendantNodeList(thingContextOrg,true)},
+ {"order_by":{"acnp":"label_sortkey"}}
+ ],
+ oncomplete: function(r) {
+ if(thingList = openils.Util.readResponse(r)) {
+ thingList = openils.Util.objectSort(thingList);
+ dojo.forEach(thingList,
+ function(e) {
+ thingGrid.store.newItem(acnp.toStoreItem(e));
+ }
+ );
+ }
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(thingInit);
+
+
+
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dijit.form.CurrencyTextBox');
-dojo.require('dijit.Dialog');
-dojo.require('dojox.widget.PlaceholderMenuItem');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-
-var thingContextOrg;
-var thingList;
-
-/** really need to put this in a shared location... */
-function getOrgInfo(rowIndex, item) {
- if(!item) return '';
- var orgId = this.grid.store.getValue(item, this.field);
- return fieldmapper.aou.findOrgUnit(orgId).shortname();
-}
-
-function thingInit() {
-
- thingGrid.disableSelectorForRow = function(rowIdx) {
- var item = thingGrid.getItem(rowIdx);
- return (thingGrid.store.getValue(item, 'id') < 0);
- }
-
- buildGrid();
- var connect = function() {
- dojo.connect(thingContextOrgSelect, 'onChange',
- function() {
- thingContextOrg = this.getValue();
- thingGrid.resetStore();
- buildGrid();
- }
- );
- };
- // go ahead and let staff see everything
- new openils.User().buildPermOrgSelector('STAFF_LOGIN', thingContextOrgSelect, null, connect);
-}
-
-function buildGrid() {
- if(thingContextOrg == null)
- thingContextOrg = openils.User.user.ws_ou();
-
- fieldmapper.standardRequest(
- ['open-ils.pcrud', 'open-ils.pcrud.search.acns.atomic'],
- { async: true,
- params: [
- openils.User.authtoken,
- {"owning_lib":fieldmapper.aou.descendantNodeList(thingContextOrg,true)},
- {"order_by":{"acns":"label_sortkey"}}
- ],
- oncomplete: function(r) {
- if(thingList = openils.Util.readResponse(r)) {
- thingList = openils.Util.objectSort(thingList);
- dojo.forEach(thingList,
- function(e) {
- thingGrid.store.newItem(acns.toStoreItem(e));
- }
- );
- }
- }
- }
- );
-}
-
-openils.Util.addOnLoad(thingInit);
-
+require([
+ "dojox/grid/DataGrid",
+ "openils/widget/AutoGrid",
+ "dojox/grid/cells/dijit",
+ "dojo/data/ItemFileWriteStore",
+ "dijit/form/CurrencyTextBox",
+ "dijit/Dialog",
+ "dojox/widget/PlaceholderMenuItem",
+ "fieldmapper/OrgUtils",
+ "dijit/form/FilteringSelect",
+ "openils/PermaCrud",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(dojox_grid_DataGrid,
+ openils_widget_AutoGrid,
+ dojox_grid_cells_dijit,
+ dojo_data_ItemFileWriteStore,
+ dijit_form_CurrencyTextBox,
+ dijit_Dialog,
+ dojox_widget_PlaceholderMenuItem,
+ fieldmapper_OrgUtils,
+ dijit_form_FilteringSelect,
+ openils_PermaCrud,
+ openils_widget_OrgUnitFilteringSelect){
+
+ var thingContextOrg;
+ var thingList;
+
+ /** really need to put this in a shared location... */
+ function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var orgId = this.grid.store.getValue(item, this.field);
+ return fieldmapper.aou.findOrgUnit(orgId).shortname();
+ }
+
+ function thingInit() {
+
+ thingGrid.disableSelectorForRow = function(rowIdx) {
+ var item = thingGrid.getItem(rowIdx);
+ return (thingGrid.store.getValue(item, 'id') < 0);
+ }
+
+ buildGrid();
+ var connect = function() {
+ dojo.connect(thingContextOrgSelect, 'onChange',
+ function() {
+ thingContextOrg = this.getValue();
+ thingGrid.resetStore();
+ buildGrid();
+ }
+ );
+ };
+ // go ahead and let staff see everything
+ new openils.User().buildPermOrgSelector('STAFF_LOGIN', thingContextOrgSelect, null, connect);
+ }
+
+ function buildGrid() {
+ if(thingContextOrg == null)
+ thingContextOrg = openils.User.user.ws_ou();
+
+ fieldmapper.standardRequest(
+ ['open-ils.pcrud', 'open-ils.pcrud.search.acns.atomic'],
+ { async: true,
+ params: [
+ openils.User.authtoken,
+ {"owning_lib":fieldmapper.aou.descendantNodeList(thingContextOrg,true)},
+ {"order_by":{"acns":"label_sortkey"}}
+ ],
+ oncomplete: function(r) {
+ if(thingList = openils.Util.readResponse(r)) {
+ thingList = openils.Util.objectSort(thingList);
+ dojo.forEach(thingList,
+ function(e) {
+ thingGrid.store.newItem(acns.toStoreItem(e));
+ }
+ );
+ }
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(thingInit);
+
+
+
+});
\ No newline at end of file
-dojo.require('dijit.layout.ContentPane');
-dojo.require('dijit.form.Button');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.ProgressDialog');
-
-function load(){
- cmGrid.overrideWidgetArgs.prefix = {hrbefore : true};
- cmGrid.overrideWidgetArgs.asset = {hrbefore: true};
- cmGrid.loadAll({order_by:{cbc:'org_unit'}});
-}
-
-openils.Util.addOnLoad(load);
+require([
+ "dijit/layout/ContentPane",
+ "dijit/form/Button",
+ "openils/widget/AutoGrid",
+ "openils/widget/AutoFieldWidget",
+ "openils/PermaCrud",
+ "openils/widget/ProgressDialog"
+ ],
+function(dijit_layout_ContentPane,
+ dijit_form_Button,
+ openils_widget_AutoGrid,
+ openils_widget_AutoFieldWidget,
+ openils_PermaCrud,
+ openils_widget_ProgressDialog){
+
+ function load(){
+ cmGrid.overrideWidgetArgs.prefix = {hrbefore : true};
+ cmGrid.overrideWidgetArgs.asset = {hrbefore: true};
+ cmGrid.loadAll({order_by:{cbc:'org_unit'}});
+ }
+
+ openils.Util.addOnLoad(load);
+
+
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dijit.form.CurrencyTextBox');
-dojo.require('dijit.Dialog');
-dojo.require('dojox.widget.PlaceholderMenuItem');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-
-var btContextOrg;
-var btList;
-
-/** really need to put this in a shared location... */
-function getOrgInfo(rowIndex, item) {
- if(!item) return '';
- var orgId = this.grid.store.getValue(item, this.field);
- return fieldmapper.aou.findOrgUnit(orgId).shortname();
-}
-
-function btInit() {
-
- btGrid.disableSelectorForRow = function(rowIdx) {
- var item = btGrid.getItem(rowIdx);
- return (btGrid.store.getValue(item, 'id') < 100);
- }
-
- buildBTGrid();
- var connect = function() {
- dojo.connect(btContextOrgSelect, 'onChange',
- function() {
- btContextOrg = this.getValue();
- btGrid.resetStore();
- buildBTGrid();
- }
- );
- };
- new openils.User().buildPermOrgSelector('VIEW_BILLING_TYPE', btContextOrgSelect, null, connect);
-}
-
-function buildBTGrid() {
- if(btContextOrg == null)
- btContextOrg = openils.User.user.ws_ou();
- fieldmapper.standardRequest(
- ['open-ils.circ', 'open-ils.circ.billing_type.ranged.retrieve.all'],
- { async: true,
- params: [openils.User.authtoken, btContextOrg, fieldmapper.aou.findOrgDepth(btContextOrg)],
- oncomplete: function(r) {
- if(btList = openils.Util.readResponse(r)) {
- btList = openils.Util.objectSort(btList);
- dojo.forEach(btList,
- function(e) {
- btGrid.store.newItem(cbt.toStoreItem(e));
- }
- );
- }
- }
- }
- );
-}
-
-openils.Util.addOnLoad(btInit);
-
+require([
+ "dojox/grid/DataGrid",
+ "openils/widget/AutoGrid",
+ "dojox/grid/cells/dijit",
+ "dojo/data/ItemFileWriteStore",
+ "dijit/form/CurrencyTextBox",
+ "dijit/Dialog",
+ "dojox/widget/PlaceholderMenuItem",
+ "fieldmapper/OrgUtils",
+ "dijit/form/FilteringSelect",
+ "openils/PermaCrud",
+ "openils/widget/OrgUnitFilteringSelect"
+ ],
+function(dojox_grid_DataGrid,
+ openils_widget_AutoGrid,
+ dojox_grid_cells_dijit,
+ dojo_data_ItemFileWriteStore,
+ dijit_form_CurrencyTextBox,
+ dijit_Dialog,
+ dojox_widget_PlaceholderMenuItem,
+ fieldmapper_OrgUtils,
+ dijit_form_FilteringSelect,
+ openils_PermaCrud,
+ openils_widget_OrgUnitFilteringSelect){
+
+ var btContextOrg;
+ var btList;
+
+ /** really need to put this in a shared location... */
+ function getOrgInfo(rowIndex, item) {
+ if(!item) return '';
+ var orgId = this.grid.store.getValue(item, this.field);
+ return fieldmapper.aou.findOrgUnit(orgId).shortname();
+ }
+
+ function btInit() {
+
+ btGrid.disableSelectorForRow = function(rowIdx) {
+ var item = btGrid.getItem(rowIdx);
+ return (btGrid.store.getValue(item, 'id') < 100);
+ }
+
+ buildBTGrid();
+ var connect = function() {
+ dojo.connect(btContextOrgSelect, 'onChange',
+ function() {
+ btContextOrg = this.getValue();
+ btGrid.resetStore();
+ buildBTGrid();
+ }
+ );
+ };
+ new openils.User().buildPermOrgSelector('VIEW_BILLING_TYPE', btContextOrgSelect, null, connect);
+ }
+
+ function buildBTGrid() {
+ if(btContextOrg == null)
+ btContextOrg = openils.User.user.ws_ou();
+ fieldmapper.standardRequest(
+ ['open-ils.circ', 'open-ils.circ.billing_type.ranged.retrieve.all'],
+ { async: true,
+ params: [openils.User.authtoken, btContextOrg, fieldmapper.aou.findOrgDepth(btContextOrg)],
+ oncomplete: function(r) {
+ if(btList = openils.Util.readResponse(r)) {
+ btList = openils.Util.objectSort(btList);
+ dojo.forEach(btList,
+ function(e) {
+ btGrid.store.newItem(cbt.toStoreItem(e));
+ }
+ );
+ }
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(btInit);
+
+
+
+});
\ No newline at end of file
-dojo.require('dijit.layout.ContentPane');
-dojo.require('dijit.form.Button');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.ProgressDialog');
-
-var linkedEditor = null;
-var circModEntryCache = [];
-var limitGroupEntryCache = [];
-var circModCache = {};
-var limitGroupCache = {};
-var curLinkedEditor;
-
-function load(){
- clsGrid.loadAll({order_by:{ccls:'name'}});
- clsGrid.onEditPane = buildEditPaneAdditions;
- clsGrid.onPostUpdate = updateLinked;
- clsGrid.onPostCreate = updateLinked;
- linkedEditor = dojo.byId('linked-editor').parentNode.removeChild(dojo.byId('linked-editor'));
-
- // Cache circ mod/limit group info for later display
- var pcrud = new openils.PermaCrud();
- var temp = pcrud.retrieveAll('ccm');
- dojo.forEach(temp, function(g) { circModCache[g.code()] = g; } );
- temp = pcrud.retrieveAll('cclg');
- dojo.forEach(temp, function(g) { limitGroupCache[g.id()] = g; } );
-}
-
-function byName(name, ctxt) {
- return dojo.query('[name=' + name + ']', ctxt)[0];
-}
-
-function buildEditPaneAdditions(editPane) {
- circModEntryCache = [];
- limitGroupEntryCache = [];
- var tr = document.createElement('tr');
- var td = document.createElement('td');
- td.setAttribute('colspan','2');
- // Explanation....
- // editPane.domNode.lastChild = Table
- // .lastChild = Table Body
- // .lastChild = Table Row containing Action Buttons
- editPane.domNode.lastChild.lastChild.insertBefore(tr, editPane.domNode.lastChild.lastChild.lastChild);
- tr.appendChild(td);
- curLinkedEditor = linkedEditor.cloneNode(true);
- td.appendChild(curLinkedEditor);
- var circModTmpl = byName('circ-mod-entry-tbody', curLinkedEditor).removeChild(byName('circ-mod-entry-row', curLinkedEditor));
- var limitGroupTmpl = byName('limit-group-entry-tbody', curLinkedEditor).removeChild(byName('limit-group-entry-row', curLinkedEditor));
-
- var cm_selector = new openils.widget.AutoFieldWidget({
- fmClass : 'cclscmm',
- fmField : 'circ_mod',
- parentNode : byName('circ-mod-selector', curLinkedEditor)
- });
- cm_selector.build();
-
- var lg_selector = new openils.widget.AutoFieldWidget({
- fmClass : 'cclsgm',
- fmField : 'limit_group',
- parentNode : byName('limit-group-selector', curLinkedEditor)
- });
- lg_selector.build();
-
- function addMod(code) {
- var row = circModTmpl.cloneNode(true);
- row.setAttribute('code', code);
- byName('circ-mod', row).innerHTML = code + ' : ' + circModCache[code].name();
- byName('remove-circ-mod', row).onclick = function() {
- byName('circ-mod-entry-tbody', clsGrid.editPane.domNode).removeChild(row);
- }
- byName('circ-mod-entry-tbody', editPane.domNode).appendChild(row);
- }
-
- function addGroup(group) {
- var row = limitGroupTmpl.cloneNode(true);
- row.setAttribute('limit_group', group);
- byName('limit-group', row).innerHTML = limitGroupCache[group].name();
- byName('remove-limit-group', row).onclick = function() {
- byName('limit-group-entry-tbody', clsGrid.editPane.domNode).removeChild(row);
- }
- byName('limit-group-entry-tbody', editPane.domNode).appendChild(row);
- }
-
- byName('add-circ-mod', editPane.domNode).onclick = function() {
- addMod(cm_selector.widget.attr('value'));
- }
-
- byName('add-limit-group', editPane.domNode).onclick = function() {
- addGroup(lg_selector.widget.attr('value'));
- }
-
- // On edit we need to load existing entries.
- // On create, not so much.
- if(!editPane.fmObject) return;
- var limitSet = editPane.fmObject.id();
-
- if(editPane.mode == 'update') {
- var pcrud = new openils.PermaCrud();
- circModEntryCache = pcrud.search('cclscmm', {limit_set: limitSet});
- limitGroupEntryCache = pcrud.search('cclsgm', {limit_set: limitSet});
- dojo.forEach(circModEntryCache, function(g) { addCircMod(circModTmpl, g); } );
- dojo.forEach(limitGroupEntryCache, function(g) { addLimitGroup(limitGroupTmpl, g); } );
- }
-}
-
-function addCircMod(tmpl, circ_mod_entry) {
- var row = tmpl.cloneNode(true);
- var code = circ_mod_entry.circ_mod();
- row.setAttribute('code', code);
- byName('circ-mod', row).innerHTML = code + ' : ' + circModCache[code].name();
- byName('remove-circ-mod', row).onclick = function() {
- byName('circ-mod-entry-tbody', clsGrid.editPane.domNode).removeChild(row);
- }
- byName('circ-mod-entry-tbody', clsGrid.editPane.domNode).appendChild(row);
-}
-
-function addLimitGroup(tmpl, limit_group_entry) {
- var row = tmpl.cloneNode(true);
- var group = limit_group_entry.limit_group();
- row.setAttribute('limit_group', group);
- byName('limit-group', row).innerHTML = limitGroupCache[group].name();
- if(limit_group_entry.check_only() == 't') {
- byName('limit-group-check-only', row).setAttribute('checked', 'true');
- }
- byName('remove-limit-group', row).onclick = function() {
- byName('limit-group-entry-tbody', clsGrid.editPane.domNode).removeChild(row);
- }
- byName('limit-group-entry-tbody', clsGrid.editPane.domNode).appendChild(row);
-}
-
-function updateLinked(fmObject, rowindex) {
- var id = null;
- if(rowindex != undefined && this.editPane && this.editPane.fmObject) {
- // Edit, grab existing ID
- id = this.editPane.fmObject.id();
- } else if(fmObject.id) {
- // Create, grab new ID
- id = fmObject.id();
- }
- // If we don't have an ID, drop out.
- if(id == null) return;
- var pcrud = new openils.PermaCrud();
- progressDialog.show(true);
-
- var add = [];
- var remove = [];
- var update = [];
-
- // First up, circ mods.
- var circ_mods = [];
- dojo.query('[name=circ-mod-entry-row]', this.editPane.domNode).forEach(
- function(row) {
- var mod = row.getAttribute('code');
- circ_mods.push(mod);
- if(!circModEntryCache.filter(function(i) { return (i.circ_mod() == mod); })[0]) {
- var entry = new fieldmapper.cclscmm();
- entry.isnew(true);
- entry.limit_set(id);
- entry.circ_mod(mod);
- add.push(entry);
- }
- }
- );
- dojo.forEach(circModEntryCache, function(eMod) {
- if(!circ_mods.filter(function(i) { return (i == eMod.circ_mod()); })[0]) {
- eMod.isdeleted(true);
- remove.push(eMod);
- }
- }
- );
-
- // Next, limit groups
- var limit_groups = [];
- dojo.query('[name=limit-group-entry-row]', this.editPane.domNode).forEach(
- function(row) {
- var group = row.getAttribute('limit_group');
- limit_groups.push(group);
- var cached = limitGroupEntryCache.filter(function(i) { return (i.limit_group() == group); })[0];
- if(!cached) {
- var entry = new fieldmapper.cclsgm();
- entry.isnew(true);
- entry.limit_set(id);
- entry.limit_group(group);
- entry.check_only(byName('limit-group-check-only', row).checked ? 't' : 'f');
- add.push(entry);
- } else {
- var check_only = byName('limit-group-check-only', row).checked;
- if(check_only != (cached.check_only() == 't')) {
- cached.check_only(check_only ? 't' : 'f');
- cached.ischanged(true);
- update.push(cached);
- }
- }
- }
- );
- dojo.forEach(limitGroupEntryCache, function(eGroup) {
- if(!limit_groups.filter(function(i) { return (i == eGroup.limit_group()); })[0]) {
- eGroup.isdeleted(true);
- remove.push(eGroup);
- }
- }
- );
-
- function updateEntries() {
- pcrud.update(update, {
- oncomplete : function () {
- progressDialog.hide();
- }
- });
- }
-
- function removeEntries() {
- pcrud.eliminate(remove, {
- oncomplete : function () {
- if(update.length) {
- updateEntries();
- } else {
- progressDialog.hide();
- }
- }
- });
- }
-
- function addEntries() {
- pcrud.create(add, {
- oncomplete : function () {
- if(remove.length) {
- removeEntries();
- } else if (update.length) {
- updateEntries();
- } else {
- progressDialog.hide();
- }
- }
- });
- }
-
- if(add.length)
- addEntries();
- else if (remove.length)
- removeEntries();
- else if (update.length)
- updateEntries();
- else
- progressDialog.hide();
-}
-
-openils.Util.addOnLoad(load);
+require([
+ "dijit/layout/ContentPane",
+ "dijit/form/Button",
+ "openils/widget/AutoGrid",
+ "openils/widget/AutoFieldWidget",
+ "openils/PermaCrud",
+ "openils/widget/ProgressDialog"
+ ],
+function(dijit_layout_ContentPane,
+ dijit_form_Button,
+ openils_widget_AutoGrid,
+ openils_widget_AutoFieldWidget,
+ openils_PermaCrud,
+ openils_widget_ProgressDialog){
+
+ var linkedEditor = null;
+ var circModEntryCache = [];
+ var limitGroupEntryCache = [];
+ var circModCache = {};
+ var limitGroupCache = {};
+ var curLinkedEditor;
+
+ function load(){
+ clsGrid.loadAll({order_by:{ccls:'name'}});
+ clsGrid.onEditPane = buildEditPaneAdditions;
+ clsGrid.onPostUpdate = updateLinked;
+ clsGrid.onPostCreate = updateLinked;
+ linkedEditor = dojo.byId('linked-editor').parentNode.removeChild(dojo.byId('linked-editor'));
+
+ // Cache circ mod/limit group info for later display
+ var pcrud = new openils_PermaCrud();
+ var temp = pcrud.retrieveAll('ccm');
+ dojo.forEach(temp, function(g) { circModCache[g.code()] = g; } );
+ temp = pcrud.retrieveAll('cclg');
+ dojo.forEach(temp, function(g) { limitGroupCache[g.id()] = g; } );
+ }
+
+ function byName(name, ctxt) {
+ return dojo.query('[name=' + name + ']', ctxt)[0];
+ }
+
+ function buildEditPaneAdditions(editPane) {
+ circModEntryCache = [];
+ limitGroupEntryCache = [];
+ var tr = document.createElement('tr');
+ var td = document.createElement('td');
+ td.setAttribute('colspan','2');
+ // Explanation....
+ // editPane.domNode.lastChild = Table
+ // .lastChild = Table Body
+ // .lastChild = Table Row containing Action Buttons
+ editPane.domNode.lastChild.lastChild.insertBefore(tr, editPane.domNode.lastChild.lastChild.lastChild);
+ tr.appendChild(td);
+ curLinkedEditor = linkedEditor.cloneNode(true);
+ td.appendChild(curLinkedEditor);
+ var circModTmpl = byName('circ-mod-entry-tbody', curLinkedEditor).removeChild(byName('circ-mod-entry-row', curLinkedEditor));
+ var limitGroupTmpl = byName('limit-group-entry-tbody', curLinkedEditor).removeChild(byName('limit-group-entry-row', curLinkedEditor));
+
+ var cm_selector = new openils_widget_AutoFieldWidget({
+ fmClass : 'cclscmm',
+ fmField : 'circ_mod',
+ parentNode : byName('circ-mod-selector', curLinkedEditor)
+ });
+ cm_selector.build();
+
+ var lg_selector = new openils_widget_AutoFieldWidget({
+ fmClass : 'cclsgm',
+ fmField : 'limit_group',
+ parentNode : byName('limit-group-selector', curLinkedEditor)
+ });
+ lg_selector.build();
+
+ function addMod(code) {
+ var row = circModTmpl.cloneNode(true);
+ row.setAttribute('code', code);
+ byName('circ-mod', row).innerHTML = code + ' : ' + circModCache[code].name();
+ byName('remove-circ-mod', row).onclick = function() {
+ byName('circ-mod-entry-tbody', clsGrid.editPane.domNode).removeChild(row);
+ }
+ byName('circ-mod-entry-tbody', editPane.domNode).appendChild(row);
+ }
+
+ function addGroup(group) {
+ var row = limitGroupTmpl.cloneNode(true);
+ row.setAttribute('limit_group', group);
+ byName('limit-group', row).innerHTML = limitGroupCache[group].name();
+ byName('remove-limit-group', row).onclick = function() {
+ byName('limit-group-entry-tbody', clsGrid.editPane.domNode).removeChild(row);
+ }
+ byName('limit-group-entry-tbody', editPane.domNode).appendChild(row);
+ }
+
+ byName('add-circ-mod', editPane.domNode).onclick = function() {
+ addMod(cm_selector.widget.attr('value'));
+ }
+
+ byName('add-limit-group', editPane.domNode).onclick = function() {
+ addGroup(lg_selector.widget.attr('value'));
+ }
+
+ // On edit we need to load existing entries.
+ // On create, not so much.
+ if(!editPane.fmObject) return;
+ var limitSet = editPane.fmObject.id();
+
+ if(editPane.mode == 'update') {
+ var pcrud = new openils_PermaCrud();
+ circModEntryCache = pcrud.search('cclscmm', {limit_set: limitSet});
+ limitGroupEntryCache = pcrud.search('cclsgm', {limit_set: limitSet});
+ dojo.forEach(circModEntryCache, function(g) { addCircMod(circModTmpl, g); } );
+ dojo.forEach(limitGroupEntryCache, function(g) { addLimitGroup(limitGroupTmpl, g); } );
+ }
+ }
+
+ function addCircMod(tmpl, circ_mod_entry) {
+ var row = tmpl.cloneNode(true);
+ var code = circ_mod_entry.circ_mod();
+ row.setAttribute('code', code);
+ byName('circ-mod', row).innerHTML = code + ' : ' + circModCache[code].name();
+ byName('remove-circ-mod', row).onclick = function() {
+ byName('circ-mod-entry-tbody', clsGrid.editPane.domNode).removeChild(row);
+ }
+ byName('circ-mod-entry-tbody', clsGrid.editPane.domNode).appendChild(row);
+ }
+
+ function addLimitGroup(tmpl, limit_group_entry) {
+ var row = tmpl.cloneNode(true);
+ var group = limit_group_entry.limit_group();
+ row.setAttribute('limit_group', group);
+ byName('limit-group', row).innerHTML = limitGroupCache[group].name();
+ if(limit_group_entry.check_only() == 't') {
+ byName('limit-group-check-only', row).setAttribute('checked', 'true');
+ }
+ byName('remove-limit-group', row).onclick = function() {
+ byName('limit-group-entry-tbody', clsGrid.editPane.domNode).removeChild(row);
+ }
+ byName('limit-group-entry-tbody', clsGrid.editPane.domNode).appendChild(row);
+ }
+
+ function updateLinked(fmObject, rowindex) {
+ var id = null;
+ if(rowindex != undefined && this.editPane && this.editPane.fmObject) {
+ // Edit, grab existing ID
+ id = this.editPane.fmObject.id();
+ } else if(fmObject.id) {
+ // Create, grab new ID
+ id = fmObject.id();
+ }
+ // If we don't have an ID, drop out.
+ if(id == null) return;
+ var pcrud = new openils_PermaCrud();
+ progressDialog.show(true);
+
+ var add = [];
+ var remove = [];
+ var update = [];
+
+ // First up, circ mods.
+ var circ_mods = [];
+ dojo.query('[name=circ-mod-entry-row]', this.editPane.domNode).forEach(
+ function(row) {
+ var mod = row.getAttribute('code');
+ circ_mods.push(mod);
+ if(!circModEntryCache.filter(function(i) { return (i.circ_mod() == mod); })[0]) {
+ var entry = new fieldmapper.cclscmm();
+ entry.isnew(true);
+ entry.limit_set(id);
+ entry.circ_mod(mod);
+ add.push(entry);
+ }
+ }
+ );
+ dojo.forEach(circModEntryCache, function(eMod) {
+ if(!circ_mods.filter(function(i) { return (i == eMod.circ_mod()); })[0]) {
+ eMod.isdeleted(true);
+ remove.push(eMod);
+ }
+ }
+ );
+
+ // Next, limit groups
+ var limit_groups = [];
+ dojo.query('[name=limit-group-entry-row]', this.editPane.domNode).forEach(
+ function(row) {
+ var group = row.getAttribute('limit_group');
+ limit_groups.push(group);
+ var cached = limitGroupEntryCache.filter(function(i) { return (i.limit_group() == group); })[0];
+ if(!cached) {
+ var entry = new fieldmapper.cclsgm();
+ entry.isnew(true);
+ entry.limit_set(id);
+ entry.limit_group(group);
+ entry.check_only(byName('limit-group-check-only', row).checked ? 't' : 'f');
+ add.push(entry);
+ } else {
+ var check_only = byName('limit-group-check-only', row).checked;
+ if(check_only != (cached.check_only() == 't')) {
+ cached.check_only(check_only ? 't' : 'f');
+ cached.ischanged(true);
+ update.push(cached);
+ }
+ }
+ }
+ );
+ dojo.forEach(limitGroupEntryCache, function(eGroup) {
+ if(!limit_groups.filter(function(i) { return (i == eGroup.limit_group()); })[0]) {
+ eGroup.isdeleted(true);
+ remove.push(eGroup);
+ }
+ }
+ );
+
+ function updateEntries() {
+ pcrud.update(update, {
+ oncomplete : function () {
+ progressDialog.hide();
+ }
+ });
+ }
+
+ function removeEntries() {
+ pcrud.eliminate(remove, {
+ oncomplete : function () {
+ if(update.length) {
+ updateEntries();
+ } else {
+ progressDialog.hide();
+ }
+ }
+ });
+ }
+
+ function addEntries() {
+ pcrud.create(add, {
+ oncomplete : function () {
+ if(remove.length) {
+ removeEntries();
+ } else if (update.length) {
+ updateEntries();
+ } else {
+ progressDialog.hide();
+ }
+ }
+ });
+ }
+
+ if(add.length)
+ addEntries();
+ else if (remove.length)
+ removeEntries();
+ else if (update.length)
+ updateEntries();
+ else
+ progressDialog.hide();
+ }
+
+ openils.Util.addOnLoad(load);
+
+
+});
\ No newline at end of file
-dojo.require('dijit.layout.ContentPane');
-dojo.require('dijit.form.Button');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.ProgressDialog');
-
-var limitSetEditor = null;
-var limitSetEntryCache = [];
-var limitSetCache = {};
-
-function load(){
- cmGrid.overrideWidgetArgs.grp = {hrbefore : true};
- cmGrid.overrideWidgetArgs.is_renewal = {ternary : true};
- cmGrid.overrideWidgetArgs.ref_flag = {ternary : true};
- cmGrid.overrideWidgetArgs.juvenile_flag = {ternary : true};
- cmGrid.overrideWidgetArgs.circulate = {inherits : true, hrbefore : true};
- cmGrid.overrideWidgetArgs.duration_rule = {inherits : true};
- cmGrid.overrideWidgetArgs.recurring_fine_rule = {inherits : true};
- cmGrid.overrideWidgetArgs.max_fine_rule = {inherits : true};
- cmGrid.overrideWidgetArgs.available_copy_hold_ratio = {inherits : true};
- cmGrid.overrideWidgetArgs.total_copy_hold_ratio = {inherits : true};
- cmGrid.overrideWidgetArgs.renewals = {inherits : true};
- cmGrid.overrideWidgetArgs.grace_period = {inherits : true};
- cmGrid.overrideWidgetArgs.hard_due_date = {inherits : true};
- cmGrid.loadAll({order_by:{ccmm:'circ_modifier'}});
- cmGrid.onEditPane = buildEditPaneAdditions;
- cmGrid.onPostUpdate = updateLinked;
- cmGrid.onPostCreate = updateLinked;
- limitSetEditor = dojo.byId('limit-set-editor').parentNode.removeChild(dojo.byId('limit-set-editor'));
-
- // Cache limit set info for later display
- var pcrud = new openils.PermaCrud();
- var temp = pcrud.retrieveAll('ccls');
- dojo.forEach(temp, function(g) { limitSetCache[g.id()] = g; } );
-}
-
-function byName(name, ctxt) {
- return dojo.query('[name=' + name + ']', ctxt)[0];
-}
-
-function buildEditPaneAdditions(editPane) {
- limitSetEntryCache = [];
- var tr = document.createElement('tr');
- var td = document.createElement('td');
- td.setAttribute('colspan','2');
- // Explanation....
- // editPane.domNode.lastChild = Table
- // .lastChild = Table Body
- // .lastChild = Table Row containing Action Buttons
- editPane.domNode.lastChild.lastChild.insertBefore(tr, editPane.domNode.lastChild.lastChild.lastChild);
- tr.appendChild(td);
- curLimitSetEditor = limitSetEditor.cloneNode(true);
- td.appendChild(curLimitSetEditor);
- var limitSetTmpl = byName('limit-set-entry-tbody', curLimitSetEditor).removeChild(byName('limit-set-entry-row', curLimitSetEditor));
-
- var selector = new openils.widget.AutoFieldWidget({
- fmClass : 'ccmlsm',
- fmField : 'limit_set',
- parentNode : byName('limit-set-selector', curLimitSetEditor)
- });
- selector.build();
-
- function addSet(lset) {
- var row = limitSetTmpl.cloneNode(true);
- row.setAttribute('limit_set', lset);
- byName('limit-set', row).innerHTML = limitSetCache[lset].name();
- byName('remove-limit-set', row).onclick = function() {
- byName('limit-set-entry-tbody', cmGrid.editPane.domNode).removeChild(row);
- }
- byName('limit-set-active', row).setAttribute('checked', 'true');
- byName('limit-set-entry-tbody', editPane.domNode).appendChild(row);
- }
-
- byName('add-limit-set', editPane.domNode).onclick = function() {
- addSet(selector.widget.attr('value'));
- }
-
- // On edit we need to load existing entries.
- // On create, not so much.
- if(!editPane.fmObject) return;
- var matchpoint = editPane.fmObject.id();
-
- if(editPane.mode == 'update') {
- var pcrud = new openils.PermaCrud();
- limitSetEntryCache = pcrud.search('ccmlsm', {matchpoint: editPane.fmObject.id()});
- dojo.forEach(limitSetEntryCache, function(g) { addLimitSet(limitSetTmpl, g); } );
- }
-}
-
-function addLimitSet(tmpl, limit_set_entry) {
- var row = tmpl.cloneNode(true);
- var lset = limit_set_entry.limit_set();
- row.setAttribute('limit_set', lset);
- byName('limit-set', row).innerHTML = limitSetCache[lset].name();
- if(limit_set_entry.active() == 't') {
- byName('limit-set-active', row).setAttribute('checked', 'true');
- }
- if(limit_set_entry.fallthrough() == 't') {
- byName('limit-set-fallthrough', row).setAttribute('checked', 'true');
- }
- byName('remove-limit-set', row).onclick = function() {
- byName('limit-set-entry-tbody', cmGrid.editPane.domNode).removeChild(row);
- }
- byName('limit-set-entry-tbody', cmGrid.editPane.domNode).appendChild(row);
-}
-
-function format_hard_due_date(name, id) {
- var item=this.grid.getItem(id);
- if(!item) return name;
- switch (this.grid.store.getValue(this.grid.getItem(id), 'hard_due_date')) {
- case null :
- case undefined :
- case 'unset' :
- return name;
- default:
- return "<a href='" + oilsBasePath +
- "/conify/global/config/hard_due_date?name=" +
- encodeURIComponent(name) + "'>" + name + "</a>";
- }
-}
-
-function updateLinked(fmObject, rowindex) {
- var id = null;
- if(rowindex != undefined && this.editPane && this.editPane.fmObject) {
- // Edit, grab existing ID
- id = this.editPane.fmObject.id();
- } else if(fmObject.id) {
- // Create, grab new ID
- id = fmObject.id();
- }
- // If we don't have an ID, drop out.
- if(id == null) return;
- var pcrud = new openils.PermaCrud();
- progressDialog.show(true);
-
- var add = [];
- var remove = [];
- var update = [];
-
- var limit_sets = [];
- dojo.query('[name=limit-set-entry-row]', this.editPane.domNode).forEach(
- function(row) {
- var lset = row.getAttribute('limit_set');
- limit_sets.push(lset);
- var cached = limitSetEntryCache.filter(function(i) { return (i.limit_set() == lset); })[0];
- if(!cached) {
- var entry = new fieldmapper.ccmlsm();
- entry.isnew(true);
- entry.matchpoint(id);
- entry.limit_set(lset);
- entry.active(byName('limit-set-active', row).checked ? 't' : 'f');
- entry.fallthrough(byName('limit-set-fallthrough', row).checked ? 't' : 'f');
- add.push(entry);
- } else {
- var active = byName('limit-set-active', row).checked;
- var fallthrough = byName('limit-set-fallthrough', row).checked;
- if((active != (cached.active() == 't')) || (fallthrough != (cached.fallthrough() == 't'))) {
- cached.active(active ? 't' : 'f');
- cached.fallthrough(fallthrough ? 't' : 'f');
- cached.ischanged(true);
- update.push(cached);
- }
- }
- }
- );
- dojo.forEach(limitSetEntryCache, function(eSet) {
- if(!limit_sets.filter(function(i) { return (i == eSet.limit_set()); })[0]) {
- eSet.isdeleted(true);
- remove.push(eSet);
- }
- }
- );
-
- function updateEntries() {
- pcrud.update(update, {
- oncomplete : function () {
- progressDialog.hide();
- }
- });
- }
-
- function removeEntries() {
- pcrud.eliminate(remove, {
- oncomplete : function () {
- if(update.length) {
- updateEntries();
- } else {
- progressDialog.hide();
- }
- }
- });
- }
-
- function addEntries() {
- pcrud.create(add, {
- oncomplete : function () {
- if(remove.length) {
- removeEntries();
- } else if (update.length) {
- updateEntries();
- } else {
- progressDialog.hide();
- }
- }
- });
- }
-
- if(add.length)
- addEntries();
- else if (remove.length)
- removeEntries();
- else if (update.length)
- updateEntries();
- else
- progressDialog.hide();
-}
-
-openils.Util.addOnLoad(load);
-
+require([
+ "dijit/layout/ContentPane",
+ "dijit/form/Button",
+ "openils/widget/AutoGrid",
+ "openils/widget/AutoFieldWidget",
+ "openils/PermaCrud",
+ "openils/widget/ProgressDialog"
+ ],
+function(dijit_layout_ContentPane,
+ dijit_form_Button,
+ openils_widget_AutoGrid,
+ openils_widget_AutoFieldWidget,
+ openils_PermaCrud,
+ openils_widget_ProgressDialog){
+
+ var limitSetEditor = null;
+ var limitSetEntryCache = [];
+ var limitSetCache = {};
+
+ function load(){
+ cmGrid.overrideWidgetArgs.grp = {hrbefore : true};
+ cmGrid.overrideWidgetArgs.is_renewal = {ternary : true};
+ cmGrid.overrideWidgetArgs.ref_flag = {ternary : true};
+ cmGrid.overrideWidgetArgs.juvenile_flag = {ternary : true};
+ cmGrid.overrideWidgetArgs.circulate = {inherits : true, hrbefore : true};
+ cmGrid.overrideWidgetArgs.duration_rule = {inherits : true};
+ cmGrid.overrideWidgetArgs.recurring_fine_rule = {inherits : true};
+ cmGrid.overrideWidgetArgs.max_fine_rule = {inherits : true};
+ cmGrid.overrideWidgetArgs.available_copy_hold_ratio = {inherits : true};
+ cmGrid.overrideWidgetArgs.total_copy_hold_ratio = {inherits : true};
+ cmGrid.overrideWidgetArgs.renewals = {inherits : true};
+ cmGrid.overrideWidgetArgs.grace_period = {inherits : true};
+ cmGrid.overrideWidgetArgs.hard_due_date = {inherits : true};
+ cmGrid.loadAll({order_by:{ccmm:'circ_modifier'}});
+ cmGrid.onEditPane = buildEditPaneAdditions;
+ cmGrid.onPostUpdate = updateLinked;
+ cmGrid.onPostCreate = updateLinked;
+ limitSetEditor = dojo.byId('limit-set-editor').parentNode.removeChild(dojo.byId('limit-set-editor'));
+
+ // Cache limit set info for later display
+ var pcrud = new openils_PermaCrud();
+ var temp = pcrud.retrieveAll('ccls');
+ dojo.forEach(temp, function(g) { limitSetCache[g.id()] = g; } );
+ }
+
+ function byName(name, ctxt) {
+ return dojo.query('[name=' + name + ']', ctxt)[0];
+ }
+
+ function buildEditPaneAdditions(editPane) {
+ limitSetEntryCache = [];
+ var tr = document.createElement('tr');
+ var td = document.createElement('td');
+ td.setAttribute('colspan','2');
+ // Explanation....
+ // editPane.domNode.lastChild = Table
+ // .lastChild = Table Body
+ // .lastChild = Table Row containing Action Buttons
+ editPane.domNode.lastChild.lastChild.insertBefore(tr, editPane.domNode.lastChild.lastChild.lastChild);
+ tr.appendChild(td);
+ curLimitSetEditor = limitSetEditor.cloneNode(true);
+ td.appendChild(curLimitSetEditor);
+ var limitSetTmpl = byName('limit-set-entry-tbody', curLimitSetEditor).removeChild(byName('limit-set-entry-row', curLimitSetEditor));
+
+ var selector = new openils_widget_AutoFieldWidget({
+ fmClass : 'ccmlsm',
+ fmField : 'limit_set',
+ parentNode : byName('limit-set-selector', curLimitSetEditor)
+ });
+ selector.build();
+
+ function addSet(lset) {
+ var row = limitSetTmpl.cloneNode(true);
+ row.setAttribute('limit_set', lset);
+ byName('limit-set', row).innerHTML = limitSetCache[lset].name();
+ byName('remove-limit-set', row).onclick = function() {
+ byName('limit-set-entry-tbody', cmGrid.editPane.domNode).removeChild(row);
+ }
+ byName('limit-set-active', row).setAttribute('checked', 'true');
+ byName('limit-set-entry-tbody', editPane.domNode).appendChild(row);
+ }
+
+ byName('add-limit-set', editPane.domNode).onclick = function() {
+ addSet(selector.widget.attr('value'));
+ }
+
+ // On edit we need to load existing entries.
+ // On create, not so much.
+ if(!editPane.fmObject) return;
+ var matchpoint = editPane.fmObject.id();
+
+ if(editPane.mode == 'update') {
+ var pcrud = new openils_PermaCrud();
+ limitSetEntryCache = pcrud.search('ccmlsm', {matchpoint: editPane.fmObject.id()});
+ dojo.forEach(limitSetEntryCache, function(g) { addLimitSet(limitSetTmpl, g); } );
+ }
+ }
+
+ function addLimitSet(tmpl, limit_set_entry) {
+ var row = tmpl.cloneNode(true);
+ var lset = limit_set_entry.limit_set();
+ row.setAttribute('limit_set', lset);
+ byName('limit-set', row).innerHTML = limitSetCache[lset].name();
+ if(limit_set_entry.active() == 't') {
+ byName('limit-set-active', row).setAttribute('checked', 'true');
+ }
+ if(limit_set_entry.fallthrough() == 't') {
+ byName('limit-set-fallthrough', row).setAttribute('checked', 'true');
+ }
+ byName('remove-limit-set', row).onclick = function() {
+ byName('limit-set-entry-tbody', cmGrid.editPane.domNode).removeChild(row);
+ }
+ byName('limit-set-entry-tbody', cmGrid.editPane.domNode).appendChild(row);
+ }
+
+ function format_hard_due_date(name, id) {
+ var item=this.grid.getItem(id);
+ if(!item) return name;
+ switch (this.grid.store.getValue(this.grid.getItem(id), 'hard_due_date')) {
+ case null :
+ case undefined :
+ case 'unset' :
+ return name;
+ default:
+ return "<a href='" + oilsBasePath +
+ "/conify/global/config/hard_due_date?name=" +
+ encodeURIComponent(name) + "'>" + name + "</a>";
+ }
+ }
+
+ function updateLinked(fmObject, rowindex) {
+ var id = null;
+ if(rowindex != undefined && this.editPane && this.editPane.fmObject) {
+ // Edit, grab existing ID
+ id = this.editPane.fmObject.id();
+ } else if(fmObject.id) {
+ // Create, grab new ID
+ id = fmObject.id();
+ }
+ // If we don't have an ID, drop out.
+ if(id == null) return;
+ var pcrud = new openils_PermaCrud();
+ progressDialog.show(true);
+
+ var add = [];
+ var remove = [];
+ var update = [];
+
+ var limit_sets = [];
+ dojo.query('[name=limit-set-entry-row]', this.editPane.domNode).forEach(
+ function(row) {
+ var lset = row.getAttribute('limit_set');
+ limit_sets.push(lset);
+ var cached = limitSetEntryCache.filter(function(i) { return (i.limit_set() == lset); })[0];
+ if(!cached) {
+ var entry = new fieldmapper.ccmlsm();
+ entry.isnew(true);
+ entry.matchpoint(id);
+ entry.limit_set(lset);
+ entry.active(byName('limit-set-active', row).checked ? 't' : 'f');
+ entry.fallthrough(byName('limit-set-fallthrough', row).checked ? 't' : 'f');
+ add.push(entry);
+ } else {
+ var active = byName('limit-set-active', row).checked;
+ var fallthrough = byName('limit-set-fallthrough', row).checked;
+ if((active != (cached.active() == 't')) || (fallthrough != (cached.fallthrough() == 't'))) {
+ cached.active(active ? 't' : 'f');
+ cached.fallthrough(fallthrough ? 't' : 'f');
+ cached.ischanged(true);
+ update.push(cached);
+ }
+ }
+ }
+ );
+ dojo.forEach(limitSetEntryCache, function(eSet) {
+ if(!limit_sets.filter(function(i) { return (i == eSet.limit_set()); })[0]) {
+ eSet.isdeleted(true);
+ remove.push(eSet);
+ }
+ }
+ );
+
+ function updateEntries() {
+ pcrud.update(update, {
+ oncomplete : function () {
+ progressDialog.hide();
+ }
+ });
+ }
+
+ function removeEntries() {
+ pcrud.eliminate(remove, {
+ oncomplete : function () {
+ if(update.length) {
+ updateEntries();
+ } else {
+ progressDialog.hide();
+ }
+ }
+ });
+ }
+
+ function addEntries() {
+ pcrud.create(add, {
+ oncomplete : function () {
+ if(remove.length) {
+ removeEntries();
+ } else if (update.length) {
+ updateEntries();
+ } else {
+ progressDialog.hide();
+ }
+ }
+ });
+ }
+
+ if(add.length)
+ addEntries();
+ else if (remove.length)
+ removeEntries();
+ else if (update.length)
+ updateEntries();
+ else
+ progressDialog.hide();
+ }
+
+ openils.Util.addOnLoad(load);
+
+
+
+});
\ No newline at end of file
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require('fieldmapper.IDL');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.AutoGrid');
-
-function updateFieldSelector() {
- var cls = this.attr('value');
- if(!cls) return;
- var flist = fieldmapper.IDL.fmclasses[cls];
- var fields = [];
- for(var f in flist.fields) {
- var field = flist.fields[f];
- if(field.virtual) continue;
- fields.push({name:field.label, value:field.name});
- }
- fdocGrid.overrideEditWidgets.field.store = new dojo.data.ItemFileReadStore(
- {data:{identifier:'value', label:'name', items:fields}});
-}
-
-function load() {
- var slist = fieldmapper.IDL.fmclasses;
- var dlist = [];
-
- fdocGrid.overrideEditWidgets.field = editFieldSelector;
- fdocGrid.overrideEditWidgets.fm_class = editClassSelector;
- dojo.connect(fdocGrid.overrideEditWidgets.fm_class, 'onChange', updateFieldSelector);
-
- for(var f in slist) {
- if(slist[f].label != slist[f].name) // only show tables that have an actual label
- dlist.push({value:slist[f].name, name:slist[f].label});
- }
- dlist = dlist.sort(function(a, b){return (a.name < b.name) ? -1 : 1;});
-
- fmClassSelector.store =
- fdocGrid.overrideEditWidgets.fm_class.store =
- new dojo.data.ItemFileReadStore({data:{identifier:'value', label:'name', items:dlist}});
-
- fmClassSelector.startup();
- dojo.connect(fmClassSelector, 'onChange',
- function() {
- fdocGrid.resetStore();
- fdocGrid.loadAll({order_by:{fdoc : 'field'}}, {fm_class: this.attr('value')});
- }
- );
-}
-
-
-openils.Util.addOnLoad(load);
-
+require([
+ "dijit/form/FilteringSelect",
+ "dojo/data/ItemFileReadStore",
+ "fieldmapper/IDL",
+ "openils/PermaCrud",
+ "openils/widget/AutoGrid"
+ ],
+function(dijit_form_FilteringSelect,
+ dojo_data_ItemFileReadStore,
+ fieldmapper_IDL,
+ openils_PermaCrud,
+ openils_widget_AutoGrid){
+
+ function updateFieldSelector() {
+ var cls = this.attr('value');
+ if(!cls) return;
+ var flist = fieldmapper_IDL.fmclasses[cls];
+ var fields = [];
+ for(var f in flist.fields) {
+ var field = flist.fields[f];
+ if(field.virtual) continue;
+ fields.push({name:field.label, value:field.name});
+ }
+ fdocGrid.overrideEditWidgets.field.store = new dojo_data_ItemFileReadStore(
+ {data:{identifier:'value', label:'name', items:fields}});
+ }
+
+ function load() {
+ var slist = fieldmapper_IDL.fmclasses;
+ var dlist = [];
+
+ fdocGrid.overrideEditWidgets.field = editFieldSelector;
+ fdocGrid.overrideEditWidgets.fm_class = editClassSelector;
+ dojo.connect(fdocGrid.overrideEditWidgets.fm_class, 'onChange', updateFieldSelector);
+
+ for(var f in slist) {
+ if(slist[f].label != slist[f].name) // only show tables that have an actual label
+ dlist.push({value:slist[f].name, name:slist[f].label});
+ }
+ dlist = dlist.sort(function(a, b){return (a.name < b.name) ? -1 : 1;});
+
+ fmClassSelector.store =
+ fdocGrid.overrideEditWidgets.fm_class.store =
+ new dojo_data_ItemFileReadStore({data:{identifier:'value', label:'name', items:dlist}});
+
+ fmClassSelector.startup();
+ dojo.connect(fmClassSelector, 'onChange',
+ function() {
+ fdocGrid.resetStore();
+ fdocGrid.loadAll({order_by:{fdoc : 'field'}}, {fm_class: this.attr('value')});
+ }
+ );
+ }
+
+
+ openils.Util.addOnLoad(load);
+
+
+
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dijit.Dialog');
-dojo.require('openils.PermaCrud');
-
-var thingList;
-
-function thingInit() {
-
- thingGrid.disableSelectorForRow = function(rowIdx) {
- var item = thingGrid.getItem(rowIdx);
- return (thingGrid.store.getValue(item, 'id') < 0);
- }
-
- buildGrid();
-}
-
-function buildGrid() {
-
- fieldmapper.standardRequest(
- ['open-ils.pcrud', 'open-ils.pcrud.search.csc.atomic'],
- { async: true,
- params: [
- openils.User.authtoken,
- {"id":{"!=":null}},
- {"order_by":{"csc":"name"}}
- ],
- oncomplete: function(r) {
- if(thingList = openils.Util.readResponse(r)) {
- thingList = openils.Util.objectSort(thingList,'name');
- dojo.forEach(thingList,
- function(e) {
- thingGrid.store.newItem(csc.toStoreItem(e));
- }
- );
- }
- }
- }
- );
-}
-
-openils.Util.addOnLoad(thingInit);
-
-
+require([
+ "dojox/grid/DataGrid",
+ "openils/widget/AutoGrid",
+ "dojox/grid/cells/dijit",
+ "dojo/data/ItemFileWriteStore",
+ "dijit/Dialog",
+ "openils/PermaCrud"
+ ],
+function(dojox_grid_DataGrid,
+ openils_widget_AutoGrid,
+ dojox_grid_cells_dijit,
+ dojo_data_ItemFileWriteStore,
+ dijit_Dialog,
+ openils_PermaCrud){
+
+ var thingList;
+
+ function thingInit() {
+
+ thingGrid.disableSelectorForRow = function(rowIdx) {
+ var item = thingGrid.getItem(rowIdx);
+ return (thingGrid.store.getValue(item, 'id') < 0);
+ }
+
+ buildGrid();
+ }
+
+ function buildGrid() {
+
+ fieldmapper.standardRequest(
+ ['open-ils.pcrud', 'open-ils.pcrud.search.csc.atomic'],
+ { async: true,
+ params: [
+ openils.User.authtoken,
+ {"id":{"!=":null}},
+ {"order_by":{"csc":"name"}}
+ ],
+ oncomplete: function(r) {
+ if(thingList = openils.Util.readResponse(r)) {
+ thingList = openils.Util.objectSort(thingList,'name');
+ dojo.forEach(thingList,
+ function(e) {
+ thingGrid.store.newItem(csc.toStoreItem(e));
+ }
+ );
+ }
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(thingInit);
+
+
+
+
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dojo.data.ItemFileWriteStore');
-dojo.require('dojox.form.CheckedMultiSelect');
-dojo.require('dijit.form.TextBox');
-dojo.require('dojox.grid.cells.dijit');
-dojo.require('openils.widget.AutoGrid');
-
- var spCache = {};
-
-function spBuildGrid() {
- spGrid.disableWidgetTest = function(field, obj) {
- if(obj && obj.id() < 100 && field == 'name')
- return true;
- return false;
- }
- spGrid.loadAll({order_by:{csp : 'name'}});
-}
-
-function formatId(inDatum) {
- if(inDatum < 100){
- return "<span style='color:red;'>"+ inDatum +"</span>";
- }
- return inDatum;
-}
-
-openils.Util.addOnLoad(spBuildGrid);
-
+require([
+ "dojox/grid/DataGrid",
+ "dojo/data/ItemFileWriteStore",
+ "dojox/form/CheckedMultiSelect",
+ "dijit/form/TextBox",
+ "dojox/grid/cells/dijit",
+ "openils/widget/AutoGrid"
+ ],
+function(dojox_grid_DataGrid,
+ dojo_data_ItemFileWriteStore,
+ dojox_form_CheckedMultiSelect,
+ dijit_form_TextBox,
+ dojox_grid_cells_dijit,
+ openils_widget_AutoGrid){
+
+ var spCache = {};
+
+ function spBuildGrid() {
+ spGrid.disableWidgetTest = function(field, obj) {
+ if(obj && obj.id() < 100 && field == 'name')
+ return true;
+ return false;
+ }
+ spGrid.loadAll({order_by:{csp : 'name'}});
+ }
+
+ function formatId(inDatum) {
+ if(inDatum < 100){
+ return "<span style='color:red;'>"+ inDatum +"</span>";
+ }
+ return inDatum;
+ }
+
+ openils.Util.addOnLoad(spBuildGrid);
+
+
+
+});
\ No newline at end of file
-dojo.require('dojox.grid.DataGrid');
-dojo.require('dojo.data.ItemFileReadStore');
-dojo.require('dijit.form.NumberTextBox');
-dojo.require('dijit.form.CheckBox');
-dojo.require('fieldmapper.OrgUtils');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('openils.widget.AutoGrid');
-var zsList;
-
-function buildZSGrid() {
- zsGrid.loadAll({order_by:{czs : 'name'}});
-}
-
-openils.Util.addOnLoad(buildZSGrid);
-
+require([
+ "dojox/grid/DataGrid",
+ "dojo/data/ItemFileReadStore",
+ "dijit/form/NumberTextBox",
+ "dijit/form/CheckBox",
+ "fieldmapper/OrgUtils",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/widget/AutoGrid"
+ ],
+function(dojox_grid_DataGrid,
+ dojo_data_ItemFileReadStore,
+ dijit_form_NumberTextBox,
+ dijit_form_CheckBox,
+ fieldmapper_OrgUtils,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_widget_AutoGrid){
+ var zsList;
+
+ function buildZSGrid() {
+ zsGrid.loadAll({order_by:{czs : 'name'}});
+ }
+
+ openils.Util.addOnLoad(buildZSGrid);
+
+
+
+});
\ No newline at end of file
-dojo.require('dijit.form.FilteringSelect');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('openils.widget.PermGrpFilteringSelect');
+require([
+ "dijit/form/FilteringSelect",
+ "openils/widget/AutoGrid",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/widget/PermGrpFilteringSelect"
+ ],
+function(dijit_form_FilteringSelect,
+ openils_widget_AutoGrid,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_widget_PermGrpFilteringSelect){
+
+
+ function buildGrid(org_id) {
+ var org_id = openils.User.user.ws_ou();
+ var list = fieldmapper.aou.findOrgUnit(org_id).orgNodeTrail().map( function (i) {
+ return i.id() } );
+
+ gptGrid.loadAll({order_by:{pgpt : 'grp'}},{org_unit:list});
+
+ new openils.User().buildPermOrgSelector('VIEW_GROUP_PENALTY_THRESHOLD', contextOrgSelector, null, function() {
+ dojo.connect(contextOrgSelector, 'onChange', filterGrid);});
+ }
+
+ function filterGrid() {
+ gptGrid.resetStore();
+ var unit = contextOrgSelector.getValue();
+ var list = fieldmapper.aou.findOrgUnit(unit).orgNodeTrail().map( function (i) {
+ return i.id() } );
+
+ if(unit)
+ gptGrid.loadAll({order_by:{pgpt: 'grp'}}, {org_unit:list});
+ else
+ gptGrid.loadAll({order_by:{pgpt : 'grp'}});
+
+ }
+
+ openils.Util.addOnLoad(buildGrid);
+
-
-function buildGrid(org_id) {
- var org_id = openils.User.user.ws_ou();
- var list = fieldmapper.aou.findOrgUnit(org_id).orgNodeTrail().map( function (i) {
- return i.id() } );
-
- gptGrid.loadAll({order_by:{pgpt : 'grp'}},{org_unit:list});
-
- new openils.User().buildPermOrgSelector('VIEW_GROUP_PENALTY_THRESHOLD', contextOrgSelector, null, function() {
- dojo.connect(contextOrgSelector, 'onChange', filterGrid);});
-}
-
-function filterGrid() {
- gptGrid.resetStore();
- var unit = contextOrgSelector.getValue();
- var list = fieldmapper.aou.findOrgUnit(unit).orgNodeTrail().map( function (i) {
- return i.id() } );
-
- if(unit)
- gptGrid.loadAll({order_by:{pgpt: 'grp'}}, {org_unit:list});
- else
- gptGrid.loadAll({order_by:{pgpt : 'grp'}});
-
-}
-
-openils.Util.addOnLoad(buildGrid);
+});
\ No newline at end of file
-dojo.require("dijit.Tree");
-dojo.require("dijit.form.Button");
-dojo.require("dojo.data.ItemFileWriteStore");
-dojo.require("dojo.dnd.Source");
-dojo.require("openils.vandelay.TreeDndSource");
-dojo.require("openils.vandelay.TreeStoreModel");
-dojo.require("openils.CGI");
-dojo.require("openils.User");
-dojo.require("openils.Util");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.widget.ProgressDialog");
-dojo.require("openils.widget.AutoGrid");
-
-var localeStrings, node_editor, qnode_editor, _crads, CGI, tree, match_set;
-
-var NodeEditorAbstract = {
- "_svf_select_template": null,
- "_simple_value_getter": function(control) {
- if (typeof control.selectedIndex != "undefined")
- return control.options[control.selectedIndex].value;
- else if (dojo.attr(control, "type") == "checkbox")
- return control.checked;
- else
- return control.value;
- },
- "is_sensible": function(thing) {
- var need_one = 0;
- this.foi.forEach(function(field) { if (thing[field]()) need_one++; });
-
- if (need_one != 1) {
- alert(localeStrings.POINT_NEEDS_ONE);
- return false;
- }
-
- if (thing.tag()) {
- if (
- !thing.tag().match(/^\d{3}$/) ||
- thing.subfield().length != 1 ||
- !thing.subfield().match(/\S/) ||
- thing.subfield().charCodeAt(0) < 32
- ) {
- alert(localeStrings.FAULTY_MARC);
- return false;
- }
- }
-
- return true;
- },
- "_add_consistent_controls": function(tgt) {
- if (!this._consistent_controls) {
- var trs = dojo.query(this._consistent_controls_query);
- this._consistent_controls = [];
- for (var i = 0; i < trs.length; i++)
- this._consistent_controls[i] = dojo.clone(trs[i]);
- }
-
- this._consistent_controls.forEach(
- function(node) { dojo.place(dojo.clone(node), tgt); }
- );
- },
- "_factories_by_type": {
- "svf": function() {
- if (!self._svf_select_template) {
- self._svf_select_template = dojo.create(
- "select", {"fmfield": "svf"}
- );
- for (var i=0; i<_crads.length; i++) {
- dojo.create(
- "option", {
- "value": _crads[i].name(),
- "innerHTML": _crads[i].label()
- }, self._svf_select_template
- );
- }
- }
-
- var select = dojo.clone(self._svf_select_template);
- dojo.attr(select, "id", "svf-select");
- var label = dojo.create(
- "label", {
- "for": "svf-select", "innerHTML": localeStrings.SVF + ":"
- }
- );
-
- var tr = dojo.create("tr");
- dojo.place(label, dojo.create("td", null, tr));
- dojo.place(select, dojo.create("td", null, tr));
-
- return [tr];
- },
- "tag": function() {
- var rows = [dojo.create("tr"), dojo.create("tr")];
- dojo.create(
- "label", {
- "for": "tag-input", "innerHTML": "Tag:"
- }, dojo.create("td", null, rows[0])
- );
- dojo.create(
- "input", {
- "id": "tag-input",
- "type": "text",
- "size": 4,
- "maxlength": 3,
- "fmfield": "tag"
- }, dojo.create("td", null, rows[0])
- );
- dojo.create(
- "label", {
- "for": "subfield-input", "innerHTML": "Subfield: \u2021"
- }, dojo.create("td", null, rows[1])
- );
- dojo.create(
- "input", {
- "id": "subfield-input",
- "type": "text",
- "size": 2,
- "maxlength": 1,
- "fmfield": "subfield"
- }, dojo.create("td", null, rows[1])
- );
- return rows;
- },
- "bool_op": function() {
- var tr = dojo.create("tr");
- dojo.create(
- "label",
- {"for": "operator-select", "innerHTML": "Operator:"},
- dojo.create("td", null, tr)
- );
- var select = dojo.create(
- "select", {"fmfield": "bool_op", "id": "operator-select"},
- dojo.create("td", null, tr)
- );
- dojo.create("option", {"value": "AND", "innerHTML": "AND"}, select);
- dojo.create("option", {"value": "OR", "innerHTML": "OR"}, select);
-
- return [tr];
- }
- }
-};
-
-function apply_base_class(cls, basecls) {
- openils.Util.objectProperties(basecls).forEach(
- function(m) { cls[m] = basecls[m]; }
- );
-}
-
-function QualityNodeEditor() {
- var self = this;
- this.foi = ["tag", "svf"]; /* Fields of Interest - starting points for UI */
-
- this._init = function(qnode_editor_container) {
- this._consistent_controls_query =
- "[consistent-controls], [quality-controls]";
- this.qnode_editor_container = dojo.byId(qnode_editor_container);
- this.clear();
- };
-
- this.clear = function() {
- dojo.create(
- "em", {"innerHTML": localeStrings.WORKING_QM_HERE},
- this.qnode_editor_container, "only"
- );
- };
-
- this.build_vmsq = function() {
- var metric = new vmsq();
- metric.match_set(match_set.id()); /* using global */
- var controls = dojo.query("[fmfield]", this.qnode_editor_container);
- for (var i = 0; i < controls.length; i++) {
- var field = dojo.attr(controls[i], "fmfield");
- var value = this._simple_value_getter(controls[i]);
- metric[field](value);
- }
-
- if (!this.is_sensible(metric)) return null; /* will alert() */
- else return metric;
- };
-
- this.add = function(type) {
- this.clear();
-
- /* these are the editing widgets */
- var table = dojo.create("table", {"className": "node-editor"});
-
- var nodes = this._factories_by_type[type]();
- for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
-
- this._add_consistent_controls(table);
-
- var ok_cxl_td = dojo.create(
- "td", {"colspan": 2, "align": "center", "className": "space-me"},
- dojo.create("tr", null, table)
- );
-
- dojo.create(
- "input", {
- "type": "submit", "value": localeStrings.OK,
- "onclick": function() {
- var metric = self.build_vmsq();
- if (metric) {
- self.clear();
- pcrud.create(
- metric, {
- /* borrowed from openils.widget.AutoGrid */
- "oncomplete": function(req, cudResults) {
- var fmObject = cudResults[0];
- if (vmsq_grid.onPostCreate)
- vmsq_grid.onPostCreate(fmObject);
- if (fmObject) {
- vmsq_grid.store.newItem(
- fmObject.toStoreItem()
- );
- }
- setTimeout(function() {
- try {
- vmsq_grid.selection.select(vmsq_grid.rowCount-1);
- vmsq_grid.views.views[0].getCellNode(vmsq_grid.rowCount-1, 1).focus();
- } catch (E) {}
- },200);
- }
- }
- );
- }
- }
- }, ok_cxl_td
- );
- dojo.create(
- "input", {
- "type": "reset", "value": localeStrings.CANCEL,
- "onclick": function() { self.clear(); }
- }, ok_cxl_td
- );
-
- dojo.place(table, this.qnode_editor_container, "only");
-
- /* nice */
- try { dojo.query("select, input", table)[0].focus(); }
- catch(E) { console.log(String(E)); }
-
- };
-
- apply_base_class(self, NodeEditorAbstract);
- this._init.apply(this, arguments);
-}
-
-function NodeEditor() {
- var self = this;
- this.foi = ["tag", "svf", "bool_op"]; /* Fields of Interest - starting points for UI */
-
- this._init = function(dnd_source, node_editor_container) {
- this._consistent_controls_query =
- "[consistent-controls], [point-controls]";
- this.dnd_source = dnd_source;
- this.node_editor_container = dojo.byId(node_editor_container);
- };
-
- this.clear = function() {
- this.dnd_source.selectAll().deleteSelectedNodes();
- dojo.create(
- "em", {"innerHTML": localeStrings.WORKING_MP_HERE},
- this.node_editor_container, "only"
- );
- this.dnd_source._ready = false;
- };
-
- this.build_vmsp = function() {
- var match_point = new vmsp();
- var controls = dojo.query("[fmfield]", this.node_editor_container);
- for (var i = 0; i < controls.length; i++) {
- var field = dojo.attr(controls[i], "fmfield");
- var value = this._simple_value_getter(controls[i]);
- match_point[field](value);
- }
-
- if (!this.is_sensible(match_point)) return null; /* will alert() */
- else return match_point;
- };
-
- this.update_draggable = function(draggable) {
- var mp;
-
- if (!(mp = this.build_vmsp())) return; /* will alert() */
-
- draggable.match_point = mp;
- dojo.attr(draggable, "innerHTML", render_vmsp_label(mp));
- this.dnd_source._ready = true;
- };
-
- this.add = function(type) {
- this.clear();
-
- /* a representation, not the editing widgets, but will also carry
- * the fieldmapper object when dragged to the tree */
- var draggable = dojo.create(
- "li", {"innerHTML": localeStrings.DEFINE_MP}
- );
-
- /* these are the editing widgets */
- var table = dojo.create("table", {"className": "node-editor"});
-
- var nodes = this._factories_by_type[type]();
- for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
-
- if (type != "bool_op")
- this._add_consistent_controls(table);
-
- dojo.create(
- "input", {
- "type": "submit", "value": localeStrings.OK,
- "onclick": function() { self.update_draggable(draggable); }
- }, dojo.create(
- "td", {"colspan": 2, "align": "center"},
- dojo.create("tr", null, table)
- )
- );
-
- dojo.place(table, this.node_editor_container, "only");
-
- this.dnd_source.insertNodes(false, [draggable]);
-
- /* nice */
- try { dojo.query("select, input", table)[0].focus(); }
- catch(E) { console.log(String(E)); }
-
- };
-
- apply_base_class(self, NodeEditorAbstract);
-
- this._init.apply(this, arguments);
-}
-
-function find_crad_by_name(name) {
- for (var i = 0; i < _crads.length; i++) {
- if (_crads[i].name() == name)
- return _crads[i];
- }
- return null;
-}
-
-function render_vmsp_label(point, minimal) {
- /* "minimal" has these implications:
- * for svf, only show the code, not the longer label.
- * no quality display
- */
- if (point.bool_op()) {
- return point.bool_op();
- } else if (point.svf()) {
- return (openils.Util.isTrue(point.negate()) ? "NOT " : "") + (
- minimal ? point.svf() :
- (point.svf() + " / " + find_crad_by_name(point.svf()).label()) +
- " | " + dojo.string.substitute(
- localeStrings.MATCH_SCORE, [point.quality()]
- )
- );
- } else {
- return (openils.Util.isTrue(point.negate()) ? "NOT " : "") +
- point.tag() + " \u2021" + point.subfield() + (minimal ? "" : " | " +
- dojo.string.substitute(
- localeStrings.MATCH_SCORE, [point.quality()]
- )
- );
- }
-}
-
-function replace_mode(explicit) {
- if (typeof explicit == "undefined")
- tree.model.replace_mode ^= 1;
- else
- tree.model.replace_mode = explicit;
-
- dojo.attr(
- "replacer", "innerHTML",
- localeStrings[
- (tree.model.replace_mode ? "EXIT" : "ENTER") + "_REPLACE_MODE"
- ]
- );
- dojo[tree.model.replace_mode ? "addClass" : "removeClass"](
- "replacer", "replace-mode"
- );
-}
-
-function delete_selected_in_tree() {
- /* relies on the fact that we only have one tree that would have
- * registered a dnd controller. */
- _tree_dnd_controllers[0].getSelectedItems().forEach(
- function(item) {
- if (item === tree.model.root)
- alert(localeStrings.LEAVE_ROOT_ALONE);
- else
- tree.model.store.deleteItem(item);
- }
- );
-}
-
-function new_match_set_tree() {
- var point = new vmsp();
- point.bool_op("AND");
- return [
- {
- "id": "root",
- "children": [],
- "name": render_vmsp_label(point),
- "match_point": point
- }
- ];
-}
-
-/* dojoize_match_set_tree() takes an argument, "point", that is actually a
- * vmsp fieldmapper object with descendants fleshed hierarchically. It turns
- * that into a syntactically flat array but preserving the hierarchy
- * semantically in the language used by dojo data stores, i.e.,
- *
- * [
- * {'id': 'root', children:[{'_reference': '0'}, {'_reference': '1'}]},
- * {'id': '0', children:[]},
- * {'id': '1', children:[]}
- * ],
- *
- */
-function dojoize_match_set_tree(point, depth) {
- var root = false;
- if (!depth) {
- if (!point) {
- return new_match_set_tree();
- }
- depth = 0;
- root = true;
- }
-
- var bathwater = point.children();
- point.children([]);
- var item = {
- "id": (root ? "root" : point.id()),
- "name": render_vmsp_label(point),
- "match_point": point.clone(),
- "children": []
- };
- point.children(bathwater);
-
- var results = [item];
-
- if (point.children()) {
- for (var i = 0; i < point.children().length; i++) {
- var child = point.children()[i];
- item.children.push({"_reference": child.id()});
- results = results.concat(
- dojoize_match_set_tree(child, ++depth)
- );
- }
- }
-
- return results;
-}
-
-function render_vms_metadata(match_set) {
- dojo.byId("vms-name").innerHTML = match_set.name();
- dojo.byId("vms-owner").innerHTML =
- aou.findOrgUnit(match_set.owner()).name();
- dojo.byId("vms-mtype").innerHTML = match_set.mtype();
-}
-
-function redraw_expression_preview() {
- tree.model.getRoot(
- function(root) {
- tree.model.get_simple_tree(
- root, function(r) {
- dojo.attr(
- "expr-preview",
- "innerHTML",
- render_expression_preview(r)
- );
- }
- );
- }
- );
-}
-
-function render_expression_preview(r) {
- if (r.children().length) {
- return "(" + r.children().map(render_expression_preview).join(
- " " + render_vmsp_label(r) + " "
- ) + ")";
- } else if (!r.bool_op()) {
- return render_vmsp_label(r, true /* minimal */);
- } else {
- return "()";
- }
-}
-
-function save_tree() {
- progress_dialog.show(true);
-
- tree.model.getRoot(
- function(root) {
- tree.model.get_simple_tree(
- root, function(r) {
- fieldmapper.standardRequest(
- ["open-ils.vandelay",
- "open-ils.vandelay.match_set.update"], {
- "params": [
- openils.User.authtoken, match_set.id(), r
- ],
- "async": true,
- "oncomplete": function(r) {
- progress_dialog.hide();
- /* catch exceptions */
- r = openils.Util.readResponse(r);
-
- location.href = location.href;
- }
- }
- );
- }
- );
- }
- );
-}
-
-function init_vmsq_grid() {
- vmsq_grid.loadAll(
- {"order_by": {"vmsq": "quality"}},
- {"match_set": match_set.id()}
- );
-}
-
-function my_init() {
- progress_dialog.show(true);
-
- dojo.requireLocalization("openils.vandelay", "match_set");
- localeStrings = dojo.i18n.getLocalization("openils.vandelay", "match_set");
-
- pcrud = new openils.PermaCrud();
- CGI = new openils.CGI();
-
- if (!CGI.param("match_set")) {
- alert(localeStrings.NO_CAN_DO);
- progress_dialog.hide();
- return;
- }
-
- render_vms_metadata(
- match_set = pcrud.retrieve("vms", CGI.param("match_set"))
- );
-
- /* No-one should have hundreds of these or anything, but theoretically
- * this could be problematic with a big enough list of crad objects. */
- _crads = pcrud.retrieveAll("crad", {"order_by": {"crad": "label"}});
-
- var match_set_tree = fieldmapper.standardRequest(
- ["open-ils.vandelay", "open-ils.vandelay.match_set.get_tree"],
- [openils.User.authtoken, CGI.param("match_set")]
- );
-
- var store = new dojo.data.ItemFileWriteStore({
- "data": {
- "identifier": "id",
- "label": "name",
- "items": dojoize_match_set_tree(match_set_tree)
- }
- });
-
- var tree_model = new openils.vandelay.TreeStoreModel({
- "store": store, "query": {"id": "root"}
- });
-
- var src = new dojo.dnd.Source("src-here");
- tree = new dijit.Tree(
- {
- "model": tree_model,
- "dndController": openils.vandelay.TreeDndSource,
- "dragThreshold": 8,
- "betweenThreshold": 5,
- "persist": false
- }, "tree-here"
- );
-
- node_editor = new NodeEditor(src, "node-editor-container");
- qnode_editor = new QualityNodeEditor("qnode-editor-container");
-
- replace_mode(0);
-
- dojo.connect(
- src, "onDndDrop", null,
- function(source, nodes, copy, target) {
- /* Because of the... interesting... characteristics of DnD
- * design in dojo/dijit (at least as of 1.3), this callback will
- * fire both for our working node dndSource and for the tree!
- */
- if (source == this)
- node_editor.clear(); /* ... because otherwise this acts like a
- copy operation no matter what the user
- does, even though we really want a
- "move." */
- }
- );
-
- redraw_expression_preview();
- node_editor.clear();
-
- init_vmsq_grid();
-
- progress_dialog.hide();
-}
-
-openils.Util.addOnLoad(my_init);
+require([
+ "dijit/Tree",
+ "dijit/form/Button",
+ "dojo/data/ItemFileWriteStore",
+ "dojo/dnd/Source",
+ "openils/vandelay/TreeDndSource",
+ "openils/vandelay/TreeStoreModel",
+ "openils/CGI",
+ "openils/User",
+ "openils/Util",
+ "openils/PermaCrud",
+ "openils/widget/ProgressDialog",
+ "openils/widget/AutoGrid"
+ ],
+function(dijit_Tree,
+ dijit_form_Button,
+ dojo_data_ItemFileWriteStore,
+ dojo_dnd_Source,
+ openils_vandelay_TreeDndSource,
+ openils_vandelay_TreeStoreModel,
+ openils_CGI,
+ openils_User,
+ openils_Util,
+ openils_PermaCrud,
+ openils_widget_ProgressDialog,
+ openils_widget_AutoGrid){
+
+ var localeStrings, node_editor, qnode_editor, _crads, CGI, tree, match_set;
+
+ var NodeEditorAbstract = {
+ "_svf_select_template": null,
+ "_simple_value_getter": function(control) {
+ if (typeof control.selectedIndex != "undefined")
+ return control.options[control.selectedIndex].value;
+ else if (dojo.attr(control, "type") == "checkbox")
+ return control.checked;
+ else
+ return control.value;
+ },
+ "is_sensible": function(thing) {
+ var need_one = 0;
+ this.foi.forEach(function(field) { if (thing[field]()) need_one++; });
+
+ if (need_one != 1) {
+ alert(localeStrings.POINT_NEEDS_ONE);
+ return false;
+ }
+
+ if (thing.tag()) {
+ if (
+ !thing.tag().match(/^\d{3}$/) ||
+ thing.subfield().length != 1 ||
+ !thing.subfield().match(/\S/) ||
+ thing.subfield().charCodeAt(0) < 32
+ ) {
+ alert(localeStrings.FAULTY_MARC);
+ return false;
+ }
+ }
+
+ return true;
+ },
+ "_add_consistent_controls": function(tgt) {
+ if (!this._consistent_controls) {
+ var trs = dojo.query(this._consistent_controls_query);
+ this._consistent_controls = [];
+ for (var i = 0; i < trs.length; i++)
+ this._consistent_controls[i] = dojo.clone(trs[i]);
+ }
+
+ this._consistent_controls.forEach(
+ function(node) { dojo.place(dojo.clone(node), tgt); }
+ );
+ },
+ "_factories_by_type": {
+ "svf": function() {
+ if (!self._svf_select_template) {
+ self._svf_select_template = dojo.create(
+ "select", {"fmfield": "svf"}
+ );
+ for (var i=0; i<_crads.length; i++) {
+ dojo.create(
+ "option", {
+ "value": _crads[i].name(),
+ "innerHTML": _crads[i].label()
+ }, self._svf_select_template
+ );
+ }
+ }
+
+ var select = dojo.clone(self._svf_select_template);
+ dojo.attr(select, "id", "svf-select");
+ var label = dojo.create(
+ "label", {
+ "for": "svf-select", "innerHTML": localeStrings.SVF + ":"
+ }
+ );
+
+ var tr = dojo.create("tr");
+ dojo.place(label, dojo.create("td", null, tr));
+ dojo.place(select, dojo.create("td", null, tr));
+
+ return [tr];
+ },
+ "tag": function() {
+ var rows = [dojo.create("tr"), dojo.create("tr")];
+ dojo.create(
+ "label", {
+ "for": "tag-input", "innerHTML": "Tag:"
+ }, dojo.create("td", null, rows[0])
+ );
+ dojo.create(
+ "input", {
+ "id": "tag-input",
+ "type": "text",
+ "size": 4,
+ "maxlength": 3,
+ "fmfield": "tag"
+ }, dojo.create("td", null, rows[0])
+ );
+ dojo.create(
+ "label", {
+ "for": "subfield-input", "innerHTML": "Subfield: \u2021"
+ }, dojo.create("td", null, rows[1])
+ );
+ dojo.create(
+ "input", {
+ "id": "subfield-input",
+ "type": "text",
+ "size": 2,
+ "maxlength": 1,
+ "fmfield": "subfield"
+ }, dojo.create("td", null, rows[1])
+ );
+ return rows;
+ },
+ "bool_op": function() {
+ var tr = dojo.create("tr");
+ dojo.create(
+ "label",
+ {"for": "operator-select", "innerHTML": "Operator:"},
+ dojo.create("td", null, tr)
+ );
+ var select = dojo.create(
+ "select", {"fmfield": "bool_op", "id": "operator-select"},
+ dojo.create("td", null, tr)
+ );
+ dojo.create("option", {"value": "AND", "innerHTML": "AND"}, select);
+ dojo.create("option", {"value": "OR", "innerHTML": "OR"}, select);
+
+ return [tr];
+ }
+ }
+ };
+
+ function apply_base_class(cls, basecls) {
+ openils_Util.objectProperties(basecls).forEach(
+ function(m) { cls[m] = basecls[m]; }
+ );
+ }
+
+ function QualityNodeEditor() {
+ var self = this;
+ this.foi = ["tag", "svf"]; /* Fields of Interest - starting points for UI */
+
+ this._init = function(qnode_editor_container) {
+ this._consistent_controls_query =
+ "[consistent-controls], [quality-controls]";
+ this.qnode_editor_container = dojo.byId(qnode_editor_container);
+ this.clear();
+ };
+
+ this.clear = function() {
+ dojo.create(
+ "em", {"innerHTML": localeStrings.WORKING_QM_HERE},
+ this.qnode_editor_container, "only"
+ );
+ };
+
+ this.build_vmsq = function() {
+ var metric = new vmsq();
+ metric.match_set(match_set.id()); /* using global */
+ var controls = dojo.query("[fmfield]", this.qnode_editor_container);
+ for (var i = 0; i < controls.length; i++) {
+ var field = dojo.attr(controls[i], "fmfield");
+ var value = this._simple_value_getter(controls[i]);
+ metric[field](value);
+ }
+
+ if (!this.is_sensible(metric)) return null; /* will alert() */
+ else return metric;
+ };
+
+ this.add = function(type) {
+ this.clear();
+
+ /* these are the editing widgets */
+ var table = dojo.create("table", {"className": "node-editor"});
+
+ var nodes = this._factories_by_type[type]();
+ for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
+
+ this._add_consistent_controls(table);
+
+ var ok_cxl_td = dojo.create(
+ "td", {"colspan": 2, "align": "center", "className": "space-me"},
+ dojo.create("tr", null, table)
+ );
+
+ dojo.create(
+ "input", {
+ "type": "submit", "value": localeStrings.OK,
+ "onclick": function() {
+ var metric = self.build_vmsq();
+ if (metric) {
+ self.clear();
+ pcrud.create(
+ metric, {
+ /* borrowed from openils_widget_AutoGrid */
+ "oncomplete": function(req, cudResults) {
+ var fmObject = cudResults[0];
+ if (vmsq_grid.onPostCreate)
+ vmsq_grid.onPostCreate(fmObject);
+ if (fmObject) {
+ vmsq_grid.store.newItem(
+ fmObject.toStoreItem()
+ );
+ }
+ setTimeout(function() {
+ try {
+ vmsq_grid.selection.select(vmsq_grid.rowCount-1);
+ vmsq_grid.views.views[0].getCellNode(vmsq_grid.rowCount-1, 1).focus();
+ } catch (E) {}
+ },200);
+ }
+ }
+ );
+ }
+ }
+ }, ok_cxl_td
+ );
+ dojo.create(
+ "input", {
+ "type": "reset", "value": localeStrings.CANCEL,
+ "onclick": function() { self.clear(); }
+ }, ok_cxl_td
+ );
+
+ dojo.place(table, this.qnode_editor_container, "only");
+
+ /* nice */
+ try { dojo.query("select, input", table)[0].focus(); }
+ catch(E) { console.log(String(E)); }
+
+ };
+
+ apply_base_class(self, NodeEditorAbstract);
+ this._init.apply(this, arguments);
+ }
+
+ function NodeEditor() {
+ var self = this;
+ this.foi = ["tag", "svf", "bool_op"]; /* Fields of Interest - starting points for UI */
+
+ this._init = function(dnd_source, node_editor_container) {
+ this._consistent_controls_query =
+ "[consistent-controls], [point-controls]";
+ this.dnd_source = dnd_source;
+ this.node_editor_container = dojo.byId(node_editor_container);
+ };
+
+ this.clear = function() {
+ this.dnd_source.selectAll().deleteSelectedNodes();
+ dojo.create(
+ "em", {"innerHTML": localeStrings.WORKING_MP_HERE},
+ this.node_editor_container, "only"
+ );
+ this.dnd_source._ready = false;
+ };
+
+ this.build_vmsp = function() {
+ var match_point = new vmsp();
+ var controls = dojo.query("[fmfield]", this.node_editor_container);
+ for (var i = 0; i < controls.length; i++) {
+ var field = dojo.attr(controls[i], "fmfield");
+ var value = this._simple_value_getter(controls[i]);
+ match_point[field](value);
+ }
+
+ if (!this.is_sensible(match_point)) return null; /* will alert() */
+ else return match_point;
+ };
+
+ this.update_draggable = function(draggable) {
+ var mp;
+
+ if (!(mp = this.build_vmsp())) return; /* will alert() */
+
+ draggable.match_point = mp;
+ dojo.attr(draggable, "innerHTML", render_vmsp_label(mp));
+ this.dnd_source._ready = true;
+ };
+
+ this.add = function(type) {
+ this.clear();
+
+ /* a representation, not the editing widgets, but will also carry
+ * the fieldmapper object when dragged to the tree */
+ var draggable = dojo.create(
+ "li", {"innerHTML": localeStrings.DEFINE_MP}
+ );
+
+ /* these are the editing widgets */
+ var table = dojo.create("table", {"className": "node-editor"});
+
+ var nodes = this._factories_by_type[type]();
+ for (var i = 0; i < nodes.length; i++) dojo.place(nodes[i], table);
+
+ if (type != "bool_op")
+ this._add_consistent_controls(table);
+
+ dojo.create(
+ "input", {
+ "type": "submit", "value": localeStrings.OK,
+ "onclick": function() { self.update_draggable(draggable); }
+ }, dojo.create(
+ "td", {"colspan": 2, "align": "center"},
+ dojo.create("tr", null, table)
+ )
+ );
+
+ dojo.place(table, this.node_editor_container, "only");
+
+ this.dnd_source.insertNodes(false, [draggable]);
+
+ /* nice */
+ try { dojo.query("select, input", table)[0].focus(); }
+ catch(E) { console.log(String(E)); }
+
+ };
+
+ apply_base_class(self, NodeEditorAbstract);
+
+ this._init.apply(this, arguments);
+ }
+
+ function find_crad_by_name(name) {
+ for (var i = 0; i < _crads.length; i++) {
+ if (_crads[i].name() == name)
+ return _crads[i];
+ }
+ return null;
+ }
+
+ function render_vmsp_label(point, minimal) {
+ /* "minimal" has these implications:
+ * for svf, only show the code, not the longer label.
+ * no quality display
+ */
+ if (point.bool_op()) {
+ return point.bool_op();
+ } else if (point.svf()) {
+ return (openils_Util.isTrue(point.negate()) ? "NOT " : "") + (
+ minimal ? point.svf() :
+ (point.svf() + " / " + find_crad_by_name(point.svf()).label()) +
+ " | " + dojo.string.substitute(
+ localeStrings.MATCH_SCORE, [point.quality()]
+ )
+ );
+ } else {
+ return (openils_Util.isTrue(point.negate()) ? "NOT " : "") +
+ point.tag() + " \u2021" + point.subfield() + (minimal ? "" : " | " +
+ dojo.string.substitute(
+ localeStrings.MATCH_SCORE, [point.quality()]
+ )
+ );
+ }
+ }
+
+ function replace_mode(explicit) {
+ if (typeof explicit == "undefined")
+ tree.model.replace_mode ^= 1;
+ else
+ tree.model.replace_mode = explicit;
+
+ dojo.attr(
+ "replacer", "innerHTML",
+ localeStrings[
+ (tree.model.replace_mode ? "EXIT" : "ENTER") + "_REPLACE_MODE"
+ ]
+ );
+ dojo[tree.model.replace_mode ? "addClass" : "removeClass"](
+ "replacer", "replace-mode"
+ );
+ }
+
+ function delete_selected_in_tree() {
+ /* relies on the fact that we only have one tree that would have
+ * registered a dnd controller. */
+ _tree_dnd_controllers[0].getSelectedItems().forEach(
+ function(item) {
+ if (item === tree.model.root)
+ alert(localeStrings.LEAVE_ROOT_ALONE);
+ else
+ tree.model.store.deleteItem(item);
+ }
+ );
+ }
+
+ function new_match_set_tree() {
+ var point = new vmsp();
+ point.bool_op("AND");
+ return [
+ {
+ "id": "root",
+ "children": [],
+ "name": render_vmsp_label(point),
+ "match_point": point
+ }
+ ];
+ }
+
+ /* dojoize_match_set_tree() takes an argument, "point", that is actually a
+ * vmsp fieldmapper object with descendants fleshed hierarchically. It turns
+ * that into a syntactically flat array but preserving the hierarchy
+ * semantically in the language used by dojo data stores, i.e.,
+ *
+ * [
+ * {'id': 'root', children:[{'_reference': '0'}, {'_reference': '1'}]},
+ * {'id': '0', children:[]},
+ * {'id': '1', children:[]}
+ * ],
+ *
+ */
+ function dojoize_match_set_tree(point, depth) {
+ var root = false;
+ if (!depth) {
+ if (!point) {
+ return new_match_set_tree();
+ }
+ depth = 0;
+ root = true;
+ }
+
+ var bathwater = point.children();
+ point.children([]);
+ var item = {
+ "id": (root ? "root" : point.id()),
+ "name": render_vmsp_label(point),
+ "match_point": point.clone(),
+ "children": []
+ };
+ point.children(bathwater);
+
+ var results = [item];
+
+ if (point.children()) {
+ for (var i = 0; i < point.children().length; i++) {
+ var child = point.children()[i];
+ item.children.push({"_reference": child.id()});
+ results = results.concat(
+ dojoize_match_set_tree(child, ++depth)
+ );
+ }
+ }
+
+ return results;
+ }
+
+ function render_vms_metadata(match_set) {
+ dojo.byId("vms-name").innerHTML = match_set.name();
+ dojo.byId("vms-owner").innerHTML =
+ aou.findOrgUnit(match_set.owner()).name();
+ dojo.byId("vms-mtype").innerHTML = match_set.mtype();
+ }
+
+ function redraw_expression_preview() {
+ tree.model.getRoot(
+ function(root) {
+ tree.model.get_simple_tree(
+ root, function(r) {
+ dojo.attr(
+ "expr-preview",
+ "innerHTML",
+ render_expression_preview(r)
+ );
+ }
+ );
+ }
+ );
+ }
+
+ function render_expression_preview(r) {
+ if (r.children().length) {
+ return "(" + r.children().map(render_expression_preview).join(
+ " " + render_vmsp_label(r) + " "
+ ) + ")";
+ } else if (!r.bool_op()) {
+ return render_vmsp_label(r, true /* minimal */);
+ } else {
+ return "()";
+ }
+ }
+
+ function save_tree() {
+ progress_dialog.show(true);
+
+ tree.model.getRoot(
+ function(root) {
+ tree.model.get_simple_tree(
+ root, function(r) {
+ fieldmapper.standardRequest(
+ ["open-ils.vandelay",
+ "open-ils.vandelay.match_set.update"], {
+ "params": [
+ openils_User.authtoken, match_set.id(), r
+ ],
+ "async": true,
+ "oncomplete": function(r) {
+ progress_dialog.hide();
+ /* catch exceptions */
+ r = openils_Util.readResponse(r);
+
+ location.href = location.href;
+ }
+ }
+ );
+ }
+ );
+ }
+ );
+ }
+
+ function init_vmsq_grid() {
+ vmsq_grid.loadAll(
+ {"order_by": {"vmsq": "quality"}},
+ {"match_set": match_set.id()}
+ );
+ }
+
+ function my_init() {
+ progress_dialog.show(true);
+
+ dojo.requireLocalization("openils.vandelay", "match_set");
+ localeStrings = dojo.i18n.getLocalization("openils.vandelay", "match_set");
+
+ pcrud = new openils_PermaCrud();
+ CGI = new openils_CGI();
+
+ if (!CGI.param("match_set")) {
+ alert(localeStrings.NO_CAN_DO);
+ progress_dialog.hide();
+ return;
+ }
+
+ render_vms_metadata(
+ match_set = pcrud.retrieve("vms", CGI.param("match_set"))
+ );
+
+ /* No-one should have hundreds of these or anything, but theoretically
+ * this could be problematic with a big enough list of crad objects. */
+ _crads = pcrud.retrieveAll("crad", {"order_by": {"crad": "label"}});
+
+ var match_set_tree = fieldmapper.standardRequest(
+ ["open-ils.vandelay", "open-ils.vandelay.match_set.get_tree"],
+ [openils_User.authtoken, CGI.param("match_set")]
+ );
+
+ var store = new dojo_data_ItemFileWriteStore({
+ "data": {
+ "identifier": "id",
+ "label": "name",
+ "items": dojoize_match_set_tree(match_set_tree)
+ }
+ });
+
+ var tree_model = new openils_vandelay_TreeStoreModel({
+ "store": store, "query": {"id": "root"}
+ });
+
+ var src = new dojo_dnd_Source("src-here");
+ tree = new dijit_Tree(
+ {
+ "model": tree_model,
+ "dndController": openils_vandelay_TreeDndSource,
+ "dragThreshold": 8,
+ "betweenThreshold": 5,
+ "persist": false
+ }, "tree-here"
+ );
+
+ node_editor = new NodeEditor(src, "node-editor-container");
+ qnode_editor = new QualityNodeEditor("qnode-editor-container");
+
+ replace_mode(0);
+
+ dojo.connect(
+ src, "onDndDrop", null,
+ function(source, nodes, copy, target) {
+ /* Because of the... interesting... characteristics of DnD
+ * design in dojo/dijit (at least as of 1.3), this callback will
+ * fire both for our working node dndSource and for the tree!
+ */
+ if (source == this)
+ node_editor.clear(); /* ... because otherwise this acts like a
+ copy operation no matter what the user
+ does, even though we really want a
+ "move." */
+ }
+ );
+
+ redraw_expression_preview();
+ node_editor.clear();
+
+ init_vmsq_grid();
+
+ progress_dialog.hide();
+ }
+
+ openils_Util.addOnLoad(my_init);
+
+
+});
\ No newline at end of file
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.DateTextBox");
-dojo.require("dijit.form.TextBox");
-dojo.require("dijit.form.NumberSpinner");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("openils.widget.PCrudAutocompleteBox");
-dojo.require("openils.widget.AutoGrid");
-dojo.require("openils.widget.ProgressDialog");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.CGI");
-
-var pcrud, cgi, issuance_id;
-var sitem_cache = {};
-
-function load_sitem_grid() {
- sitem_grid.overrideEditWidgets.status = status_selector;
- sitem_grid.overrideEditWidgets.status.shove = {}; /* sic */
-
- sitem_grid.dataLoader = sitem_data_loader;
- sitem_grid.dataLoader();
-}
-
-function load_siss_display() {
- pcrud.retrieve(
- "siss", issuance_id, {
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- var link = dojo.byId("siss_label_here");
- link.onclick = function() {
- location.href = oilsBasePath +
- "/serial/subscription?id=" +
- r.subscription() + "&tab=issuances";
- }
- link.innerHTML = r.label();
- prepare_create_dialog(r.subscription());
- }
- }
- }
- );
-}
-
-function sitem_data_loader() {
- sitem_grid.resetStore();
- sitem_grid.showLoadProgressIndicator();
-
- fieldmapper.standardRequest(
- ["open-ils.serial", "open-ils.serial.items.by_issuance"], {
- "params": [
- openils.User.authtoken, issuance_id, {
- "limit": sitem_grid.displayLimit,
- "offset": sitem_grid.displayOffset
- }
- ],
- "async": true,
- "onresponse": function(r) {
- var item = openils.Util.readResponse(r);
- sitem_cache[item.id()] = item;
- sitem_grid.store.newItem(item.toStoreItem());
- },
- "oncomplete": function(r) {
- sitem_grid.hideLoadProgressIndicator();
- }
- }
- );
-}
-
-function _get_field(store, item, field) {
- if (!item) return "";
- var id = store.getValue(item, "id");
- return sitem_cache[id][field]();
-}
-
-/* create the get_foo() functions used by our AutoGrid */
-["creator", "editor", "stream", "unit"].forEach(
- function(field) {
- window["get_" + field] = function(row_index, item) {
- return _get_field(this.grid.store, item, field);
- };
- }
-);
-
-function format_user(user) {
- return user ? user.usrname() : "";
-}
-
-function format_stream(stream) {
- return stream ? (stream.routing_label() || "[None]") : ""; /* XXX i18n */
-}
-
-function format_unit(unit) {
- return unit ? (unit.barcode() || "[None]") : ""; /* XXX i18n */
-}
-
-function update_sitem_safely(obj, opts, edit_pane) {
- fieldmapper.standardRequest(
- ["open-ils.serial", "open-ils.serial.item.update"], {
- "params": [openils.User.authtoken, obj],
- "async": true,
- "oncomplete": function(r) {
- if (r = openils.Util.readResponse(r)) {
- if (edit_pane.onPostSubmit)
- edit_pane.onPostSubmit(null, [r]);
- }
- }
- }
- );
-}
-
-function prepare_create_dialog(sub_id) {
- pcrud.search(
- "sdist", {"subscription": sub_id}, {
- "id_list": true,
- "async": true,
- "oncomplete": function(r) {
- if (r = openils.Util.readResponse(r)) {
- new openils.widget.PCrudAutocompleteBox({
- "fmclass": "sstr",
- "searchAttr": "routing_label",
- "hasDownArrow": true,
- "name": "stream",
- "store_options": {
- "base_filter": {"distribution": r},
- "honor_retrieve_all": true
- }
- }, "stream_selector");
- }
- }
- }
- );
-}
-
-function create_new_items(form) {
- var item = new sitem();
-
- item.issuance(issuance_id); /* from global */
- item.stream(form.stream);
- item.status(form.status);
- item.date_expected(
- form.date_expected ?
- dojo.date.stamp.toISOString(form.date_expected) : null
- );
- item.date_received(
- form.date_received ?
- dojo.date.stamp.toISOString(form.date_received) : null
- );
-
- progress_dialog.show(true);
- fieldmapper.standardRequest(
- ["open-ils.serial", "open-ils.serial.item.create"], {
- "params": [openils.User.authtoken, item, form.count],
- "async": true,
- "oncomplete": function(r) {
- progress_dialog.hide();
- if (r = openils.Util.readResponse(r)) {
- sitem_grid.refresh();
- }
- }
- }
- );
-}
-
-openils.Util.addOnLoad(
- function() {
- cgi = new openils.CGI();
- pcrud = new openils.PermaCrud();
-
- issuance_id = cgi.param("issuance");
- load_siss_display();
- load_sitem_grid();
- }
-);
+require([
+ "dijit/form/Button",
+ "dijit/form/DateTextBox",
+ "dijit/form/TextBox",
+ "dijit/form/NumberSpinner",
+ "dijit/form/FilteringSelect",
+ "openils/widget/PCrudAutocompleteBox",
+ "openils/widget/AutoGrid",
+ "openils/widget/ProgressDialog",
+ "openils/PermaCrud",
+ "openils/CGI"
+ ],
+function(dijit_form_Button,
+ dijit_form_DateTextBox,
+ dijit_form_TextBox,
+ dijit_form_NumberSpinner,
+ dijit_form_FilteringSelect,
+ openils_widget_PCrudAutocompleteBox,
+ openils_widget_AutoGrid,
+ openils_widget_ProgressDialog,
+ openils_PermaCrud,
+ openils_CGI){
+
+ var pcrud, cgi, issuance_id;
+ var sitem_cache = {};
+
+ function load_sitem_grid() {
+ sitem_grid.overrideEditWidgets.status = status_selector;
+ sitem_grid.overrideEditWidgets.status.shove = {}; /* sic */
+
+ sitem_grid.dataLoader = sitem_data_loader;
+ sitem_grid.dataLoader();
+ }
+
+ function load_siss_display() {
+ pcrud.retrieve(
+ "siss", issuance_id, {
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ var link = dojo.byId("siss_label_here");
+ link.onclick = function() {
+ location.href = oilsBasePath +
+ "/serial/subscription?id=" +
+ r.subscription() + "&tab=issuances";
+ }
+ link.innerHTML = r.label();
+ prepare_create_dialog(r.subscription());
+ }
+ }
+ }
+ );
+ }
+
+ function sitem_data_loader() {
+ sitem_grid.resetStore();
+ sitem_grid.showLoadProgressIndicator();
+
+ fieldmapper.standardRequest(
+ ["open-ils.serial", "open-ils.serial.items.by_issuance"], {
+ "params": [
+ openils.User.authtoken, issuance_id, {
+ "limit": sitem_grid.displayLimit,
+ "offset": sitem_grid.displayOffset
+ }
+ ],
+ "async": true,
+ "onresponse": function(r) {
+ var item = openils.Util.readResponse(r);
+ sitem_cache[item.id()] = item;
+ sitem_grid.store.newItem(item.toStoreItem());
+ },
+ "oncomplete": function(r) {
+ sitem_grid.hideLoadProgressIndicator();
+ }
+ }
+ );
+ }
+
+ function _get_field(store, item, field) {
+ if (!item) return "";
+ var id = store.getValue(item, "id");
+ return sitem_cache[id][field]();
+ }
+
+ /* create the get_foo() functions used by our AutoGrid */
+ ["creator", "editor", "stream", "unit"].forEach(
+ function(field) {
+ window["get_" + field] = function(row_index, item) {
+ return _get_field(this.grid.store, item, field);
+ };
+ }
+ );
+
+ function format_user(user) {
+ return user ? user.usrname() : "";
+ }
+
+ function format_stream(stream) {
+ return stream ? (stream.routing_label() || "[None]") : ""; /* XXX i18n */
+ }
+
+ function format_unit(unit) {
+ return unit ? (unit.barcode() || "[None]") : ""; /* XXX i18n */
+ }
+
+ function update_sitem_safely(obj, opts, edit_pane) {
+ fieldmapper.standardRequest(
+ ["open-ils.serial", "open-ils.serial.item.update"], {
+ "params": [openils.User.authtoken, obj],
+ "async": true,
+ "oncomplete": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ if (edit_pane.onPostSubmit)
+ edit_pane.onPostSubmit(null, [r]);
+ }
+ }
+ }
+ );
+ }
+
+ function prepare_create_dialog(sub_id) {
+ pcrud.search(
+ "sdist", {"subscription": sub_id}, {
+ "id_list": true,
+ "async": true,
+ "oncomplete": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ new openils_widget_PCrudAutocompleteBox({
+ "fmclass": "sstr",
+ "searchAttr": "routing_label",
+ "hasDownArrow": true,
+ "name": "stream",
+ "store_options": {
+ "base_filter": {"distribution": r},
+ "honor_retrieve_all": true
+ }
+ }, "stream_selector");
+ }
+ }
+ }
+ );
+ }
+
+ function create_new_items(form) {
+ var item = new sitem();
+
+ item.issuance(issuance_id); /* from global */
+ item.stream(form.stream);
+ item.status(form.status);
+ item.date_expected(
+ form.date_expected ?
+ dojo.date.stamp.toISOString(form.date_expected) : null
+ );
+ item.date_received(
+ form.date_received ?
+ dojo.date.stamp.toISOString(form.date_received) : null
+ );
+
+ progress_dialog.show(true);
+ fieldmapper.standardRequest(
+ ["open-ils.serial", "open-ils.serial.item.create"], {
+ "params": [openils.User.authtoken, item, form.count],
+ "async": true,
+ "oncomplete": function(r) {
+ progress_dialog.hide();
+ if (r = openils.Util.readResponse(r)) {
+ sitem_grid.refresh();
+ }
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(
+ function() {
+ cgi = new openils_CGI();
+ pcrud = new openils_PermaCrud();
+
+ issuance_id = cgi.param("issuance");
+ load_siss_display();
+ load_sitem_grid();
+ }
+ );
+
+
+});
\ No newline at end of file
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.RadioButton");
-dojo.require("dijit.form.NumberSpinner");
-dojo.require("dijit.form.TextBox");
-dojo.require("dojo.dnd.Source");
-dojo.require("openils.widget.AutoGrid");
-dojo.require("openils.widget.ProgressDialog");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.CGI");
-
-var pcrud;
-var dist_id;
-var rlu_editor;
-var cgi;
-
-function format_routing_label(routing_label) {
- return routing_label ? routing_label : "[None]";
-}
-
-function load_sstr_grid() {
- sstr_grid.overrideEditWidgets.distribution =
- new dijit.form.TextBox({"disabled": true, "value": dist_id});
-
- sstr_grid.resetStore();
- sstr_grid.loadAll(
- {"order_by": {"ssub": "start_date DESC"}},
- {"distribution": dist_id}
- );
-}
-
-function load_sdist_display() {
- pcrud.retrieve(
- "sdist", dist_id, {
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- var link = dojo.byId("sdist_label_here");
- link.onclick = function() {
- location.href = oilsBasePath +
- "/serial/subscription?id=" +
- r.subscription() + "&tab=distributions";
- }
- link.innerHTML = r.label();
- load_sdist_org_unit_display(r);
- }
- }
- }
- );
-}
-
-function load_sdist_org_unit_display(dist) {
- dojo.byId("sdist_org_unit_name_here").innerHTML =
- aou.findOrgUnit(dist.holding_lib()).name();
-}
-
-function create_many_streams(fields) {
- var streams = [];
- for (var i = 0; i < fields.quantity; i++) {
- var stream = new sstr();
- stream.distribution(dist_id);
- streams.push(stream);
- }
-
- progress_dialog.show(true);
- this.pcrud.create(
- streams, {
- "oncomplete": function(r, list) {
- progress_dialog.hide();
- sstr_grid.refresh();
- },
- "onerror": function(r) {
- progress_dialog.hide();
- alert("Error creating streams!"); /* XXX i18n */
- }
- }
- );
-}
-
-function RLUEditor() {
- var self = this;
-
- function _reader_xor_dept_toggle(value) {
- var reader = dijit.byId("reader");
- var department = dijit.byId("department");
-
- if (this.id.match(/\w+$/).pop() == "reader")
- _reader_toggle(value, reader, department);
- else
- _department_toggle(value, reader, department);
- }
-
- function _reader_toggle(value, reader, department) {
- if (value) {
- reader.attr("disabled", false);
- department.attr("disabled", true);
- setTimeout(function() { reader.focus(); }, 125);
- }
- }
-
- function _department_toggle(value, reader, department) {
- if (value) {
- reader.attr("disabled", true);
- department.attr("disabled", false);
- setTimeout(function() { department.focus(); }, 125);
- }
- }
-
- this.user_to_source_entry = function(user) {
- var node = dojo.create("li");
- var s;
- if (user.reader()) {
- s = dojo.string.substitute(
- this.template.reader, [
- user.reader().card().barcode(),
- user.reader().family_name(),
- user.reader().first_given_name(),
- user.reader().second_given_name(),
- user.reader().home_ou().shortname()
- ].map(function(o) { return o == null ? "" : o; })
- );
- } else {
- s = dojo.string.substitute(
- this.template.department, [user.department()]
- );
- }
-
- if (user.note()) {
- s += dojo.string.substitute(this.template.note, [user.note()]);
- }
-
- node.innerHTML = " " + s;
-
- dojo.create(
- "a", {
- "href": "javascript:void(0);",
- "onclick": function() { self.toggle_deleted(node); },
- "innerHTML": this.template.remove
- }, node, "first"
- );
-
- node._user = user;
- return node;
- };
-
- this.toggle_deleted = function(node) {
- if (node._user.isdeleted()) {
- dojo.style(node, "textDecoration", "none");
- node._user.isdeleted(false);
- } else {
- dojo.style(node, "textDecoration", "line-through");
- node._user.isdeleted(true);
- }
- };
-
- this.new_user = function() {
- var form = this.dialog.attr("value");
- var user = new fieldmapper.srlu();
- user.isnew(true);
- user.stream(this.stream);
-
- if (form.note)
- user.note(form.note);
-
- if (form.department) {
- user.department(form.department);
- } else if (form.reader) {
- this.add_button.attr("disabled", true);
- fieldmapper.standardRequest(
- ["open-ils.actor",
- "open-ils.actor.user.fleshed.retrieve_by_barcode"], {
- "params": [openils.User.authtoken, form.reader, true],
- "timeout": 10, /* sync */
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- user.reader(r);
- }
- }
- }
- );
- this.add_button.attr("disabled", false);
- } else {
- alert("Provide either a reader or a department."); /* XXX i18n */
- return;
- }
-
- ["reader", "department", "note"].forEach(
- function(s) { dijit.byId(s).attr("value", ""); }
- );
-
- this.source.insertNodes(false, [self.user_to_source_entry(user)]);
- }
-
- this.show = function() {
- if (sstr_grid.getSelectedRows().length != 1) {
- alert(
- "Use the checkboxes to select exactly one stream " +
- "for this operation." /* XXX i18n */
- );
- } else {
- /* AutoGrid.getSelectedItems() yields a weird, non-FM object */
- this.stream = sstr_grid.getSelectedItems()[0].id[0];
-
- this.source.selectAll();
- this.source.deleteSelectedNodes();
- this.source.clearItems();
-
- this.dialog.show();
-
- fieldmapper.standardRequest(
- ["open-ils.serial",
- "open-ils.serial.routing_list_users.fleshed_and_ordered"], {
- "params": [openils.User.authtoken, this.stream],
- "async": true,
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- self.source.insertNodes(
- false, [self.user_to_source_entry(r)]
- );
- }
- },
- "oncomplete": function() {
- setTimeout(
- function() { self.save_button.focus(); }, 125
- );
- }
- }
- );
- }
- };
-
- this.save = function() {
- var obj_list = this.source.getAllNodes().map(
- function(node) {
- var obj = node._user;
- if (obj.reader())
- obj.reader(obj.reader().id());
-
- return obj;
- }
- );
-
- this.save_button.attr("disabled", true);
-
- /* pcrud.apply *almost* could have handled this, but there's a reason
- * it doesn't, and it has to do with the unique key constraint on the
- * pos field in srlu objects.
- */
- try {
- fieldmapper.standardRequest(
- /* This method will set pos in ascending order. */
- ["open-ils.serial",
- "open-ils.serial.routing_list_users.replace"], {
- "params": [openils.User.authtoken, obj_list],
- "timeout": 10, /* sync */
- "oncomplete": function(r) {
- openils.Util.readResponse(r); /* display exceptions */
- }
- }
- );
- } catch (E) {
- alert(E); /* XXX i18n */
- }
-
- this.save_button.attr("disabled", false);
- };
-
- this._init = function(dialog) {
- this.dialog = dijit.byId("routing_list_dialog");
- this.source = routing_list_source;
-
- this.template = {};
- ["reader", "department", "note", "remove"].forEach(
- function(n) {
- self.template[n] =
- dojo.byId("routing_list_user_template_" + n).innerHTML;
- }
- );
-
- this.add_button = dijit.byId("routing_list_add_button");
- this.save_button = dijit.byId("routing_list_save_button");
-
- dijit.byId("reader_xor_dept-reader").onChange =
- _reader_xor_dept_toggle;
- dijit.byId("reader_xor_dept-department").onChange =
- _reader_xor_dept_toggle;
- };
-
- this._init.apply(this, arguments);
-}
-
-openils.Util.addOnLoad(
- function() {
- cgi = new openils.CGI();
- pcrud = new openils.PermaCrud();
- rlu_editor = new RLUEditor();
-
- dist_id = cgi.param("distribution");
- load_sdist_display();
- load_sstr_grid();
- }
-);
+require([
+ "dijit/form/Button",
+ "dijit/form/RadioButton",
+ "dijit/form/NumberSpinner",
+ "dijit/form/TextBox",
+ "dojo/dnd/Source",
+ "openils/widget/AutoGrid",
+ "openils/widget/ProgressDialog",
+ "openils/PermaCrud",
+ "openils/CGI"
+ ],
+function(dijit_form_Button,
+ dijit_form_RadioButton,
+ dijit_form_NumberSpinner,
+ dijit_form_TextBox,
+ dojo_dnd_Source,
+ openils_widget_AutoGrid,
+ openils_widget_ProgressDialog,
+ openils_PermaCrud,
+ openils_CGI){
+
+ var pcrud;
+ var dist_id;
+ var rlu_editor;
+ var cgi;
+
+ function format_routing_label(routing_label) {
+ return routing_label ? routing_label : "[None]";
+ }
+
+ function load_sstr_grid() {
+ sstr_grid.overrideEditWidgets.distribution =
+ new dijit_form_TextBox({"disabled": true, "value": dist_id});
+
+ sstr_grid.resetStore();
+ sstr_grid.loadAll(
+ {"order_by": {"ssub": "start_date DESC"}},
+ {"distribution": dist_id}
+ );
+ }
+
+ function load_sdist_display() {
+ pcrud.retrieve(
+ "sdist", dist_id, {
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ var link = dojo.byId("sdist_label_here");
+ link.onclick = function() {
+ location.href = oilsBasePath +
+ "/serial/subscription?id=" +
+ r.subscription() + "&tab=distributions";
+ }
+ link.innerHTML = r.label();
+ load_sdist_org_unit_display(r);
+ }
+ }
+ }
+ );
+ }
+
+ function load_sdist_org_unit_display(dist) {
+ dojo.byId("sdist_org_unit_name_here").innerHTML =
+ aou.findOrgUnit(dist.holding_lib()).name();
+ }
+
+ function create_many_streams(fields) {
+ var streams = [];
+ for (var i = 0; i < fields.quantity; i++) {
+ var stream = new sstr();
+ stream.distribution(dist_id);
+ streams.push(stream);
+ }
+
+ progress_dialog.show(true);
+ this.pcrud.create(
+ streams, {
+ "oncomplete": function(r, list) {
+ progress_dialog.hide();
+ sstr_grid.refresh();
+ },
+ "onerror": function(r) {
+ progress_dialog.hide();
+ alert("Error creating streams!"); /* XXX i18n */
+ }
+ }
+ );
+ }
+
+ function RLUEditor() {
+ var self = this;
+
+ function _reader_xor_dept_toggle(value) {
+ var reader = dijit.byId("reader");
+ var department = dijit.byId("department");
+
+ if (this.id.match(/\w+$/).pop() == "reader")
+ _reader_toggle(value, reader, department);
+ else
+ _department_toggle(value, reader, department);
+ }
+
+ function _reader_toggle(value, reader, department) {
+ if (value) {
+ reader.attr("disabled", false);
+ department.attr("disabled", true);
+ setTimeout(function() { reader.focus(); }, 125);
+ }
+ }
+
+ function _department_toggle(value, reader, department) {
+ if (value) {
+ reader.attr("disabled", true);
+ department.attr("disabled", false);
+ setTimeout(function() { department.focus(); }, 125);
+ }
+ }
+
+ this.user_to_source_entry = function(user) {
+ var node = dojo.create("li");
+ var s;
+ if (user.reader()) {
+ s = dojo.string.substitute(
+ this.template.reader, [
+ user.reader().card().barcode(),
+ user.reader().family_name(),
+ user.reader().first_given_name(),
+ user.reader().second_given_name(),
+ user.reader().home_ou().shortname()
+ ].map(function(o) { return o == null ? "" : o; })
+ );
+ } else {
+ s = dojo.string.substitute(
+ this.template.department, [user.department()]
+ );
+ }
+
+ if (user.note()) {
+ s += dojo.string.substitute(this.template.note, [user.note()]);
+ }
+
+ node.innerHTML = " " + s;
+
+ dojo.create(
+ "a", {
+ "href": "javascript:void(0);",
+ "onclick": function() { self.toggle_deleted(node); },
+ "innerHTML": this.template.remove
+ }, node, "first"
+ );
+
+ node._user = user;
+ return node;
+ };
+
+ this.toggle_deleted = function(node) {
+ if (node._user.isdeleted()) {
+ dojo.style(node, "textDecoration", "none");
+ node._user.isdeleted(false);
+ } else {
+ dojo.style(node, "textDecoration", "line-through");
+ node._user.isdeleted(true);
+ }
+ };
+
+ this.new_user = function() {
+ var form = this.dialog.attr("value");
+ var user = new fieldmapper.srlu();
+ user.isnew(true);
+ user.stream(this.stream);
+
+ if (form.note)
+ user.note(form.note);
+
+ if (form.department) {
+ user.department(form.department);
+ } else if (form.reader) {
+ this.add_button.attr("disabled", true);
+ fieldmapper.standardRequest(
+ ["open-ils.actor",
+ "open-ils.actor.user.fleshed.retrieve_by_barcode"], {
+ "params": [openils.User.authtoken, form.reader, true],
+ "timeout": 10, /* sync */
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ user.reader(r);
+ }
+ }
+ }
+ );
+ this.add_button.attr("disabled", false);
+ } else {
+ alert("Provide either a reader or a department."); /* XXX i18n */
+ return;
+ }
+
+ ["reader", "department", "note"].forEach(
+ function(s) { dijit.byId(s).attr("value", ""); }
+ );
+
+ this.source.insertNodes(false, [self.user_to_source_entry(user)]);
+ }
+
+ this.show = function() {
+ if (sstr_grid.getSelectedRows().length != 1) {
+ alert(
+ "Use the checkboxes to select exactly one stream " +
+ "for this operation." /* XXX i18n */
+ );
+ } else {
+ /* AutoGrid.getSelectedItems() yields a weird, non-FM object */
+ this.stream = sstr_grid.getSelectedItems()[0].id[0];
+
+ this.source.selectAll();
+ this.source.deleteSelectedNodes();
+ this.source.clearItems();
+
+ this.dialog.show();
+
+ fieldmapper.standardRequest(
+ ["open-ils.serial",
+ "open-ils.serial.routing_list_users.fleshed_and_ordered"], {
+ "params": [openils.User.authtoken, this.stream],
+ "async": true,
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ self.source.insertNodes(
+ false, [self.user_to_source_entry(r)]
+ );
+ }
+ },
+ "oncomplete": function() {
+ setTimeout(
+ function() { self.save_button.focus(); }, 125
+ );
+ }
+ }
+ );
+ }
+ };
+
+ this.save = function() {
+ var obj_list = this.source.getAllNodes().map(
+ function(node) {
+ var obj = node._user;
+ if (obj.reader())
+ obj.reader(obj.reader().id());
+
+ return obj;
+ }
+ );
+
+ this.save_button.attr("disabled", true);
+
+ /* pcrud.apply *almost* could have handled this, but there's a reason
+ * it doesn't, and it has to do with the unique key constraint on the
+ * pos field in srlu objects.
+ */
+ try {
+ fieldmapper.standardRequest(
+ /* This method will set pos in ascending order. */
+ ["open-ils.serial",
+ "open-ils.serial.routing_list_users.replace"], {
+ "params": [openils.User.authtoken, obj_list],
+ "timeout": 10, /* sync */
+ "oncomplete": function(r) {
+ openils.Util.readResponse(r); /* display exceptions */
+ }
+ }
+ );
+ } catch (E) {
+ alert(E); /* XXX i18n */
+ }
+
+ this.save_button.attr("disabled", false);
+ };
+
+ this._init = function(dialog) {
+ this.dialog = dijit.byId("routing_list_dialog");
+ this.source = routing_list_source;
+
+ this.template = {};
+ ["reader", "department", "note", "remove"].forEach(
+ function(n) {
+ self.template[n] =
+ dojo.byId("routing_list_user_template_" + n).innerHTML;
+ }
+ );
+
+ this.add_button = dijit.byId("routing_list_add_button");
+ this.save_button = dijit.byId("routing_list_save_button");
+
+ dijit.byId("reader_xor_dept-reader").onChange =
+ _reader_xor_dept_toggle;
+ dijit.byId("reader_xor_dept-department").onChange =
+ _reader_xor_dept_toggle;
+ };
+
+ this._init.apply(this, arguments);
+ }
+
+ openils.Util.addOnLoad(
+ function() {
+ cgi = new openils_CGI();
+ pcrud = new openils_PermaCrud();
+ rlu_editor = new RLUEditor();
+
+ dist_id = cgi.param("distribution");
+ load_sdist_display();
+ load_sstr_grid();
+ }
+ );
+
+
+});
\ No newline at end of file
-dojo.require("dijit.form.Button");
-dojo.require("openils.widget.AutoGrid");
-dojo.require("openils.widget.OrgUnitFilteringSelect");
-dojo.require("openils.BibTemplate");
-dojo.require("openils.CGI");
+require([
+ "dijit/form/Button",
+ "openils/widget/AutoGrid",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/BibTemplate",
+ "openils/CGI"
+ ],
+function(dijit_form_Button,
+ openils_widget_AutoGrid,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_BibTemplate,
+ openils_CGI){
+
+ var terms;
+ var cgi;
+
+ function format_ssub_link(id) {
+ return "<a href='" + oilsBasePath + "/serial/subscription?id=" +
+ id + "'>" + id + "</a>";
+ }
+
+ function load_ssub_grid() {
+ ssub_grid.resetStore();
+ ssub_grid.loadAll({"order_by": {"ssub": "start_date DESC"}}, terms);
+ }
+
+ openils.Util.addOnLoad(
+ function() {
+ cgi = new openils_CGI();
+
+ terms = {
+ "owning_lib": aou.orgNodeTrail(
+ aou.findOrgUnit(openils.User.user.ws_ou()),
+ true /* asId */
+ ),
+ "record_entry": cgi.param("record_entry") || _fallback_record_entry
+ };
+
+ if (terms.record_entry)
+ new openils_BibTemplate({"record": terms.record_entry}).render();
+
+ /* This should be present even if terms.record_entry is undef */
+ ssub_grid.overrideEditWidgets.record_entry = new dijit.form.TextBox(
+ {"value": terms.record_entry, "disabled": true}
+ );
+
+ new openils.User().buildPermOrgSelector(
+ "ADMIN_SERIAL_SUBSCRIPTION",
+ ssub_owner_select,
+ null,
+ function() {
+ dojo.connect(
+ ssub_owner_select,
+ "onChange",
+ function() {
+ terms.owning_lib = aou.orgNodeTrail(
+ aou.findOrgUnit(this.attr("value")),
+ true /* asId */
+ );
+ load_ssub_grid();
+ }
+ );
+ load_ssub_grid();
+ }
+ );
+ }
+ );
+
-var terms;
-var cgi;
-
-function format_ssub_link(id) {
- return "<a href='" + oilsBasePath + "/serial/subscription?id=" +
- id + "'>" + id + "</a>";
-}
-
-function load_ssub_grid() {
- ssub_grid.resetStore();
- ssub_grid.loadAll({"order_by": {"ssub": "start_date DESC"}}, terms);
-}
-
-openils.Util.addOnLoad(
- function() {
- cgi = new openils.CGI();
-
- terms = {
- "owning_lib": aou.orgNodeTrail(
- aou.findOrgUnit(openils.User.user.ws_ou()),
- true /* asId */
- ),
- "record_entry": cgi.param("record_entry") || _fallback_record_entry
- };
-
- if (terms.record_entry)
- new openils.BibTemplate({"record": terms.record_entry}).render();
-
- /* This should be present even if terms.record_entry is undef */
- ssub_grid.overrideEditWidgets.record_entry = new dijit.form.TextBox(
- {"value": terms.record_entry, "disabled": true}
- );
-
- new openils.User().buildPermOrgSelector(
- "ADMIN_SERIAL_SUBSCRIPTION",
- ssub_owner_select,
- null,
- function() {
- dojo.connect(
- ssub_owner_select,
- "onChange",
- function() {
- terms.owning_lib = aou.orgNodeTrail(
- aou.findOrgUnit(this.attr("value")),
- true /* asId */
- );
- load_ssub_grid();
- }
- );
- load_ssub_grid();
- }
- );
- }
-);
+});
\ No newline at end of file
-dojo.require("dojo.string");
-
-var list_renderer;
-
-function n(name, ctx) { return dojo.query("[name='" + name + "']", ctx)[0]; }
-
-function ListRenderer() {
- var self = this;
-
- this.render = function() {
- for (var i = 0; i < this.streams.length; i++) {
- var stream = this.streams[i];
-
- if (!this.users_by_stream[stream.id()])
- continue; /* no users on this stream */
-
- var list = dojo.clone(this.list_template);
- n("title", list).innerHTML = this.mvr.title();
- n("issuance_label", list).innerHTML = this.issuance.label();
- n("distribution_holding_lib", list).innerHTML =
- stream.distribution().holding_lib().shortname();
- n("distribution_label", list).innerHTML =
- stream.distribution().label();
- if (stream.routing_label()) {
- n("stream_routing_label", list).innerHTML =
- stream.routing_label();
- openils.Util.show(
- n("stream_routing_label", list), "inline"
- );
- } else {
- n("stream_id", list).innerHTML = stream.id();
- openils.Util.show(n("stream_id_container", list), "inline");
- }
-
- this.render_users(stream, list);
-
- if (i) {
- dojo.create(
- "hr",
- {"style": "page-break-after: always"}, this.target, "last"
- );
- }
-
- dojo.place(list, this.target, "last");
- }
-
- return this; /* for chaining */
- };
-
- this.render_users = function(stream, list) {
- for (var i = 0; i < this.users_by_stream[stream.id()].length; i++) {
- var user = this.users_by_stream[stream.id()][i];
- var node = dojo.clone(this.user_template);
-
- if (user.reader()) {
- n("barcode", node).innerHTML = user.reader().card().barcode();
- n("name", node).innerHTML = dojo.string.substitute(
- "${0}, ${1} ${2}", [
- user.reader().family_name(),
- user.reader().first_given_name(),
- user.reader().second_given_name()
- ].map(function(n) { return n || ""; })
- );
- n("ou", node).innerHTML = user.reader().home_ou().shortname();
- openils.Util.show(n("reader_container", node), "inline");
- } else if (user.department()) {
- n("department", node).innerHTML = user.department();
- openils.Util.show(n("department_container", node), "inline");
- }
-
- if (user.note()) {
- n("note", node).innerHTML = user.note();
- openils.Util.show(n("note_container", node), "inline");
- }
-
- dojo.place(node, n("users", list), "last");
- }
- };
-
- this.print = function() {
- this.print_target.print();
- }
-
- this._sort_users = function() {
- this.users_by_stream = {};
- this.users.forEach(
- function(user) {
- var key = user.stream();
- if (!self.users_by_stream[key])
- self.users_by_stream[key] = [];
- self.users_by_stream[key].push(user);
- }
- );
- };
-
- /* Unfortunately, when we print the main window with dijits
- * wrapping everything, the page-break-* CSS properties don't work
- * inside of there, so we need an iframe to print from.
- */
- this._prepare_iframe = function() {
- var iframe = dojo.create(
- "iframe", {
- "src": "", "width": "100%", "height": "500", "frameborder": 0
- }, "iframe_in_here", "only"
- );
-
- iframe.contentWindow.document.open();
- iframe.contentWindow.document.write(
- "<html><head><style type='text/css'>" +
- ".item-title { font-size: 130%; font-weight: bold; }\n" +
- ".item-issuance-label { font-size: 120%; }\n" +
- ".item-dist-and-stream { font-size: 110%; }\n" +
- ".hidden { display: none; }\n" +
- "</style></head>\n<body></body></html>"
- );
- iframe.contentWindow.document.close();
- this.target = iframe.contentWindow.document.body;
- this.print_target = iframe.contentWindow;
- };
-
- this._init = function(data) {
- this.user_template = dojo.byId("user_template");
- this.user_template.removeAttribute("id");
- this.user_template.parentNode.removeChild(this.user_template);
-
- this.list_template = dojo.byId("list_template");
- this.list_template.removeAttribute("id");
- this.list_template.parentNode.removeChild(this.list_template);
-
- dojo.mixin(this, data);
-
- this._sort_users();
- this._prepare_iframe();
- }
-
- this._init.apply(this, arguments);
-}
-
-openils.Util.addOnLoad(
- function() {
- if (!xulG) {
- alert(
- "This interface is not designed for use outside " +
- "the staff client." /* XXX i18n */
- );
- } else {
- list_renderer = new ListRenderer(xulG.routing_list_data);
- list_renderer.render().print();
- }
- }
-);
+require([
+ "dojo/string"
+ ],
+function(dojo_string){
+
+ var list_renderer;
+
+ function n(name, ctx) { return dojo.query("[name='" + name + "']", ctx)[0]; }
+
+ function ListRenderer() {
+ var self = this;
+
+ this.render = function() {
+ for (var i = 0; i < this.streams.length; i++) {
+ var stream = this.streams[i];
+
+ if (!this.users_by_stream[stream.id()])
+ continue; /* no users on this stream */
+
+ var list = dojo.clone(this.list_template);
+ n("title", list).innerHTML = this.mvr.title();
+ n("issuance_label", list).innerHTML = this.issuance.label();
+ n("distribution_holding_lib", list).innerHTML =
+ stream.distribution().holding_lib().shortname();
+ n("distribution_label", list).innerHTML =
+ stream.distribution().label();
+ if (stream.routing_label()) {
+ n("stream_routing_label", list).innerHTML =
+ stream.routing_label();
+ openils.Util.show(
+ n("stream_routing_label", list), "inline"
+ );
+ } else {
+ n("stream_id", list).innerHTML = stream.id();
+ openils.Util.show(n("stream_id_container", list), "inline");
+ }
+
+ this.render_users(stream, list);
+
+ if (i) {
+ dojo.create(
+ "hr",
+ {"style": "page-break-after: always"}, this.target, "last"
+ );
+ }
+
+ dojo.place(list, this.target, "last");
+ }
+
+ return this; /* for chaining */
+ };
+
+ this.render_users = function(stream, list) {
+ for (var i = 0; i < this.users_by_stream[stream.id()].length; i++) {
+ var user = this.users_by_stream[stream.id()][i];
+ var node = dojo.clone(this.user_template);
+
+ if (user.reader()) {
+ n("barcode", node).innerHTML = user.reader().card().barcode();
+ n("name", node).innerHTML = dojo_string.substitute(
+ "${0}, ${1} ${2}", [
+ user.reader().family_name(),
+ user.reader().first_given_name(),
+ user.reader().second_given_name()
+ ].map(function(n) { return n || ""; })
+ );
+ n("ou", node).innerHTML = user.reader().home_ou().shortname();
+ openils.Util.show(n("reader_container", node), "inline");
+ } else if (user.department()) {
+ n("department", node).innerHTML = user.department();
+ openils.Util.show(n("department_container", node), "inline");
+ }
+
+ if (user.note()) {
+ n("note", node).innerHTML = user.note();
+ openils.Util.show(n("note_container", node), "inline");
+ }
+
+ dojo.place(node, n("users", list), "last");
+ }
+ };
+
+ this.print = function() {
+ this.print_target.print();
+ }
+
+ this._sort_users = function() {
+ this.users_by_stream = {};
+ this.users.forEach(
+ function(user) {
+ var key = user.stream();
+ if (!self.users_by_stream[key])
+ self.users_by_stream[key] = [];
+ self.users_by_stream[key].push(user);
+ }
+ );
+ };
+
+ /* Unfortunately, when we print the main window with dijits
+ * wrapping everything, the page-break-* CSS properties don't work
+ * inside of there, so we need an iframe to print from.
+ */
+ this._prepare_iframe = function() {
+ var iframe = dojo.create(
+ "iframe", {
+ "src": "", "width": "100%", "height": "500", "frameborder": 0
+ }, "iframe_in_here", "only"
+ );
+
+ iframe.contentWindow.document.open();
+ iframe.contentWindow.document.write(
+ "<html><head><style type='text/css'>" +
+ ".item-title { font-size: 130%; font-weight: bold; }\n" +
+ ".item-issuance-label { font-size: 120%; }\n" +
+ ".item-dist-and-stream { font-size: 110%; }\n" +
+ ".hidden { display: none; }\n" +
+ "</style></head>\n<body></body></html>"
+ );
+ iframe.contentWindow.document.close();
+ this.target = iframe.contentWindow.document.body;
+ this.print_target = iframe.contentWindow;
+ };
+
+ this._init = function(data) {
+ this.user_template = dojo.byId("user_template");
+ this.user_template.removeAttribute("id");
+ this.user_template.parentNode.removeChild(this.user_template);
+
+ this.list_template = dojo.byId("list_template");
+ this.list_template.removeAttribute("id");
+ this.list_template.parentNode.removeChild(this.list_template);
+
+ dojo.mixin(this, data);
+
+ this._sort_users();
+ this._prepare_iframe();
+ }
+
+ this._init.apply(this, arguments);
+ }
+
+ openils.Util.addOnLoad(
+ function() {
+ if (!xulG) {
+ alert(
+ "This interface is not designed for use outside " +
+ "the staff client." /* XXX i18n */
+ );
+ } else {
+ list_renderer = new ListRenderer(xulG.routing_list_data);
+ list_renderer.render().print();
+ }
+ }
+ );
+
+
+});
\ No newline at end of file
-dojo.require("dijit.form.Button");
-dojo.require("dijit.form.RadioButton");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("dijit.form.DropDownButton");
-dojo.require("dijit.TooltipDialog");
-dojo.require("dijit.layout.TabContainer");
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dojox.grid.DataGrid");
-dojo.require("openils.widget.AutoGrid");
-dojo.require("openils.widget.ProgressDialog");
-dojo.require("openils.widget.HoldingCode");
-dojo.require("openils.PermaCrud");
-dojo.require("openils.CGI");
+require([
+ "dijit/form/Button",
+ "dijit/form/RadioButton",
+ "dijit/form/FilteringSelect",
+ "dijit/form/DropDownButton",
+ "dijit/TooltipDialog",
+ "dijit/layout/TabContainer",
+ "dijit/layout/ContentPane",
+ "dojox/grid/DataGrid",
+ "openils/widget/AutoGrid",
+ "openils/widget/ProgressDialog",
+ "openils/widget/HoldingCode",
+ "openils/PermaCrud",
+ "openils/CGI"
+ ],
+function(dijit_form_Button,
+ dijit_form_RadioButton,
+ dijit_form_FilteringSelect,
+ dijit_form_DropDownButton,
+ dijit_TooltipDialog,
+ dijit_layout_TabContainer,
+ dijit_layout_ContentPane,
+ dojox_grid_DataGrid,
+ openils_widget_AutoGrid,
+ openils_widget_ProgressDialog,
+ openils_widget_HoldingCode,
+ openils_PermaCrud,
+ openils_CGI){
+
+ var pcrud;
+ var cgi;
+ var sub;
+ var sub_id;
+
+ function node_by_name(name, ctx) {
+ return dojo.query("[name='" + name + "']", ctx)[0];
+ }
+
+ /* typing save: add {get,set}Value() to all HTML <select> elements */
+ HTMLSelectElement.prototype.getValue = function() {
+ return this.options[this.selectedIndex].value;
+ }
+ HTMLSelectElement.prototype.setValue = function(s) {
+ for (var i = 0; i < this.options.length; i++) {
+ if (s == this.options[i].value) {
+ this.selectedIndex = i;
+ break;
+ }
+ }
+ }
+
+ function load_sub_grid(id, oncomplete) {
+ if (!pcrud) return; /* first run, onLoad hasn't fired yet */
+ if (!sub_grid._fresh) {
+ var dist_ids = pcrud.search(
+ "sdist", {"subscription": id}, {"id_list": true}
+ );
+ pcrud.retrieve(
+ "ssub", id, {
+ "onresponse": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ sub = r;
+ var data = ssub.toStoreData([r]);
+ data.items[0].num_dist = dist_ids ? dist_ids.length : 0;
+ sub_grid.setStore(
+ new dojo.data.ItemFileReadStore({"data": data})
+ );
+ sub_grid._fresh = true;
+ }
+ },
+ "oncomplete": function() {
+ if (oncomplete) oncomplete();
+ }
+ }
+ );
+ }
+ }
+
+ /* TODO: make these formatters caching */
+ function format_bib(bib_id) {
+ if (!bib_id) {
+ return "";
+ } else {
+ var result;
+ fieldmapper.standardRequest(
+ ["open-ils.search",
+ "open-ils.search.biblio.record.mods_slim.retrieve"], {
+ "async": false,
+ "params": [bib_id],
+ "oncomplete": function(r) {
+ if (r = openils.Util.readResponse(r)) {
+ var parts = [];
+ if (r.title())
+ parts.push(r.title());
+ if (r.author())
+ parts.push(r.author());
+ if (r.author())
+ parts.push(r.publisher());
+
+ if (!parts.length)
+ parts.push(r.tcn());
+
+ result = parts.join(" / ");
+ }
+ }
+ }
+ );
+ return "<a href='" + oilsBasePath +
+ "/serial/list_subscription?record_entry=" + bib_id + "'>" +
+ result + "</a>";
+ }
+ }
+
+ function format_date(s) {
+ return s ? openils.Util.timeStamp(s, {"selector": "date"}) : "";
+ }
+
+ function format_org_unit(aou_id) {
+ return aou_id ? aou.findOrgUnit(aou_id).shortname() : "";
+ }
+
+ function get_id_and_label(rowIndex, item) {
+ if (!item) return {"id": "", "label": ""};
+ return {
+ "id": this.grid.store.getValue(item, "id"),
+ "label": this.grid.store.getValue(item, "label")
+ };
+ }
+
+ function format_siss_label(blob) {
+ if (!blob.id) return "";
+ return "<a href='" +
+ oilsBasePath + "/serial/list_item?issuance=" + blob.id +
+ "'>" + (blob.label ? blob.label : "[None]") + "</a>"; /* XXX i18n */
+ }
+
+ function format_sdist_label(blob) {
+ if (!blob.id) return "";
+ var link = "<a href='" +
+ oilsBasePath + "/serial/list_stream?distribution=" + blob.id +
+ "'>" + (blob.label ? blob.label : "[None]") + "</a>"; /* XXX i18n */
+
+ var sstr_list = pcrud.search(
+ "sstr",{"distribution":blob.id},{"id_list":true}
+ );
+ count = sstr_list ? sstr_list.length : 0;
+ link += " " + count + " stream(s)";
+ return link;
+ }
+
+ function append_stream_count(dist_id) {
+ var span = dojo.byId("dist_link_" + dist_id);
+ if (span.childNodes.length) /* textNodes count as childnodes */
+ return;
+ pcrud.search(
+ "sstr", {"distribution": dist_id}, {
+ "id_list": true,
+ "oncomplete": function(r) {
+ var resp = openils.Util.readResponse(r);
+ var count = resp ? resp.length : 0;
+
+ /* XXX i18n */
+ span.innerHTML = " " + count + " stream(s)";
+ }
+ }
+ );
+ }
+
+ function open_batch_receive() {
+ if (!sub) {
+ alert("Let the interface load all the way first.");
+ return;
+ }
+
+ var url = "/xul/server/serial/batch_receive.xul?docid=" +
+ sub.record_entry() + "&subid=" + sub.id();
+
+ try {
+ openils.XUL.newTabEasy(url, "Batch Receive"); /* XXX i18n */
+ } catch (E) {
+ location.href = url;
+ }
+ }
+
+ function toggle_clone_ident_field(dij) {
+ setTimeout(
+ function() {
+ var disabled = !dij.attr("checked");
+ clone_ident.attr("disabled", disabled);
+ if (!disabled) clone_ident.focus();
+ }, 175
+ );
+ }
+
+ function clone_subscription(form) {
+ if (form.use_ident == "yes") {
+ fieldmapper.standardRequest(
+ ["open-ils.serial",
+ "open-ils.serial.biblio.record_entry.by_identifier.atomic"], {
+ "params": [form.ident, {"id_list": true}],
+ "async": true,
+ "oncomplete": function(r) {
+ r = openils.Util.readResponse(r);
+ if (!r || !r.length) {
+ alert("No matches for that indentifier."); /*XXX i18n*/
+ } else if (r.length != 1) {
+ alert("Too many matches for that identifier. Use a " +
+ "unique identifier."); /* XXX i18n */
+ } else {
+ _clone_subscription(r[0]);
+ }
+ }
+ }
+ );
+ } else {
+ _clone_subscription();
+ }
+ }
+
+ function _clone_subscription(bre_id) {
+ progress_dialog.show(true);
+
+ fieldmapper.standardRequest(
+ ["open-ils.serial", "open-ils.serial.subscription.clone"], {
+ "params": [openils.User.authtoken, sub_id, bre_id],
+ "async": false,
+ "oncomplete": function(r) {
+ progress_dialog.hide();
+ if (!(r = openils.Util.readResponse(r))) {
+ alert("Error cloning subscription."); /* XXX i18n */
+ } else {
+ location.href =
+ oilsBasePath + "/serial/subscription?id=" + r;
+ }
+
+ /* cloning doesn't clone holdings, so nothing changes at
+ * OPAC view just because of this, so no need to try
+ * reload_opac(). */
+ }
+ }
+ );
+ }
+
+ openils.Util.addOnLoad(
+ function() {
+ var tab_dispatch = {
+ "distributions": distributions_tab,
+ "issuances": issuances_tab
+ };
+
+ cgi = new openils_CGI();
+ pcrud = new openils_PermaCrud();
+
+ sub_id = cgi.param("id");
+ load_sub_grid(
+ sub_id,
+ (cgi.param("tab") in tab_dispatch) ?
+ function() {
+ tab_container.selectChild(
+ tab_dispatch[cgi.param("tab")]
+ );
+ } : null
+ );
+ }
+ );
+
-var pcrud;
-var cgi;
-var sub;
-var sub_id;
-
-function node_by_name(name, ctx) {
- return dojo.query("[name='" + name + "']", ctx)[0];
-}
-
-/* typing save: add {get,set}Value() to all HTML <select> elements */
-HTMLSelectElement.prototype.getValue = function() {
- return this.options[this.selectedIndex].value;
-}
-HTMLSelectElement.prototype.setValue = function(s) {
- for (var i = 0; i < this.options.length; i++) {
- if (s == this.options[i].value) {
- this.selectedIndex = i;
- break;
- }
- }
-}
-
-function load_sub_grid(id, oncomplete) {
- if (!pcrud) return; /* first run, onLoad hasn't fired yet */
- if (!sub_grid._fresh) {
- var dist_ids = pcrud.search(
- "sdist", {"subscription": id}, {"id_list": true}
- );
- pcrud.retrieve(
- "ssub", id, {
- "onresponse": function(r) {
- if (r = openils.Util.readResponse(r)) {
- sub = r;
- var data = ssub.toStoreData([r]);
- data.items[0].num_dist = dist_ids ? dist_ids.length : 0;
- sub_grid.setStore(
- new dojo.data.ItemFileReadStore({"data": data})
- );
- sub_grid._fresh = true;
- }
- },
- "oncomplete": function() {
- if (oncomplete) oncomplete();
- }
- }
- );
- }
-}
-
-/* TODO: make these formatters caching */
-function format_bib(bib_id) {
- if (!bib_id) {
- return "";
- } else {
- var result;
- fieldmapper.standardRequest(
- ["open-ils.search",
- "open-ils.search.biblio.record.mods_slim.retrieve"], {
- "async": false,
- "params": [bib_id],
- "oncomplete": function(r) {
- if (r = openils.Util.readResponse(r)) {
- var parts = [];
- if (r.title())
- parts.push(r.title());
- if (r.author())
- parts.push(r.author());
- if (r.author())
- parts.push(r.publisher());
-
- if (!parts.length)
- parts.push(r.tcn());
-
- result = parts.join(" / ");
- }
- }
- }
- );
- return "<a href='" + oilsBasePath +
- "/serial/list_subscription?record_entry=" + bib_id + "'>" +
- result + "</a>";
- }
-}
-
-function format_date(s) {
- return s ? openils.Util.timeStamp(s, {"selector": "date"}) : "";
-}
-
-function format_org_unit(aou_id) {
- return aou_id ? aou.findOrgUnit(aou_id).shortname() : "";
-}
-
-function get_id_and_label(rowIndex, item) {
- if (!item) return {"id": "", "label": ""};
- return {
- "id": this.grid.store.getValue(item, "id"),
- "label": this.grid.store.getValue(item, "label")
- };
-}
-
-function format_siss_label(blob) {
- if (!blob.id) return "";
- return "<a href='" +
- oilsBasePath + "/serial/list_item?issuance=" + blob.id +
- "'>" + (blob.label ? blob.label : "[None]") + "</a>"; /* XXX i18n */
-}
-
-function format_sdist_label(blob) {
- if (!blob.id) return "";
- var link = "<a href='" +
- oilsBasePath + "/serial/list_stream?distribution=" + blob.id +
- "'>" + (blob.label ? blob.label : "[None]") + "</a>"; /* XXX i18n */
-
- var sstr_list = pcrud.search(
- "sstr",{"distribution":blob.id},{"id_list":true}
- );
- count = sstr_list ? sstr_list.length : 0;
- link += " " + count + " stream(s)";
- return link;
-}
-
-function append_stream_count(dist_id) {
- var span = dojo.byId("dist_link_" + dist_id);
- if (span.childNodes.length) /* textNodes count as childnodes */
- return;
- pcrud.search(
- "sstr", {"distribution": dist_id}, {
- "id_list": true,
- "oncomplete": function(r) {
- var resp = openils.Util.readResponse(r);
- var count = resp ? resp.length : 0;
-
- /* XXX i18n */
- span.innerHTML = " " + count + " stream(s)";
- }
- }
- );
-}
-
-function open_batch_receive() {
- if (!sub) {
- alert("Let the interface load all the way first.");
- return;
- }
-
- var url = "/xul/server/serial/batch_receive.xul?docid=" +
- sub.record_entry() + "&subid=" + sub.id();
-
- try {
- openils.XUL.newTabEasy(url, "Batch Receive"); /* XXX i18n */
- } catch (E) {
- location.href = url;
- }
-}
-
-function toggle_clone_ident_field(dij) {
- setTimeout(
- function() {
- var disabled = !dij.attr("checked");
- clone_ident.attr("disabled", disabled);
- if (!disabled) clone_ident.focus();
- }, 175
- );
-}
-
-function clone_subscription(form) {
- if (form.use_ident == "yes") {
- fieldmapper.standardRequest(
- ["open-ils.serial",
- "open-ils.serial.biblio.record_entry.by_identifier.atomic"], {
- "params": [form.ident, {"id_list": true}],
- "async": true,
- "oncomplete": function(r) {
- r = openils.Util.readResponse(r);
- if (!r || !r.length) {
- alert("No matches for that indentifier."); /*XXX i18n*/
- } else if (r.length != 1) {
- alert("Too many matches for that identifier. Use a " +
- "unique identifier."); /* XXX i18n */
- } else {
- _clone_subscription(r[0]);
- }
- }
- }
- );
- } else {
- _clone_subscription();
- }
-}
-
-function _clone_subscription(bre_id) {
- progress_dialog.show(true);
-
- fieldmapper.standardRequest(
- ["open-ils.serial", "open-ils.serial.subscription.clone"], {
- "params": [openils.User.authtoken, sub_id, bre_id],
- "async": false,
- "oncomplete": function(r) {
- progress_dialog.hide();
- if (!(r = openils.Util.readResponse(r))) {
- alert("Error cloning subscription."); /* XXX i18n */
- } else {
- location.href =
- oilsBasePath + "/serial/subscription?id=" + r;
- }
-
- /* cloning doesn't clone holdings, so nothing changes at
- * OPAC view just because of this, so no need to try
- * reload_opac(). */
- }
- }
- );
-}
-
-openils.Util.addOnLoad(
- function() {
- var tab_dispatch = {
- "distributions": distributions_tab,
- "issuances": issuances_tab
- };
-
- cgi = new openils.CGI();
- pcrud = new openils.PermaCrud();
-
- sub_id = cgi.param("id");
- load_sub_grid(
- sub_id,
- (cgi.param("tab") in tab_dispatch) ?
- function() {
- tab_container.selectChild(
- tab_dispatch[cgi.param("tab")]
- );
- } : null
- );
- }
-);
+});
\ No newline at end of file
-dojo.require("dijit.form.DateTextBox");
+require([
+ "dijit/form/DateTextBox"
+ ],
+function(dijit_form_DateTextBox){
+
+ function fresh_scap_selector(grid) {
+ /* this really needs to be sync, not async */
+ pcrud.search(
+ "scap", {"subscription": sub_id, "active": "t"}, {
+ "timeout": 10,
+ "oncomplete": function(r) {
+ var data = scap.toStoreData(openils.Util.readResponse(r));
+ var selector = new dijit.form.FilteringSelect(
+ {
+ "store": new dojo.data.ItemFileReadStore({"data":data}),
+ "searchAttr": "id"
+ },
+ dojo.create("span")
+ );
+ selector.shove = {
+ "create": data.items.length ? data.items[0].id : ""
+ };
+ dojo.connect(
+ selector, "onChange", null, function() {
+ if (this.item) {
+ var widget =
+ iss_grid.overrideEditWidgets.holding_type;
+ widget.attr("value", this.item.type);
+ widget.attr("disabled", true);
+ }
+ }
+ );
+
+ grid.overrideEditWidgets.caption_and_pattern = selector;
+ if (grid.overrideEditWidgets.holding_code) {
+ grid.overrideEditWidgets.holding_code.update_scap_selector(
+ selector
+ );
+ } else {
+ grid.overrideEditWidgets.holding_code =
+ new openils.widget.HoldingCode({
+ "scap_selector": selector
+ });
+ grid.overrideEditWidgets.holding_code.shove = {
+ "create": "[]"
+ };
+ grid.overrideEditWidgets.holding_code.startup();
+ }
+
+ grid.overrideEditWidgets.date_published =
+ new dijit_form_DateTextBox();
+ grid.overrideEditWidgets.date_published.shove = {};
+ grid.overrideEditWidgets.holding_code.date_widget =
+ grid.overrideEditWidgets.date_published;
+ }
+ }
+ );
+ }
+
+ function prepare_prediction_dialog() {
+ if (sub.end_date()) {
+ prediction_dialog_end_date.attr("disabled", false);
+ prediction_dialog_end_date.attr("checked", true);
+ } else {
+ prediction_dialog_end_num.attr("checked", true);
+ prediction_dialog_end_date.attr("disabled", true);
+ prediction_dialog_num_to_predict.focus();
+ }
+ prediction_dialog_submit.attr("disabled", false);
+ }
+
+ function generate_predictions(fields) {
+ var args = {"ssub_id": sub.id()};
+
+ if (fields.end_how == "date") {
+ args.end_date = sub.end_date();
+ } else if ((num = Number(fields.num_to_predict)) > 0) {
+ args.num_to_predict = num;
+ } else {
+ alert("Go with a whole, positive number."); /* XXX i18n */
+ return;
+ }
+
+ progress_dialog.show(true);
+ try {
+ fieldmapper.standardRequest(
+ ["open-ils.serial", "open-ils.serial.make_predictions"], {
+ "params": [openils.User.authtoken, args],
+ "async": true,
+ "onresponse": function(r) {
+ openils.Util.readResponse(r); /* tests for events */
+ },
+ "oncomplete": function() {
+ progress_dialog.hide();
+ iss_grid.refresh();
+ }
+ }
+ );
+ } catch (E) {
+ alert(E);
+ progess_dialog.hide();
+ }
+ }
+
-function fresh_scap_selector(grid) {
- /* this really needs to be sync, not async */
- pcrud.search(
- "scap", {"subscription": sub_id, "active": "t"}, {
- "timeout": 10,
- "oncomplete": function(r) {
- var data = scap.toStoreData(openils.Util.readResponse(r));
- var selector = new dijit.form.FilteringSelect(
- {
- "store": new dojo.data.ItemFileReadStore({"data":data}),
- "searchAttr": "id"
- },
- dojo.create("span")
- );
- selector.shove = {
- "create": data.items.length ? data.items[0].id : ""
- };
- dojo.connect(
- selector, "onChange", null, function() {
- if (this.item) {
- var widget =
- iss_grid.overrideEditWidgets.holding_type;
- widget.attr("value", this.item.type);
- widget.attr("disabled", true);
- }
- }
- );
-
- grid.overrideEditWidgets.caption_and_pattern = selector;
- if (grid.overrideEditWidgets.holding_code) {
- grid.overrideEditWidgets.holding_code.update_scap_selector(
- selector
- );
- } else {
- grid.overrideEditWidgets.holding_code =
- new openils.widget.HoldingCode({
- "scap_selector": selector
- });
- grid.overrideEditWidgets.holding_code.shove = {
- "create": "[]"
- };
- grid.overrideEditWidgets.holding_code.startup();
- }
-
- grid.overrideEditWidgets.date_published =
- new dijit.form.DateTextBox();
- grid.overrideEditWidgets.date_published.shove = {};
- grid.overrideEditWidgets.holding_code.date_widget =
- grid.overrideEditWidgets.date_published;
- }
- }
- );
-}
-
-function prepare_prediction_dialog() {
- if (sub.end_date()) {
- prediction_dialog_end_date.attr("disabled", false);
- prediction_dialog_end_date.attr("checked", true);
- } else {
- prediction_dialog_end_num.attr("checked", true);
- prediction_dialog_end_date.attr("disabled", true);
- prediction_dialog_num_to_predict.focus();
- }
- prediction_dialog_submit.attr("disabled", false);
-}
-
-function generate_predictions(fields) {
- var args = {"ssub_id": sub.id()};
-
- if (fields.end_how == "date") {
- args.end_date = sub.end_date();
- } else if ((num = Number(fields.num_to_predict)) > 0) {
- args.num_to_predict = num;
- } else {
- alert("Go with a whole, positive number."); /* XXX i18n */
- return;
- }
-
- progress_dialog.show(true);
- try {
- fieldmapper.standardRequest(
- ["open-ils.serial", "open-ils.serial.make_predictions"], {
- "params": [openils.User.authtoken, args],
- "async": true,
- "onresponse": function(r) {
- openils.Util.readResponse(r); /* tests for events */
- },
- "oncomplete": function() {
- progress_dialog.hide();
- iss_grid.refresh();
- }
- }
- );
- } catch (E) {
- alert(E);
- progess_dialog.hide();
- }
-}
+});
\ No newline at end of file
-/* ---------------------------------------------------------------------------
-# Copyright (C) 2008 Georgia Public Library Service
-# Bill Erickson <erickson@esilibrary.com>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-# --------------------------------------------------------------------------- */
-dojo.require("dojo.parser");
-dojo.require("dojo.io.iframe");
-dojo.require("dijit.ProgressBar");
-dojo.require("dijit.form.FilteringSelect");
-dojo.require("dijit.layout.ContentPane");
-dojo.require("dijit.layout.TabContainer");
-dojo.require("dijit.layout.LayoutContainer");
-dojo.require('dijit.form.Button');
-dojo.require('dijit.form.CheckBox');
-dojo.require('dijit.Toolbar');
-dojo.require('dijit.Tooltip');
-dojo.require('dijit.Menu');
-dojo.require("dijit.Dialog");
-dojo.require("dojo.cookie");
-dojo.require('dojox.grid.DataGrid');
-dojo.require("dojo.data.ItemFileReadStore");
-dojo.require('dojo.date.locale');
-dojo.require('dojo.date.stamp');
-dojo.require("fieldmapper.Fieldmapper");
-dojo.require("fieldmapper.dojoData");
-dojo.require("fieldmapper.OrgUtils");
-dojo.require('openils.CGI');
-dojo.require('openils.User');
-dojo.require('openils.Event');
-dojo.require('openils.Util');
-dojo.require('openils.MarcXPathParser');
-dojo.require('openils.widget.GridColumnPicker');
-dojo.require('openils.PermaCrud');
-dojo.require('openils.widget.OrgUnitFilteringSelect');
-dojo.require('openils.widget.AutoGrid');
-dojo.require('openils.widget.AutoFieldWidget');
-dojo.require('openils.widget.ProgressDialog');
-
-
-var globalDivs = [
- 'vl-generic-progress',
- 'vl-generic-progress-with-total',
- 'vl-marc-upload-div',
- 'vl-queue-div',
- 'vl-match-div',
- 'vl-marc-html-div',
- 'vl-queue-select-div',
- 'vl-marc-upload-status-div',
- 'vl-attr-editor-div',
- 'vl-marc-export-div',
- 'vl-profile-editor-div',
- 'vl-item-attr-editor-div',
- 'vl-import-error-div'
-];
-
-var authtoken;
-var VANDELAY_URL = '/vandelay-upload';
-var bibAttrDefs = [];
-var authAttrDefs = [];
-var queuedRecords = [];
-var queuedRecordsMap = {};
-var bibAttrsFetched = false;
-var authAttrsFetched = false;
-var attrDefMap = {}; // maps attr def code names to attr def ids
-var currentType;
-var currentQueueId = null;
-var userCache = {};
-var currentMatchedRecords; // set of loaded matched bib records
-var currentOverlayRecordsMap; // map of import record to overlay record
-var currentOverlayRecordsMapGid; // map of import record to overlay record grid id
-var currentImportRecId; // when analyzing matches, this is the current import record
-var userBibQueues = []; // only non-complete queues
-var userAuthQueues = []; // only non-complete queues
-var allUserBibQueues;
-var allUserAuthQueues;
-var selectableGridRecords;
-var cgi = new openils.CGI();
-var vlQueueGridColumePicker = {};
-var vlBibSources = [];
-var importItemDefs = [];
-var matchSets = {};
-var mergeProfiles = [];
-var copyStatusCache = {};
-var copyLocationCache = {};
-var localeStrings;
-
-/**
- * Grab initial data
- */
-function vlInit() {
-
- dojo.requireLocalization("openils.vandelay", "vandelay");
- localeStrings = dojo.i18n.getLocalization("openils.vandelay", "vandelay");
-
- authtoken = openils.User.authtoken;
- var initNeeded = 8; // how many async responses do we need before we're init'd
- var initCount = 0; // how many async reponses we've received
-
- openils.Util.registerEnterHandler(
- vlQueueDisplayPage.domNode, function(){retrieveQueuedRecords();});
- openils.Util.addCSSClass(dojo.byId('vl-menu-marc-upload'), 'toolbar_selected');
-
- function checkInitDone() {
- initCount++;
- if(initCount == initNeeded)
- runStartupCommands();
- }
-
- mergeProfiles = new openils.PermaCrud().retrieveAll('vmp');
- vlUploadMergeProfile.store = new dojo.data.ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
- vlUploadMergeProfile.labelAttr = 'name';
- vlUploadMergeProfile.searchAttr = 'name';
- vlUploadMergeProfile.startup();
-
- vlUploadMergeProfile2.store = new dojo.data.ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
- vlUploadMergeProfile2.labelAttr = 'name';
- vlUploadMergeProfile2.searchAttr = 'name';
- vlUploadMergeProfile2.startup();
-
- vlUploadFtMergeProfile.store = new dojo.data.ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
- vlUploadFtMergeProfile.labelAttr = 'name';
- vlUploadFtMergeProfile.searchAttr = 'name';
- vlUploadFtMergeProfile.startup();
-
- vlUploadFtMergeProfile2.store = new dojo.data.ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
- vlUploadFtMergeProfile2.labelAttr = 'name';
- vlUploadFtMergeProfile2.searchAttr = 'name';
- vlUploadFtMergeProfile2.startup();
-
-
- // Fetch the bib and authority attribute definitions
- vlFetchBibAttrDefs(function () { checkInitDone(); });
- vlFetchAuthAttrDefs(function () { checkInitDone(); });
-
- vlRetrieveQueueList('bib', null,
- function(list) {
- allUserBibQueues = list;
- for(var i = 0; i < allUserBibQueues.length; i++) {
- if(allUserBibQueues[i].complete() == 'f')
- userBibQueues.push(allUserBibQueues[i]);
- }
- checkInitDone();
- }
- );
-
- vlRetrieveQueueList('auth', null,
- function(list) {
- allUserAuthQueues = list;
- for(var i = 0; i < allUserAuthQueues.length; i++) {
- if(allUserAuthQueues[i].complete() == 'f')
- userAuthQueues.push(allUserAuthQueues[i]);
- }
- checkInitDone();
- }
- );
-
- fieldmapper.standardRequest(
- ['open-ils.permacrud', 'open-ils.permacrud.search.cbs.atomic'],
- { async: true,
- params: [authtoken, {id:{"!=":null}}, {order_by:{cbs:'id'}}],
- oncomplete : function(r) {
- vlBibSources = openils.Util.readResponse(r, false, true);
- checkInitDone();
- }
- }
- );
-
- var owner = fieldmapper.aou.orgNodeTrail(fieldmapper.aou.findOrgUnit(new openils.User().user.ws_ou()));
- new openils.PermaCrud().search('viiad',
- {owner: owner.map(function(org) { return org.id(); })},
- { async: true,
- oncomplete: function(r) {
- importItemDefs = openils.Util.readResponse(r);
- checkInitDone();
- }
- }
- );
-
- new openils.PermaCrud().search('vms',
- {owner: owner.map(function(org) { return org.id(); })},
- { async: true,
- oncomplete: function(r) {
- var sets = openils.Util.readResponse(r);
- dojo.forEach(sets,
- function(set) {
- if(!matchSets[set.mtype()])
- matchSets[set.mtype()] = [];
- matchSets[set.mtype()].push(set);
- }
- );
- checkInitDone();
- }
- }
- );
-
- new openils.PermaCrud().retrieveAll('ccs',
- { async: true,
- oncomplete: function(r) {
- var stats = openils.Util.readResponse(r);
- dojo.forEach(stats, function(stat){copyStatusCache[stat.id()] = stat});
- checkInitDone();
- }
- }
- );
-
- vlAttrEditorInit();
- vlExportInit();
-}
-
-
-openils.Util.addOnLoad(vlInit);
-
-
-// fetch the bib and authority attribute definitions
-
-function vlFetchBibAttrDefs(postcomplete) {
- bibAttrDefs = [];
- fieldmapper.standardRequest(
- ['open-ils.permacrud', 'open-ils.permacrud.search.vqbrad'],
- { async: true,
- params: [authtoken, {id:{'!=':null}}],
- onresponse: function(r) {
- var def = r.recv().content();
- if(e = openils.Event.parse(def[0]))
- return alert(e);
- bibAttrDefs.push(def);
- },
- oncomplete: function() {
- bibAttrDefs = bibAttrDefs.sort(
- function(a, b) {
- if(a.id() > b.id()) return 1;
- if(a.id() < b.id()) return -1;
- return 0;
- }
- );
- postcomplete();
- }
- }
- );
-}
-
-function vlFetchAuthAttrDefs(postcomplete) {
- authAttrDefs = [];
- fieldmapper.standardRequest(
- ['open-ils.permacrud', 'open-ils.permacrud.search.vqarad'],
- { async: true,
- params: [authtoken, {id:{'!=':null}}],
- onresponse: function(r) {
- var def = r.recv().content();
- if(e = openils.Event.parse(def[0]))
- return alert(e);
- authAttrDefs.push(def);
- },
- oncomplete: function() {
- authAttrDefs = authAttrDefs.sort(
- function(a, b) {
- if(a.id() > b.id()) return 1;
- if(a.id() < b.id()) return -1;
- return 0;
- }
- );
- postcomplete();
- }
- }
- );
-}
-
-function vlRetrieveQueueList(type, filter, onload) {
- type = (type == 'bib') ? type : 'authority';
- fieldmapper.standardRequest(
- ['open-ils.vandelay', 'open-ils.vandelay.'+type+'_queue.owner.retrieve.atomic'],
- { async: true,
- params: [authtoken, null, filter],
- oncomplete: function(r) {
- var list = r.recv().content();
- if(e = openils.Event.parse(list[0]))
- return alert(e);
- onload(list);
- }
- }
- );
-
-}
-
-function displayGlobalDiv(id) {
- for(var i = 0; i < globalDivs.length; i++) {
- try {
- dojo.style(dojo.byId(globalDivs[i]), 'display', 'none');
- } catch(e) {
- alert('please define div ' + globalDivs[i]);
- }
- }
- dojo.style(dojo.byId(id),'display','block');
-
- openils.Util.removeCSSClass(dojo.byId('vl-menu-marc-export'), 'toolbar_selected');
- openils.Util.removeCSSClass(dojo.byId('vl-menu-marc-upload'), 'toolbar_selected');
- openils.Util.removeCSSClass(dojo.byId('vl-menu-queue-select'), 'toolbar_selected');
- openils.Util.removeCSSClass(dojo.byId('vl-menu-attr-editor'), 'toolbar_selected');
- openils.Util.removeCSSClass(dojo.byId('vl-menu-profile-editor'), 'toolbar_selected');
- openils.Util.removeCSSClass(dojo.byId('vl-menu-match-set-editor'), 'toolbar_selected');
-
- if(dojo.byId('vl-match-set-iframe'))
- dojo.byId('vl-match-set-editor-div').removeChild(dojo.byId('vl-match-set-iframe'));
-
- switch(id) {
- case 'vl-marc-export-div':
- openils.Util.addCSSClass(dojo.byId('vl-menu-marc-export'), 'toolbar_selected');
- break;
- case 'vl-marc-upload-div':
- openils.Util.addCSSClass(dojo.byId('vl-menu-marc-upload'), 'toolbar_selected');
- break;
- case 'vl-queue-select-div':
- openils.Util.addCSSClass(dojo.byId('vl-menu-queue-select'), 'toolbar_selected');
- break;
- case 'vl-attr-editor-div':
- openils.Util.addCSSClass(dojo.byId('vl-menu-attr-editor'), 'toolbar_selected');
- break;
- case 'vl-profile-editor-div':
- openils.Util.addCSSClass(dojo.byId('vl-menu-profile-editor'), 'toolbar_selected');
- break;
- case 'vl-item-attr-editor-div':
- openils.Util.addCSSClass(dojo.byId('vl-menu-import-item-attr-editor'), 'toolbar_selected');
- break;
- case 'vl-match-set-editor-div':
- openils.Util.addCSSClass(dojo.byId('vl-menu-match-set-editor'), 'toolbar_selected');
- break;
- }
-}
-
-function runStartupCommands() {
- openils.Util.hide(dojo.byId('vl-page-loading'));
- openils.Util.show(dojo.byId('vl-body-wrapper'));
- currentQueueId = cgi.param('qid');
- currentType = cgi.param('qtype');
- dojo.style('vl-nav-bar', 'visibility', 'visible');
- if(currentQueueId)
- return retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
- if (cgi.param('page', 'inspectq'))
- return displayGlobalDiv('vl-queue-select-div');
-
- vlShowUploadForm();
-}
-
-/**
- * asynchronously upload a file of MARC records
- */
-function uploadMARC(onload){
- dojo.byId('vl-upload-status-count').innerHTML = '0';
- dojo.byId('vl-ses-input').value = authtoken;
- displayGlobalDiv('vl-marc-upload-status-div');
- dojo.io.iframe.send({
- url: VANDELAY_URL,
- method: "post",
- handleAs: "html",
- form: dojo.byId('vl-marc-upload-form'),
- handle: function(data,ioArgs){
- var content = data.documentElement.textContent;
- onload(content);
- }
- });
-}
-
-/**
- * Creates a new vandelay queue
- */
-function createQueue(queueName, type, onload, importDefId, matchSet) {
- var name = (type=='bib') ? 'bib' : 'authority';
- var method = 'open-ils.vandelay.'+ name +'_queue.create'
- fieldmapper.standardRequest(
- ['open-ils.vandelay', method],
- { async: true,
- params: [authtoken, queueName, null, name, matchSet, importDefId],
- oncomplete : function(r) {
- var queue = r.recv().content();
- if(e = openils.Event.parse(queue))
- return alert(e);
- onload(queue);
- }
- }
- );
-}
-
-/**
- * Tells vandelay to pull a batch of records from the cache and explode them
- * out into the vandelay tables
- */
-function processSpool(key, queueId, type, onload) {
- fieldmapper.standardRequest(
- ['open-ils.vandelay', 'open-ils.vandelay.'+type+'.process_spool'],
- { async: true,
- params: [authtoken, key, queueId],
- onresponse : function(r) {
- var resp = r.recv().content();
- if(e = openils.Event.parse(resp))
- return alert(e);
- dojo.byId('vl-upload-status-count').innerHTML = resp;
- },
- oncomplete : function(r) {onload();}
- }
- );
-}
-
-function vlExportInit() {
-
- // queue export
- var qsel = dojo.byId('vl-queue-export-options');
- qsel.onchange = function(newVal) {
- var value = qsel.options[qsel.selectedIndex].value;
- qsel.selectedIndex = 0;
- if(!value) return;
- if(!confirm('Export as "' + value + '"?')) return; // TODO: i18n
- retrieveQueuedRecords(
- currentType,
- currentQueueId,
- function(r) {
- exportHandler(value, r);
- displayGlobalDiv('vl-queue-div');
- },
- value
- );
- }
-
- // item export
- var isel = dojo.byId('vl-item-export-options');
- isel.onchange = function(newVal) {
- var value = isel.options[isel.selectedIndex].value;
- isel.selectedIndex = 0;
- if(!value) return;
- if(!confirm('Export as "' + value + '"?')) return; // TODO: i18n
-
- displayGlobalDiv('vl-generic-progress');
- var method = 'open-ils.vandelay.import_item.queue.export.' + value + '.atomic';
-
- fieldmapper.standardRequest(
- ['open-ils.vandelay', method],
- {
- params : [
- authtoken,
- currentQueueId,
- {with_import_error: (vlImportItemsShowErrors.checked) ? 1 : null}
- ],
- async : true,
- oncomplete : function(r) {exportHandler(value, r)}
- }
- );
- }
-}
-
-function exportHandler(type, response) {
- displayGlobalDiv('vl-import-error-div');
- try {
- var content = openils.Util.readResponse(response);
- if (type=='email') {
- if (content==1) { alert('Email sent.'); return; }
- throw(content);
- }
- /* handle .atomic versus non-atomic method calls */
- content = content.constructor == Array
- ? content[0].template_output().data()
- : content.template_output().data();
- switch(type) {
- case 'print':
- openils.Util.printHtmlString(content);
- break;
- case 'csv':
- //content = content.replace(/\\t/g,'\t'); // if we really wanted to do .tsv instead
- openils.XUL.contentToFileSaveDialog(content, null, {
- defaultString : 'VandelayExport.csv',
- defaultExtension : '.csv',
- filterName : 'CSV',
- filterExtension : '*.csv',
- filterAll : true
- } );
- break;
- default:
- alert('response = ' + response + '\tcontent:\n' + content);
- }
- } catch(E) {
- alert('Error exporting data: ' + E);
- }
-}
-
-function retrieveQueuedRecords(type, queueId, onload, doExport) {
- displayGlobalDiv('vl-generic-progress');
- queuedRecords = [];
- queuedRecordsMap = {};
- currentOverlayRecordsMap = {};
- currentOverlayRecordsMapGid = {};
- selectableGridRecords = {};
-
- if(!type) type = currentType;
- if(!queueId) queueId = currentQueueId;
- if(!onload) onload = handleRetrieveRecords;
-
- var method = 'open-ils.vandelay.'+type+'_queue.records.retrieve';
-
- if(doExport) method += '.export.' + doExport;
- if(vlQueueGridShowMatches.checked)
- method = method.replace('records', 'records.matches');
-
- method += '.atomic';
-
- var sel = dojo.byId('vl-queue-display-limit-selector');
- var limit = parseInt(sel.options[sel.selectedIndex].value);
- var offset = limit * parseInt(vlQueueDisplayPage.attr('value')-1);
-
- var params = [authtoken, queueId, {clear_marc: 1, offset: offset, limit: limit, flesh_import_items:1}];
- if(vlQueueGridShowNonImport.checked)
- params[2].non_imported = 1;
-
- if(vlQueueGridShowImportErrors.checked)
- params[2].with_import_error = 1;
-
- fieldmapper.standardRequest(
- ['open-ils.vandelay', method],
- { async: true,
- params: params,
- oncomplete: function(r){
- if(doExport) return onload(r);
- var recs = r.recv().content();
- if(e = openils.Event.parse(recs[0]))
- return alert(e);
- for(var i = 0; i < recs.length; i++) {
- var rec = recs[i];
- queuedRecords.push(rec);
- queuedRecordsMap[rec.id()] = rec;
- }
- onload();
- }
- }
- );
-}
-
-function vlLoadMatchUI(recId) {
- displayGlobalDiv('vl-generic-progress');
- var queuedRec = queuedRecordsMap[recId];
- var matches = queuedRec.matches();
- var records = [];
- currentImportRecId = recId;
- for(var i = 0; i < matches.length; i++)
- records.push(matches[i].eg_record());
-
- var retrieve = ['open-ils.search', 'open-ils.search.biblio.record_entry.slim.retrieve'];
- var params = [records];
- if(currentType == 'auth') {
- retrieve = ['open-ils.cat', 'open-ils.cat.authority.record.retrieve'];
- params = [authtoken, records, {clear_marc:1}];
- }
-
- fieldmapper.standardRequest(
- retrieve,
- { async: true,
- params:params,
- oncomplete: function(r) {
- var recs = r.recv().content();
- if(e = openils.Event.parse(recs))
- return alert(e);
-
- /* ui mangling */
- displayGlobalDiv('vl-match-div');
- resetVlMatchGridLayout();
- currentMatchedRecords = recs;
- vlMatchGrid.setStructure(vlMatchGridLayout);
-
- // build the data store of records with match information
- var dataStore = bre.toStoreData(recs, null,
- {virtualFields:['_id', 'match_score', 'match_quality', 'rec_quality']});
- dataStore.identifier = '_id';
-
- var matchSeenMap = {};
-
- for(var i = 0; i < dataStore.items.length; i++) {
- var item = dataStore.items[i];
- item._id = i; // just need something unique
- for(var j = 0; j < matches.length; j++) {
- var match = matches[j];
- if(match.eg_record() == item.id && !matchSeenMap[match.id()]) {
- if(match.match_score)
- item.match_score = match.match_score();
- item.match_quality = match.quality();
- item.rec_quality = queuedRec.quality();
- matchSeenMap[match.id()] = 1;
- break;
- }
- }
- }
-
- // now populate the grid
- vlPopulateMatchGrid(vlMatchGrid, dataStore);
- }
- }
- );
-}
-
-function vlPopulateMatchGrid(grid, data) {
- var store = new dojo.data.ItemFileReadStore({data:data});
- grid.setStore(store);
- grid.update();
-}
-
-function showMe(id) {
- dojo.style(dojo.byId(id), 'display', 'block');
-}
-function hideMe(id) {
- dojo.style(dojo.byId(id), 'display', 'none');
-}
-
-
-function vlLoadMARCHtml(recId, inCat, oncomplete) {
- dijit.byId('vl-marc-html-done-button').onClick = oncomplete;
- displayGlobalDiv('vl-generic-progress');
- var api;
- var params = [recId, 1];
-
- if(inCat) {
- hideMe('vl-marc-html-edit-button'); // don't show marc editor button
- dijit.byId('vl-marc-html-edit-button').onClick = function(){}
- api = ['open-ils.search', 'open-ils.search.biblio.record.html'];
- if(currentType == 'auth')
- api = ['open-ils.search', 'open-ils.search.authority.to_html'];
- } else {
- showMe('vl-marc-html-edit-button'); // plug in the marc editor button
- dijit.byId('vl-marc-html-edit-button').onClick =
- function() {vlLoadMarcEditor(currentType, recId, oncomplete);};
- params = [authtoken, recId];
- api = ['open-ils.vandelay', 'open-ils.vandelay.queued_bib_record.html'];
- if(currentType == 'auth')
- api = ['open-ils.vandelay', 'open-ils.vandelay.queued_authority_record.html'];
- }
-
- fieldmapper.standardRequest(
- api,
- { async: true,
- params: params,
- oncomplete: function(r) {
- displayGlobalDiv('vl-marc-html-div');
- var html = r.recv().content();
- dojo.byId('vl-marc-record-html').innerHTML = html;
- }
- }
- );
-}
-
-
-/*
-function getRecMatchesFromAttrCode(rec, attrCode) {
- var matches = [];
- var attr = getRecAttrFromCode(rec, attrCode);
- for(var j = 0; j < rec.matches().length; j++) {
- var match = rec.matches()[j];
- if(match.matched_attr() == attr.id())
- matches.push(match);
- }
- return matches;
-}
-*/
-
-/*
-function getRecAttrFromMatch(rec, match) {
- for(var i = 0; i < rec.attributes().length; i++) {
- var attr = rec.attributes()[i];
- if(attr.id() == match.matched_attr())
- return attr;
- }
-}
-*/
-
-function getRecAttrDefFromAttr(attr, type) {
- var defs = (type == 'bib') ? bibAttrDefs : authAttrDefs;
- for(var i = 0; i < defs.length; i++) {
- var def = defs[i];
- if(def.id() == attr.field())
- return def;
- }
-}
-
-function getRecAttrFromCode(rec, attrCode) {
- var defId = attrDefMap[currentType][attrCode];
- var attrs = rec.attributes();
- for(var i = 0; i < attrs.length; i++) {
- var attr = attrs[i];
- if(attr.field() == defId)
- return attr;
- }
- return null;
-}
-
-function vlGetViewMatches(rowIdx, item) {
- if(item) {
- var id = this.grid.store.getValue(item, 'id');
- var rec = queuedRecordsMap[id];
- if(rec.matches().length > 0)
- return id + ':' + rec.matches().length;
- }
- return -1
-}
-
-function vlFormatViewMatches(id) {
- if(id == -1) return '';
- var chunks = id.split(':');
- id = chunks[0];
- count = chunks[1];
- return '<a href="javascript:void(0);" onclick="vlLoadMatchUI(' + id + ');">' + this.name + ' (' + count + ')</a>';
-}
-
-function vlGetViewErrors(rowIdx, item) {
- if(item) {
- var id = this.grid.store.getValue(item, 'id');
- var rec = queuedRecordsMap[id];
- // id:rec_error:item_import_error_count
- return id + ':' +
- (rec.import_error() ? 1 : '') + ':' +
- (typeof rec.import_items == 'function'
- ? rec.import_items().filter(function(i) {return i.import_error()}).length
- :''
- );
- }
- return -1
-}
-
-function vlFormatViewErrors(chunk) {
- if(chunk == -1) return '';
- var id = chunk.split(':')[0];
- var rec = chunk.split(':')[1];
- var count = chunk.split(':')[2];
- var links = '';
- if(rec)
- links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');">Record</a><br/>'; // TODO I18N
- if(Number(count))
- links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');">Items ('+count+')</a>'; // TODO I18N
- return links;
-}
-
-//var vlItemErrorColumnPicker;
-function vlLoadErrorUI(id) {
-
- displayGlobalDiv('vl-import-error-div');
- openils.Util.hide('vl-import-error-grid-all');
- openils.Util.show('vl-import-error-record');
-
- var rec = queuedRecordsMap[id];
-
- dojo.byId('vl-error-id').innerHTML = rec.id();
- dojo.forEach( // TODO sane authority rec. fields
- ['title', 'author', 'isbn', 'issn', 'upc'],
- function(field) {
- var attr = getRecAttrFromCode(rec, field);
- var eid = 'vl-error-' + field;
- if(attr) {
- openils.Util.show(dojo.byId(eid).parentNode, 'table-row');
- dojo.byId(eid).innerHTML = attr.attr_value();
- } else {
- openils.Util.hide(dojo.byId(eid).parentNode);
- }
- }
- );
- var iediv = dojo.byId('vl-error-import-error');
- var eddiv = dojo.byId('vl-error-error-detail');
- if(rec.import_error()) {
- openils.Util.show(iediv.parentNode, 'table-row');
- openils.Util.show(eddiv.parentNode, 'table-row');
- iediv.innerHTML = rec.import_error();
- eddiv.innerHTML = rec.error_detail();
- } else {
- openils.Util.hide(iediv.parentNode);
- openils.Util.hide(eddiv.parentNode);
- }
-
- var errorItems = rec.import_items().filter(function(i) {return i.import_error()});
- if(errorItems.length) {
- openils.Util.show('vl-import-error-grid-some');
- storeData = vqbr.toStoreData(errorItems);
- var store = new dojo.data.ItemFileReadStore({data:storeData});
- vlImportErrorGrid.setStore(store);
- vlImportErrorGrid.update();
- } else {
- openils.Util.hide('vl-import-error-grid-some');
- }
-}
-
-function vlLoadErrorUIAll() {
-
- displayGlobalDiv('vl-import-error-div');
- openils.Util.hide('vl-import-error-grid-some');
- openils.Util.hide('vl-import-error-record');
- openils.Util.show('vl-import-error-grid-all');
- vlAllImportErrorGrid.resetStore();
-
- vlImportErrorGrid.displayOffset = 0;
-
- vlAllImportErrorGrid.dataLoader = function() {
-
- vlAllImportErrorGrid.showLoadProgressIndicator();
-
- fieldmapper.standardRequest(
- ['open-ils.vandelay', 'open-ils.vandelay.import_item.queue.retrieve'],
- {
- async : true,
- params : [
- authtoken, currentQueueId, {
- with_import_error: (vlImportItemsShowErrors.checked) ? 1 : null,
- offset : vlAllImportErrorGrid.displayOffset,
- limit : vlAllImportErrorGrid.displayLimit
- }
- ],
- onresponse : function(r) {
- var item = openils.Util.readResponse(r);
- if(!item) return;
- vlAllImportErrorGrid.store.newItem(vii.toStoreItem(item));
- },
- oncomplete : function() {
- vlAllImportErrorGrid.hideLoadProgressIndicator();
- }
- }
- );
- };
-
- vlAllImportErrorGrid.dataLoader();
-}
-
-function vlGetOrg(rowIdx, item) {
- if(!item) return '';
- var value = this.grid.store.getValue(item, this.field);
- if(value) return fieldmapper.aou.findOrgUnit(value).shortname();
- return '';
-}
-
-function vlCopyStatus(rowIdx, item) {
- if(!item) return '';
- var value = this.grid.store.getValue(item, this.field);
- if(value) return copyStatusCache[value].name();
- return '';
-}
-
-// Note, we don't pre-fetch all copy locations because there could be
-// a lot of them. Instead, fetch-and-cache on demand.
-function vlCopyLocation(rowIdx, item) {
- if(item) {
- var value = this.grid.store.getValue(item, this.field);
- if(value) {
- if(!copyLocationCache[value]) {
- copyLocationCache[value] =
- new openils.PermaCrud().retrieve('acpl', value);
- }
- return copyLocationCache[value].name();
- }
- }
- return '';
-}
-
-function vlFormatViewMatchMARC(id) {
- return '<a href="javascript:void(0);" onclick="vlLoadMARCHtml(' + id + ', true, '+
- 'function(){displayGlobalDiv(\'vl-match-div\');});">' + this.name + '</a>';
-}
-
-function getAttrValue(rowIdx, item) {
- if(!item) return '';
- var attrCode = this.field.split('.')[1];
- var rec = queuedRecordsMap[this.grid.store.getValue(item, 'id')];
- var attr = getRecAttrFromCode(rec, attrCode);
- return (attr) ? attr.attr_value() : '';
-}
-
-function vlGetDateTimeField(rowIdx, item) {
- if(!item) return '';
- var value = this.grid.store.getValue(item, this.field);
- if(!value) return '';
- var date = dojo.date.stamp.fromISOString(value);
- return dojo.date.locale.format(date, {selector:'date'});
-}
-
-function vlGetCreator(rowIdx, item) {
- if(!item) return '';
- var id = this.grid.store.getValue(item, 'creator');
- if(userCache[id])
- return userCache[id].usrname();
- var user = fieldmapper.standardRequest(
- ['open-ils.actor', 'open-ils.actor.user.retrieve'], [authtoken, id]);
- if(e = openils.Event.parse(user))
- return alert(e);
- userCache[id] = user;
- return user.usrname();
-}
-
-function vlGetViewMARC(rowIdx, item) {
- return item && this.grid.store.getValue(item, 'id');
-}
-
-function vlFormatViewMARC(id) {
- return '<a href="javascript:void(0);" onclick="vlLoadMARCHtml(' + id + ', false, '+
- 'function(){displayGlobalDiv(\'vl-queue-div\');});">' + this.name + '</a>';
-}
-
-function vlGetOverlayTargetSelector(rowIdx, item) {
- if(!item) return;
- return this.grid.store.getValue(item, '_id') + ':' + this.grid.store.getValue(item, 'id');
-}
-
-function vlFormatOverlayTargetSelector(val) {
- if(!val) return '';
- var parts = val.split(':');
- var _id = parts[0];
- var id = parts[1];
- var value = '<input type="checkbox" name="vl-overlay-target-RECID" '+
- 'onclick="vlHandleOverlayTargetSelected(ID, GRIDID);" gridid="GRIDID" match="ID"/>';
- value = value.replace(/GRIDID/g, _id);
- value = value.replace(/RECID/g, currentImportRecId);
- value = value.replace(/ID/g, id);
- if(_id == currentOverlayRecordsMapGid[currentImportRecId])
- return value.replace('/>', 'checked="checked"/>');
- return value;
-}
-
-
-/**
- * see if the user has enabled overlays for the current match set and,
- * if so, map the current import record to the overlay target.
- */
-function vlHandleOverlayTargetSelected(recId, gridId) {
- var noneSelected = true;
- var checkboxes = dojo.query('[name=vl-overlay-target-'+currentImportRecId+']');
- for(var i = 0; i < checkboxes.length; i++) {
- var checkbox = checkboxes[i];
- var matchRecId = checkbox.getAttribute('match');
- var gid = checkbox.getAttribute('gridid');
- if(checkbox.checked) {
- if(matchRecId == recId && gid == gridId) {
- noneSelected = false;
- currentOverlayRecordsMap[currentImportRecId] = matchRecId;
- currentOverlayRecordsMapGid[currentImportRecId] = gid;
- dojo.byId('vl-record-list-selected-' + currentImportRecId).checked = true;
- dojo.byId('vl-record-list-selected-' + currentImportRecId).parentNode.className = 'overlay_selected';
- } else {
- checkbox.checked = false;
- }
- }
- }
-
- if(noneSelected) {
- delete currentOverlayRecordsMap[currentImportRecId];
- delete currentOverlayRecordsMapGid[currentImportRecId];
- dojo.byId('vl-record-list-selected-' + currentImportRecId).checked = false;
- dojo.byId('vl-record-list-selected-' + currentImportRecId).parentNode.className = '';
- }
-}
-
-var valLastQueueType = null;
-var vlQueueGridLayout = null;
-function buildRecordGrid(type) {
- displayGlobalDiv('vl-queue-div');
-
- vlBibQueueGrid.canSort = function(col){ if(Math.abs(col) == 1) { return false; } else { return true; } };
- vlAuthQueueGrid.canSort = function(col){ if(Math.abs(col) == 1) { return false; } else { return true; } };
-
- if(type == 'bib') {
- openils.Util.show('vl-bib-queue-grid-wrapper');
- openils.Util.hide('vl-auth-queue-grid-wrapper');
- vlQueueGrid = vlBibQueueGrid;
- openils.Util.show('add-to-bucket-action', 'table-row');
- } else {
- openils.Util.show('vl-auth-queue-grid-wrapper');
- openils.Util.hide('vl-bib-queue-grid-wrapper');
- vlQueueGrid = vlAuthQueueGrid;
- openils.Util.hide('add-to-bucket-action');
- }
-
-
- if(valLastQueueType != type) {
- valLastQueueType = type;
- vlQueueGridLayout = vlQueueGrid.attr('structure');
- var defs = (type == 'bib') ? bibAttrDefs : authAttrDefs;
- attrDefMap[type] = {};
- for(var i = 0; i < defs.length; i++) {
- var def = defs[i]
- attrDefMap[type][def.code()] = def.id();
- var col = {
- name:def.description(),
- field:'attr.' + def.code(),
- get: getAttrValue,
- selectableColumn:true
- };
- vlQueueGridLayout[0].cells[0].push(col);
- }
- }
-
- dojo.forEach(vlQueueGridLayout[0].cells[0],
- function(cell) {
- if(cell.field.match(/^\+/))
- cell.nonSelectable=true;
- }
- );
-
- var storeData;
- if(type == 'bib')
- storeData = vqbr.toStoreData(queuedRecords);
- else
- storeData = vqar.toStoreData(queuedRecords);
-
- var store = new dojo.data.ItemFileReadStore({data:storeData});
- vlQueueGrid.setStore(store);
-
- if(vlQueueGridColumePicker[type]) {
- vlQueueGrid.update();
- } else {
-
- vlQueueGridColumePicker[type] =
- new openils.widget.GridColumnPicker(
- authtoken, 'vandelay.queue.'+type, vlQueueGrid, vlQueueGridLayout);
- vlQueueGridColumePicker[type].load();
- }
-}
-
-function vlQueueGridPrevPage() {
- var page = parseInt(vlQueueDisplayPage.getValue());
- if(page < 2) return;
- vlQueueDisplayPage.setValue(page - 1);
- retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
-}
-
-function vlQueueGridNextPage() {
- vlQueueDisplayPage.setValue(parseInt(vlQueueDisplayPage.getValue())+1);
- retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
-}
-
-function vlDeleteQueue(type, queueId, onload) {
- fieldmapper.standardRequest(
- ['open-ils.vandelay', 'open-ils.vandelay.'+type+'_queue.delete'],
- { async: true,
- params: [authtoken, queueId],
- oncomplete: function(r) {
- var resp = r.recv().content();
- if(e = openils.Event.parse(resp))
- return alert(e);
- onload();
- }
- }
- );
-}
-
-
-function vlQueueGridDrawSelectBox(rowIdx, item) {
- return item && this.grid.store.getValue(item, 'id');
-}
-
-function vlQueueGridFormatSelectBox(id) {
- var domId = 'vl-record-list-selected-' + id;
- if (id) { selectableGridRecords[domId] = id; }
- return "<div><input type='checkbox' id='"+domId+"'/></div>";
-}
-
-function vlSelectAllQueueGridRecords() {
- for(var id in selectableGridRecords)
- dojo.byId(id).checked = true;
-}
-function vlSelectNoQueueGridRecords() {
- for(var id in selectableGridRecords)
- dojo.byId(id).checked = false;
-}
-function vlToggleQueueGridSelect() {
- if(dojo.byId('vl-queue-grid-row-selector').checked)
- vlSelectAllQueueGridRecords();
- else
- vlSelectNoQueueGridRecords();
-}
-
-var handleRetrieveRecords = function() {
- buildRecordGrid(currentType);
- vlFetchQueueSummary(currentQueueId, currentType,
- function(summary) {
- dojo.byId('vl-queue-summary-name').innerHTML = summary.queue.name();
- dojo.byId('vl-queue-summary-total-count').innerHTML = summary.total +'';
- dojo.byId('vl-queue-summary-import-count').innerHTML = summary.imported + '';
- dojo.byId('vl-queue-summary-import-item-count').innerHTML = summary.total_items + '';
- dojo.byId('vl-queue-summary-import-item-imported-count').innerHTML = summary.total_items_imported + '';
- dojo.byId('vl-queue-summary-rec-error-count').innerHTML = summary.rec_import_errors + '';
- dojo.byId('vl-queue-summary-item-error-count').innerHTML = summary.item_import_errors + '';
-
- if (dojo.byId('create-bucket-dialog-name')) {
- dojo.byId('create-bucket-dialog-name').value = summary.queue.name();
- }
- }
- );
-}
-
-function vlFetchQueueSummary(qId, type, onload) {
- fieldmapper.standardRequest(
- ['open-ils.vandelay', 'open-ils.vandelay.'+type+'_queue.summary.retrieve'],
- { async: true,
- params: [authtoken, qId],
- oncomplete : function(r) {
- var summary = r.recv().content();
- if(e = openils.Event.parse(summary))
- return alert(e);
- return onload(summary);
- }
- }
- );
-}
-
-function handleCreateBucket(args) {
- var bname = dojo.byId('create-bucket-dialog-name').value;
- if (!bname) return;
-
- progressDialog.show(true);
- fieldmapper.standardRequest(
- ['open-ils.vandelay', 'open-ils.vandelay.bib_queue.to_bucket'],
- { async : true,
- params : [authtoken, currentQueueId, bname],
- oncomplete : function(r) {
- progressDialog.hide();
- setTimeout(function() {
- var resp = openils.Util.readResponse(r);
- if (resp.add_count == 0) {
- alert(localeStrings.NO_BUCKET_ITEMS);
- } else {
- alert(
- dojo.string.substitute(
- localeStrings.BUCKET_CREATE_SUCCESS,
- [resp.add_count, bname, resp.item_count]
- )
- );
- }
- }, 200); // give the dialog a chance to hide
- }
- }
- );
-}
-
-
-var _importCancelHandler;
-var _importGoHandler;
-function vlHandleQueueItemsAction(action) {
-
- if(_importCancelHandler) dojo.disconnect(_importCancelHandler);
-
- _importCancelHandler = dojo.connect(
- queueItemsImportCancelButton,
- 'onClick',
- function() {
- queueItemsImportDialog.hide();
- }
- );
-
- if(_importGoHandler)
- dojo.disconnect(_importGoHandler);
-
- _importGoHandler = dojo.connect(
- queueItemsImportGoButton,
- 'onClick',
- function() {
- queueItemsImportDialog.hide();
-
- // hack to set the widgets the import funcs will be looking at. Reset them below.
- vlUploadQueueImportNoMatch.attr('value', vlUploadQueueImportNoMatch2.attr('value'));
- vlUploadQueueAutoOverlayExact.attr('value', vlUploadQueueAutoOverlayExact2.attr('value'));
- vlUploadQueueAutoOverlay1Match.attr('value', vlUploadQueueAutoOverlay1Match2.attr('value'));
- vlUploadMergeProfile.attr('value', vlUploadMergeProfile2.attr('value'));
- vlUploadFtMergeProfile.attr('value', vlUploadFtMergeProfile2.attr('value'));
- vlUploadQueueAutoOverlayBestMatch.attr('value', vlUploadQueueAutoOverlayBestMatch2.attr('value'));
- vlUploadQueueAutoOverlayBestMatchRatio.attr('value', vlUploadQueueAutoOverlayBestMatchRatio2.attr('value'));
-
- if(action == 'import') {
- vlImportSelectedRecords();
- } else if(action == 'import_all') {
- vlImportAllRecords();
- }
-
- // reset the widgets to prevent accidental future actions
- vlUploadQueueImportNoMatch.attr('value', false);
- vlUploadQueueImportNoMatch2.attr('value', false);
- vlUploadQueueAutoOverlayExact.attr('value', false);
- vlUploadQueueAutoOverlayExact2.attr('value', false);
- vlUploadQueueAutoOverlay1Match.attr('value', false);
- vlUploadQueueAutoOverlay1Match2.attr('value', false);
- vlUploadMergeProfile.attr('value', '');
- vlUploadMergeProfile2.attr('value', '');
- vlUploadFtMergeProfile.attr('value', '');
- vlUploadFtMergeProfile2.attr('value', '');
- vlUploadQueueAutoOverlayBestMatch.attr('value', false);
- vlUploadQueueAutoOverlayBestMatch2.attr('value', false);
- vlUploadQueueAutoOverlayBestMatchRatio.attr('value', '0.0');
- vlUploadQueueAutoOverlayBestMatchRatio2.attr('value', '0.0');
- }
- );
-
- queueItemsImportDialog.show();
-}
-
-function vlHandleCreateBucket() {
-
- create-bucket-dialog-name
-}
-
-
-/* import user-selected records */
-function vlImportSelectedRecords() {
- var records = [];
-
- for(var id in selectableGridRecords) {
- if(dojo.byId(id).checked) {
- var recId = selectableGridRecords[id];
- var rec = queuedRecordsMap[recId];
- if(!rec.import_time())
- records.push(recId);
- }
- }
-
- vlImportRecordQueue(
- currentType,
- currentQueueId,
- records,
- function(){
- retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
- }
- );
-}
-
-/* import all (non-imported) queue records */
-function vlImportAllRecords() {
- vlImportRecordQueue(
- currentType,
- currentQueueId,
- null,
- function(){
- retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
- }
- );
-}
-
-/* if recList has values, import only those records */
-function vlImportRecordQueue(type, queueId, recList, onload) {
- displayGlobalDiv('vl-generic-progress-with-total');
-
- /* set up options */
- var options = {overlay_map : currentOverlayRecordsMap};
-
- if(vlUploadQueueImportNoMatch.checked) {
- options.import_no_match = true;
- vlUploadQueueImportNoMatch.checked = false;
- }
-
- if(vlUploadQueueAutoOverlayExact.checked) {
- options.auto_overlay_exact = true;
- vlUploadQueueAutoOverlayExact.checked = false;
- }
-
- if(vlUploadQueueAutoOverlayBestMatch.checked) {
- options.auto_overlay_best_match = true;
- vlUploadQueueAutoOverlayBestMatch.checked = false;
- options.match_quality_ratio = vlUploadQueueAutoOverlayBestMatchRatio.attr('value');
- }
-
- if(vlUploadQueueAutoOverlay1Match.checked) {
- options.auto_overlay_1match = true;
- vlUploadQueueAutoOverlay1Match.checked = false;
- options.match_quality_ratio = vlUploadQueueAutoOverlayBestMatchRatio.attr('value');
- }
-
- var profile = vlUploadMergeProfile.attr('value');
- if(profile != null && profile != '') {
- options.merge_profile = profile;
- }
-
- var ftprofile = vlUploadFtMergeProfile.attr('value');
- if(ftprofile != null && ftprofile != '') {
- options.fall_through_merge_profile = ftprofile;
- }
-
-
- /* determine which method we're calling */
-
- var method = 'open-ils.vandelay.bib_queue.import';
- if(type == 'auth')
- method = method.replace('bib', 'auth');
-
- var params = [authtoken, queueId, options];
- if(recList) {
- method = 'open-ils.vandelay.'+currentType+'_record.list.import';
- params[1] = recList;
- }
-
- fieldmapper.standardRequest(
- ['open-ils.vandelay', method],
- { async: true,
- params: params,
- onresponse: function(r) {
- var resp = r.recv().content();
- if(e = openils.Event.parse(resp))
- return alert(e);
- vlControlledProgressBar.update({maximum:resp.total, progress:resp.progress});
- },
- oncomplete: function() {onload();}
- }
- );
-}
-
-
-/**
- * Create queue, upload MARC, process spool, load the newly created queue
- */
-function batchUpload() {
- var queueName = dijit.byId('vl-queue-name').getValue();
- currentType = dijit.byId('vl-record-type').getValue();
-
- var handleProcessSpool = function() {
- if(
- vlUploadQueueImportNoMatch.checked ||
- vlUploadQueueAutoOverlayExact.checked ||
- vlUploadQueueAutoOverlay1Match.checked ||
- vlUploadQueueAutoOverlayBestMatch.checked ) {
-
- vlImportRecordQueue(
- currentType,
- currentQueueId,
- null,
- function() {
- retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
- }
- );
- } else {
- retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
- }
- }
-
- var handleUploadMARC = function(key) {
- dojo.style(dojo.byId('vl-upload-status-processing'), 'display', 'block');
- processSpool(key, currentQueueId, currentType, handleProcessSpool);
- };
-
- var handleCreateQueue = function(queue) {
- currentQueueId = queue.id();
- uploadMARC(handleUploadMARC);
- };
-
- if(vlUploadQueueSelector.getValue() && !queueName) {
- currentQueueId = vlUploadQueueSelector.getValue();
- uploadMARC(handleUploadMARC);
- } else {
- createQueue(queueName, currentType, handleCreateQueue,
- vlUploadQueueHoldingsImportProfile.attr('value'),
- vlUploadQueueMatchSet.attr('value')
- );
- }
-}
-
-
-function vlFleshQueueSelect(selector, type) {
- var data;
- if (type == 'bib') {
- var bibList = allUserBibQueues.filter(
- function(q) {
- return (q.queue_type() == 'bib');
- }
- );
- data = vbq.toStoreData(bibList);
- } else if (type == 'bib-acq') {
- // ACQ queues are a special type of bib queue
- var acqList = allUserBibQueues.filter(
- function(q) {
- return (q.queue_type() == 'acq');
- }
- );
- data = vbq.toStoreData(acqList);
- } else {
- data = vaq.toStoreData(allUserAuthQueues);
- }
-
- selector.store = new dojo.data.ItemFileReadStore({data:data});
- selector.setValue(null);
- selector.setDisplayedValue('');
- if(data[0])
- selector.setValue(data[0].id());
-
- var qInput = dijit.byId('vl-queue-name');
-
- var selChange = function(val) {
- console.log('selector onchange');
- // user selected a queue from the selector; clear the input and
- // set the item import profile already defined for the queue
- var queue = allUserBibQueues.filter(function(q) { return (q.id() == val) })[0];
- if(val) {
- vlUploadQueueHoldingsImportProfile.attr('value', queue.item_attr_def() || '');
- vlUploadQueueHoldingsImportProfile.attr('disabled', true);
- vlUploadQueueMatchSet.attr('value', queue.match_set() || '');
- vlUploadQueueMatchSet.attr('disabled', true);
- } else {
- vlUploadQueueHoldingsImportProfile.attr('value', '');
- vlUploadQueueHoldingsImportProfile.attr('disabled', false);
- vlUploadQueueMatchSet.attr('value', '');
- vlUploadQueueMatchSet.attr('disabled', false);
- }
- dojo.disconnect(qInput._onchange);
- qInput.attr('value', '');
- qInput._onchange = dojo.connect(qInput, 'onChange', inputChange);
- }
-
- var inputChange = function(val) {
- console.log('qinput onchange');
- // user entered a new queue name. clear the selector
- vlUploadQueueHoldingsImportProfile.attr('disabled', false);
- vlUploadQueueMatchSet.attr('disabled', false);
- dojo.disconnect(selector._onchange);
- selector.attr('value', '');
- selector._onchange = dojo.connect(selector, 'onChange', selChange);
- }
-
- selector._onchange = dojo.connect(selector, 'onChange', selChange);
- qInput._onchange = dojo.connect(qInput, 'onChange', inputChange);
-}
-
-function vlUpdateMatchSetSelector(type) {
- type = (type.match(/bib/)) ? 'biblio' : 'authority';
- vlUploadQueueMatchSet.store =
- new dojo.data.ItemFileReadStore({data:vms.toStoreData(matchSets[type])});
-}
-
-function vlShowUploadForm() {
- displayGlobalDiv('vl-marc-upload-div');
- vlFleshQueueSelect(vlUploadQueueSelector, vlUploadRecordType.getValue());
- vlUploadSourceSelector.store =
- new dojo.data.ItemFileReadStore({data:cbs.toStoreData(vlBibSources, 'source')});
- vlUploadSourceSelector.setValue(vlBibSources[0].id());
- vlUploadQueueHoldingsImportProfile.store =
- new dojo.data.ItemFileReadStore({data:viiad.toStoreData(importItemDefs)});
- vlUpdateMatchSetSelector(vlUploadRecordType.getValue());
-
- // use ratio from the merge profile if it's set
- dojo.connect(
- vlUploadMergeProfile,
- 'onChange',
- function(val) {
- if(!val) return;
- var profile = mergeProfiles.filter(function(p) { return (p.id() == val); })[0];
- if(profile.lwm_ratio() != null)
- vlUploadQueueAutoOverlayBestMatchRatio.attr('value', profile.lwm_ratio()+'');
- }
- );
- dojo.connect(
- vlUploadMergeProfile2,
- 'onChange',
- function(val) {
- if(!val) return;
- var profile = mergeProfiles.filter(function(p) { return (p.id() == val); })[0];
- if(profile.lwm_ratio() != null)
- vlUploadQueueAutoOverlayBestMatchRatio2.attr('value', profile.lwm_ratio()+'');
- }
- );
-
-}
-
-function vlShowQueueSelect() {
- displayGlobalDiv('vl-queue-select-div');
- vlFleshQueueSelect(vlQueueSelectQueueList, vlQueueSelectType.getValue());
-}
-
-function vlShowMatchSetEditor() {
- displayGlobalDiv('vl-match-set-editor-div');
- dojo.byId('vl-match-set-editor-div').appendChild(
- dojo.create('iframe', {
- id : 'vl-match-set-iframe',
- src : oilsBasePath + '/conify/global/vandelay/match_set',
- style : 'width:100%; height:500px; border:none; margin:0px;'
- })
- );
-}
-
-function vlFetchQueueFromForm() {
- currentType = vlQueueSelectType.attr('value').replace(/-.*/, ''); // trim bib-acq
- currentQueueId = vlQueueSelectQueueList.getValue();
- retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
-}
-
-function vlOpenMarcEditWindow(rec, postReloadHTMLHandler) {
- /*
- To run in Firefox directly, must set signed.applets.codebase_principal_support
- to true in about:config
- */
- netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
- win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?
-
- var type;
- if (currentType == 'bib') {
- type = 'bre';
- } else {
- type = 'are';
- }
-
- function onsave(r) {
- // after the record is saved, reload the HTML display
- var stat = r.recv().content();
- if(e = openils.Event.parse(stat))
- return alert(e);
- alert(dojo.byId('vl-marc-edit-complete-label').innerHTML);
- win.close();
- vlLoadMARCHtml(rec.id(), false, postReloadHTMLHandler);
- }
-
- win.xulG = {
- record : {marc : rec.marc(), "rtype": type},
- save : {
- label: dojo.byId('vl-marc-edit-save-label').innerHTML,
- func: function(xmlString) {
- var method = 'open-ils.permacrud.update.' + rec.classname;
- rec.marc(xmlString);
- fieldmapper.standardRequest(
- ['open-ils.permacrud', method],
- { async: true,
- params: [authtoken, rec],
- oncomplete: onsave
- }
- );
- },
- },
- 'lock_tab' : typeof xulG != 'undefined' ? (typeof xulG['lock_tab'] != 'undefined' ? xulG.lock_tab : undefined) : undefined,
- 'unlock_tab' : typeof xulG != 'undefined' ? (typeof xulG['unlock_tab'] != 'undefined' ? xulG.unlock_tab : undefined) : undefined
- };
-}
-
-function vlLoadMarcEditor(type, recId, postReloadHTMLHandler) {
- var method = 'open-ils.permacrud.search.vqbr';
- if(currentType != 'bib')
- method = method.replace(/vqbr/,'vqar');
-
- fieldmapper.standardRequest(
- ['open-ils.permacrud', method],
- { async: true,
- params: [authtoken, {id : recId}],
- oncomplete: function(r) {
- var rec = r.recv().content();
- if(e = openils.Event.parse(rec))
- return alert(e);
- vlOpenMarcEditWindow(rec, postReloadHTMLHandler);
- }
- }
- );
-}
-
-
-
-//------------------------------------------------------------
-// attribute editors
-
-// attribute-editor global variables
-
-var ATTR_EDITOR_IN_UPDATE_MODE = false; // true on 'edit', false on 'create'
-var ATTR_EDIT_ID = null; // id of current 'edit' attribute
-var ATTR_EDIT_GROUP = 'bib'; // bib-attrs or auth-attrs
-
-function vlAttrEditorInit() {
- // set up tooltips on the edit form
- connectTooltip('attr-editor-tags');
- connectTooltip('attr-editor-subfields');
-}
-
-function vlShowAttrEditor() {
- displayGlobalDiv('vl-attr-editor-div');
- loadAttrEditorGrid();
- idHide('vl-generic-progress');
-}
-
-function setAttrEditorGroup(groupName) {
- // put us into 'bib'-attr or 'auth'-attr mode.
- if (ATTR_EDIT_GROUP != groupName) {
- ATTR_EDIT_GROUP = groupName;
- loadAttrEditorGrid();
- }
-}
-
-function onAttrEditorOpen() {
- // the "bars" have the create/update/cancel/etc. buttons.
- var create_bar = document.getElementById('attr-editor-create-bar');
- var update_bar = document.getElementById('attr-editor-update-bar');
- if (ATTR_EDITOR_IN_UPDATE_MODE) {
- update_bar.style.display='table-row';
- create_bar.style.display='none';
- // hide the dropdown-button
- idStyle('vl-create-attr-editor-button', 'visibility', 'hidden');
- } else {
- dijit.byId('attr-editor-dialog').reset();
- create_bar.style.display='table-row';
- update_bar.style.display='none';
- }
-}
-
-function onAttrEditorClose() {
- // reset the form to a "create" form. (We may have borrowed it for editing.)
- ATTR_EDITOR_IN_UPDATE_MODE = false;
- // show the dropdown-button
- idStyle('vl-create-attr-editor-button', 'visibility', 'visible');
-}
-
-function loadAttrEditorGrid() {
- var _data = (ATTR_EDIT_GROUP == 'auth') ?
- vqarad.toStoreData(authAttrDefs) : vqbrad.toStoreData(bibAttrDefs) ;
-
- var store = new dojo.data.ItemFileReadStore({data:_data});
- attrEditorGrid.setStore(store);
- attrEditorGrid.onRowDblClick = onAttrEditorClick;
- attrEditorGrid.update();
-}
-
-function attrGridGetTag(n, item) {
- // grid helper: return the tags from the row's xpath column.
- return item && xpathParser.parse(this.grid.store.getValue(item, 'xpath')).tags;
-}
-
-function attrGridGetSubfield(n, item) {
- // grid helper: return the subfields from the row's xpath column.
- return item && xpathParser.parse(this.grid.store.getValue(item, 'xpath')).subfields;
-}
-
-function onAttrEditorClick() {
- var row = this.getItem(this.focus.rowIndex);
- ATTR_EDIT_ID = this.store.getValue(row, 'id');
- ATTR_EDITOR_IN_UPDATE_MODE = true;
-
- // populate the popup editor.
- dijit.byId('attr-editor-code').attr('value', this.store.getValue(row, 'code'));
- dijit.byId('attr-editor-description').attr('value', this.store.getValue(row, 'description'));
- var parsed_xpath = xpathParser.parse(this.store.getValue(row, 'xpath'));
- dijit.byId('attr-editor-tags').attr('value', parsed_xpath.tags);
- dijit.byId('attr-editor-subfields').attr('value', parsed_xpath.subfields);
- dijit.byId('attr-editor-xpath').attr('value', this.store.getValue(row, 'xpath'));
- dijit.byId('attr-editor-remove').attr('value', this.store.getValue(row, 'remove'));
-
- // set up UI for editing
- dojo.byId('vl-create-attr-editor-button').click();
-}
-
-function vlSaveAttrDefinition(data) {
- idHide('vl-attr-editor-div');
- idShow('vl-generic-progress');
-
- data.id = ATTR_EDIT_ID;
-
- // this ought to honour custom xpaths, but overwrite xpaths
- // derived from tags/subfields.
- if (data.xpath == '' || looksLikeDerivedXpath(data.xpath)) {
- var _xpath = tagAndSubFieldsToXpath(data.tag, data.subfield);
- data.xpath = _xpath;
- }
-
- // build up our permacrud params. Key variables here are
- // "create or update" and "bib or auth".
-
- var isAuth = (ATTR_EDIT_GROUP == 'auth');
- var isCreate = (ATTR_EDIT_ID == null);
- var rad = isAuth ? new vqarad() : new vqbrad() ;
- var method = 'open-ils.permacrud' + (isCreate ? '.create.' : '.update.')
- + (isAuth ? 'vqarad' : 'vqbrad');
- var _data = rad.fromStoreItem(data);
-
- _data.ischanged(1);
-
- fieldmapper.standardRequest(
- ['open-ils.permacrud', method],
- { async: true,
- params: [authtoken, _data ],
- onresponse: function(r) { },
- oncomplete: function(r) {
- attrEditorFetchAttrDefs(vlShowAttrEditor);
- ATTR_EDIT_ID = null;
- },
- onerror: function(r) {
- alert('vlSaveAttrDefinition comms error: ' + r);
+require([
+ "dojo/parser",
+ "dojo/io/iframe",
+ "dijit/ProgressBar",
+ "dijit/form/FilteringSelect",
+ "dijit/layout/ContentPane",
+ "dijit/layout/TabContainer",
+ "dijit/layout/LayoutContainer",
+ "dijit/form/Button",
+ "dijit/form/CheckBox",
+ "dijit/Toolbar",
+ "dijit/Tooltip",
+ "dijit/Menu",
+ "dijit/Dialog",
+ "dojo/cookie",
+ "dojox/grid/DataGrid",
+ "dojo/data/ItemFileReadStore",
+ "dojo/date/locale",
+ "dojo/date/stamp",
+ "fieldmapper/Fieldmapper",
+ "fieldmapper/dojoData",
+ "fieldmapper/OrgUtils",
+ "openils/CGI",
+ "openils/User",
+ "openils/Event",
+ "openils/Util",
+ "openils/MarcXPathParser",
+ "openils/widget/GridColumnPicker",
+ "openils/PermaCrud",
+ "openils/widget/OrgUnitFilteringSelect",
+ "openils/widget/AutoGrid",
+ "openils/widget/AutoFieldWidget",
+ "openils/widget/ProgressDialog"
+ ],
+function(dojo_parser,
+ dojo_io_iframe,
+ dijit_ProgressBar,
+ dijit_form_FilteringSelect,
+ dijit_layout_ContentPane,
+ dijit_layout_TabContainer,
+ dijit_layout_LayoutContainer,
+ dijit_form_Button,
+ dijit_form_CheckBox,
+ dijit_Toolbar,
+ dijit_Tooltip,
+ dijit_Menu,
+ dijit_Dialog,
+ dojo_cookie,
+ dojox_grid_DataGrid,
+ dojo_data_ItemFileReadStore,
+ dojo_date_locale,
+ dojo_date_stamp,
+ fieldmapper_Fieldmapper,
+ fieldmapper_dojoData,
+ fieldmapper_OrgUtils,
+ openils_CGI,
+ openils_User,
+ openils_Event,
+ openils_Util,
+ openils_MarcXPathParser,
+ openils_widget_GridColumnPicker,
+ openils_PermaCrud,
+ openils_widget_OrgUnitFilteringSelect,
+ openils_widget_AutoGrid,
+ openils_widget_AutoFieldWidget,
+ openils_widget_ProgressDialog){
+ /* ---------------------------------------------------------------------------
+ # Copyright (C) 2008 Georgia Public Library Service
+ # Bill Erickson <erickson@esilibrary.com>
+ #
+ # This program is free software; you can redistribute it and/or
+ # modify it under the terms of the GNU General Public License
+ # as published by the Free Software Foundation; either version 2
+ # of the License, or (at your option) any later version.
+ #
+ # This program is distributed in the hope that it will be useful,
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ # GNU General Public License for more details.
+ # --------------------------------------------------------------------------- */
+
+
+ var globalDivs = [
+ 'vl-generic-progress',
+ 'vl-generic-progress-with-total',
+ 'vl-marc-upload-div',
+ 'vl-queue-div',
+ 'vl-match-div',
+ 'vl-marc-html-div',
+ 'vl-queue-select-div',
+ 'vl-marc-upload-status-div',
+ 'vl-attr-editor-div',
+ 'vl-marc-export-div',
+ 'vl-profile-editor-div',
+ 'vl-item-attr-editor-div',
+ 'vl-import-error-div'
+ ];
+
+ var authtoken;
+ var VANDELAY_URL = '/vandelay-upload';
+ var bibAttrDefs = [];
+ var authAttrDefs = [];
+ var queuedRecords = [];
+ var queuedRecordsMap = {};
+ var bibAttrsFetched = false;
+ var authAttrsFetched = false;
+ var attrDefMap = {}; // maps attr def code names to attr def ids
+ var currentType;
+ var currentQueueId = null;
+ var userCache = {};
+ var currentMatchedRecords; // set of loaded matched bib records
+ var currentOverlayRecordsMap; // map of import record to overlay record
+ var currentOverlayRecordsMapGid; // map of import record to overlay record grid id
+ var currentImportRecId; // when analyzing matches, this is the current import record
+ var userBibQueues = []; // only non-complete queues
+ var userAuthQueues = []; // only non-complete queues
+ var allUserBibQueues;
+ var allUserAuthQueues;
+ var selectableGridRecords;
+ var cgi = new openils_CGI();
+ var vlQueueGridColumePicker = {};
+ var vlBibSources = [];
+ var importItemDefs = [];
+ var matchSets = {};
+ var mergeProfiles = [];
+ var copyStatusCache = {};
+ var copyLocationCache = {};
+ var localeStrings;
+
+ /**
+ * Grab initial data
+ */
+ function vlInit() {
+
+ dojo.requireLocalization("openils.vandelay", "vandelay");
+ localeStrings = dojo.i18n.getLocalization("openils.vandelay", "vandelay");
+
+ authtoken = openils_User.authtoken;
+ var initNeeded = 8; // how many async responses do we need before we're init'd
+ var initCount = 0; // how many async reponses we've received
+
+ openils_Util.registerEnterHandler(
+ vlQueueDisplayPage.domNode, function(){retrieveQueuedRecords();});
+ openils_Util.addCSSClass(dojo.byId('vl-menu-marc-upload'), 'toolbar_selected');
+
+ function checkInitDone() {
+ initCount++;
+ if(initCount == initNeeded)
+ runStartupCommands();
}
- }
- );
-}
-
-function attrEditorFetchAttrDefs(callback) {
- var fn = (ATTR_EDIT_GROUP == 'auth') ? vlFetchAuthAttrDefs : vlFetchBibAttrDefs;
- return fn(callback);
-}
-
-function vlAttrDelete() {
- idHide('vl-attr-editor-div');
- idShow('vl-generic-progress');
-
- var isAuth = (ATTR_EDIT_GROUP == 'auth');
- var method = 'open-ils.permacrud.delete.' + (isAuth ? 'vqarad' : 'vqbrad');
- var rad = isAuth ? new vqarad() : new vqbrad() ;
- fieldmapper.standardRequest(
- ['open-ils.permacrud', method],
- { async: true,
- params: [authtoken, rad.fromHash({ id : ATTR_EDIT_ID }), ],
- oncomplete: function() {
- dijit.byId('attr-editor-dialog').onCancel(); // close the dialog
- attrEditorFetchAttrDefs(vlShowAttrEditor);
- ATTR_EDIT_ID = null;
- },
- onerror: function(r) {
- alert('vlAttrDelete comms error: ' + r);
+
+ mergeProfiles = new openils_PermaCrud().retrieveAll('vmp');
+ vlUploadMergeProfile.store = new dojo_data_ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
+ vlUploadMergeProfile.labelAttr = 'name';
+ vlUploadMergeProfile.searchAttr = 'name';
+ vlUploadMergeProfile.startup();
+
+ vlUploadMergeProfile2.store = new dojo_data_ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
+ vlUploadMergeProfile2.labelAttr = 'name';
+ vlUploadMergeProfile2.searchAttr = 'name';
+ vlUploadMergeProfile2.startup();
+
+ vlUploadFtMergeProfile.store = new dojo_data_ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
+ vlUploadFtMergeProfile.labelAttr = 'name';
+ vlUploadFtMergeProfile.searchAttr = 'name';
+ vlUploadFtMergeProfile.startup();
+
+ vlUploadFtMergeProfile2.store = new dojo_data_ItemFileReadStore({data:fieldmapper.vmp.toStoreData(mergeProfiles)});
+ vlUploadFtMergeProfile2.labelAttr = 'name';
+ vlUploadFtMergeProfile2.searchAttr = 'name';
+ vlUploadFtMergeProfile2.startup();
+
+
+ // Fetch the bib and authority attribute definitions
+ vlFetchBibAttrDefs(function () { checkInitDone(); });
+ vlFetchAuthAttrDefs(function () { checkInitDone(); });
+
+ vlRetrieveQueueList('bib', null,
+ function(list) {
+ allUserBibQueues = list;
+ for(var i = 0; i < allUserBibQueues.length; i++) {
+ if(allUserBibQueues[i].complete() == 'f')
+ userBibQueues.push(allUserBibQueues[i]);
+ }
+ checkInitDone();
+ }
+ );
+
+ vlRetrieveQueueList('auth', null,
+ function(list) {
+ allUserAuthQueues = list;
+ for(var i = 0; i < allUserAuthQueues.length; i++) {
+ if(allUserAuthQueues[i].complete() == 'f')
+ userAuthQueues.push(allUserAuthQueues[i]);
+ }
+ checkInitDone();
+ }
+ );
+
+ fieldmapper.standardRequest(
+ ['open-ils.permacrud', 'open-ils.permacrud.search.cbs.atomic'],
+ { async: true,
+ params: [authtoken, {id:{"!=":null}}, {order_by:{cbs:'id'}}],
+ oncomplete : function(r) {
+ vlBibSources = openils_Util.readResponse(r, false, true);
+ checkInitDone();
+ }
+ }
+ );
+
+ var owner = fieldmapper.aou.orgNodeTrail(fieldmapper.aou.findOrgUnit(new openils_User().user.ws_ou()));
+ new openils_PermaCrud().search('viiad',
+ {owner: owner.map(function(org) { return org.id(); })},
+ { async: true,
+ oncomplete: function(r) {
+ importItemDefs = openils_Util.readResponse(r);
+ checkInitDone();
+ }
+ }
+ );
+
+ new openils_PermaCrud().search('vms',
+ {owner: owner.map(function(org) { return org.id(); })},
+ { async: true,
+ oncomplete: function(r) {
+ var sets = openils_Util.readResponse(r);
+ dojo.forEach(sets,
+ function(set) {
+ if(!matchSets[set.mtype()])
+ matchSets[set.mtype()] = [];
+ matchSets[set.mtype()].push(set);
+ }
+ );
+ checkInitDone();
+ }
+ }
+ );
+
+ new openils_PermaCrud().retrieveAll('ccs',
+ { async: true,
+ oncomplete: function(r) {
+ var stats = openils_Util.readResponse(r);
+ dojo.forEach(stats, function(stat){copyStatusCache[stat.id()] = stat});
+ checkInitDone();
+ }
+ }
+ );
+
+ vlAttrEditorInit();
+ vlExportInit();
+ }
+
+
+ openils_Util.addOnLoad(vlInit);
+
+
+ // fetch the bib and authority attribute definitions
+
+ function vlFetchBibAttrDefs(postcomplete) {
+ bibAttrDefs = [];
+ fieldmapper.standardRequest(
+ ['open-ils.permacrud', 'open-ils.permacrud.search.vqbrad'],
+ { async: true,
+ params: [authtoken, {id:{'!=':null}}],
+ onresponse: function(r) {
+ var def = r.recv().content();
+ if(e = openils_Event.parse(def[0]))
+ return alert(e);
+ bibAttrDefs.push(def);
+ },
+ oncomplete: function() {
+ bibAttrDefs = bibAttrDefs.sort(
+ function(a, b) {
+ if(a.id() > b.id()) return 1;
+ if(a.id() < b.id()) return -1;
+ return 0;
+ }
+ );
+ postcomplete();
+ }
+ }
+ );
+ }
+
+ function vlFetchAuthAttrDefs(postcomplete) {
+ authAttrDefs = [];
+ fieldmapper.standardRequest(
+ ['open-ils.permacrud', 'open-ils.permacrud.search.vqarad'],
+ { async: true,
+ params: [authtoken, {id:{'!=':null}}],
+ onresponse: function(r) {
+ var def = r.recv().content();
+ if(e = openils_Event.parse(def[0]))
+ return alert(e);
+ authAttrDefs.push(def);
+ },
+ oncomplete: function() {
+ authAttrDefs = authAttrDefs.sort(
+ function(a, b) {
+ if(a.id() > b.id()) return 1;
+ if(a.id() < b.id()) return -1;
+ return 0;
+ }
+ );
+ postcomplete();
+ }
+ }
+ );
+ }
+
+ function vlRetrieveQueueList(type, filter, onload) {
+ type = (type == 'bib') ? type : 'authority';
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', 'open-ils.vandelay.'+type+'_queue.owner.retrieve.atomic'],
+ { async: true,
+ params: [authtoken, null, filter],
+ oncomplete: function(r) {
+ var list = r.recv().content();
+ if(e = openils_Event.parse(list[0]))
+ return alert(e);
+ onload(list);
+ }
+ }
+ );
+
+ }
+
+ function displayGlobalDiv(id) {
+ for(var i = 0; i < globalDivs.length; i++) {
+ try {
+ dojo.style(dojo.byId(globalDivs[i]), 'display', 'none');
+ } catch(e) {
+ alert('please define div ' + globalDivs[i]);
+ }
}
- }
- );
-}
-
-// ------------------------------------------------------------
-// utilities for attribute editors
-
-// dom utilities (maybe dojo does these, and these should be replaced)
-
-function idStyle(obId, k, v) { document.getElementById(obId).style[k] = v; }
-function idShow(obId) { idStyle(obId, 'display', 'block'); }
-function idHide(obId) { idStyle(obId, 'display' , 'none'); }
-
-function connectTooltip(fieldId) {
- // Given an element id, look up a tooltip element in the doc (same
- // id with a '-tip' suffix) and associate the two. Maybe dojo has
- // a better way to do this?
- var fld = dojo.byId(fieldId);
- var tip = dojo.byId(fieldId + '-tip');
- dojo.connect(fld, 'onfocus', function(evt) {
- dijit.showTooltip(tip.innerHTML, fld, ['below', 'after']); });
- dojo.connect(fld, 'onblur', function(evt) { dijit.hideTooltip(fld); });
-}
-
-// xpath utilities
-
-var xpathParser = new openils.MarcXPathParser();
-
-function tagAndSubFieldsToXpath(tags, subfields) {
- // given tags, and subfields, build up an XPath.
- try {
- var parts = {
- 'tags':tags.match(/[\d]+/g),
- 'subfields':subfields.match(/[a-zA-z]/g) };
- return xpathParser.compile(parts);
- } catch (err) {
- return {'parts':null, 'tags':null, 'error':err};
- }
-}
-
-function looksLikeDerivedXpath(path) {
- // Does this path look like it was derived from tags and subfields?
- var parsed = xpathParser.parse(path);
- if (parsed.tags == null)
- return false;
- var compiled = xpathParser.compile(parsed);
- return (path == compiled);
-}
-
-// amazing xpath-util unit-tests
-if (!looksLikeDerivedXpath('//*[@tag="901"]/*[@code="c"]')) alert('vandelay xpath-utility error');
-if ( looksLikeDerivedXpath('ba-boo-ba-boo!')) alert('vandelay xpath-utility error');
-
-
-
-var profileContextOrg
-function vlShowProfileEditor() {
- displayGlobalDiv('vl-profile-editor-div');
- buildProfileGrid();
-
- var connect = function() {
- dojo.connect(profileContextOrgSelector, 'onChange',
- function() {
- profileContextOrg = this.attr('value');
- pGrid.resetStore();
- buildProfileGrid();
- }
- );
- };
-
- new openils.User().buildPermOrgSelector(
- 'ADMIN_MERGE_PROFILE', profileContextOrgSelector, null, connect);
-}
-
-function buildProfileGrid() {
-
- if(profileContextOrg == null)
- profileContextOrg = openils.User.user.ws_ou();
-
- pGrid.loadAll(
- {order_by : {vmp : 'name'}},
- {owner : fieldmapper.aou.fullPath(profileContextOrg, true)}
- );
-}
-
-/* --- Import Item Attr Grid --------------- */
-
-var itemAttrContextOrg;
-var itemAttrGridFirstTime = true;
-function vlShowImportItemAttrEditor() {
- displayGlobalDiv('vl-item-attr-editor-div');
-
- if (itemAttrGridFirstTime) {
-
- buildImportItemAttrGrid();
-
- var connect = function() {
- dojo.connect(itemAttrContextOrgSelector, 'onChange',
- function() {
- itemAttrContextOrg = this.attr('value');
- itemAttrGrid.resetStore();
- buildImportItemAttrGrid();
- }
- );
- };
-
- new openils.User().buildPermOrgSelector(
- 'ADMIN_IMPORT_ITEM_ATTR_DEF',
- itemAttrContextOrgSelector, null, connect);
-
- itemAttrGridFirstTime = false;
- }
-}
-
-function buildImportItemAttrGrid() {
-
- if(itemAttrContextOrg == null)
- itemAttrContextOrg = openils.User.user.ws_ou();
-
- itemAttrGrid.loadAll(
- {order_by : {viiad : 'name'}},
- {owner : fieldmapper.aou.fullPath(itemAttrContextOrg, true)}
- );
-}
-
+ dojo.style(dojo.byId(id),'display','block');
+
+ openils_Util.removeCSSClass(dojo.byId('vl-menu-marc-export'), 'toolbar_selected');
+ openils_Util.removeCSSClass(dojo.byId('vl-menu-marc-upload'), 'toolbar_selected');
+ openils_Util.removeCSSClass(dojo.byId('vl-menu-queue-select'), 'toolbar_selected');
+ openils_Util.removeCSSClass(dojo.byId('vl-menu-attr-editor'), 'toolbar_selected');
+ openils_Util.removeCSSClass(dojo.byId('vl-menu-profile-editor'), 'toolbar_selected');
+ openils_Util.removeCSSClass(dojo.byId('vl-menu-match-set-editor'), 'toolbar_selected');
+
+ if(dojo.byId('vl-match-set-iframe'))
+ dojo.byId('vl-match-set-editor-div').removeChild(dojo.byId('vl-match-set-iframe'));
+
+ switch(id) {
+ case 'vl-marc-export-div':
+ openils_Util.addCSSClass(dojo.byId('vl-menu-marc-export'), 'toolbar_selected');
+ break;
+ case 'vl-marc-upload-div':
+ openils_Util.addCSSClass(dojo.byId('vl-menu-marc-upload'), 'toolbar_selected');
+ break;
+ case 'vl-queue-select-div':
+ openils_Util.addCSSClass(dojo.byId('vl-menu-queue-select'), 'toolbar_selected');
+ break;
+ case 'vl-attr-editor-div':
+ openils_Util.addCSSClass(dojo.byId('vl-menu-attr-editor'), 'toolbar_selected');
+ break;
+ case 'vl-profile-editor-div':
+ openils_Util.addCSSClass(dojo.byId('vl-menu-profile-editor'), 'toolbar_selected');
+ break;
+ case 'vl-item-attr-editor-div':
+ openils_Util.addCSSClass(dojo.byId('vl-menu-import-item-attr-editor'), 'toolbar_selected');
+ break;
+ case 'vl-match-set-editor-div':
+ openils_Util.addCSSClass(dojo.byId('vl-menu-match-set-editor'), 'toolbar_selected');
+ break;
+ }
+ }
+
+ function runStartupCommands() {
+ openils_Util.hide(dojo.byId('vl-page-loading'));
+ openils_Util.show(dojo.byId('vl-body-wrapper'));
+ currentQueueId = cgi.param('qid');
+ currentType = cgi.param('qtype');
+ dojo.style('vl-nav-bar', 'visibility', 'visible');
+ if(currentQueueId)
+ return retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ if (cgi.param('page', 'inspectq'))
+ return displayGlobalDiv('vl-queue-select-div');
+
+ vlShowUploadForm();
+ }
+
+ /**
+ * asynchronously upload a file of MARC records
+ */
+ function uploadMARC(onload){
+ dojo.byId('vl-upload-status-count').innerHTML = '0';
+ dojo.byId('vl-ses-input').value = authtoken;
+ displayGlobalDiv('vl-marc-upload-status-div');
+ dojo_io_iframe.send({
+ url: VANDELAY_URL,
+ method: "post",
+ handleAs: "html",
+ form: dojo.byId('vl-marc-upload-form'),
+ handle: function(data,ioArgs){
+ var content = data.documentElement.textContent;
+ onload(content);
+ }
+ });
+ }
+
+ /**
+ * Creates a new vandelay queue
+ */
+ function createQueue(queueName, type, onload, importDefId, matchSet) {
+ var name = (type=='bib') ? 'bib' : 'authority';
+ var method = 'open-ils.vandelay.'+ name +'_queue.create'
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', method],
+ { async: true,
+ params: [authtoken, queueName, null, name, matchSet, importDefId],
+ oncomplete : function(r) {
+ var queue = r.recv().content();
+ if(e = openils_Event.parse(queue))
+ return alert(e);
+ onload(queue);
+ }
+ }
+ );
+ }
+
+ /**
+ * Tells vandelay to pull a batch of records from the cache and explode them
+ * out into the vandelay tables
+ */
+ function processSpool(key, queueId, type, onload) {
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', 'open-ils.vandelay.'+type+'.process_spool'],
+ { async: true,
+ params: [authtoken, key, queueId],
+ onresponse : function(r) {
+ var resp = r.recv().content();
+ if(e = openils_Event.parse(resp))
+ return alert(e);
+ dojo.byId('vl-upload-status-count').innerHTML = resp;
+ },
+ oncomplete : function(r) {onload();}
+ }
+ );
+ }
+
+ function vlExportInit() {
+
+ // queue export
+ var qsel = dojo.byId('vl-queue-export-options');
+ qsel.onchange = function(newVal) {
+ var value = qsel.options[qsel.selectedIndex].value;
+ qsel.selectedIndex = 0;
+ if(!value) return;
+ if(!confirm('Export as "' + value + '"?')) return; // TODO: i18n
+ retrieveQueuedRecords(
+ currentType,
+ currentQueueId,
+ function(r) {
+ exportHandler(value, r);
+ displayGlobalDiv('vl-queue-div');
+ },
+ value
+ );
+ }
+
+ // item export
+ var isel = dojo.byId('vl-item-export-options');
+ isel.onchange = function(newVal) {
+ var value = isel.options[isel.selectedIndex].value;
+ isel.selectedIndex = 0;
+ if(!value) return;
+ if(!confirm('Export as "' + value + '"?')) return; // TODO: i18n
+
+ displayGlobalDiv('vl-generic-progress');
+ var method = 'open-ils.vandelay.import_item.queue.export.' + value + '.atomic';
+
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', method],
+ {
+ params : [
+ authtoken,
+ currentQueueId,
+ {with_import_error: (vlImportItemsShowErrors.checked) ? 1 : null}
+ ],
+ async : true,
+ oncomplete : function(r) {exportHandler(value, r)}
+ }
+ );
+ }
+ }
+
+ function exportHandler(type, response) {
+ displayGlobalDiv('vl-import-error-div');
+ try {
+ var content = openils_Util.readResponse(response);
+ if (type=='email') {
+ if (content==1) { alert('Email sent.'); return; }
+ throw(content);
+ }
+ /* handle .atomic versus non-atomic method calls */
+ content = content.constructor == Array
+ ? content[0].template_output().data()
+ : content.template_output().data();
+ switch(type) {
+ case 'print':
+ openils_Util.printHtmlString(content);
+ break;
+ case 'csv':
+ //content = content.replace(/\\t/g,'\t'); // if we really wanted to do .tsv instead
+ openils.XUL.contentToFileSaveDialog(content, null, {
+ defaultString : 'VandelayExport.csv',
+ defaultExtension : '.csv',
+ filterName : 'CSV',
+ filterExtension : '*.csv',
+ filterAll : true
+ } );
+ break;
+ default:
+ alert('response = ' + response + '\tcontent:\n' + content);
+ }
+ } catch(E) {
+ alert('Error exporting data: ' + E);
+ }
+ }
+
+ function retrieveQueuedRecords(type, queueId, onload, doExport) {
+ displayGlobalDiv('vl-generic-progress');
+ queuedRecords = [];
+ queuedRecordsMap = {};
+ currentOverlayRecordsMap = {};
+ currentOverlayRecordsMapGid = {};
+ selectableGridRecords = {};
+
+ if(!type) type = currentType;
+ if(!queueId) queueId = currentQueueId;
+ if(!onload) onload = handleRetrieveRecords;
+
+ var method = 'open-ils.vandelay.'+type+'_queue.records.retrieve';
+
+ if(doExport) method += '.export.' + doExport;
+ if(vlQueueGridShowMatches.checked)
+ method = method.replace('records', 'records.matches');
+
+ method += '.atomic';
+
+ var sel = dojo.byId('vl-queue-display-limit-selector');
+ var limit = parseInt(sel.options[sel.selectedIndex].value);
+ var offset = limit * parseInt(vlQueueDisplayPage.attr('value')-1);
+
+ var params = [authtoken, queueId, {clear_marc: 1, offset: offset, limit: limit, flesh_import_items:1}];
+ if(vlQueueGridShowNonImport.checked)
+ params[2].non_imported = 1;
+
+ if(vlQueueGridShowImportErrors.checked)
+ params[2].with_import_error = 1;
+
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', method],
+ { async: true,
+ params: params,
+ oncomplete: function(r){
+ if(doExport) return onload(r);
+ var recs = r.recv().content();
+ if(e = openils_Event.parse(recs[0]))
+ return alert(e);
+ for(var i = 0; i < recs.length; i++) {
+ var rec = recs[i];
+ queuedRecords.push(rec);
+ queuedRecordsMap[rec.id()] = rec;
+ }
+ onload();
+ }
+ }
+ );
+ }
+
+ function vlLoadMatchUI(recId) {
+ displayGlobalDiv('vl-generic-progress');
+ var queuedRec = queuedRecordsMap[recId];
+ var matches = queuedRec.matches();
+ var records = [];
+ currentImportRecId = recId;
+ for(var i = 0; i < matches.length; i++)
+ records.push(matches[i].eg_record());
+
+ var retrieve = ['open-ils.search', 'open-ils.search.biblio.record_entry.slim.retrieve'];
+ var params = [records];
+ if(currentType == 'auth') {
+ retrieve = ['open-ils.cat', 'open-ils.cat.authority.record.retrieve'];
+ params = [authtoken, records, {clear_marc:1}];
+ }
+
+ fieldmapper.standardRequest(
+ retrieve,
+ { async: true,
+ params:params,
+ oncomplete: function(r) {
+ var recs = r.recv().content();
+ if(e = openils_Event.parse(recs))
+ return alert(e);
+
+ /* ui mangling */
+ displayGlobalDiv('vl-match-div');
+ resetVlMatchGridLayout();
+ currentMatchedRecords = recs;
+ vlMatchGrid.setStructure(vlMatchGridLayout);
+
+ // build the data store of records with match information
+ var dataStore = bre.toStoreData(recs, null,
+ {virtualFields:['_id', 'match_score', 'match_quality', 'rec_quality']});
+ dataStore.identifier = '_id';
+
+ var matchSeenMap = {};
+
+ for(var i = 0; i < dataStore.items.length; i++) {
+ var item = dataStore.items[i];
+ item._id = i; // just need something unique
+ for(var j = 0; j < matches.length; j++) {
+ var match = matches[j];
+ if(match.eg_record() == item.id && !matchSeenMap[match.id()]) {
+ if(match.match_score)
+ item.match_score = match.match_score();
+ item.match_quality = match.quality();
+ item.rec_quality = queuedRec.quality();
+ matchSeenMap[match.id()] = 1;
+ break;
+ }
+ }
+ }
+
+ // now populate the grid
+ vlPopulateMatchGrid(vlMatchGrid, dataStore);
+ }
+ }
+ );
+ }
+
+ function vlPopulateMatchGrid(grid, data) {
+ var store = new dojo_data_ItemFileReadStore({data:data});
+ grid.setStore(store);
+ grid.update();
+ }
+
+ function showMe(id) {
+ dojo.style(dojo.byId(id), 'display', 'block');
+ }
+ function hideMe(id) {
+ dojo.style(dojo.byId(id), 'display', 'none');
+ }
+
+
+ function vlLoadMARCHtml(recId, inCat, oncomplete) {
+ dijit.byId('vl-marc-html-done-button').onClick = oncomplete;
+ displayGlobalDiv('vl-generic-progress');
+ var api;
+ var params = [recId, 1];
+
+ if(inCat) {
+ hideMe('vl-marc-html-edit-button'); // don't show marc editor button
+ dijit.byId('vl-marc-html-edit-button').onClick = function(){}
+ api = ['open-ils.search', 'open-ils.search.biblio.record.html'];
+ if(currentType == 'auth')
+ api = ['open-ils.search', 'open-ils.search.authority.to_html'];
+ } else {
+ showMe('vl-marc-html-edit-button'); // plug in the marc editor button
+ dijit.byId('vl-marc-html-edit-button').onClick =
+ function() {vlLoadMarcEditor(currentType, recId, oncomplete);};
+ params = [authtoken, recId];
+ api = ['open-ils.vandelay', 'open-ils.vandelay.queued_bib_record.html'];
+ if(currentType == 'auth')
+ api = ['open-ils.vandelay', 'open-ils.vandelay.queued_authority_record.html'];
+ }
+
+ fieldmapper.standardRequest(
+ api,
+ { async: true,
+ params: params,
+ oncomplete: function(r) {
+ displayGlobalDiv('vl-marc-html-div');
+ var html = r.recv().content();
+ dojo.byId('vl-marc-record-html').innerHTML = html;
+ }
+ }
+ );
+ }
+
+
+ /*
+ function getRecMatchesFromAttrCode(rec, attrCode) {
+ var matches = [];
+ var attr = getRecAttrFromCode(rec, attrCode);
+ for(var j = 0; j < rec.matches().length; j++) {
+ var match = rec.matches()[j];
+ if(match.matched_attr() == attr.id())
+ matches.push(match);
+ }
+ return matches;
+ }
+ */
+
+ /*
+ function getRecAttrFromMatch(rec, match) {
+ for(var i = 0; i < rec.attributes().length; i++) {
+ var attr = rec.attributes()[i];
+ if(attr.id() == match.matched_attr())
+ return attr;
+ }
+ }
+ */
+
+ function getRecAttrDefFromAttr(attr, type) {
+ var defs = (type == 'bib') ? bibAttrDefs : authAttrDefs;
+ for(var i = 0; i < defs.length; i++) {
+ var def = defs[i];
+ if(def.id() == attr.field())
+ return def;
+ }
+ }
+
+ function getRecAttrFromCode(rec, attrCode) {
+ var defId = attrDefMap[currentType][attrCode];
+ var attrs = rec.attributes();
+ for(var i = 0; i < attrs.length; i++) {
+ var attr = attrs[i];
+ if(attr.field() == defId)
+ return attr;
+ }
+ return null;
+ }
+
+ function vlGetViewMatches(rowIdx, item) {
+ if(item) {
+ var id = this.grid.store.getValue(item, 'id');
+ var rec = queuedRecordsMap[id];
+ if(rec.matches().length > 0)
+ return id + ':' + rec.matches().length;
+ }
+ return -1
+ }
+
+ function vlFormatViewMatches(id) {
+ if(id == -1) return '';
+ var chunks = id.split(':');
+ id = chunks[0];
+ count = chunks[1];
+ return '<a href="javascript:void(0);" onclick="vlLoadMatchUI(' + id + ');">' + this.name + ' (' + count + ')</a>';
+ }
+
+ function vlGetViewErrors(rowIdx, item) {
+ if(item) {
+ var id = this.grid.store.getValue(item, 'id');
+ var rec = queuedRecordsMap[id];
+ // id:rec_error:item_import_error_count
+ return id + ':' +
+ (rec.import_error() ? 1 : '') + ':' +
+ (typeof rec.import_items == 'function'
+ ? rec.import_items().filter(function(i) {return i.import_error()}).length
+ :''
+ );
+ }
+ return -1
+ }
+
+ function vlFormatViewErrors(chunk) {
+ if(chunk == -1) return '';
+ var id = chunk.split(':')[0];
+ var rec = chunk.split(':')[1];
+ var count = chunk.split(':')[2];
+ var links = '';
+ if(rec)
+ links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');">Record</a><br/>'; // TODO I18N
+ if(Number(count))
+ links += '<a href="javascript:void(0);" onclick="vlLoadErrorUI(' + id + ');">Items ('+count+')</a>'; // TODO I18N
+ return links;
+ }
+
+ //var vlItemErrorColumnPicker;
+ function vlLoadErrorUI(id) {
+
+ displayGlobalDiv('vl-import-error-div');
+ openils_Util.hide('vl-import-error-grid-all');
+ openils_Util.show('vl-import-error-record');
+
+ var rec = queuedRecordsMap[id];
+
+ dojo.byId('vl-error-id').innerHTML = rec.id();
+ dojo.forEach( // TODO sane authority rec. fields
+ ['title', 'author', 'isbn', 'issn', 'upc'],
+ function(field) {
+ var attr = getRecAttrFromCode(rec, field);
+ var eid = 'vl-error-' + field;
+ if(attr) {
+ openils_Util.show(dojo.byId(eid).parentNode, 'table-row');
+ dojo.byId(eid).innerHTML = attr.attr_value();
+ } else {
+ openils_Util.hide(dojo.byId(eid).parentNode);
+ }
+ }
+ );
+ var iediv = dojo.byId('vl-error-import-error');
+ var eddiv = dojo.byId('vl-error-error-detail');
+ if(rec.import_error()) {
+ openils_Util.show(iediv.parentNode, 'table-row');
+ openils_Util.show(eddiv.parentNode, 'table-row');
+ iediv.innerHTML = rec.import_error();
+ eddiv.innerHTML = rec.error_detail();
+ } else {
+ openils_Util.hide(iediv.parentNode);
+ openils_Util.hide(eddiv.parentNode);
+ }
+
+ var errorItems = rec.import_items().filter(function(i) {return i.import_error()});
+ if(errorItems.length) {
+ openils_Util.show('vl-import-error-grid-some');
+ storeData = vqbr.toStoreData(errorItems);
+ var store = new dojo_data_ItemFileReadStore({data:storeData});
+ vlImportErrorGrid.setStore(store);
+ vlImportErrorGrid.update();
+ } else {
+ openils_Util.hide('vl-import-error-grid-some');
+ }
+ }
+
+ function vlLoadErrorUIAll() {
+
+ displayGlobalDiv('vl-import-error-div');
+ openils_Util.hide('vl-import-error-grid-some');
+ openils_Util.hide('vl-import-error-record');
+ openils_Util.show('vl-import-error-grid-all');
+ vlAllImportErrorGrid.resetStore();
+
+ vlImportErrorGrid.displayOffset = 0;
+
+ vlAllImportErrorGrid.dataLoader = function() {
+
+ vlAllImportErrorGrid.showLoadProgressIndicator();
+
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', 'open-ils.vandelay.import_item.queue.retrieve'],
+ {
+ async : true,
+ params : [
+ authtoken, currentQueueId, {
+ with_import_error: (vlImportItemsShowErrors.checked) ? 1 : null,
+ offset : vlAllImportErrorGrid.displayOffset,
+ limit : vlAllImportErrorGrid.displayLimit
+ }
+ ],
+ onresponse : function(r) {
+ var item = openils_Util.readResponse(r);
+ if(!item) return;
+ vlAllImportErrorGrid.store.newItem(vii.toStoreItem(item));
+ },
+ oncomplete : function() {
+ vlAllImportErrorGrid.hideLoadProgressIndicator();
+ }
+ }
+ );
+ };
+
+ vlAllImportErrorGrid.dataLoader();
+ }
+
+ function vlGetOrg(rowIdx, item) {
+ if(!item) return '';
+ var value = this.grid.store.getValue(item, this.field);
+ if(value) return fieldmapper.aou.findOrgUnit(value).shortname();
+ return '';
+ }
+
+ function vlCopyStatus(rowIdx, item) {
+ if(!item) return '';
+ var value = this.grid.store.getValue(item, this.field);
+ if(value) return copyStatusCache[value].name();
+ return '';
+ }
+
+ // Note, we don't pre-fetch all copy locations because there could be
+ // a lot of them. Instead, fetch-and-cache on demand.
+ function vlCopyLocation(rowIdx, item) {
+ if(item) {
+ var value = this.grid.store.getValue(item, this.field);
+ if(value) {
+ if(!copyLocationCache[value]) {
+ copyLocationCache[value] =
+ new openils_PermaCrud().retrieve('acpl', value);
+ }
+ return copyLocationCache[value].name();
+ }
+ }
+ return '';
+ }
+
+ function vlFormatViewMatchMARC(id) {
+ return '<a href="javascript:void(0);" onclick="vlLoadMARCHtml(' + id + ', true, '+
+ 'function(){displayGlobalDiv(\'vl-match-div\');});">' + this.name + '</a>';
+ }
+
+ function getAttrValue(rowIdx, item) {
+ if(!item) return '';
+ var attrCode = this.field.split('.')[1];
+ var rec = queuedRecordsMap[this.grid.store.getValue(item, 'id')];
+ var attr = getRecAttrFromCode(rec, attrCode);
+ return (attr) ? attr.attr_value() : '';
+ }
+
+ function vlGetDateTimeField(rowIdx, item) {
+ if(!item) return '';
+ var value = this.grid.store.getValue(item, this.field);
+ if(!value) return '';
+ var date = dojo_date_stamp.fromISOString(value);
+ return dojo_date_locale.format(date, {selector:'date'});
+ }
+
+ function vlGetCreator(rowIdx, item) {
+ if(!item) return '';
+ var id = this.grid.store.getValue(item, 'creator');
+ if(userCache[id])
+ return userCache[id].usrname();
+ var user = fieldmapper.standardRequest(
+ ['open-ils.actor', 'open-ils.actor.user.retrieve'], [authtoken, id]);
+ if(e = openils_Event.parse(user))
+ return alert(e);
+ userCache[id] = user;
+ return user.usrname();
+ }
+
+ function vlGetViewMARC(rowIdx, item) {
+ return item && this.grid.store.getValue(item, 'id');
+ }
+
+ function vlFormatViewMARC(id) {
+ return '<a href="javascript:void(0);" onclick="vlLoadMARCHtml(' + id + ', false, '+
+ 'function(){displayGlobalDiv(\'vl-queue-div\');});">' + this.name + '</a>';
+ }
+
+ function vlGetOverlayTargetSelector(rowIdx, item) {
+ if(!item) return;
+ return this.grid.store.getValue(item, '_id') + ':' + this.grid.store.getValue(item, 'id');
+ }
+
+ function vlFormatOverlayTargetSelector(val) {
+ if(!val) return '';
+ var parts = val.split(':');
+ var _id = parts[0];
+ var id = parts[1];
+ var value = '<input type="checkbox" name="vl-overlay-target-RECID" '+
+ 'onclick="vlHandleOverlayTargetSelected(ID, GRIDID);" gridid="GRIDID" match="ID"/>';
+ value = value.replace(/GRIDID/g, _id);
+ value = value.replace(/RECID/g, currentImportRecId);
+ value = value.replace(/ID/g, id);
+ if(_id == currentOverlayRecordsMapGid[currentImportRecId])
+ return value.replace('/>', 'checked="checked"/>');
+ return value;
+ }
+
+
+ /**
+ * see if the user has enabled overlays for the current match set and,
+ * if so, map the current import record to the overlay target.
+ */
+ function vlHandleOverlayTargetSelected(recId, gridId) {
+ var noneSelected = true;
+ var checkboxes = dojo.query('[name=vl-overlay-target-'+currentImportRecId+']');
+ for(var i = 0; i < checkboxes.length; i++) {
+ var checkbox = checkboxes[i];
+ var matchRecId = checkbox.getAttribute('match');
+ var gid = checkbox.getAttribute('gridid');
+ if(checkbox.checked) {
+ if(matchRecId == recId && gid == gridId) {
+ noneSelected = false;
+ currentOverlayRecordsMap[currentImportRecId] = matchRecId;
+ currentOverlayRecordsMapGid[currentImportRecId] = gid;
+ dojo.byId('vl-record-list-selected-' + currentImportRecId).checked = true;
+ dojo.byId('vl-record-list-selected-' + currentImportRecId).parentNode.className = 'overlay_selected';
+ } else {
+ checkbox.checked = false;
+ }
+ }
+ }
+
+ if(noneSelected) {
+ delete currentOverlayRecordsMap[currentImportRecId];
+ delete currentOverlayRecordsMapGid[currentImportRecId];
+ dojo.byId('vl-record-list-selected-' + currentImportRecId).checked = false;
+ dojo.byId('vl-record-list-selected-' + currentImportRecId).parentNode.className = '';
+ }
+ }
+
+ var valLastQueueType = null;
+ var vlQueueGridLayout = null;
+ function buildRecordGrid(type) {
+ displayGlobalDiv('vl-queue-div');
+
+ vlBibQueueGrid.canSort = function(col){ if(Math.abs(col) == 1) { return false; } else { return true; } };
+ vlAuthQueueGrid.canSort = function(col){ if(Math.abs(col) == 1) { return false; } else { return true; } };
+
+ if(type == 'bib') {
+ openils_Util.show('vl-bib-queue-grid-wrapper');
+ openils_Util.hide('vl-auth-queue-grid-wrapper');
+ vlQueueGrid = vlBibQueueGrid;
+ openils_Util.show('add-to-bucket-action', 'table-row');
+ } else {
+ openils_Util.show('vl-auth-queue-grid-wrapper');
+ openils_Util.hide('vl-bib-queue-grid-wrapper');
+ vlQueueGrid = vlAuthQueueGrid;
+ openils_Util.hide('add-to-bucket-action');
+ }
+
+
+ if(valLastQueueType != type) {
+ valLastQueueType = type;
+ vlQueueGridLayout = vlQueueGrid.attr('structure');
+ var defs = (type == 'bib') ? bibAttrDefs : authAttrDefs;
+ attrDefMap[type] = {};
+ for(var i = 0; i < defs.length; i++) {
+ var def = defs[i]
+ attrDefMap[type][def.code()] = def.id();
+ var col = {
+ name:def.description(),
+ field:'attr.' + def.code(),
+ get: getAttrValue,
+ selectableColumn:true
+ };
+ vlQueueGridLayout[0].cells[0].push(col);
+ }
+ }
+
+ dojo.forEach(vlQueueGridLayout[0].cells[0],
+ function(cell) {
+ if(cell.field.match(/^\+/))
+ cell.nonSelectable=true;
+ }
+ );
+
+ var storeData;
+ if(type == 'bib')
+ storeData = vqbr.toStoreData(queuedRecords);
+ else
+ storeData = vqar.toStoreData(queuedRecords);
+
+ var store = new dojo_data_ItemFileReadStore({data:storeData});
+ vlQueueGrid.setStore(store);
+
+ if(vlQueueGridColumePicker[type]) {
+ vlQueueGrid.update();
+ } else {
+
+ vlQueueGridColumePicker[type] =
+ new openils_widget_GridColumnPicker(
+ authtoken, 'vandelay.queue.'+type, vlQueueGrid, vlQueueGridLayout);
+ vlQueueGridColumePicker[type].load();
+ }
+ }
+
+ function vlQueueGridPrevPage() {
+ var page = parseInt(vlQueueDisplayPage.getValue());
+ if(page < 2) return;
+ vlQueueDisplayPage.setValue(page - 1);
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+
+ function vlQueueGridNextPage() {
+ vlQueueDisplayPage.setValue(parseInt(vlQueueDisplayPage.getValue())+1);
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+
+ function vlDeleteQueue(type, queueId, onload) {
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', 'open-ils.vandelay.'+type+'_queue.delete'],
+ { async: true,
+ params: [authtoken, queueId],
+ oncomplete: function(r) {
+ var resp = r.recv().content();
+ if(e = openils_Event.parse(resp))
+ return alert(e);
+ onload();
+ }
+ }
+ );
+ }
+
+
+ function vlQueueGridDrawSelectBox(rowIdx, item) {
+ return item && this.grid.store.getValue(item, 'id');
+ }
+
+ function vlQueueGridFormatSelectBox(id) {
+ var domId = 'vl-record-list-selected-' + id;
+ if (id) { selectableGridRecords[domId] = id; }
+ return "<div><input type='checkbox' id='"+domId+"'/></div>";
+ }
+
+ function vlSelectAllQueueGridRecords() {
+ for(var id in selectableGridRecords)
+ dojo.byId(id).checked = true;
+ }
+ function vlSelectNoQueueGridRecords() {
+ for(var id in selectableGridRecords)
+ dojo.byId(id).checked = false;
+ }
+ function vlToggleQueueGridSelect() {
+ if(dojo.byId('vl-queue-grid-row-selector').checked)
+ vlSelectAllQueueGridRecords();
+ else
+ vlSelectNoQueueGridRecords();
+ }
+
+ var handleRetrieveRecords = function() {
+ buildRecordGrid(currentType);
+ vlFetchQueueSummary(currentQueueId, currentType,
+ function(summary) {
+ dojo.byId('vl-queue-summary-name').innerHTML = summary.queue.name();
+ dojo.byId('vl-queue-summary-total-count').innerHTML = summary.total +'';
+ dojo.byId('vl-queue-summary-import-count').innerHTML = summary.imported + '';
+ dojo.byId('vl-queue-summary-import-item-count').innerHTML = summary.total_items + '';
+ dojo.byId('vl-queue-summary-import-item-imported-count').innerHTML = summary.total_items_imported + '';
+ dojo.byId('vl-queue-summary-rec-error-count').innerHTML = summary.rec_import_errors + '';
+ dojo.byId('vl-queue-summary-item-error-count').innerHTML = summary.item_import_errors + '';
+
+ if (dojo.byId('create-bucket-dialog-name')) {
+ dojo.byId('create-bucket-dialog-name').value = summary.queue.name();
+ }
+ }
+ );
+ }
+
+ function vlFetchQueueSummary(qId, type, onload) {
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', 'open-ils.vandelay.'+type+'_queue.summary.retrieve'],
+ { async: true,
+ params: [authtoken, qId],
+ oncomplete : function(r) {
+ var summary = r.recv().content();
+ if(e = openils_Event.parse(summary))
+ return alert(e);
+ return onload(summary);
+ }
+ }
+ );
+ }
+
+ function handleCreateBucket(args) {
+ var bname = dojo.byId('create-bucket-dialog-name').value;
+ if (!bname) return;
+
+ progressDialog.show(true);
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', 'open-ils.vandelay.bib_queue.to_bucket'],
+ { async : true,
+ params : [authtoken, currentQueueId, bname],
+ oncomplete : function(r) {
+ progressDialog.hide();
+ setTimeout(function() {
+ var resp = openils_Util.readResponse(r);
+ if (resp.add_count == 0) {
+ alert(localeStrings.NO_BUCKET_ITEMS);
+ } else {
+ alert(
+ dojo.string.substitute(
+ localeStrings.BUCKET_CREATE_SUCCESS,
+ [resp.add_count, bname, resp.item_count]
+ )
+ );
+ }
+ }, 200); // give the dialog a chance to hide
+ }
+ }
+ );
+ }
+
+
+ var _importCancelHandler;
+ var _importGoHandler;
+ function vlHandleQueueItemsAction(action) {
+
+ if(_importCancelHandler) dojo.disconnect(_importCancelHandler);
+
+ _importCancelHandler = dojo.connect(
+ queueItemsImportCancelButton,
+ 'onClick',
+ function() {
+ queueItemsImportDialog.hide();
+ }
+ );
+
+ if(_importGoHandler)
+ dojo.disconnect(_importGoHandler);
+
+ _importGoHandler = dojo.connect(
+ queueItemsImportGoButton,
+ 'onClick',
+ function() {
+ queueItemsImportDialog.hide();
+
+ // hack to set the widgets the import funcs will be looking at. Reset them below.
+ vlUploadQueueImportNoMatch.attr('value', vlUploadQueueImportNoMatch2.attr('value'));
+ vlUploadQueueAutoOverlayExact.attr('value', vlUploadQueueAutoOverlayExact2.attr('value'));
+ vlUploadQueueAutoOverlay1Match.attr('value', vlUploadQueueAutoOverlay1Match2.attr('value'));
+ vlUploadMergeProfile.attr('value', vlUploadMergeProfile2.attr('value'));
+ vlUploadFtMergeProfile.attr('value', vlUploadFtMergeProfile2.attr('value'));
+ vlUploadQueueAutoOverlayBestMatch.attr('value', vlUploadQueueAutoOverlayBestMatch2.attr('value'));
+ vlUploadQueueAutoOverlayBestMatchRatio.attr('value', vlUploadQueueAutoOverlayBestMatchRatio2.attr('value'));
+
+ if(action == 'import') {
+ vlImportSelectedRecords();
+ } else if(action == 'import_all') {
+ vlImportAllRecords();
+ }
+
+ // reset the widgets to prevent accidental future actions
+ vlUploadQueueImportNoMatch.attr('value', false);
+ vlUploadQueueImportNoMatch2.attr('value', false);
+ vlUploadQueueAutoOverlayExact.attr('value', false);
+ vlUploadQueueAutoOverlayExact2.attr('value', false);
+ vlUploadQueueAutoOverlay1Match.attr('value', false);
+ vlUploadQueueAutoOverlay1Match2.attr('value', false);
+ vlUploadMergeProfile.attr('value', '');
+ vlUploadMergeProfile2.attr('value', '');
+ vlUploadFtMergeProfile.attr('value', '');
+ vlUploadFtMergeProfile2.attr('value', '');
+ vlUploadQueueAutoOverlayBestMatch.attr('value', false);
+ vlUploadQueueAutoOverlayBestMatch2.attr('value', false);
+ vlUploadQueueAutoOverlayBestMatchRatio.attr('value', '0.0');
+ vlUploadQueueAutoOverlayBestMatchRatio2.attr('value', '0.0');
+ }
+ );
+
+ queueItemsImportDialog.show();
+ }
+
+ function vlHandleCreateBucket() {
+
+ create-bucket-dialog-name
+ }
+
+
+ /* import user-selected records */
+ function vlImportSelectedRecords() {
+ var records = [];
+
+ for(var id in selectableGridRecords) {
+ if(dojo.byId(id).checked) {
+ var recId = selectableGridRecords[id];
+ var rec = queuedRecordsMap[recId];
+ if(!rec.import_time())
+ records.push(recId);
+ }
+ }
+
+ vlImportRecordQueue(
+ currentType,
+ currentQueueId,
+ records,
+ function(){
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+ );
+ }
+
+ /* import all (non-imported) queue records */
+ function vlImportAllRecords() {
+ vlImportRecordQueue(
+ currentType,
+ currentQueueId,
+ null,
+ function(){
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+ );
+ }
+
+ /* if recList has values, import only those records */
+ function vlImportRecordQueue(type, queueId, recList, onload) {
+ displayGlobalDiv('vl-generic-progress-with-total');
+
+ /* set up options */
+ var options = {overlay_map : currentOverlayRecordsMap};
+
+ if(vlUploadQueueImportNoMatch.checked) {
+ options.import_no_match = true;
+ vlUploadQueueImportNoMatch.checked = false;
+ }
+
+ if(vlUploadQueueAutoOverlayExact.checked) {
+ options.auto_overlay_exact = true;
+ vlUploadQueueAutoOverlayExact.checked = false;
+ }
+
+ if(vlUploadQueueAutoOverlayBestMatch.checked) {
+ options.auto_overlay_best_match = true;
+ vlUploadQueueAutoOverlayBestMatch.checked = false;
+ options.match_quality_ratio = vlUploadQueueAutoOverlayBestMatchRatio.attr('value');
+ }
+
+ if(vlUploadQueueAutoOverlay1Match.checked) {
+ options.auto_overlay_1match = true;
+ vlUploadQueueAutoOverlay1Match.checked = false;
+ options.match_quality_ratio = vlUploadQueueAutoOverlayBestMatchRatio.attr('value');
+ }
+
+ var profile = vlUploadMergeProfile.attr('value');
+ if(profile != null && profile != '') {
+ options.merge_profile = profile;
+ }
+
+ var ftprofile = vlUploadFtMergeProfile.attr('value');
+ if(ftprofile != null && ftprofile != '') {
+ options.fall_through_merge_profile = ftprofile;
+ }
+
+
+ /* determine which method we're calling */
+
+ var method = 'open-ils.vandelay.bib_queue.import';
+ if(type == 'auth')
+ method = method.replace('bib', 'auth');
+
+ var params = [authtoken, queueId, options];
+ if(recList) {
+ method = 'open-ils.vandelay.'+currentType+'_record.list.import';
+ params[1] = recList;
+ }
+
+ fieldmapper.standardRequest(
+ ['open-ils.vandelay', method],
+ { async: true,
+ params: params,
+ onresponse: function(r) {
+ var resp = r.recv().content();
+ if(e = openils_Event.parse(resp))
+ return alert(e);
+ vlControlledProgressBar.update({maximum:resp.total, progress:resp.progress});
+ },
+ oncomplete: function() {onload();}
+ }
+ );
+ }
+
+
+ /**
+ * Create queue, upload MARC, process spool, load the newly created queue
+ */
+ function batchUpload() {
+ var queueName = dijit.byId('vl-queue-name').getValue();
+ currentType = dijit.byId('vl-record-type').getValue();
+
+ var handleProcessSpool = function() {
+ if(
+ vlUploadQueueImportNoMatch.checked ||
+ vlUploadQueueAutoOverlayExact.checked ||
+ vlUploadQueueAutoOverlay1Match.checked ||
+ vlUploadQueueAutoOverlayBestMatch.checked ) {
+
+ vlImportRecordQueue(
+ currentType,
+ currentQueueId,
+ null,
+ function() {
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+ );
+ } else {
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+ }
+
+ var handleUploadMARC = function(key) {
+ dojo.style(dojo.byId('vl-upload-status-processing'), 'display', 'block');
+ processSpool(key, currentQueueId, currentType, handleProcessSpool);
+ };
+
+ var handleCreateQueue = function(queue) {
+ currentQueueId = queue.id();
+ uploadMARC(handleUploadMARC);
+ };
+
+ if(vlUploadQueueSelector.getValue() && !queueName) {
+ currentQueueId = vlUploadQueueSelector.getValue();
+ uploadMARC(handleUploadMARC);
+ } else {
+ createQueue(queueName, currentType, handleCreateQueue,
+ vlUploadQueueHoldingsImportProfile.attr('value'),
+ vlUploadQueueMatchSet.attr('value')
+ );
+ }
+ }
+
+
+ function vlFleshQueueSelect(selector, type) {
+ var data;
+ if (type == 'bib') {
+ var bibList = allUserBibQueues.filter(
+ function(q) {
+ return (q.queue_type() == 'bib');
+ }
+ );
+ data = vbq.toStoreData(bibList);
+ } else if (type == 'bib-acq') {
+ // ACQ queues are a special type of bib queue
+ var acqList = allUserBibQueues.filter(
+ function(q) {
+ return (q.queue_type() == 'acq');
+ }
+ );
+ data = vbq.toStoreData(acqList);
+ } else {
+ data = vaq.toStoreData(allUserAuthQueues);
+ }
+
+ selector.store = new dojo_data_ItemFileReadStore({data:data});
+ selector.setValue(null);
+ selector.setDisplayedValue('');
+ if(data[0])
+ selector.setValue(data[0].id());
+
+ var qInput = dijit.byId('vl-queue-name');
+
+ var selChange = function(val) {
+ console.log('selector onchange');
+ // user selected a queue from the selector; clear the input and
+ // set the item import profile already defined for the queue
+ var queue = allUserBibQueues.filter(function(q) { return (q.id() == val) })[0];
+ if(val) {
+ vlUploadQueueHoldingsImportProfile.attr('value', queue.item_attr_def() || '');
+ vlUploadQueueHoldingsImportProfile.attr('disabled', true);
+ vlUploadQueueMatchSet.attr('value', queue.match_set() || '');
+ vlUploadQueueMatchSet.attr('disabled', true);
+ } else {
+ vlUploadQueueHoldingsImportProfile.attr('value', '');
+ vlUploadQueueHoldingsImportProfile.attr('disabled', false);
+ vlUploadQueueMatchSet.attr('value', '');
+ vlUploadQueueMatchSet.attr('disabled', false);
+ }
+ dojo.disconnect(qInput._onchange);
+ qInput.attr('value', '');
+ qInput._onchange = dojo.connect(qInput, 'onChange', inputChange);
+ }
+
+ var inputChange = function(val) {
+ console.log('qinput onchange');
+ // user entered a new queue name. clear the selector
+ vlUploadQueueHoldingsImportProfile.attr('disabled', false);
+ vlUploadQueueMatchSet.attr('disabled', false);
+ dojo.disconnect(selector._onchange);
+ selector.attr('value', '');
+ selector._onchange = dojo.connect(selector, 'onChange', selChange);
+ }
+
+ selector._onchange = dojo.connect(selector, 'onChange', selChange);
+ qInput._onchange = dojo.connect(qInput, 'onChange', inputChange);
+ }
+
+ function vlUpdateMatchSetSelector(type) {
+ type = (type.match(/bib/)) ? 'biblio' : 'authority';
+ vlUploadQueueMatchSet.store =
+ new dojo_data_ItemFileReadStore({data:vms.toStoreData(matchSets[type])});
+ }
+
+ function vlShowUploadForm() {
+ displayGlobalDiv('vl-marc-upload-div');
+ vlFleshQueueSelect(vlUploadQueueSelector, vlUploadRecordType.getValue());
+ vlUploadSourceSelector.store =
+ new dojo_data_ItemFileReadStore({data:cbs.toStoreData(vlBibSources, 'source')});
+ vlUploadSourceSelector.setValue(vlBibSources[0].id());
+ vlUploadQueueHoldingsImportProfile.store =
+ new dojo_data_ItemFileReadStore({data:viiad.toStoreData(importItemDefs)});
+ vlUpdateMatchSetSelector(vlUploadRecordType.getValue());
+
+ // use ratio from the merge profile if it's set
+ dojo.connect(
+ vlUploadMergeProfile,
+ 'onChange',
+ function(val) {
+ if(!val) return;
+ var profile = mergeProfiles.filter(function(p) { return (p.id() == val); })[0];
+ if(profile.lwm_ratio() != null)
+ vlUploadQueueAutoOverlayBestMatchRatio.attr('value', profile.lwm_ratio()+'');
+ }
+ );
+ dojo.connect(
+ vlUploadMergeProfile2,
+ 'onChange',
+ function(val) {
+ if(!val) return;
+ var profile = mergeProfiles.filter(function(p) { return (p.id() == val); })[0];
+ if(profile.lwm_ratio() != null)
+ vlUploadQueueAutoOverlayBestMatchRatio2.attr('value', profile.lwm_ratio()+'');
+ }
+ );
+
+ }
+
+ function vlShowQueueSelect() {
+ displayGlobalDiv('vl-queue-select-div');
+ vlFleshQueueSelect(vlQueueSelectQueueList, vlQueueSelectType.getValue());
+ }
+
+ function vlShowMatchSetEditor() {
+ displayGlobalDiv('vl-match-set-editor-div');
+ dojo.byId('vl-match-set-editor-div').appendChild(
+ dojo.create('iframe', {
+ id : 'vl-match-set-iframe',
+ src : oilsBasePath + '/conify/global/vandelay/match_set',
+ style : 'width:100%; height:500px; border:none; margin:0px;'
+ })
+ );
+ }
+
+ function vlFetchQueueFromForm() {
+ currentType = vlQueueSelectType.attr('value').replace(/-.*/, ''); // trim bib-acq
+ currentQueueId = vlQueueSelectQueueList.getValue();
+ retrieveQueuedRecords(currentType, currentQueueId, handleRetrieveRecords);
+ }
+
+ function vlOpenMarcEditWindow(rec, postReloadHTMLHandler) {
+ /*
+ To run in Firefox directly, must set signed.applets.codebase_principal_support
+ to true in about:config
+ */
+ netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
+ win = window.open('/xul/server/cat/marcedit.xul'); // XXX version?
+
+ var type;
+ if (currentType == 'bib') {
+ type = 'bre';
+ } else {
+ type = 'are';
+ }
+
+ function onsave(r) {
+ // after the record is saved, reload the HTML display
+ var stat = r.recv().content();
+ if(e = openils_Event.parse(stat))
+ return alert(e);
+ alert(dojo.byId('vl-marc-edit-complete-label').innerHTML);
+ win.close();
+ vlLoadMARCHtml(rec.id(), false, postReloadHTMLHandler);
+ }
+
+ win.xulG = {
+ record : {marc : rec.marc(), "rtype": type},
+ save : {
+ label: dojo.byId('vl-marc-edit-save-label').innerHTML,
+ func: function(xmlString) {
+ var method = 'open-ils.permacrud.update.' + rec.classname;
+ rec.marc(xmlString);
+ fieldmapper.standardRequest(
+ ['open-ils.permacrud', method],
+ { async: true,
+ params: [authtoken, rec],
+ oncomplete: onsave
+ }
+ );
+ },
+ },
+ 'lock_tab' : typeof xulG != 'undefined' ? (typeof xulG['lock_tab'] != 'undefined' ? xulG.lock_tab : undefined) : undefined,
+ 'unlock_tab' : typeof xulG != 'undefined' ? (typeof xulG['unlock_tab'] != 'undefined' ? xulG.unlock_tab : undefined) : undefined
+ };
+ }
+
+ function vlLoadMarcEditor(type, recId, postReloadHTMLHandler) {
+ var method = 'open-ils.permacrud.search.vqbr';
+ if(currentType != 'bib')
+ method = method.replace(/vqbr/,'vqar');
+
+ fieldmapper.standardRequest(
+ ['open-ils.permacrud', method],
+ { async: true,
+ params: [authtoken, {id : recId}],
+ oncomplete: function(r) {
+ var rec = r.recv().content();
+ if(e = openils_Event.parse(rec))
+ return alert(e);
+ vlOpenMarcEditWindow(rec, postReloadHTMLHandler);
+ }
+ }
+ );
+ }
+
+
+
+ //------------------------------------------------------------
+ // attribute editors
+
+ // attribute-editor global variables
+
+ var ATTR_EDITOR_IN_UPDATE_MODE = false; // true on 'edit', false on 'create'
+ var ATTR_EDIT_ID = null; // id of current 'edit' attribute
+ var ATTR_EDIT_GROUP = 'bib'; // bib-attrs or auth-attrs
+
+ function vlAttrEditorInit() {
+ // set up tooltips on the edit form
+ connectTooltip('attr-editor-tags');
+ connectTooltip('attr-editor-subfields');
+ }
+
+ function vlShowAttrEditor() {
+ displayGlobalDiv('vl-attr-editor-div');
+ loadAttrEditorGrid();
+ idHide('vl-generic-progress');
+ }
+
+ function setAttrEditorGroup(groupName) {
+ // put us into 'bib'-attr or 'auth'-attr mode.
+ if (ATTR_EDIT_GROUP != groupName) {
+ ATTR_EDIT_GROUP = groupName;
+ loadAttrEditorGrid();
+ }
+ }
+
+ function onAttrEditorOpen() {
+ // the "bars" have the create/update/cancel/etc. buttons.
+ var create_bar = document.getElementById('attr-editor-create-bar');
+ var update_bar = document.getElementById('attr-editor-update-bar');
+ if (ATTR_EDITOR_IN_UPDATE_MODE) {
+ update_bar.style.display='table-row';
+ create_bar.style.display='none';
+ // hide the dropdown-button
+ idStyle('vl-create-attr-editor-button', 'visibility', 'hidden');
+ } else {
+ dijit.byId('attr-editor-dialog').reset();
+ create_bar.style.display='table-row';
+ update_bar.style.display='none';
+ }
+ }
+
+ function onAttrEditorClose() {
+ // reset the form to a "create" form. (We may have borrowed it for editing.)
+ ATTR_EDITOR_IN_UPDATE_MODE = false;
+ // show the dropdown-button
+ idStyle('vl-create-attr-editor-button', 'visibility', 'visible');
+ }
+
+ function loadAttrEditorGrid() {
+ var _data = (ATTR_EDIT_GROUP == 'auth') ?
+ vqarad.toStoreData(authAttrDefs) : vqbrad.toStoreData(bibAttrDefs) ;
+
+ var store = new dojo_data_ItemFileReadStore({data:_data});
+ attrEditorGrid.setStore(store);
+ attrEditorGrid.onRowDblClick = onAttrEditorClick;
+ attrEditorGrid.update();
+ }
+
+ function attrGridGetTag(n, item) {
+ // grid helper: return the tags from the row's xpath column.
+ return item && xpathParser.parse(this.grid.store.getValue(item, 'xpath')).tags;
+ }
+
+ function attrGridGetSubfield(n, item) {
+ // grid helper: return the subfields from the row's xpath column.
+ return item && xpathParser.parse(this.grid.store.getValue(item, 'xpath')).subfields;
+ }
+
+ function onAttrEditorClick() {
+ var row = this.getItem(this.focus.rowIndex);
+ ATTR_EDIT_ID = this.store.getValue(row, 'id');
+ ATTR_EDITOR_IN_UPDATE_MODE = true;
+
+ // populate the popup editor.
+ dijit.byId('attr-editor-code').attr('value', this.store.getValue(row, 'code'));
+ dijit.byId('attr-editor-description').attr('value', this.store.getValue(row, 'description'));
+ var parsed_xpath = xpathParser.parse(this.store.getValue(row, 'xpath'));
+ dijit.byId('attr-editor-tags').attr('value', parsed_xpath.tags);
+ dijit.byId('attr-editor-subfields').attr('value', parsed_xpath.subfields);
+ dijit.byId('attr-editor-xpath').attr('value', this.store.getValue(row, 'xpath'));
+ dijit.byId('attr-editor-remove').attr('value', this.store.getValue(row, 'remove'));
+
+ // set up UI for editing
+ dojo.byId('vl-create-attr-editor-button').click();
+ }
+
+ function vlSaveAttrDefinition(data) {
+ idHide('vl-attr-editor-div');
+ idShow('vl-generic-progress');
+
+ data.id = ATTR_EDIT_ID;
+
+ // this ought to honour custom xpaths, but overwrite xpaths
+ // derived from tags/subfields.
+ if (data.xpath == '' || looksLikeDerivedXpath(data.xpath)) {
+ var _xpath = tagAndSubFieldsToXpath(data.tag, data.subfield);
+ data.xpath = _xpath;
+ }
+
+ // build up our permacrud params. Key variables here are
+ // "create or update" and "bib or auth".
+
+ var isAuth = (ATTR_EDIT_GROUP == 'auth');
+ var isCreate = (ATTR_EDIT_ID == null);
+ var rad = isAuth ? new vqarad() : new vqbrad() ;
+ var method = 'open-ils.permacrud' + (isCreate ? '.create.' : '.update.')
+ + (isAuth ? 'vqarad' : 'vqbrad');
+ var _data = rad.fromStoreItem(data);
+
+ _data.ischanged(1);
+
+ fieldmapper.standardRequest(
+ ['open-ils.permacrud', method],
+ { async: true,
+ params: [authtoken, _data ],
+ onresponse: function(r) { },
+ oncomplete: function(r) {
+ attrEditorFetchAttrDefs(vlShowAttrEditor);
+ ATTR_EDIT_ID = null;
+ },
+ onerror: function(r) {
+ alert('vlSaveAttrDefinition comms error: ' + r);
+ }
+ }
+ );
+ }
+
+ function attrEditorFetchAttrDefs(callback) {
+ var fn = (ATTR_EDIT_GROUP == 'auth') ? vlFetchAuthAttrDefs : vlFetchBibAttrDefs;
+ return fn(callback);
+ }
+
+ function vlAttrDelete() {
+ idHide('vl-attr-editor-div');
+ idShow('vl-generic-progress');
+
+ var isAuth = (ATTR_EDIT_GROUP == 'auth');
+ var method = 'open-ils.permacrud.delete.' + (isAuth ? 'vqarad' : 'vqbrad');
+ var rad = isAuth ? new vqarad() : new vqbrad() ;
+ fieldmapper.standardRequest(
+ ['open-ils.permacrud', method],
+ { async: true,
+ params: [authtoken, rad.fromHash({ id : ATTR_EDIT_ID }), ],
+ oncomplete: function() {
+ dijit.byId('attr-editor-dialog').onCancel(); // close the dialog
+ attrEditorFetchAttrDefs(vlShowAttrEditor);
+ ATTR_EDIT_ID = null;
+ },
+ onerror: function(r) {
+ alert('vlAttrDelete comms error: ' + r);
+ }
+ }
+ );
+ }
+
+ // ------------------------------------------------------------
+ // utilities for attribute editors
+
+ // dom utilities (maybe dojo does these, and these should be replaced)
+
+ function idStyle(obId, k, v) { document.getElementById(obId).style[k] = v; }
+ function idShow(obId) { idStyle(obId, 'display', 'block'); }
+ function idHide(obId) { idStyle(obId, 'display' , 'none'); }
+
+ function connectTooltip(fieldId) {
+ // Given an element id, look up a tooltip element in the doc (same
+ // id with a '-tip' suffix) and associate the two. Maybe dojo has
+ // a better way to do this?
+ var fld = dojo.byId(fieldId);
+ var tip = dojo.byId(fieldId + '-tip');
+ dojo.connect(fld, 'onfocus', function(evt) {
+ dijit.showTooltip(tip.innerHTML, fld, ['below', 'after']); });
+ dojo.connect(fld, 'onblur', function(evt) { dijit.hideTooltip(fld); });
+ }
+
+ // xpath utilities
+
+ var xpathParser = new openils_MarcXPathParser();
+
+ function tagAndSubFieldsToXpath(tags, subfields) {
+ // given tags, and subfields, build up an XPath.
+ try {
+ var parts = {
+ 'tags':tags.match(/[\d]+/g),
+ 'subfields':subfields.match(/[a-zA-z]/g) };
+ return xpathParser.compile(parts);
+ } catch (err) {
+ return {'parts':null, 'tags':null, 'error':err};
+ }
+ }
+
+ function looksLikeDerivedXpath(path) {
+ // Does this path look like it was derived from tags and subfields?
+ var parsed = xpathParser.parse(path);
+ if (parsed.tags == null)
+ return false;
+ var compiled = xpathParser.compile(parsed);
+ return (path == compiled);
+ }
+
+ // amazing xpath-util unit-tests
+ if (!looksLikeDerivedXpath('//*[@tag="901"]/*[@code="c"]')) alert('vandelay xpath-utility error');
+ if ( looksLikeDerivedXpath('ba-boo-ba-boo!')) alert('vandelay xpath-utility error');
+
+
+
+ var profileContextOrg
+ function vlShowProfileEditor() {
+ displayGlobalDiv('vl-profile-editor-div');
+ buildProfileGrid();
+
+ var connect = function() {
+ dojo.connect(profileContextOrgSelector, 'onChange',
+ function() {
+ profileContextOrg = this.attr('value');
+ pGrid.resetStore();
+ buildProfileGrid();
+ }
+ );
+ };
+
+ new openils_User().buildPermOrgSelector(
+ 'ADMIN_MERGE_PROFILE', profileContextOrgSelector, null, connect);
+ }
+
+ function buildProfileGrid() {
+
+ if(profileContextOrg == null)
+ profileContextOrg = openils_User.user.ws_ou();
+
+ pGrid.loadAll(
+ {order_by : {vmp : 'name'}},
+ {owner : fieldmapper.aou.fullPath(profileContextOrg, true)}
+ );
+ }
+
+ /* --- Import Item Attr Grid --------------- */
+
+ var itemAttrContextOrg;
+ var itemAttrGridFirstTime = true;
+ function vlShowImportItemAttrEditor() {
+ displayGlobalDiv('vl-item-attr-editor-div');
+
+ if (itemAttrGridFirstTime) {
+
+ buildImportItemAttrGrid();
+
+ var connect = function() {
+ dojo.connect(itemAttrContextOrgSelector, 'onChange',
+ function() {
+ itemAttrContextOrg = this.attr('value');
+ itemAttrGrid.resetStore();
+ buildImportItemAttrGrid();
+ }
+ );
+ };
+
+ new openils_User().buildPermOrgSelector(
+ 'ADMIN_IMPORT_ITEM_ATTR_DEF',
+ itemAttrContextOrgSelector, null, connect);
+
+ itemAttrGridFirstTime = false;
+ }
+ }
+
+ function buildImportItemAttrGrid() {
+
+ if(itemAttrContextOrg == null)
+ itemAttrContextOrg = openils_User.user.ws_ou();
+
+ itemAttrGrid.loadAll(
+ {order_by : {viiad : 'name'}},
+ {owner : fieldmapper.aou.fullPath(itemAttrContextOrg, true)}
+ );
+ }
+
+
+
+});
\ No newline at end of file