10 var BLOCK_PARSE_REGEX
= /\$\{(\w+)\}/igm;
11 // hack for mock data testing:
12 var _LAST_PARSED_DICT
= null;
13 String
.prototype.parse_vars = function(dataDict
)
15 _LAST_PARSED_DICT
= dataDict
;
16 return this.replace(BLOCK_PARSE_REGEX
, function(match
, param
, offset
, orig
)
18 if (!dataDict
) { return ""; }
19 return (dataDict
[param
] || (dataDict
[param
] == 0)) ? (dataDict
[param
]) : ("");
24 * The "bind()" function extension from Prototype.js, extracted for general use
26 * @author Richard Harrison, http://www.pluggable.co.uk
27 * @author Sam Stephenson (Modified from Prototype Javascript framework)
28 * @license MIT-style license @see http://www.prototypejs.org/
30 Function
.prototype.bind = function()
34 return Array
.prototype.slice
.call(a
);
36 if ((arguments
.length
< 2) && (typeof arguments
[0] == "undefined"))
40 var __method
= this, args
= _
$A(arguments
), object
= args
.shift();
43 return __method
.apply(object
, args
.concat(_
$A(arguments
)));
49 var MOCK_DATA
= false;
50 var MOCK_DATA_FAILURES_MODE
= false;
54 var LOGIN_COMMAND
= "login (user -username ${username} -password ${password});";
55 var REGISTER_COMMAND
= "var someVariable = add ( " +
56 "(load (`/system[ @id='main.system']`)) " +
57 "<user xmlns='com/interrupt/bookkeeping/users' id='${username}' username='${username}' password='${password}'>" +
58 "<allowedActions id='${username}.allowedActions' xmlns='com/interrupt/bookkeeping/cc/bkell/aauth' >" +
59 "<command id='command.create' name='create' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
60 "<command id='command.add' name='add' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
61 "<command id='command.remove' name='remove' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
62 "<command id='command.reverse' name='reverse' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
63 "<command id='command.find' name='find' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
64 "<command id='command.load' name='load' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
65 "<command id='command.list' name='list' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
66 "<command id='command.print' name='print' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
67 "<command id='command.commit' name='commit' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
68 "<command id='command.login' name='login' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
69 "<command id='command.logout' name='logout' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
70 "<command id='command.exit' name='exit' xmlns='com/interrupt/bookkeeping/cc/bkell/command' />" +
72 "<profileDetails xmlns='com/interrupt/bookkeeping/users' id='user.details'>" +
73 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='firstname' name='first.name' value='${firstname}'/>" +
74 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='lastname' name='last.name' value='${lastname}'/>" +
75 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='email' name='email' value='${email}'/>" +
76 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='country' name='country' value='${country}'/>" +
77 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='defaultCurrency' name='defaultCurrency' value='${currency}' />" +
79 "</user> , user -returninput true" +
81 var GETPROFILE_COMMAND
= "load (`/system[@id='main.system']/aauthentication[@id='main.authentication']/users[@id='aauth.users']/user[@id='${username}']`);";
82 var UPDATEPROFILE_COMMAND
= "var someVariable = update ( " +
83 "(`/system[ @id='main.system']/aauthentication[@id='main.authentication']/users[@id='aauth.users']/user[@id='${username}']/profileDetails[@id='user.details']`) " +
84 "<profileDetails xmlns='com/interrupt/bookkeeping/users' id='user.details'>" +
85 "<profileDetail name='first.name' value='${firstname}'/>" +
86 "<profileDetail name='last.name' value='${lastname}'/>" +
87 "<profileDetail name='email' value='${email}'/>" +
88 "<profileDetail name='country' value='${country}'/>" +
90 ");commit ((`/system[ @id='main.system']/aauthentication[@id='main.authentication']/users[@id='aauth.users']/user[@id='${username}']/profileDetails[@id='user.details']`) @someVariable);";
92 var LISTACCOUNTS_COMMAND
= "load ( `/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/accounts[@id='main.accounts']`);";
93 var LISTJOURNALS_COMMAND
= "load ( `/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[@id='main.journals']`);";
94 var LISTENTRIES_COMMAND
= "load ( `/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[ @id='main.journals' ]/journal[@id='${journal}']/entries[@id='main.entries']`);";
95 var LISTENTRY_COMMAND
= "load ( `/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[ @id='main.journals' ]/journal[@id='${journal}']/entries[@id='main.entries']/entry[@id='${entry}']`);";
97 var LOADDEFAULTCURRENCY_COMMAND
= "load ( `/system[ @id='main.system' ]/aauthentication[ @id='main.authentication' ]/users[ @id='aauth.users' ]/user[ @id='${username}' ]/profileDetails[ @id='user.details' ]/profileDetail[ @id='defaultCurrency' ] `);";
103 var ADDACCOUNT_COMMAND
= "var addedAccount = add((load(`/system[@id='main.system']/groups[@id='main.groups']/group[@id='${username}.group']/bookkeeping[@id='main.bookkeeping']/accounts[@id='main.accounts']`))" +
104 "<account xmlns='com/interrupt/bookkeeping/account' type=\"${type}\" id=\"${id}\" name=\"${name}\" counterWeight=\"${cw}\" currency='CDN' /> );"+
105 "commit((`/system[@id='main.system']/groups[@id='main.groups']/group[@id='${username}.group']/bookkeeping[@id='main.bookkeeping']/accounts[@id='main.accounts']`) @addedAccount);";
107 var REMOVEACCOUNT_COMMAND
= "var removedAccount = remove ((`/system[@id='main.system']/groups[@id='main.groups']/group[@id='${username}.group']/bookkeeping[@id='main.bookkeeping']/accounts[@id='main.accounts']`) account -id ${aid});" +
108 "commit((`/system[@id='main.system']/groups[@id='main.groups']/group[@id='${username}.group']/bookkeeping[@id='main.bookkeeping']/accounts[@id='main.accounts']`) @removedAccount);";
109 var UPDATEACCOUNT_COMMAND
= "var updatedAccount = update((`/system[@id='main.system']/groups[@id='main.groups']/group[@id='${username}.group']/bookkeeping[@id='main.bookkeeping']/accounts[@id='main.accounts']/account[@id='${id}']`)" +
110 "<account xmlns=\"com/interrupt/bookkeeping/account\" type=\"${type}\" id=\"${id}\" name=\"${name}\" counterWeight=\"${cw}\"/>);" +
111 "commit( (`/system[@id='main.system']/groups[@id='main.groups']/group[@id='${username}.group']/bookkeeping[@id='main.bookkeeping']/accounts[@id='main.accounts']/account[@id='${id}']`) @updatedAccount);";
116 var ADDJOURNAL_COMMAND
= "var addedJournal = add((`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}\"]/bookkeeping[@id='main.bookkeeping']/journals[@id='main.journals']/journal`)" +
117 "<journal:journal id='${jid}' name='${jname}' type='${jtype}' balance='${jbalance}'/>" +
118 "commit((`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}\"]/bookkeeping[@id='main.bookkeeping']/journals[@id='main.journals']/journal`) @addedJournal);";
119 var REMOVEJOURNAL_COMMAND
= "var removedJournal = remove ((`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}\"]/bookkeeping[@id='main.bookkeeping']/journals[@id='main.journals']/journal`) journal -id ${jid});" +
120 "commit((`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}\"]/bookkeeping[@id='main.bookkeeping']/journals[@id='main.journals']/journal`) @removedJournal);";
121 var UPDATEJOURNAL_COMMAND
= "var updatedJournal = update(( load(`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[@id='main.journals']/journal[@id='${id}']`)) " +
122 "<journal xmlns=\"com/interrupt/bookkeeping/journal\" id='${id}' name='${name}' type='${jtype}' balance='${jbalance}'/> ); " +
123 "commit((`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[@id='main.journals']/journal[@id='${id}']`) @updatedJournal);";
129 var ADDENTRY_COMMAND
= "var addedEntry = add((`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}\"]/bookkeeping[@id='main.bookkeeping']/journals[ @id='main.journals' ]/journal[@id='${jid}']/entries[@id='main.entries']`)" +
130 "<entry xmlns='com/interrupt/bookkeeping/journal' id='${eid}' entrynum='' state='' journalid='${jid}' date='${date}' currency='${cc}'>" +
131 "${debitsANDcredits}" +
133 "commit((`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[@id='main.journals' ]/journal[@id='${jid}']/entries[@id='main.entries']`) @addedEntry);";
135 var REMOVEENTRY_COMMAND
= "var removedEntry = remove ((load(`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[ @id='main.journals' ]/journal[@id='${jid}']/entries[@id='main.entries']`)) entry -id ${eid});" +
136 "commit((`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[ @id='main.journals' ]/journal[@id='${jid}']/entries[@id='main.entries']`) @removedEntry);";
138 var UPDATEENTRY_COMMAND
= "var updatedEntry = update( (load(`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[ @id='main.journals' ]/journal[@id='${jid}']/entries[@id='main.entries']/entry[@id='${id}']`))" +
139 "<entry xmlns=\"com/interrupt/bookkeeping/journal\" id='${id}' entrynum='' state='' journalid='${jid}' date='${date}' currency='${cc}'>" +
140 "${debitsANDcredits}" +
142 "commit( (`/system[@id='main.system']/groups[@id=\"main.groups\"]/group[@id=\"${username}.group\"]/bookkeeping[@id='main.bookkeeping']/journals[@id='main.journals']/journal[@id='${jid}']/entries[@id='main.entries']/entry[@id='${id}']`) @updatedEntry);";
149 var ACCOUNT_ROW
= '<div id="${rowid}" class="acl_row row">' +
150 '<div class="edit_column left_column"><a href="javascript:bkeeping.editAccount(\'${rowid}\');"><img border="0" src="images/editrow.jpg"/></a></div>' +
151 '<div class="name_column left_column" style="margin-left: 10px;" >${aname}</div>' +
152 '<div class="category_column left_column" style="margin-left: 40px; margin-right: 20px;" >${category}</div>' +
153 // '<div class="balance_column left_column">${balance}</div>' +
154 '<div class="delete_column left_column"><a href="javascript:bkeeping.deleteAccount(\'${rowid}\');"><img border="0" src="images/deleterow.jpg"/></a></div>' +
157 var JOURNAL_ROW
= '<div id="${rowid}" class="js_row row">' +
158 '<div class="edit_column left_column"><a href="javascript:bkeeping.editJournal(\'${rowid}\');"><img border="0" src="images/editrow.jpg"/></a></div>' +
159 '<div class="large_name_column left_column"><a onclick="bkeeping.showJournal(\'${rowid}\')">${jname}</a></div>' +
160 '<div class="delete_column left_column"><a href="javascript: alert(\'Coming Soon\'); "><img border="0" src="images/deleterow.jpg"/></a></div>' +
164 var ENTRY_ROW
= '<div id="${rowid}" class="j_row row">' +
166 '<div class="edit_column left_column"><a href="javascript:bkeeping.editEntry(\'${rowid}\');"><img border="0" src="images/editrow.jpg"/></a></div>' +
168 '<div class="date_column left_column" style="margin:0 50px;" >${date}</div>' +
169 '<div class="entry_column left_column" style="margin:0 50px;" >${entry}</div>' +
170 '<div class="balance_column left_column" style="margin:0 50px;" >${balance}</div>' +
172 '<div class="delete_column left_column"><a href="javascript:bkeeping.deleteThing(\'entry\', \'${rowid}\');"><img border="0" src="images/deleterow.jpg"/></a></div>' +
178 var TENTRY_ROW
= '<div id="jentry_rows" class="j_rows rows">' +
180 ' <div class="edit_column left_column"><a href="javascript:bkeeping.addEditEntryPart(\'${rowid}\', \'${eid}\');"><img border="0" src="images/editrow.jpg"/></a></div>' +
182 ' <div style="float:left; width: 18%; margin-left: 90px; ">${dname}</div><div style="float:left; width: 20%; ">${damount}</div>' +
183 ' <div style="float:left; width: 20%; ">${cname}</div><div style="float:left; width: 20%; ">${camount}</div>' +
185 ' <div class="delete_column left_column"><a href="javascript: alert(\'Coming Soon. Please replace entry\');"><img border="0" src="images/deleterow.jpg"/></a></div>' +
190 var AE_ACCOUNT
= ["Add/Edit Account", '<table class="formtable">' +
196 '<input type="text" name="account_name" id="account_name" class="data_field" value="${aname}" />' +
204 '<select name="account_type" id="account_type" class="data_field">' +
211 var AE_JOURNAL
= ["Add/Edit Journal", '<table class="formtable">' +
217 '<input type="text" name="journal_name" id="journal_name" class="data_field" value="${name}" />' +
225 '<select name="journal_type" id="journal_type" class="data_field">' +
226 '<option>default</option>' +
235 '<input type="text" name="journal_balance" id="journal_balance" class="data_field" value="${balance}" />' +
241 var AE_ENTRY
= ["Add/Edit Entry", '<table class="formtable">' +
242 '<input type="hidden" name="entryid" value="${entryid}" />' +
246 '<span class="smallformtext">Currency:</span> ' +
247 '<select name="entry_cc" id="entry_cc" class="data_field">' +
248 '<option value="CDN" ${curr_cdn} >Canadian Dollar</option>' +
249 '<option value="USD" ${curr_usd} >US Dollar</option>' +
250 '<option value="BP" ${curr_bp} >British Pound</option>' +
251 '<option value="EUR" ${curr_eur} >European Euro</option>' +
252 '<option value="JPN" ${curr_jpn} >Japanese Yen</option>' +
258 '<span class="smallformtext">Amount:</span> <input type="text" size="6" name="entry_ecamount" id="entry_ecamount" class="data_field" value="${evalue}" > ' +
263 '<span class="smallformtext">Account:</span> ' +
264 '<select name="entry_caid" id="entry_caid" class="data_field">' +
271 '<span class="smallformtext">Type:</span> ' +
272 '<select name="entry_ctype" id="entry_ctype" class="data_field">' +
273 '<option value="debit" ${entry_dtype} >debit</option><option value="credit" ${entry_ctype} >credit</option>' +
282 var DIALOG_HOLDER
= "<div id='bkeeping_dialog' class='dialog'>Dialog default text.</div>";
283 var _DIALOG_FIRST
= true;
290 ACTIVE_SESSION
: null,
291 DEFAULT_CURRENCY
: null,
304 debug: function(message
)
310 //console.log(message);
319 log: function(message
)
323 //console.log(message);
331 raise: function(message
)
339 processLogin: function() {
342 $('#loading-msg').animate({ left
: 0 }, { duration
: 750, easing
: 'swing', queue
: false });
344 processRegister: function() {
347 $('#loading-msg').animate({ left
: 0 }, { duration
: 750, easing
: 'swing', queue
: false });
352 modalDialogScreen: function(showhide
)
354 var m
= $("#modal_screen");
355 if (showhide
== "show")
357 m
.css('display', 'block');
361 m
.css('display', 'none');
365 showModalDialog: function()
367 bkeeping
.modalDialogScreen("show");
368 bkeeping
.showDialog
.apply(this, arguments
);
371 showDialog: function()
373 bkeeping
.setDialogContent
.apply(this, arguments
);
374 bkeeping
.openDialog();
377 setDialogContent: function()
379 var args
= Array
.prototype.slice
.call(arguments
);
380 var content
= args
.shift();
381 if (content
instanceof Function
)
383 $("#bkeeping_dialog").html(content
.apply(this, args
));
387 $("#bkeeping_dialog").html(content
);
391 openDialog: function()
395 _DIALOG_FIRST
= false;
396 $("#bkeeping_dialog").dialog({ close
: bkeeping
.modalDialogScreen
.bind(this, "hide") });
400 $("#bkeeping_dialog").dialog("open");
405 toggleAccountsOpen: function()
408 if (bkeeping
._a_open
)
410 bkeeping
._a_open
= false;
415 bkeeping
._a_open
= true;
418 $("#accounts_ui").animate({ left
: newleft
}, { duration
: 750, easing
: "swing", complete: function() {}, queue
: false });
423 toggleJournalsOpen: function()
425 var newleft
= "436px";
426 if (bkeeping
._j_open
)
428 bkeeping
._j_open
= false;
433 bkeeping
._j_open
= true;
435 $("#journals_ui").animate({ left
: newleft
}, { duration
: 750, easing
: "swing", complete: function() {}, queue
: false });
439 /* cookie functions: http://techpatterns.com/downloads/javascript_cookies.php */
440 setCookie: function(name, value, expires, path, domain, secure)
442 // set time, it's in milliseconds
443 var today = new Date();
444 today.setTime(today.getTime());
446 // EdA: override this to default to base path instead of "" (easier for simplistic auth systems)
454 expires
= expires
* 1000 * 60 * 60 * 24;
456 var expires_date
= new Date(today
.getTime() + (expires
));
457 document
.cookie
= name
+ "=" + escape(value
) +
458 ((expires
) ? ";expires=" + expires_date
.toGMTString() : "") +
459 ((path
) ? ";path=" + path
: "") +
460 ((domain
) ? ";domain=" + domain
: "") +
461 ((secure
) ? ";secure" : "" );
464 getCookie: function(name
)
466 // first we'll split this cookie up into name/value pairs
467 // note: document.cookie only returns name=value, not the other components
468 var a_all_cookies
= document
.cookie
.split(';');
469 var a_temp_cookie
= '';
470 var cookie_name
= '';
471 var cookie_value
= '';
472 var b_cookie_found
= false; // set boolean t/f default f
474 for (var i
= 0; i
< a_all_cookies
.length
; i
++)
476 // now we'll split apart each name=value pair
477 a_temp_cookie
= a_all_cookies
[i
].split('=');
479 // and trim left/right whitespace while we're at it
480 cookie_name
= a_temp_cookie
[0].replace(/^\s+|\s+$/g, '');
482 // if the extracted name matches passed name
483 if (cookie_name
== name
)
485 b_cookie_found
= true;
486 // we need to handle case where cookie has no value but exists (no = sign, that is):
487 if (a_temp_cookie
.length
> 1)
489 cookie_value
= unescape(a_temp_cookie
[1].replace(/^\s+|\s+$/g, ''));
491 // note that in cases where cookie is initialized but no value, null is returned
495 a_temp_cookie
= null;
504 deleteCookie: function(name
, path
, domain
)
506 if (this.getCookie(name
))
508 // EdA: override this to default to base path instead of "" (easier for simplistic auth systems)
510 document
.cookie
= name
+ "=" +
511 ((path
) ? ";path=" + path
: "") +
512 ((domain
) ? ";domain=" + domain
: "" ) +
513 ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
517 Session: function(sessionId
, loggedInUserid
, loggedInGroup
)
519 this.cookieName
= "_bk_session_js";
521 this.sessionId
= sessionId
|| null;
522 this.loggedInUserid
= loggedInUserid
|| null;
523 this.loggedInGroup
= loggedInGroup
|| null;
525 this.update = function(sessionId
, loggedInUserid
, loggedInGroup
)
527 this.sessionId
= sessionId
|| null;
528 this.loggedInUserid
= loggedInUserid
|| null;
529 this.loggedInGroup
= loggedInGroup
|| null;
533 this.clear = function()
536 this.sessionId
= null;
537 this.loggedInUserid
= null;
538 this.loggedInGroup
= null;
539 bkeeping
.deleteCookie(this.cookieName
);
543 function saveToSessionCookie()
545 bkeeping
.setCookie(this.cookieName
, this.sessionId
+ "," + this.loggedInUserid
+ "," + this.loggedInGroup
);
548 this.save
= saveToSessionCookie
.bind(this);
550 function loadFromSessionCookie()
552 var cookievalues
= bkeeping
.getCookie(this.cookieName
);
555 var vals
= cookievalues
.split(',');
556 this.sessionId
= vals
[0];
557 this.loggedInUserid
= vals
[1];
558 this.loggedInGroup
= vals
[2];
566 // try to load from cookie:
567 this.loaded
= loadFromSessionCookie
.call(this); // true if there was a session cookie, false otherwise
579 this.getProfileDetailsList = function()
581 return this.root
["children"][0]["profileDetails"]["children"];
584 this.getUserid = function()
586 return this.root
["id"];
589 this.getUsername = function()
591 return this.root
["username"];
594 this.getPassword = function()
596 return this.root
["password"];
599 this.getFirstname = function()
601 return this.root
["children"][0]["profileDetails"]["children"][0]["profileDetail"].value
;
604 this.getLastname = function()
606 return this.root
["children"][0]["profileDetails"]["children"][1]["profileDetail"].value
;
609 this.getEmail = function()
611 return this.root
["children"][0]["profileDetails"]["children"][2]["profileDetail"].value
;
614 this.getCountry = function()
616 return this.root
["children"][0]["profileDetails"]["children"][3]["profileDetail"].value
;
620 UserSession: function(root
)
623 this.getSessionId = function()
625 return this.root
["id"];
628 this.getGroup = function()
630 return this.root
["groupid"];
633 this.getUser = function()
635 return this.root
["userid"];
641 DefaultCurrency: function(root
)
644 this.getDefaultCurrency
= this.lister
.bind(this, "profileDetail", bkeeping
.DefaultCurrency
);
645 this.getDefaultCurrencyRaw
= this.rawlister
.bind(this);
648 lister: function(nodename
, _class
)
650 if( this.root
["children"] != null ) {
652 var c
= this.root
["children"];
656 for (var i
= 0; i
< c
.length
; i
++) {
658 if( c
[i
][nodename
] != undefined ) {
659 a
.push(new _class(c
[i
][nodename
]));
661 else if( c
[i
]["debit"] != undefined ) {
662 a
.push( new bkeeping
.Subentry( c
[i
]["debit"], "debit" ) );
664 else if( c
[i
]["credit"] != undefined ) {
665 a
.push( new bkeeping
.Subentry( c
[i
]["credit"], "credit" ) );
673 rawlister: function()
675 return this.root
["children"];
680 this.lister
= bkeeping
.lister
;
681 this.rawlister
= bkeeping
.rawlister
;
684 AccountList: function(root
)
687 this.getAccounts
= this.lister
.bind(this, "account", bkeeping
.Account
);
688 this.getAsList
= this.getAccounts
;
689 this.getAccountsRaw
= this.rawlister
.bind(this);
690 this.getAsRawList
= this.getAccountsRaw
;
693 Account: function(root
)
697 this.getType = function()
699 return this.root
['type'];
702 this.getId = function()
704 return this.root
['id'];
707 this.getName = function()
709 return this.root
['name'];
712 this.getCounterWeight = function()
714 return this.root
['counterWeight'];
717 this.getBalance = function()
719 // XXX balance not in account structure, HELP
724 JournalList: function(root
)
727 this.getJournals
= this.lister
.bind(this, "journal", bkeeping
.Journal
);
728 this.getAsList
= this.getJournals
;
729 this.getJournalsRaw
= this.rawlister
.bind(this);
730 this.getAsRawList
= this.getJournalsRaw
;
733 Journal: function(root
)
737 this.getId = function()
739 return this.root
["id"];
742 this.getName = function()
744 return this.root
["name"];
747 this.getType = function()
749 return this.root
["type"];
752 this.getBalance = function()
754 return this.root
["balance"];
758 EntryList: function(root
)
761 this.getEntries
= this.lister
.bind(this, "entry", bkeeping
.Entry
);
762 this.getAsRawList
= this.rawlister
.bind(this);
765 Entry: function(root
)
769 this.getId = function()
771 return this.root
["id"];
774 this.getEntrynum = function()
776 return this.root
["entrynum"];
779 this.getState = function()
781 return this.root
["state"];
784 this.getJournalid = function()
786 return this.root
["journalid"];
789 this.getDate = function()
791 return this.root
["date"];
794 this.getCurrency = function()
796 return this.root
["currency"];
799 this.getSubentries = function(type
, raw
)
801 var d
= this.root
["children"];
803 for (var i
= 0; i
< d
.length
; i
++)
813 a
.push(new bkeeping
.Subentry(d
[i
], type
));
820 this.getDebits = function()
822 return this.getSubentries("debit");
825 this.getCredits = function()
827 return this.getSubentries("credit");
830 this.getDebitsRaw = function()
832 return this.getSubentries("debit", true);
835 this.getCreditsRaw = function()
837 return this.getSubentries("credit", true);
841 Subentry: function(root
, type
)
846 this.getId = function()
848 return this.root
["id"];
851 this.getAmount = function()
853 return this.root
["amount"];
856 this.getEntryid = function()
858 return this.root
["entryid"];
861 this.getAccountid = function()
863 return this.root
["accountid"];
866 this.getAccount = function()
868 return this.root
["account"];
871 this.getCurrency = function()
873 return this.root
["currency"];
881 var u
= $("#u").val();
882 var p
= $("#p").val();
883 var ret
= new this.LoginCommand(u
, p
).run();
889 var ret
= new this.LogoutCommand().run();
895 var username
= $("#username").val();
896 var password
= $("#password").val();
897 var firstname
= $("#firstname").val();
898 var lastname
= $("#lastname").val();
899 var email
= $("#email").val();
900 var country
= $("#country").val();
901 var currency
= $("#currency").val();
902 var ret
= new this.RegisterCommand(username
, password
, firstname
, lastname
, email
, country
, currency
).run();
905 editprofile: function()
907 var username
= $("#username").val();
908 var password
= $("#password").val();
909 var firstname
= $("#firstname").val();
910 var lastname
= $("#lastname").val();
911 var email
= $("#email").val();
912 var country
= $("#country").val();
913 var ret
= new this.RegisterCommand(username
, password
, firstname
, lastname
, email
, country
, currency
, true).run();
916 deleteThing: function(thingtype
, id
)
918 var goAhead = function(id
)
920 $('#bkeeping_dialog').dialog("close");
921 var ret
= new this.RemoveCommand(thingtype
, function(id
) { alert(thingtype
+ " " + id
+ " removed"); }.bind(this, id
), {'eid': id
, 'jid': bkeeping
._displayed_journal
, 'username': bkeeping
.ACTIVE_SESSION
.loggedInUserid
}).run();
923 bkeeping
.showDialog("Are you sure you want to delete " + thingtype
+ " with id[" + id
+ "] ?");
924 $('#bkeeping_dialog').dialog('option', 'buttons', { "CANCEL": function() { $(this).dialog("close"); }, "DELETE": goAhead
});
927 addedEdited: function(jsonData
)
929 bkeeping
.debug("addedEdited: returned jsonData:");
930 bkeeping
.debug(jsonData
);
931 alert('Recored added/edited. Reloading UI to display updates.');
932 var loc
= document
.location
.href
;
933 if (loc
.indexOf('?') != -1)
935 loc
= loc
.substring(0, loc
.indexOf('?'));
939 document
.location
.href
= loc
+ '?timestamp=' + new Date().getTime();
943 //** closing entry window
944 $("#entry_ui").css("display", "none");
947 //** reloading journal window
948 bkeeping
.showJournal(bkeeping
._displayed_journal
);
952 addedEditedJournal: function(jsonData
)
954 bkeeping
.debug("addedEditedJournal: returned jsonData:");
955 bkeeping
.debug(jsonData
);
956 alert('Recored added/edited. Reloading UI to display updates.');
958 //** reload the current page
959 setTimeout("document.location.href='"+ bkeeping
.ROOT_URL
+"';", 0);
963 wrapFormAsObj: function()
966 var fields
= $(".data_field");
967 for (var i
= 0; i
< fields
.length
; i
++)
969 var field
= fields
[i
];
970 var n
= field
.id
.substring(field
.id
.lastIndexOf('_') + 1);
971 var v
= $(field
).val();
972 bkeeping
.debug('wrapFormAsObj: found ' + n
+ '/' + v
);
978 getAccountsAsOptionsList: function(atype
)
980 // we have to assume they're cached, coz this is a synchronous call
982 var accounts
= bkeeping
.cache
.accounts
;
983 for (var i
= 0; i
< accounts
.length
; i
++)
985 var id
= accounts
[i
].account
.id
;
986 var nam
= accounts
[i
].account
.name
;
987 var type
= accounts
[i
].account
.type
;
990 if( atype
== type
) {
991 html
+= '<option value="' + id
+ '" selected="selected" >' + nam
+ '</option>';
994 html
+= '<option value="' + id
+ '">' + nam
+ '</option>';
1000 getAccountTypesAsOptionsList: function(atype
)
1002 // we have to assume they're cached, coz this is a synchronous call
1004 var thingy
= { asset
: '<option ${selected}>asset</option>',
1005 expense
: '<option ${selected}>expense</option>',
1006 liability
: '<option ${selected}>liability</option>',
1007 revenue
: '<option ${selected}>revenue</option>'
1010 for( property
in thingy
) {
1012 if ( property
== atype
) {
1014 html
+= thingy
[property
].parse_vars( { selected
:"selected='selected'" } );
1018 html
+= thingy
[property
].parse_vars();
1024 getCounterWeight: function(type
)
1041 getCurrentDate: function()
1044 var day
= d
.getDate();
1045 var month
= d
.getMonth() + 1;
1046 var year
= d
.getFullYear();
1047 if (day
< 10) { day
= '0' + day
; }
1048 if (month
< 10) { month
= '0' + month
; }
1049 return day
+ '' + month
+ '' + year
;
1052 getAccountNameForId: function(aid
) {
1054 var accounts
= bkeeping
.cache
.accounts
;
1055 for (var i
= 0; i
< accounts
.length
; i
++)
1057 var id
= accounts
[i
].account
.id
;
1058 var nam
= accounts
[i
].account
.name
;
1068 goJournalPart: function(thingtype
, id
)
1071 var type
= id
? this.EditCommand
: this.AddCommand
;
1072 var pars
= this.wrapFormAsObj();
1073 pars
["username"] = bkeeping
["ACTIVE_SESSION"]["loggedInUserid"];
1077 $('#bkeeping_dialog').dialog("close");
1079 var ret
= new type(thingtype
, this.addedEditedJournal
, pars
).run();
1083 goAccountPart: function(thingtype
, id
)
1086 var type
= id
? this.EditCommand
: this.AddCommand
;
1087 var pars
= this.wrapFormAsObj();
1088 pars
["username"] = bkeeping
["ACTIVE_SESSION"]["loggedInUserid"];
1092 if( (pars
["type"] == "asset") || (pars
["type"] == "expense") ) { //** if asset or expense - debit
1093 pars
["cw"] = "debit";
1095 else { //** otherwise - credit
1096 pars
["cw"] = "credit";
1099 $('#bkeeping_dialog').dialog("close");
1102 var ret
= new type(thingtype
, this.addedEdited
, pars
).run();
1105 goJournalEntryPart: function(thingtype
, id
)
1108 var type
= id
? this.EditCommand
: this.AddCommand
;
1109 var pars
= this.wrapFormAsObj();
1111 //** put in data mapping
1114 //** TODO - i) take ID and update entry or ii) put a new entry with ID of 'new'
1116 if( (id
!= null) && (id
.length
> 0) ) {
1118 entry
= bkeeping
.findEntry(id
);
1120 else if( bkeeping
.findEntry("new") != null ) {
1122 entry
= bkeeping
.findEntry("new");
1126 entry
= new bkeeping
.Entry();
1127 entry
["children"] = [];
1129 entry
["id"] = "new";
1130 entry
["currency"] = pars
["cc"];
1132 entry
["entrynum"] = null;
1133 entry
["journalid"] = "";
1134 entry
["state"] = null;
1135 entry
["xmlns"] = "com/interrupt/bookkeeping/journal";
1137 //bkeeping.cache.entries[ bkeeping.cache.entries.length ] =
1138 bkeeping
.cache
.entries
.push( { entry
: entry
} );
1142 //** set the entry currency
1143 if( pars
["cc"] == null ) {
1144 if( entry
!= null ) {
1145 pars
["cc"] = entry
["currency"];
1150 if( pars
["ctype"] == "debit" ) {
1153 account
: bkeeping
.getAccountNameForId( pars
["caid"] ),
1154 accountid
: pars
["caid"],
1155 amount
: pars
["ecamount"],
1156 currency
: pars
["cc"],
1158 id
: ( id
!= null ) ? id
: "" ,
1159 xmlns
: "com/interrupt/bookkeeping/account"
1162 dname
: bkeeping
.getAccountNameForId( pars
["caid"] ),
1164 damount
: pars
["ecamount"],
1170 entry
.children
.push( { debit
: debit
} );
1176 account
: bkeeping
.getAccountNameForId( pars
["caid"] ),
1177 accountid
: pars
["caid"],
1178 amount
: pars
["ecamount"],
1179 currency
: pars
["cc"],
1181 id
: ( id
!= null ) ? id
: "" ,
1182 xmlns
: "com/interrupt/bookkeeping/account"
1188 cname
: bkeeping
.getAccountNameForId( pars
["caid"] ),
1190 camount
: pars
["ecamount"]
1194 entry
.children
.push( { credit
: credit
} );
1199 var entryPart
= TENTRY_ROW
.parse_vars( obj
);
1200 var thing
= $("#jentry_rows");
1201 $("#jentry_rows").append( entryPart
);
1203 $('#bkeeping_dialog').dialog("close");
1205 //var ret = new type(thingtype, this.addedEdited, pars).run();
1209 findJournalName: function(jid
) {
1211 var resultName
= null;
1212 for( var i
= 0; i
< bkeeping
.cache
.journals
.length
; i
++ ) {
1214 var eachJ
= bkeeping
.cache
.journals
[i
]["journal"];
1215 if( eachJ
["id"] == jid
) {
1217 resultName
= eachJ
["name"];
1226 findAccountName: function(aid
) {
1228 var returnName
= null;
1229 for( var i
= 0; i
< bkeeping
.cache
.accounts
.length
; i
++ ) {
1231 var eachAccount
= bkeeping
.cache
.accounts
[i
]["account"];
1232 if( eachAccount
["id"] == aid
) {
1234 returnName
= eachAccount
["name"];
1242 findAccountType: function(aid
) {
1244 var returnType
= null;
1245 for( var i
= 0; i
< bkeeping
.cache
.accounts
.length
; i
++ ) {
1247 var eachAccount
= bkeeping
.cache
.accounts
[i
]["account"];
1248 if( eachAccount
["id"] == aid
) {
1250 returnType
= eachAccount
["type"];
1258 findEntry: function(eid
) {
1261 for( var i
= 0; i
< bkeeping
.cache
.entries
.length
; i
++ ) {
1263 var eachEntry
= bkeeping
.cache
.entries
[i
]["entry"];
1264 if( eachEntry
["id"] == eid
) {
1275 addEditJournal: function(thingtype
, id
, returnHandler
) // id is null on adds
1278 // raise correct form
1279 var x
= eval("AE_" + thingtype
.toUpperCase());
1282 var journalName
= bkeeping
.findJournalName(id
);
1285 form
= form
.parse_vars( { 'name': journalName
} );
1286 bkeeping
.showModalDialog(form
);
1287 $('#bkeeping_dialog').dialog('option', 'title', x
[0]);
1289 $('#bkeeping_dialog').dialog('option', 'buttons', { "CANCEL": function() { $(this).dialog("close"); }, "SAVE": returnHandler
});
1294 addEditAccount: function(thingtype
, id
, returnHandler
) // id is null on adds
1297 // raise correct form
1298 var x
= eval("AE_" + thingtype
.toUpperCase());
1301 var accountName
= bkeeping
.findAccountName(id
);
1302 var accountType
= bkeeping
.findAccountType(id
);
1305 form
= form
.parse_vars( { accounts
:bkeeping
.getAccountTypesAsOptionsList(accountType
), aname
: accountName
} );
1306 bkeeping
.showModalDialog(form
);
1307 $('#bkeeping_dialog').dialog('option', 'title', x
[0]);
1309 $('#bkeeping_dialog').dialog('option', 'buttons', { "CANCEL": function() { $(this).dialog("close"); }, "SAVE": returnHandler
});
1314 addEditEntry: function(thingtype
, id
, eid
, returnHandler
) // id is null on adds
1317 // raise correct form
1318 var x
= eval("AE_" + thingtype
.toUpperCase());
1321 if( (eid
!= undefined) && (eid
!= null) ) {
1322 obj
["entryid"] = eid
1325 var entryF
= bkeeping
.findEntry(eid
);
1328 if( entryF
!= null ) {
1330 var entryPartF
= null;
1331 for( var i
=0; i
< entryF
.children
.length
; i
++ ) {
1333 var eachC
= entryF
.children
[i
];
1336 if( eachC
["credit"] || eachC
["debit"] ) {
1338 if( eachC
["credit"] ) {
1340 obj
["entry_ctype"] = " selected='selected' ";
1341 thing
= eachC
["credit"];
1343 else if( eachC
["debit"] ) {
1345 obj
["entry_dtype"] = " selected='selected' ";
1346 thing
= eachC
["debit"];
1349 var accountType
= bkeeping
.findAccountType( thing
["accountid"] );
1350 obj
["accounts"] = bkeeping
.getAccountsAsOptionsList(accountType
);
1351 obj
["evalue"] = thing
["amount"];
1353 if( thing
["currency"] == "CDN" ) {
1354 obj
["curr_cdn"] = " selected='selected' ";
1356 else if( thing
["currency"] == "USD" ) {
1357 obj
["curr_usd"] = " selected='selected' ";
1359 else if( thing
["currency"] == "BP" ) {
1360 obj
["curr_bp"] = " selected='selected' ";
1362 else if( thing
["currency"] == "EUR" ) {
1363 obj
["curr_eur"] = " selected='selected' ";
1365 else if( thing
["currency"] == "JPN" ) {
1366 obj
["curr_jpn"] = " selected='selected' ";
1375 obj
["accounts"] = bkeeping
.getAccountsAsOptionsList(null);
1380 form
= form
.parse_vars( obj
);
1382 bkeeping
.showModalDialog(form
);
1383 $('#bkeeping_dialog').dialog('option', 'title', x
[0]);
1385 $('#bkeeping_dialog').dialog('option', 'buttons', { "CANCEL": function() { $(this).dialog("close"); }, "SAVE": returnHandler
});
1390 saveEntry: function(id
)
1393 var type
= id
? this.EditCommand
: this.AddCommand
;
1394 var pars
= this.wrapFormAsObj();
1395 pars
['date'] = bkeeping
.getCurrentDate();
1397 pars
['jid'] = bkeeping
._displayed_journal
;
1398 pars
['username'] = bkeeping
.ACTIVE_SESSION
["loggedInUserid"];
1402 //** 1. findEntry 'entryid' or 'new'
1404 if( id
.length
> 0 ) {
1406 entry
= bkeeping
.findEntry(id
);
1410 entry
= bkeeping
.findEntry("new");
1414 if( entry
!= null ) {
1415 pars
["cc"] = entry
["currency"];
1419 //** 2. ensure balances
1426 for( var i
= 0; i
< entry
["children"].length
; i
++ ) { //** sum up debits & credits
1429 //** on debit side ( asset / expense )
1430 //** on credit side ( liability / revenue )
1431 if( entry
["children"][i
]["credit"] ) {
1433 var thing
= entry
["children"][i
]["credit"];
1435 // check account type
1436 var atype
= bkeeping
.findAccountType( thing
["accountid"] );
1437 if( atype
== "asset" || atype
== "expense" ) {
1439 csumDEBIT
+= parseFloat( thing
["amount"] );
1441 else if( atype
== "liability" || atype
== "revenue" ) {
1443 csumCREDIT
+= parseFloat( thing
["amount"] );
1447 else if( entry
["children"][i
]["debit"] ) {
1449 var thing
= entry
["children"][i
]["debit"];
1451 // check account type
1452 var atype
= bkeeping
.findAccountType( thing
["accountid"] );
1453 if( atype
== "asset" || atype
== "expense" ) {
1455 dsumDEBIT
+= parseFloat( thing
["amount"] );
1457 else if( atype
== "liability" || atype
== "revenue" ) {
1459 dsumCREDIT
+= parseFloat( thing
["amount"] );
1468 * check that debits and credots are balanced
1470 var lhs
= csumDEBIT
+ dsumCREDIT
;
1471 var rhs
= csumCREDIT
+ dsumDEBIT
;
1474 alert("debit and credits are not equal");
1481 * 3. build debit and credit XML parts
1483 pars
['debitsANDcredits'] = "";
1484 for( var i
= 0; i
< entry
["children"].length
; i
++ ) { //** sum up debits & credits
1487 if( entry
["children"][i
]["credit"] ) {
1489 var cthing
= entry
["children"][i
]["credit"];
1490 var cthingXML
= "<credit xmlns='com/interrupt/bookkeeping/account' id='"+ cthing
["id"] +"' amount='"+
1491 cthing
["amount"] +"' entryid='"+ cthing
["entryid"] +"' accountid='"+ cthing
["accountid"] +"' account='"+
1492 cthing
["account"] +"' currency='"+ cthing
["currency"] +"'/>";
1494 pars
['debitsANDcredits'] += cthingXML
;
1497 else if( entry
["children"][i
]["debit"] ) {
1499 var dthing
= entry
["children"][i
]["debit"];
1500 var dthingXML
= "<debit xmlns='com/interrupt/bookkeeping/account' id='"+ dthing
["id"] +"' amount='"+
1501 dthing
["amount"] +"' entryid='"+ dthing
["entryid"] +"' accountid='"+ dthing
["accountid"] +"' account='"+
1502 dthing
["account"] +"' currency='"+ dthing
["currency"] +"'/>";
1504 pars
['debitsANDcredits'] += dthingXML
;
1511 //** 4. refresh the entries list at the end of 'run'
1512 var ret
= new type("entry", this.addedEdited
, pars
).run();
1516 addAccount: function()
1518 var returnHandler
= bkeeping
.goAccountPart
.bind(this, "account", null);
1519 bkeeping
.addEditAccount("account", null, returnHandler
);
1522 editAccount: function(aid
)
1524 var returnHandler
= bkeeping
.goAccountPart
.bind(this, "account", aid
);
1525 bkeeping
.addEditAccount("account", aid
, returnHandler
);
1528 deleteAccount: function()
1533 addJournal: function()
1535 var returnHandler
= bkeeping
.goJournalPart
.bind(this, "journal", null);
1536 return bkeeping
.addEditJournal("journal", null, returnHandler
);
1539 editJournal: function(jid
)
1542 var returnHandler
= bkeeping
.goJournalPart
.bind(this, "journal", jid
);
1544 bkeeping
.addEditJournal("journal", jid
, returnHandler
);
1546 /*var a = new bkeeping.GetCommand("journal", jid, function(journalObj)
1548 $("#journal_name").val(journalObj.getName());
1549 //$("#journal_type").val(journalObj.getType());
1550 //$("#journal_balance").val(journalObj.getBalance());
1556 deleteJournal: function()
1561 addEntry: function()
1563 return bkeeping
.showJournalEntry(null);
1566 addEditEntryPart: function(id
, eid
)
1568 var returnHandler
= bkeeping
.goJournalEntryPart
.bind(this, "entry", null);
1569 bkeeping
.addEditEntry("entry", id
, eid
, returnHandler
);
1572 editEntry: function(eid
)
1574 bkeeping
.showJournalEntry( eid
);
1575 var a
= new bkeeping
.GetCommand("entry", eid
, function(entryObj
)
1577 $("#entry_caid").val(entryObj
.getCaid());
1578 $("#entry_daid").val(entryObj
.getDaid());
1579 $("#entry_ecamount").val(entryObj
.getEcamount());
1580 $("#entry_edamount").val(entryObj
.getEdamount());
1581 $("#entry_cc").val(entryObj
.getCurrency());
1585 deleteEntry: function()
1587 //var a = new bkeeping.RemoveCommand("entry", callback)...
1591 _displayed_journal
: null,
1592 showJournal: function(id
)
1595 //** clear previous content
1596 var jrows
= document
.getElementById( "j_rows" );
1597 jrows
["innerHTML"] = "";
1600 //** show journal UI
1601 var journalUI
= $("#journal_ui");
1602 journalUI
.css("display", "block");
1605 bkeeping
._displayed_journal
= id
;
1606 $("#_journal_id").html(id
);
1608 new bkeeping
.ListCommand("entries", bkeeping
.displayEntries
, id
).run();
1611 showJournalEntry: function(id
)
1614 //** clear previous content
1615 var erows
= document
.getElementById( "jentry_rows" );
1616 erows
["innerHTML"] = "";
1619 var eui
= $("#entry_ui");
1620 eui
.css("display", "block");
1622 var eui2
= document
.getElementById( "entry_ui" ); // trying to put the entryid in the template
1624 eui2
["innerHTML"].parse_vars
= String
.prototype.parse_vars
;
1625 eui2
["innerHTML"] = eui2
["innerHTML"].parse_vars( { entryid
: id
} );
1628 $("#_journalentry_id").html(id
);
1631 new bkeeping
.ListCommand("entry", bkeeping
.displayEntry
, id
).run();
1635 isAauthFailure: function( jsonData
) {
1637 var thing
= jsonData
["logs"]["children"][0]["log"]["children"][0]["logMessages"]["children"][0]["logMessage"]["value"];
1638 if( (thing
!= undefined) || (thing
!= null) ) {
1640 var containS
= thing
.indexOf("Authenticated");
1641 if( containS
> 0 ) {
1649 getGenericFailureReason: function(jsonData
)
1654 r
= jsonData
["logs"]["children"][0]["log"]["children"][0]["logMessages"]["children"][0]["logMessage"]["value"];
1664 loadProfile: function(data
)
1666 for (var i
= 0; i
< data
.length
; i
++)
1668 var o
= data
[i
]["profileDetail"];
1669 $("#" + o
.id
).val(o
.value
);
1673 GetprofileCommand: function(callback
)
1675 this.callback
= callback
;
1677 function isSuccess(jsonData
)
1679 return (jsonData
&& jsonData
["user"]);
1682 var getFailureReason
= bkeeping
.getGenericFailureReason
;
1684 function handleResponse(jsonData
, textStatus
)
1686 if (isSuccess(jsonData
))
1688 var u
= new bkeeping
.User(jsonData
["user"]);
1689 setTimeout(callback
.bind(this, u
.getProfileDetailsList()), 1000);
1693 var reason
= getFailureReason(jsonData
);
1694 alert("Failed to get profile. Reason: " + reason
);
1698 this.run = function()
1700 bkeeping
.send_bkexpr("getprofile", GETPROFILE_COMMAND
.parse_vars({username
:bkeeping
.ACTIVE_SESSION
.loggedInUserid
}), handleResponse
.bind(this));
1704 RegisterCommand: function(username
, password
, firstname
, lastname
, email
, country
, currency
, updating
)
1706 this.username
= username
;
1707 this.password
= password
;
1708 this.firstname
= firstname
;
1709 this.lastname
= lastname
;
1711 this.country
= country
;
1712 this.currency
= currency
;
1713 this.updating
= updating
;
1715 function isSuccess(jsonData
)
1717 return (jsonData
&& jsonData
["user"]);
1720 var getFailureReason
= bkeeping
.getGenericFailureReason
;
1722 function handleResponse(jsonData
, textStatus
)
1725 // put back the 'Loading...' message
1726 $('#loading-msg').animate({ left
: -100 }, { duration
: 750, easing
: 'swing', queue
: false });
1729 // on successful register, user is redirected to the home page and messaged about his ability to login or that his changes were saved
1730 if (isSuccess(jsonData
))
1732 var flag
= "canlogin";
1735 flag
= "changessaved";
1737 setTimeout("document.location.href='accounts.html';", 0);
1741 // show a UI for registration failure:
1742 var reason
= getFailureReason(jsonData
);
1743 var verb
= "register";
1746 verb
= "save changes"
1748 alert("Failed to " + verb
+ ". Reason: " + reason
);
1752 this.run = function()
1754 var command
= REGISTER_COMMAND
;
1755 var cname
= "register";
1758 command
= UPDATEPROFILE_COMMAND
;
1759 cname
= "updateprofile";
1761 bkeeping
.send_bkexpr(cname
, command
.parse_vars({username
: this.username
, password
: this.password
, firstname
: this.firstname
, lastname
: this.lastname
, email
: this.email
, country
: this.country
, currency
: this.currency
}), handleResponse
.bind(this));
1765 LoginCommand: function(username
, password
)
1767 this.username
= username
;
1768 this.password
= password
;
1770 function isSuccess(jsonData
)
1772 return (jsonData
&& jsonData
["userSession"]);
1775 var getFailureReason
= bkeeping
.getGenericFailureReason
;
1777 function handleResponse(jsonData
, textStatus
)
1780 // put back the 'Loading...' message
1781 $('#loading-msg').animate({ left
: -100 }, { duration
: 750, easing
: 'swing', queue
: false });
1784 // on successful login, user is redirected to the accounts page (accounts.html)
1785 if (isSuccess(jsonData
))
1789 var us
= new bkeeping
.UserSession(jsonData
["userSession"]);
1790 bkeeping
.ACTIVE_SESSION
.update(us
.getSessionId(), us
.getUser(), us
.getGroup()).save();
1792 // go to the accounts page
1793 setTimeout("document.location.href='accounts.html';", 2000);
1797 // show a UI for login failure:
1798 var reason
= getFailureReason(jsonData
);
1799 alert("Failed to login. Reason: " + reason
);
1803 this.run = function()
1805 bkeeping
.send_bkexpr("login", LOGIN_COMMAND
.parse_vars({username
: this.username
, password
: this.password
}), handleResponse
.bind(this));
1809 LogoutCommand: function()
1812 function isSuccess(jsonData
)
1815 return (jsonData
&& !(jsonData
["logs"]));
1818 var getFailureReason
= bkeeping
.getGenericFailureReason
;
1820 function handleResponse(jsonData
, textStatus
)
1822 // on successful logout, user is redirected to the home page
1823 if (isSuccess(jsonData
))
1825 // go to the accounts page
1826 bkeeping
.ACTIVE_SESSION
.clear();
1827 setTimeout('document.location.href = "'+ bkeeping
.ROOT_URL
+'";', 2000);
1832 // show a UI for login failure:
1833 var reason
= getFailureReason(jsonData
);
1834 alert("Failed to logout. Reason: " + reason
);
1838 this.run = function()
1840 bkeeping
.send_bkexpr("logout", "logout;", handleResponse
.bind(this));
1845 getEntryBalance: function( entryF
) {
1848 //** 2. ensure balances
1855 var entry
= entryF
["root"];
1857 for( var i
= 0; i
< entry
["children"].length
; i
++ ) { //** sum up debits & credits
1860 //** on debit side ( asset / expense )
1861 //** on credit side ( liability / revenue )
1862 if( entry
["children"][i
]["credit"] ) {
1864 var thing
= entry
["children"][i
]["credit"];
1866 // check account type
1867 var atype
= bkeeping
.findAccountType( thing
["accountid"] );
1868 if( atype
== "asset" || atype
== "expense" ) {
1870 csumDEBIT
+= parseFloat( thing
["amount"] );
1872 else if( atype
== "liability" || atype
== "revenue" ) {
1874 csumCREDIT
+= parseFloat( thing
["amount"] );
1878 else if( entry
["children"][i
]["debit"] ) {
1880 var thing
= entry
["children"][i
]["debit"];
1882 // check account type
1883 var atype
= bkeeping
.findAccountType( thing
["accountid"] );
1884 if( atype
== "asset" || atype
== "expense" ) {
1886 dsumDEBIT
+= parseFloat( thing
["amount"] );
1888 else if( atype
== "liability" || atype
== "revenue" ) {
1890 dsumCREDIT
+= parseFloat( thing
["amount"] );
1898 * check that debits and credots are balanced
1900 var lhs
= csumDEBIT
+ dsumCREDIT
;
1901 var rhs
= csumCREDIT
+ dsumDEBIT
;
1904 alert("debit and credits are not equal");
1911 displayAccounts: function(accountListObj
)
1913 var as
= accountListObj
.getAccounts();
1916 var lister
= $("#acl_rows");
1918 for (var i
= 0; i
< as
.length
; i
++)
1923 //var obj = { rowid: a.getId(), aname: a.getName(), category: a.getType(), balance: a.getBalance() };
1924 var obj
= { rowid
: a
.getId(), aname
: a
.getName(), category
: a
.getType() };
1925 html
+= ACCOUNT_ROW
.parse_vars(obj
);
1932 displayJournals: function(journalListObj
)
1934 var js
= journalListObj
.getJournals();
1936 var lister
= $("#js_rows");
1938 for (var i
= 0; i
< js
.length
; i
++)
1942 var obj
= { rowid
: j
.getId(), jname
: j
.getName() };
1943 html
+= JOURNAL_ROW
.parse_vars(obj
);
1950 //** display all the entries in a journal
1951 displayEntries: function(entryListObj
)
1953 var es
= entryListObj
.getEntries();
1954 var lister
= $("#j_rows");
1957 for (var i
= 0; i
< es
.length
; i
++)
1961 // ??? xxx not sure what data to put here
1962 //var obj = { rowid: e.getId(), date: (e.getDate() || "<none>"), entry: ("..." + e.getId().substring(e.getId().length - 6) || "<none>"), balance: (e.getBalance() || "0.00") };
1964 if( e
["root"] != undefined ) {
1966 var bal
= bkeeping
.getEntryBalance( e
);
1970 date
: (e
.getDate() || "<none>"),
1971 entry
: ("..." + e
.getId().substring(e
.getId().length
- 20) || "<none>"),
1976 html
+= ENTRY_ROW
.parse_vars(obj
);
1984 //** display the debit / credits in a single entry
1985 displayEntry: function(entryListObj
)
1987 var es
= entryListObj
.getEntries();
1988 var lister
= $("#jentry_rows");
1991 for (var i
= 0; i
< es
.length
; i
++)
1995 // ??? xxx not sure what data to put here
1996 //var obj = { rowid: e.getId(), date: (e.getDate() || "<none>"), entry: ("..." + e.getId().substring(e.getId().length - 6) || "<none>"), balance: (e.getBalance() || "0.00") };
1998 //var obj = { rowid: e.getId(), date: (e.getDate() || "<none>"), entry: ("..." + e.getId().substring(e.getId().length - 6) || "<none>"), balance: ( "0.00" ) };
2001 if( e
["type"] == "debit" ) {
2003 dname
: e
.getAccount(),
2004 damount
: e
.getAmount(),
2009 else if( e
["type"] == "credit" ) {
2013 cname
: e
.getAccount(),
2014 camount
: e
.getAmount()
2018 obj
["rowid"] = e
.getId();
2019 obj
["eid"] = entryListObj
["root"]["id"];
2021 html
+= TENTRY_ROW
.parse_vars(obj
);
2028 objectIsOfType: function(obj
, single_or_plural_type
)
2030 var t
= (single_or_plural_type
.charAt(single_or_plural_type
.length
- 1) == 's') ? (single_or_plural_type
.substring(0, single_or_plural_type
.length
- 1)) : single_or_plural_type
;
2031 if (t
== 'entrie') { t
= "entry"; }
2039 addToCacheAsList: function(plural_type
, listObj
)
2041 var list
= listObj
.getAsRawList();
2042 bkeeping
.debug('AddToCacheAsList: listing (' + plural_type
+ '/' + list
.length
+ ')');
2043 bkeeping
.debug(list
);
2044 if (list
&& (list
.length
> 0))
2046 for (var i
= 0; i
< list
.length
; i
++)
2048 if (bkeeping
.objectIsOfType(list
[i
], plural_type
))
2050 bkeeping
.addToCache(plural_type
, null, list
[i
]);
2056 addToCache: function(plural_type
, id
, jsonData
)
2059 var single_type
= (plural_type
== 'entries') ? 'entry' : plural_type
.substring(0, plural_type
.length
- 1);
2060 for (var i
= 0; i
< bkeeping
.cache
[plural_type
].length
; i
++)
2062 var item
= bkeeping
.cache
[plural_type
][i
];
2063 bkeeping
.debug('addToCache:iterating cache, found item ' + item
[single_type
].id
+ '/' + id
);
2064 bkeeping
.debug(item
);
2065 if (item
&& (item
[single_type
].id
== id
))
2067 // item could be changed, so re-add
2069 bkeeping
.cache
[plural_type
][i
] = jsonData
;
2074 bkeeping
.debug('addToCache: pushing jsonData onto cache');
2075 bkeeping
.debug(jsonData
);
2076 bkeeping
.cache
[plural_type
].push(jsonData
);
2080 getFromCache: function(plural_type
, id
)
2082 var single_type
= (plural_type
== 'entries') ? 'entry' : plural_type
.substring(0, plural_type
.length
- 1);
2083 for (var i
= 0; i
< bkeeping
.cache
[plural_type
].length
; i
++)
2085 var item
= bkeeping
.cache
[plural_type
][i
];
2086 bkeeping
.debug('getFromCache:iterating cache, found item ' + item
[single_type
].id
+ '/' + id
);
2087 bkeeping
.debug(item
);
2088 if (item
&& (item
[single_type
].id
== id
))
2095 deleteFromCache: function(single_type
, id
)
2097 var plural_type
= (single_type
== 'entry') ? 'entries' : (single_type
+ 's');
2098 for (var i
= 0; i
< bkeeping
.cache
[plural_type
].length
; i
++)
2100 var item
= bkeeping
.cache
[plural_type
][i
];
2101 bkeeping
.debug('deleteFromCache:iterating cache, found item ' + item
[single_type
].id
+ '/' + id
);
2102 bkeeping
.debug(item
);
2103 if (item
&& (item
[single_type
].id
== id
))
2105 delete bkeeping
.cache
[plural_type
][i
];
2111 GetCommand: function(calltype
, id
, callback
)
2113 this.calltype
= calltype
;
2114 this.calltype_list
= (this.calltype
== 'entry') ? 'entries' : (this.calltype
+ 's');
2116 this.callback
= callback
;
2119 var u
= bkeeping
.ACTIVE_SESSION
.loggedInUserid
;
2120 var g
= (u
== 'root') ? "webkell" : (u
+ '.group');
2121 this.pars
= {username
: u
, group
: g
, id
: this.id
};
2122 switch (this.calltype
)
2125 this.command
= GETACCOUNT_COMMAND
;
2126 this.type
= bkeeping
.Account
;
2129 this.command
= GETJOURNAL_COMMAND
;
2130 this.type
= bkeeping
.Journal
;
2133 this.command
= GETENTRY_COMMAND
;
2134 this.type
= bkeeping
.Entry
;
2135 this.pars
['jid'] = bkeeping
._displayed_journal
;
2138 alert("Unknown calltype: " + this.calltype
);
2142 function isSuccess(jsonData
)
2144 return (jsonData
&& (jsonData
[this.calltype
]) || jsonData
[this.calltype_list
]);
2147 var getFailureReason
= bkeeping
.getGenericFailureReason
;
2149 function handleResponse(jsonData
, textStatus
, cached
)
2151 if (isSuccess
.call(this, jsonData
))
2153 if (!cached
|| (cached
!= 'true'))
2155 bkeeping
.addToCache(this.calltype_list
, this.id
, jsonData
);
2157 return this.callback(new this.type(jsonData
[this.calltype
]));
2161 // show a UI for login failure:
2162 var reason
= getFailureReason(jsonData
);
2163 alert("Failed to get list " + this.calltype
+ ". Reason: " + reason
);
2167 this.run = function()
2169 var item
= bkeeping
.getFromCache(this.calltype_list
, this.id
);
2172 bkeeping
.debug('handling call type ' + this.calltype
+ '/' + this.id
+ ' from cache');
2173 handleResponse
.call(this, item
, 'success', 'true');
2177 bkeeping
.debug('handling call type ' + this.calltype
+ ' from ajax');
2178 var t
= "get" + this.calltype
;
2179 bkeeping
.send_bkexpr(t
, this.command
.parse_vars(this.pars
), handleResponse
.bind(this));
2185 setDefaultCurrency: function(profileDetailObj
)
2188 bkeeping
.DEFAULT_CURRENCY
= profileDetailObj
["root"]["value"];
2192 ListCommand: function(listtype
, callback
, optJournalid
)
2194 this.listtype
= listtype
;
2195 this.callback
= callback
;
2198 this.pars
= { username
: bkeeping
.ACTIVE_SESSION
.loggedInUserid
};
2199 switch (this.listtype
)
2202 this.command
= LISTACCOUNTS_COMMAND
;
2203 this.type
= bkeeping
.AccountList
;
2206 this.command
= LISTJOURNALS_COMMAND
;
2207 this.type
= bkeeping
.JournalList
;
2208 this.pars
["journal"] = optJournalid
;
2211 this.command
= LISTENTRIES_COMMAND
;
2212 this.type
= bkeeping
.EntryList
;
2213 this.pars
["journal"] = bkeeping
["_displayed_journal"];
2216 this.command
= LISTENTRY_COMMAND
;
2217 this.type
= bkeeping
.EntryList
;
2218 this.pars
["journal"] = bkeeping
["_displayed_journal"];
2219 this.pars
["entry"] = optJournalid
;
2222 alert("Unknown list: " + this.listtype
);
2226 function isSuccess(jsonData
)
2228 return (jsonData
&& jsonData
[this.listtype
]);
2231 var getFailureReason
= bkeeping
.getGenericFailureReason
;
2234 function handleResponse(jsonData
, textStatus
, cached
)
2237 if (cached
|| isSuccess
.call(this, jsonData
))
2240 if (cached
&& (cached
== 'true'))
2242 r
= new this.type({ "children" : jsonData
});
2246 r
= new this.type(jsonData
[this.listtype
]);
2247 bkeeping
.debug("Add to cache as list in ListCommand: " + this.listtype
);
2249 bkeeping
.addToCacheAsList(this.listtype
, r
);
2251 return this.callback(r
);
2253 else if( bkeeping
.isAauthFailure(jsonData
) ) {
2255 var msg
= jsonData
["logs"]["children"][0]["log"]["children"][0]["logMessages"]["children"][0]["logMessage"]["value"];
2258 var rootURL
= document
.URL
.substring( 0, document
.URL
.lastIndexOf("accounts.html") );
2260 setTimeout("document.location.href='"+ rootURL
+"';", 0);
2265 // show a UI for login failure:
2266 var reason
= getFailureReason(jsonData
);
2267 alert("Failed to get list " + this.listtype
+ ". Reason: " + reason
);
2271 this.run = function()
2273 if ( (bkeeping
.cache
[this.listtype
] != undefined) && (bkeeping
.cache
[this.listtype
].length
> 0) )
2275 bkeeping
.debug('handling list type ' + this.listtype
+ ' from CACHE');
2276 handleResponse
.call(this, bkeeping
.cache
[this.listtype
], 'success', 'true');
2280 bkeeping
.debug('handling list type ' + this.listtype
+ ' from AJAX');
2281 var t
= "list" + this.listtype
;
2282 bkeeping
.send_bkexpr(t
, this.command
.parse_vars(this.pars
), handleResponse
.bind(this));
2288 LoadCommand: function(listtype
, callback
, optJournalid
)
2290 this.listtype
= listtype
;
2291 this.callback
= callback
;
2294 this.pars
= {username
: bkeeping
.ACTIVE_SESSION
.loggedInUserid
};
2295 switch (this.listtype
)
2297 case "profileDetail":
2298 this.command
= LOADDEFAULTCURRENCY_COMMAND
;
2299 this.type
= bkeeping
.DefaultCurrency
;
2302 alert("Unknown list: " + this.listtype
);
2306 function isSuccess(jsonData
)
2308 return (jsonData
&& jsonData
[this.listtype
]);
2311 var getFailureReason
= bkeeping
.getGenericFailureReason
;
2313 function handleResponse(jsonData
, textStatus
)
2315 if (isSuccess
.call(this, jsonData
))
2317 this.callback(new this.type(jsonData
[this.listtype
]));
2321 // show a UI for login failure:
2322 var reason
= getFailureReason(jsonData
);
2323 alert("Failed to get list " + this.listtype
+ ". Reason: " + reason
);
2327 this.run = function()
2329 var t
= "list" + this.listtype
;
2330 bkeeping
.send_bkexpr(t
, this.command
.parse_vars(this.pars
), handleResponse
.bind(this));
2335 /* pars is an object containing the data to be added */
2336 AddCommand: function(type
, callback
, pars
)
2338 // pars for account: ${aid} ${atype} ${aname} ${acw} ${username}
2339 // pars for journal: ${jid} ${jname} ${jtype} ${jbalance} ${username}
2340 // pars for entry: ${eid} ${cc} ${edid} ${edamount} ${aid} ${ecid} ${ecamount} ${username} ${jid}
2342 this.callback
= callback
;
2348 this.command
= ADDACCOUNT_COMMAND
;
2350 this.type
= "accounts"; // special case where what's returned will be an 'accounts'
2353 this.command
= ADDJOURNAL_COMMAND
;
2356 this.command
= ADDENTRY_COMMAND
;
2359 alert("Unknown add: " + this.type
);
2363 function isSuccess(jsonData
)
2366 return (jsonData
&& ( jsonData
["logMessages"] == undefined ) );
2370 var getFailureReason
= bkeeping
.getGenericFailureReason
;
2372 function handleResponse(jsonData
, textStatus
)
2374 if (isSuccess
.call(this, jsonData
))
2376 return this.callback(jsonData
);
2378 else if( bkeeping
.isAauthFailure(jsonData
) ) {
2380 var msg
= jsonData
["logs"]["children"][0]["log"]["children"][0]["logMessages"]["children"][0]["logMessage"]["value"];
2383 var rootURL
= document
.URL
.substring( 0, document
.URL
.lastIndexOf("accounts.html") );
2385 setTimeout("document.location.href='"+ rootURL
+"';", 0);
2390 // show a UI for login failure:
2391 var reason
= getFailureReason(jsonData
);
2392 alert("Failed to add " + this.type
+ ". Reason: " + reason
);
2396 this.run = function()
2398 bkeeping
.send_bkexpr("add" + this.type
, this.command
.parse_vars(pars
), handleResponse
.bind(this));
2402 RemoveCommand: function(type
, callback
, pars
)
2404 // pars for account: ${aid}
2405 // pars for journal: ${jid}
2406 // pars for entry: ${eid}
2408 this.callback
= callback
;
2413 this.command
= REMOVEACCOUNT_COMMAND
;
2416 this.command
= REMOVEJOURNAL_COMMAND
;
2419 this.command
= REMOVEENTRY_COMMAND
;
2422 alert("Unknown remove: " + this.type
);
2426 function isSuccess(jsonData
)
2428 return (jsonData
&& jsonData
[this.type
]);
2431 var getFailureReason
= bkeeping
.getGenericFailureReason
;
2433 function handleResponse(jsonData
, textStatus
)
2435 if (isSuccess
.call(this, jsonData
))
2437 return this.callback(jsonData
);
2441 // show a UI for login failure:
2442 var reason
= getFailureReason(jsonData
);
2443 alert("Failed to add " + this.type
+ ". Reason: " + reason
);
2447 this.run = function()
2449 bkeeping
.send_bkexpr("remove" + this.type
, this.command
.parse_vars( pars
), handleResponse
.bind(this) );
2453 /* pars is an object containing the data to be added */
2454 EditCommand: function(type
, callback
, pars
)
2456 // pars for account: ${aid} ${atype} ${aname} ${acw} ${username}
2457 // pars for journal: ${jid} ${jname} ${jtype} ${jbalance} ${username}
2458 // pars for entry: ${eid} ${cc} ${edid} ${edamount} ${aid} ${ecid} ${ecamount} ${username} ${jid}
2460 this.callback
= callback
;
2466 this.command
= UPDATEACCOUNT_COMMAND
;
2469 this.command
= UPDATEJOURNAL_COMMAND
;
2472 this.command
= UPDATEENTRY_COMMAND
;
2475 alert("Unknown edit: " + this.type
);
2479 function isSuccess(jsonData
)
2481 return (jsonData
&& ( jsonData
["logMessages"] == undefined ) );
2484 var getFailureReason
= bkeeping
.getGenericFailureReason
;
2486 function handleResponse(jsonData
, textStatus
)
2488 if (isSuccess
.call(this, jsonData
))
2490 return this.callback(jsonData
);
2492 else if( bkeeping
.isAauthFailure(jsonData
) ) {
2494 var msg
= jsonData
["logs"]["children"][0]["log"]["children"][0]["logMessages"]["children"][0]["logMessage"]["value"];
2497 var rootURL
= document
.URL
.substring( 0, document
.URL
.lastIndexOf("accounts.html") );
2499 setTimeout("document.location.href='"+ rootURL
+"';", 0);
2504 // show a UI for login failure:
2505 var reason
= getFailureReason(jsonData
);
2506 alert("Failed to add " + this.type
+ ". Reason: " + reason
);
2510 this.run = function()
2512 bkeeping
.send_bkexpr("edit" + this.type
, this.command
.parse_vars(pars
), handleResponse
.bind(this));
2518 error: function(xmlHttpRequest
, textStatus
, errorThrown
)
2520 bkeeping
.raise('There was a problem with the server request: ' + textStatus
+ '/' + errorThrown
);
2523 success: function(data
, textStatus
)
2525 bkeeping
.log('genericSuccess');
2528 complete: function(xmlHttRequest
, textStatus
)
2530 bkeeping
.log('genericComplete');
2533 // caveat: this function does NOT handle xml with textnodes mixed in with other element children
2534 xmlRecurse: function(node
, context
)
2536 // squeeze the attributes and add to the context
2537 var attributes
= node
.attributes
;
2540 for (var i
= 0; i
< attributes
.length
; i
++)
2542 var n
= attributes
[i
].name
;
2543 var v
= attributes
[i
].nodeValue
;
2548 var children
= node
.childNodes
;
2551 if (children
.length
> 0)
2553 if ((children
.length
== 1) && (children
[0].nodeType
== 3)) // 3 is text node
2555 context
["value"] = children
[0].textContent
;
2559 if (!context
["children"])
2561 context
["children"] = [];
2563 for (var j
= 0; j
< children
.length
; j
++)
2566 p
[children
[j
].nodeName
] = {};
2567 context
["children"].push(p
);
2568 this.xmlRecurse(children
[j
], p
[children
[j
].nodeName
]);
2576 // caveat: this function does NOT handle xml with textnodes mixed in with other element children
2577 xmlToJson: function(data
, type
)
2585 try //Internet Explorer
2587 xmlDoc
= new ActiveXObject("Microsoft.XMLDOM");
2588 xmlDoc
.async
= "false";
2589 xmlDoc
.loadXML(data
);
2593 var parser
= new DOMParser();
2594 //xmlDoc = parser.parseFromString(data, "text/xml");
2598 // convert to json (simplified greatly)
2599 // we'll take advantage of the fact that all the data being passed around is linked to attributes
2600 // and thus we'll go ahead and make our json like this:
2601 // <name1 attr1=val attr2=val...>
2602 // <name2 attr3=val attr4=val...>
2603 // <name2 attr5=val attr6=val...>
2604 // <name3 attr7=val attr8=val...>
2613 // "value": null, // special value -- the text node child of this ele, exclusive with children
2640 var root
= xmlDoc
.firstChild
;
2641 json
[root
.nodeName
] = {};
2642 //json[root.nodeName] = this.xmlRecurse(root, json[root.nodeName]);
2643 json
[root
.nodeName
] = bkeeping
.xmlRecurse(root
, json
[root
.nodeName
]);
2647 zzz: function (xhr
, ajaxOptions
, thrownError
) {
2651 send_bkexpr: function(bkexprname
, expr
, callback
, optErrorCallback
, optCompleteCallback
)
2653 if ( MOCK_DATA
== "true" || MOCK_DATA
== true )
2656 if (MOCK_DATA_FAILURES_MODE
)
2658 r
= MOCK_DATA
["failures"][bkexprname
];
2662 r
= MOCK_DATA
["successes"][bkexprname
];
2664 var response
= r
.response
.parse_vars(_LAST_PARSED_DICT
);
2666 var textStatus
= r
.textStatus
;
2667 var sanitizedData
= this.xmlToJson(response
, type
);
2668 callback(sanitizedData
, textStatus
);
2672 var url
= (PROD_ENV
) ? "/webkell" : "/webkell/webkell";
2673 if (bkexprname
== "register")
2675 url
= (PROD_ENV
) ? "/authenticate" : "/webkell/authenticate";
2679 success
: callback
|| bkeeping
.success
,
2680 error
: optErrorCallback
|| bkeeping
.error
,
2681 complete
: optCompleteCallback
|| bkeeping
.complete
,
2682 data
: {"bkexpr": expr
},
2683 dataFilter
: this.xmlToJson
,
2693 /* initialization */
2694 displayLoginBlurb: function()
2696 $("#loggedinnote").css('display', "block");
2697 var template
= $("#loggedinnote").html();
2698 $("#loggedinnote").html(template
.parse_vars({"name": bkeeping
.ACTIVE_SESSION
.loggedInUserid
}));
2701 $("#loginholder").css("visibility", "hidden");
2705 // element not there
2709 page_loader_init: function()
2711 if (window
.page_loader
)
2713 page_loader(); // defined in e.g. accounts.html, or any other UI page
2717 page_init: function()
2719 var path
= document
.location
.href
.match(/^http:\/\/[^\/]+\/(.*)$/);
2723 // cut off querystring and hash
2724 if (path
.indexOf("?") > -1)
2726 path
= path
.substring(0, path
.indexOf("?"));
2728 if (path
.indexOf("#") > -1)
2730 path
= path
.substring(0, path
.indexOf("#"));
2732 // if it's under webkell, remove that:
2733 if (path
.indexOf("webkell") == 0)
2735 path
= path
.substring(8);
2743 if ((path
== "") || (path
== "/") || (path
== "index.html"))
2751 // this is not exactly efficient, but we'll do this til we're on a proper server-side template engine
2752 var mode
= document
.location
.href
.substring(document
.location
.href
.indexOf("mode=") + 5).match(/^(\w+)(.*)$/);
2761 $("#contentbox").load(mode
+ ".html");
2762 if (mode
== "userprofile")
2764 var u
= new bkeeping
.GetprofileCommand(bkeeping
.loadProfile
).run();
2767 case "accounts.html":
2768 // do nothing, this UI is generated dynamically
2771 bkeeping
.debug("Not a known page: " + path
);
2774 if (bkeeping
.ACTIVE_SESSION
.loaded
)
2776 bkeeping
.displayLoginBlurb();
2779 var flag
= document
.location
.href
.indexOf("flag=");
2782 var value
= document
.location
.href
.substring(flag
);
2783 if (value
.indexOf("canlogin") != -1)
2785 bkeeping
.showDialog("You have registered successfully. You can now log in.")
2787 if (value
.indexOf("changessaved") != -1)
2789 bkeeping
.showDialog("Your changes have been saved.");
2796 bkeeping
.ACTIVE_SESSION
= new bkeeping
.Session(); // load from cookie if present
2797 if (!$("#bkeeping_dialog").length
)
2799 $("body").append(DIALOG_HOLDER
);
2801 //bkeeping.page_init(); // initializations related to the page we're on
2802 //bkeeping.page_loader_init(); // initializations defined on the page we're on
2813 bkeeping
.AccountList
.prototype = new bkeeping
.Lister();
2814 bkeeping
.JournalList
.prototype = new bkeeping
.Lister();
2815 bkeeping
.EntryList
.prototype = new bkeeping
.Lister();
2817 bkeeping
.DefaultCurrency
.prototype = new bkeeping
.Lister();
2822 $(document
).ready(bkeeping
.init
);
2823 $(window
).unload(bkeeping
.unload
);
2831 response
: "<userSession xmlns='com/interrupt/bookkeeping/users' id='c4e2e5344b91c6c1-1c82792712270d305b2-7ffd' groupid='${username}' userid='${username}' />",
2838 response
: "<user xmlns='com/interrupt/bookkeeping/users' id='${username}' username='${username}' password='${password}' logintimeout='600000' accountLevel='FREE' defaultGroup='webkell' authenticated=''>" +
2839 "<profileDetails xmlns='com/interrupt/bookkeeping/users' id='user.details'>" +
2840 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='firstname' name='first.name' value='${firstname}'/>" +
2841 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='lastname' name='last.name' value='${lastname}'/>" +
2842 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='email' name='email' value='${email}'/>" +
2843 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='country' name='country' value='${country}'/>" +
2844 "</profileDetails>" +
2852 response
: "<user xmlns='com/interrupt/bookkeeping/users' id='${username}' username='${username}' password='${password}' logintimeout='600000' accountLevel='FREE' defaultGroup='webkell' authenticated=''>" +
2853 "<profileDetails xmlns='com/interrupt/bookkeeping/users' id='user.details'>" +
2854 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='username' name='user.name' value='ed'/>" +
2855 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='password' name='password' value='foo'/>" +
2856 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='firstname' name='first.name' value='Eddie'/>" +
2857 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='lastname' name='last.name' value='Abrams'/>" +
2858 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='email' name='email' value='ed@abra.ms'/>" +
2859 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='country' name='country' value='Canada'/>" +
2860 "</profileDetails>" +
2868 response
: "<user xmlns='com/interrupt/bookkeeping/users' id='${username}' username='${username}' password='${password}' logintimeout='600000' accountLevel='FREE' defaultGroup='webkell' authenticated=''>" +
2869 "<profileDetails xmlns='com/interrupt/bookkeeping/users' id='user.details'>" +
2870 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='username' name='user.name' value='${username}'/>" +
2871 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='password' name='password' value='${password}'/>" +
2872 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='firstname' name='first.name' value='${firstname}'/>" +
2873 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='lastname' name='last.name' value='${lastname}'/>" +
2874 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='email' name='email' value='${email}'/>" +
2875 "<profileDetail xmlns='com/interrupt/bookkeeping/users' id='country' name='country' value='${country}'/>" +
2876 "</profileDetails>" +
2884 response
: "<accounts id='main.accounts'>" +
2885 "<account id='05' name='bankaccount' type='asset' counterWeight='debit' currency=''/>" +
2886 "<account id='06' name='creditcard' type='liability' counterWeight='credit' currency=''/>" +
2894 response
: "<journals xmlns:journal='com/interrupt/bookkeeping/journal' id='main.journals'>" +
2895 "<journal id='generalledger' name='generalledger' type='' balance=''>" +
2896 "<entries id='main.entries'>" +
2897 "<entry id='qwertySTUB' entrynum='' state='' journalid='generalledger' date='' currency='CDN'>" +
2898 "<debit xmlns:account='com/interrupt/bookkeeping/account' id='dtS' amount='120.00' entryid='qwertySTUB' accountid='05' account='' currency='CDN'/>" +
2899 "<credit xmlns:account='com/interrupt/bookkeeping/account' id='crS' amount='120.00' entryid='qwertySTUB' accountid='06' account='' currency='CDN'/>" +
2903 "<journal id='otherledger' name='otherledger' type='' balance=''>" +
2904 "<entries id='main.entries'>" +
2905 "<entry id='qwertySTUB' entrynum='' state='' journalid='generalledger' date='' currency='CDN'>" +
2906 "<debit xmlns:account='com/interrupt/bookkeeping/account' id='dtS' amount='120.00' entryid='qwertySTUB' accountid='05' account='' currency='CDN'/>" +
2907 "<credit xmlns:account='com/interrupt/bookkeeping/account' id='crS' amount='120.00' entryid='qwertySTUB' accountid='06' account='' currency='CDN'/>" +
2918 response
: "<entries id='main.entries'>" +
2919 "<entry id='qwertySTUB' entrynum='' state='' journalid='generalledger' date='' currency='CDN'>" +
2920 "<debit xmlns:account='com/interrupt/bookkeeping/account' id='dtS' amount='120.00' entryid='qwertySTUB' accountid='05' account='' currency='CDN'/>" +
2921 "<credit xmlns:account='com/interrupt/bookkeeping/account' id='crS' amount='120.00' entryid='qwertySTUB' accountid='06' account='' currency='CDN'/>" +
2930 response
: "<account id='${aid}' name='${aname}' type='${atype}' counterWeight='${acn}' currency='${cc}'/>",
2944 response
: "<account id='${aid}' name='${aname}' type='${atype}' counterWeight='${acw}' currency='${cc}'/>",
2951 response
: "<journal id='${jid}' name='${jname}' type='${jtype}' balance='${jbalance}'>" +
2952 // "<entries id='main.entries'>" +
2953 // "<entry id='qwertySTUB' entrynum='' state='' journalid='generalledger' date='' currency='CDN'>" +
2954 // "<debit xmlns:account='com/interrupt/bookkeeping/account' id='dtS' amount='120.00' entryid='qwertySTUB' accountid='05' account='' currency='CDN'/>" +
2955 // "<credit xmlns:account='com/interrupt/bookkeeping/account' id='crS' amount='120.00' entryid='qwertySTUB' accountid='06' account='' currency='CDN'/>" +
2972 response
: "<journal id='${jid}' name='${jname}' type='${jtype}' balance='${jbalance}'>" +
2973 // "<entries id='main.entries'>" +
2974 // "<entry id='qwertySTUB' entrynum='' state='' journalid='generalledger' date='' currency='CDN'>" +
2975 // "<debit xmlns:account='com/interrupt/bookkeeping/account' id='dtS' amount='120.00' entryid='qwertySTUB' accountid='05' account='' currency='CDN'/>" +
2976 // "<credit xmlns:account='com/interrupt/bookkeeping/account' id='crS' amount='120.00' entryid='qwertySTUB' accountid='06' account='' currency='CDN'/>" +
2986 response
: "<entry id='${eid}' entrynum='' state='' journalid='${jid}' date='' currency='${cc}'>" +
2987 "<debit xmlns:account='com/interrupt/bookkeeping/account' id='${edid}' amount='${edamount}' entryid='${eid}' accountid='${aid}' account='' currency='${cc}'/>" +
2988 "<credit xmlns:account='com/interrupt/bookkeeping/account' id='${ecid}' amount='${ecamount}' entryid='${eid}' accountid='${aid}' account='' currency='${cc}'/>" +
3003 response
: "<entry id='${eid}' entrynum='' state='' journalid='${jid}' date='' currency='${cc}'>" +
3004 "<debit xmlns:account='com/interrupt/bookkeeping/account' id='${edid}' amount='${edamount}' entryid='${eid}' accountid='${aid}' account='' currency='${cc}'/>" +
3005 "<credit xmlns:account='com/interrupt/bookkeeping/account' id='${ecid}' amount='${ecamount}' entryid='${eid}' accountid='${aid}' account='' currency='${cc}'/>" +
3015 response
: "<logs>" +
3018 "<logMessage>Failed to login.</logMessage>" +
3028 response
: "<logs>" +
3031 "<logMessage>Failed to register.</logMessage>" +
3041 response
: "<logs>" +
3044 "<logMessage>Failed to get user profile.</logMessage>" +
3054 response
: "<logs>" +
3057 "<logMessage>Failed to update user profile.</logMessage>" +
3067 response
: "<logs>" +
3070 "<logMessage>Failed to get accounts list.</logMessage>" +
3080 response
: "<logs>" +
3083 "<logMessage>Failed to get journals list.</logMessage>" +
3093 response
: "<logs>" +
3096 "<logMessage>Failed to get entries list.</logMessage>" +
3106 response
: "<logs>" +
3109 "<logMessage>Failed to add account.</logMessage>" +
3119 response
: "<logs>" +
3122 "<logMessage>Failed to remove account.</logMessage>" +
3132 response
: "<logs>" +
3135 "<logMessage>Failed to edit account.</logMessage>" +
3145 response
: "<logs>" +
3148 "<logMessage>Failed to add journal.</logMessage>" +
3158 response
: "<logs>" +
3161 "<logMessage>Failed to remove journal.</logMessage>" +
3171 response
: "<logs>" +
3174 "<logMessage>Failed to edit journal.</logMessage>" +
3184 response
: "<logs>" +
3187 "<logMessage>Failed to add entry.</logMessage>" +
3197 response
: "<logs>" +
3200 "<logMessage>Failed to remove entry.</logMessage>" +
3210 response
: "<logs>" +
3213 "<logMessage>Failed to edit entry.</logMessage>" +
3223 var _TEST_AC
= "<accounts id='main.accounts'>" +
3224 "<account id='05' name='bankaccount' type='asset' counterWeight='debit' currency=''/>" +
3225 "<account id='06' name='creditcard' type='liability' counterWeight='credit' currency=''/>" +
3227 var _TEST_XML
= "<bookkeeping xmlns='com/interrupt/bookkeeping' xmlns:account='com/interrupt/bookkeeping/account' xmlns:journal='com/interrupt/bookkeeping/journal' xmlns:currency='com/interrupt/bookkeeping/currency' id='main.bookkeeping'>" +
3228 "<currency:currencies id='main.currencies' default='CDN'>" +
3229 "<currency:currency id='CDN' name='Canadian Dollar'/>" +
3230 "<currency:currency id='USD' name='US Dollar'/>" +
3231 "<currency:currency id='BP' name='British Pound'/>" +
3232 "<currency:currency id='EUR' name='Euoropean Euro'/>" +
3233 "<currency:currency id='JPN' name='Japanese Yen'/>" +
3234 "</currency:currencies>" +
3235 "<accounts xmlns='com/interrupt/bookkeeping/account' id='main.accounts'>" +
3236 "<account xmlns='com/interrupt/bookkeeping/account' type='asset' id='' name='' counterWeight='debit'/>" +
3238 "<journal:journals id='main.journals'>" +
3239 "<journal:journal id='generalledger' name='generalledger' type='' balance=''>" +
3240 "<journal:entries id='main.entries'>" +
3241 "<journal:entry id='qwertySTUB' entrynum='' state='' journalid='generalledger' date='' currency='CDN'>" +
3242 "<debit xmlns='com/interrupt/bookkeeping/account' id='dtS' amount='120.00' entryid='qwertySTUB' accountid='05' account='' currency='CDN'/>" +
3243 "<credit xmlns='com/interrupt/bookkeeping/account' id='crS' amount='120.00' entryid='qwertySTUB' accountid='06' account='' currency='CDN'/>" +
3244 "</journal:entry>" +
3245 "</journal:entries>" +
3246 "</journal:journal>" +
3247 "</journal:journals>" +