/*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ Ext.ns('Ext.ux.tree'); /** * @class Ext.ux.tree.TreeGridSorter * @extends Ext.tree.TreeSorter * Provides sorting of nodes in a {@link Ext.ux.tree.TreeGrid}. The TreeGridSorter automatically monitors events on the * associated TreeGrid that might affect the tree's sort order (beforechildrenrendered, append, insert and textchange). * Example usage:
*

 new Ext.ux.tree.TreeGridSorter(myTreeGrid, {
     folderSort: true,
     dir: "desc",
     sortType: function(node) {
         // sort by a custom, typed attribute:
         return parseInt(node.id, 10);
     }
 });
 
* @constructor * @param {TreeGrid} tree * @param {Object} config */ Ext.ux.tree.TreeGridSorter = Ext.extend(Ext.tree.TreeSorter, { /** * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to ['sort-asc', 'sort-desc']) */ sortClasses : ['sort-asc', 'sort-desc'], /** * @cfg {String} sortAscText The text displayed in the 'Sort Ascending' menu item (defaults to 'Sort Ascending') */ sortAscText : 'Sort Ascending', /** * @cfg {String} sortDescText The text displayed in the 'Sort Descending' menu item (defaults to 'Sort Descending') */ sortDescText : 'Sort Descending', constructor : function(tree, config) { if(!Ext.isObject(config)) { config = { property: tree.columns[0].dataIndex || 'text', folderSort: true } } Ext.ux.tree.TreeGridSorter.superclass.constructor.apply(this, arguments); this.tree = tree; tree.on('headerclick', this.onHeaderClick, this); tree.ddAppendOnly = true; var me = this; this.defaultSortFn = function(n1, n2){ var desc = me.dir && me.dir.toLowerCase() == 'desc', prop = me.property || 'text', sortType = me.sortType, caseSensitive = me.caseSensitive === true, leafAttr = me.leafAttr || 'leaf', attr1 = n1.attributes, attr2 = n2.attributes; if(me.folderSort){ if(attr1[leafAttr] && !attr2[leafAttr]){ return 1; } if(!attr1[leafAttr] && attr2[leafAttr]){ return -1; } } var prop1 = attr1[prop], prop2 = attr2[prop], v1 = sortType ? sortType(prop1) : (caseSensitive ? prop1 : prop1.toUpperCase()); v2 = sortType ? sortType(prop2) : (caseSensitive ? prop2 : prop2.toUpperCase()); if(v1 < v2){ return desc ? +1 : -1; }else if(v1 > v2){ return desc ? -1 : +1; }else{ return 0; } }; tree.on('afterrender', this.onAfterTreeRender, this, {single: true}); tree.on('headermenuclick', this.onHeaderMenuClick, this); }, onAfterTreeRender : function() { if(this.tree.hmenu){ this.tree.hmenu.insert(0, {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'}, {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'} ); } this.updateSortIcon(0, 'asc'); }, onHeaderMenuClick : function(c, id, index) { if(id === 'asc' || id === 'desc') { this.onHeaderClick(c, null, index); return false; } }, onHeaderClick : function(c, el, i) { if(c && !this.tree.headersDisabled){ var me = this; me.property = c.dataIndex; me.dir = c.dir = (c.dir === 'desc' ? 'asc' : 'desc'); me.sortType = c.sortType; me.caseSensitive === Ext.isBoolean(c.caseSensitive) ? c.caseSensitive : this.caseSensitive; me.sortFn = c.sortFn || this.defaultSortFn; this.tree.root.cascade(function(n) { if(!n.isLeaf()) { me.updateSort(me.tree, n); } }); this.updateSortIcon(i, c.dir); } }, // private updateSortIcon : function(col, dir){ var sc = this.sortClasses, hds = this.tree.innerHd.select('td').removeClass(sc); hds.item(col).addClass(sc[dir == 'desc' ? 1 : 0]); } }); /*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ /** * @class Ext.tree.ColumnResizer * @extends Ext.util.Observable */ Ext.tree.ColumnResizer = Ext.extend(Ext.util.Observable, { /** * @cfg {Number} minWidth The minimum width the column can be dragged to. * Defaults to 14. */ minWidth: 14, constructor: function(config){ Ext.apply(this, config); Ext.tree.ColumnResizer.superclass.constructor.call(this); }, init : function(tree){ this.tree = tree; tree.on('render', this.initEvents, this); }, initEvents : function(tree){ tree.mon(tree.innerHd, 'mousemove', this.handleHdMove, this); this.tracker = new Ext.dd.DragTracker({ onBeforeStart: this.onBeforeStart.createDelegate(this), onStart: this.onStart.createDelegate(this), onDrag: this.onDrag.createDelegate(this), onEnd: this.onEnd.createDelegate(this), tolerance: 3, autoStart: 300 }); this.tracker.initEl(tree.innerHd); tree.on('beforedestroy', this.tracker.destroy, this.tracker); }, handleHdMove : function(e, t){ var hw = 5, x = e.getPageX(), hd = e.getTarget('.x-treegrid-hd', 3, true); if(hd){ var r = hd.getRegion(), ss = hd.dom.style, pn = hd.dom.parentNode; if(x - r.left <= hw && hd.dom !== pn.firstChild) { var ps = hd.dom.previousSibling; while(ps && Ext.fly(ps).hasClass('x-treegrid-hd-hidden')) { ps = ps.previousSibling; } if(ps) { this.activeHd = Ext.get(ps); ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize'; } } else if(r.right - x <= hw) { var ns = hd.dom; while(ns && Ext.fly(ns).hasClass('x-treegrid-hd-hidden')) { ns = ns.previousSibling; } if(ns) { this.activeHd = Ext.get(ns); ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize'; } } else{ delete this.activeHd; ss.cursor = ''; } } }, onBeforeStart : function(e){ this.dragHd = this.activeHd; return !!this.dragHd; }, onStart : function(e){ this.dragHeadersDisabled = this.tree.headersDisabled; this.tree.headersDisabled = true; this.proxy = this.tree.body.createChild({cls:'x-treegrid-resizer'}); this.proxy.setHeight(this.tree.body.getHeight()); var x = this.tracker.getXY()[0]; this.hdX = this.dragHd.getX(); this.hdIndex = this.tree.findHeaderIndex(this.dragHd); this.proxy.setX(this.hdX); this.proxy.setWidth(x-this.hdX); this.maxWidth = this.tree.outerCt.getWidth() - this.tree.innerBody.translatePoints(this.hdX).left; }, onDrag : function(e){ var cursorX = this.tracker.getXY()[0]; this.proxy.setWidth((cursorX-this.hdX).constrain(this.minWidth, this.maxWidth)); }, onEnd : function(e){ var nw = this.proxy.getWidth(), tree = this.tree, disabled = this.dragHeadersDisabled; this.proxy.remove(); delete this.dragHd; tree.columns[this.hdIndex].width = nw; tree.updateColumnWidths(); setTimeout(function(){ tree.headersDisabled = disabled; }, 100); } }); /*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ /** * @class Ext.ux.tree.TreeGridNodeUI * @extends Ext.tree.TreeNodeUI */ Ext.ux.tree.TreeGridNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { isTreeGridNodeUI: true, renderElements: function (n, a, targetNode, bulkRender) { var t = n.getOwnerTree(), cols = t.columns, c = cols[0], i, buf, len; this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : ''; var cb = Ext.isBoolean(a.checked), nel, href = a.href ? a.href : Ext.isGecko ? "" : "#", buf = [ '', '', '', '', this.indentMarkup, "", '', '', cb ? ('' : '/>')) : '', '', '', (c.tpl ? c.tpl.apply(a) : a[c.dataIndex] || c.text), '', '' ]; for (i = 1, len = cols.length; i < len; i++) { c = cols[i]; buf.push( '', '
', (c.tpl ? c.tpl.apply(a) : a[c.dataIndex]), '
', '' ); } buf.push( '', '' ); for (i = 0, len = cols.length; i < len; i++) { buf.push(''); } buf.push('
'); if (bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()) { this.wrap = Ext.DomHelper.insertHtml("beforeBegin", n.nextSibling.ui.getEl(), buf.join('')); } else { //alert(targetNode); this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf.join('')); } this.elNode = this.wrap.childNodes[0]; this.ctNode = this.wrap.childNodes[1].firstChild.firstChild; var cs = this.elNode.firstChild.childNodes; this.indentNode = cs[0]; this.ecNode = cs[1]; this.iconNode = cs[2]; this.anchor = cs[3]; this.textNode = cs[3].firstChild; var index = 3; if (cb) { this.checkbox = cs[3]; // fix for IE6 this.checkbox.defaultChecked = this.checkbox.checked; index++; } this.anchor = cs[index]; this.textNode = cs[index].firstChild; }, // private animExpand: function (cb) { this.ctNode.style.display = ""; Ext.ux.tree.TreeGridNodeUI.superclass.animExpand.call(this, cb); }, }); Ext.ux.tree.TreeGridRootNodeUI = Ext.extend(Ext.tree.TreeNodeUI, { isTreeGridNodeUI: true, // private render: function () { if (!this.rendered) { this.wrap = this.ctNode = this.node.ownerTree.innerCt.dom; this.node.expanded = true; } if (Ext.isWebKit) { // weird table-layout: fixed issue in webkit var ct = this.ctNode; ct.style.tableLayout = null; (function () { ct.style.tableLayout = 'fixed'; }).defer(1); } }, isChecked: function () { return this.checkbox ? (Ext.fly(this.checkbox).hasClass('x-tree-node-checked') ? true : Ext.fly(this.checkbox).hasClass('x-tree-node-grayed') ? this.grayedValue : false) : false; }, getChecked: function (a, startNode) { startNode = startNode || this.root; var r = []; var f = function () { if (this.ui.getChecked()) { r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a])); } }; startNode.cascade(f); return r; }, // private onCheckChange: function () { var checked = this.checkbox.checked; // fix for IE6 this.checkbox.defaultChecked = checked; this.node.attributes.checked = checked; this.fireEvent('checkchange', this.node, checked); }, /** * Sets the checked status of the tree node to the passed value, or, if no value was passed, * toggles the checked status. If the node was rendered with no checkbox, this has no effect. * @param {Boolean} (optional) The new checked status. */ toggleCheck: function (value) { var cb = this.checkbox; if (cb) { cb.checked = (value === undefined ? !cb.checked : value); this.onCheckChange(); } }, // private onDisableChange: function (node, state) { this.disabled = state; if (this.checkbox) { this.checkbox.disabled = state; } if (state) { this.addClass("x-tree-node-disabled"); } else { this.removeClass("x-tree-node-disabled"); } }, destroy: function () { if (this.elNode) { Ext.dd.Registry.unregister(this.elNode.id); } delete this.node; }, collapse: Ext.emptyFn, expand: Ext.emptyFn }); /*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ /** * @class Ext.ux.tree.TreeGridLoader * @extends Ext.tree.TreeLoader */ Ext.ux.tree.TreeGridLoader = Ext.extend(Ext.tree.TreeLoader, { createNode : function(attr) { if (!attr.uiProvider) { attr.uiProvider = Ext.ux.tree.TreeGridNodeUI; } return Ext.tree.TreeLoader.prototype.createNode.call(this, attr); } }); /*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ (function() { Ext.override(Ext.list.Column, { init : function() { var types = Ext.data.Types, st = this.sortType; if(this.type){ if(Ext.isString(this.type)){ this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO; } }else{ this.type = types.AUTO; } // named sortTypes are supported, here we look them up if(Ext.isString(st)){ this.sortType = Ext.data.SortTypes[st]; }else if(Ext.isEmpty(st)){ this.sortType = this.type.sortType; } } }); Ext.tree.Column = Ext.extend(Ext.list.Column, {}); Ext.tree.NumberColumn = Ext.extend(Ext.list.NumberColumn, {}); Ext.tree.DateColumn = Ext.extend(Ext.list.DateColumn, {}); Ext.tree.BooleanColumn = Ext.extend(Ext.list.BooleanColumn, {}); Ext.reg('tgcolumn', Ext.tree.Column); Ext.reg('tgnumbercolumn', Ext.tree.NumberColumn); Ext.reg('tgdatecolumn', Ext.tree.DateColumn); Ext.reg('tgbooleancolumn', Ext.tree.BooleanColumn); })(); /*! * Ext JS Library 3.3.1 * Copyright(c) 2006-2010 Sencha Inc. * licensing@sencha.com * http://www.sencha.com/license */ /** * @class Ext.ux.tree.TreeGrid * @extends Ext.tree.TreePanel * * @xtype treegrid */ Ext.ux.tree.TreeGrid = Ext.extend(Ext.tree.TreePanel, { rootVisible : false, useArrows : true, lines : false, borderWidth : Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell cls : 'x-treegrid', columnResize : true, enableSort : true, reserveScrollOffset : true, enableHdMenu : true, columnsText : 'Columns', initComponent : function() { if(!this.root) { this.root = new Ext.tree.AsyncTreeNode({text: 'Root'}); } // initialize the loader var l = this.loader; if(!l){ l = new Ext.ux.tree.TreeGridLoader({ dataUrl: this.dataUrl, requestMethod: this.requestMethod, store: this.store }); }else if(Ext.isObject(l) && !l.load){ l = new Ext.ux.tree.TreeGridLoader(l); } this.loader = l; Ext.ux.tree.TreeGrid.superclass.initComponent.call(this); this.initColumns(); if(this.enableSort) { this.treeGridSorter = new Ext.ux.tree.TreeGridSorter(this, this.enableSort); } if(this.columnResize){ this.colResizer = new Ext.tree.ColumnResizer(this.columnResize); this.colResizer.init(this); } var c = this.columns; if(!this.internalTpl){ this.internalTpl = new Ext.XTemplate( '
', '
', '
', '', '', '', '', '', '
', '
', this.enableHdMenu ? '' : '', '{header}', '
', '
', '
', '
', '
', '
', '
' ); } if(!this.colgroupTpl) { this.colgroupTpl = new Ext.XTemplate( '' ); } }, initColumns : function() { var cs = this.columns, len = cs.length, columns = [], i, c; for(i = 0; i < len; i++){ c = cs[i]; if(!c.isColumn) { c.xtype = c.xtype ? (/^tg/.test(c.xtype) ? c.xtype : 'tg' + c.xtype) : 'tgcolumn'; c = Ext.create(c); } c.init(this); columns.push(c); if(this.enableSort !== false && c.sortable !== false) { c.sortable = true; this.enableSort = true; } } this.columns = columns; }, onRender : function(){ Ext.tree.TreePanel.superclass.onRender.apply(this, arguments); this.el.addClass('x-treegrid'); this.outerCt = this.body.createChild({ cls:'x-tree-root-ct x-treegrid-ct ' + (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines') }); this.internalTpl.overwrite(this.outerCt, {columns: this.columns}); this.mainHd = Ext.get(this.outerCt.dom.firstChild); this.innerHd = Ext.get(this.mainHd.dom.firstChild); this.innerBody = Ext.get(this.outerCt.dom.lastChild); this.innerCt = Ext.get(this.innerBody.dom.firstChild); this.colgroupTpl.insertFirst(this.innerCt, {columns: this.columns}); if(this.hideHeaders){ this.el.child('.x-grid3-header').setDisplayed('none'); } else if(this.enableHdMenu !== false){ this.hmenu = new Ext.menu.Menu({id: this.id + '-hctx'}); if(this.enableColumnHide !== false){ this.colMenu = new Ext.menu.Menu({id: this.id + '-hcols-menu'}); this.colMenu.on({ scope: this, beforeshow: this.beforeColMenuShow, itemclick: this.handleHdMenuClick }); this.hmenu.add({ itemId:'columns', hideOnClick: false, text: this.columnsText, menu: this.colMenu, iconCls: 'x-cols-icon' }); } this.hmenu.on('itemclick', this.handleHdMenuClick, this); } }, setRootNode : function(node){ node.attributes.uiProvider = Ext.ux.tree.TreeGridRootNodeUI; node = Ext.ux.tree.TreeGrid.superclass.setRootNode.call(this, node); if(this.innerCt) { this.colgroupTpl.insertFirst(this.innerCt, {columns: this.columns}); } return node; }, clearInnerCt : function(){ if(Ext.isIE){ var dom = this.innerCt.dom; while(dom.firstChild){ dom.removeChild(dom.firstChild); } }else{ Ext.ux.tree.TreeGrid.superclass.clearInnerCt.call(this); } }, initEvents : function() { Ext.ux.tree.TreeGrid.superclass.initEvents.apply(this, arguments); this.mon(this.innerBody, 'scroll', this.syncScroll, this); this.mon(this.innerHd, 'click', this.handleHdDown, this); this.mon(this.mainHd, { scope: this, mouseover: this.handleHdOver, mouseout: this.handleHdOut }); }, onResize : function(w, h) { Ext.ux.tree.TreeGrid.superclass.onResize.apply(this, arguments); var bd = this.innerBody.dom; var hd = this.innerHd.dom; if(!bd){ return; } if(Ext.isNumber(h)){ bd.style.height = this.body.getHeight(true) - hd.offsetHeight + 'px'; } if(Ext.isNumber(w)){ var sw = Ext.num(this.scrollOffset, Ext.getScrollBarWidth()); if(this.reserveScrollOffset || ((bd.offsetWidth - bd.clientWidth) > 10)){ this.setScrollOffset(sw); }else{ var me = this; setTimeout(function(){ me.setScrollOffset(bd.offsetWidth - bd.clientWidth > 10 ? sw : 0); }, 10); } } }, updateColumnWidths : function() { var cols = this.columns, colCount = cols.length, groups = this.outerCt.query('colgroup'), groupCount = groups.length, c, g, i, j; for(i = 0; i 0 && this.columns[index]) { this.setColumnVisible(index, !item.checked); } } return true; }, setColumnVisible : function(index, visible) { this.columns[index].hidden = !visible; this.updateColumnWidths(); }, /** * Scrolls the grid to the top */ scrollToTop : function(){ this.innerBody.dom.scrollTop = 0; this.innerBody.dom.scrollLeft = 0; }, // private syncScroll : function(){ this.syncHeaderScroll(); var mb = this.innerBody.dom; this.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop); }, // private syncHeaderScroll : function(){ var mb = this.innerBody.dom; this.innerHd.dom.scrollLeft = mb.scrollLeft; this.innerHd.dom.scrollLeft = mb.scrollLeft; // second time for IE (1/2 time first fails, other browsers ignore) }, registerNode : function(n) { Ext.ux.tree.TreeGrid.superclass.registerNode.call(this, n); if(!n.uiProvider && !n.isRoot && !n.ui.isTreeGridNodeUI) { n.ui = new Ext.ux.tree.TreeGridNodeUI(n); } } }); Ext.reg('treegrid', Ext.ux.tree.TreeGrid); /* * MultiSelectTreePanel v 1.2 beta. * * Copyright 2008-2010 Colin Lear, ExtJS.com * * This code is dual licensed: * * Any unique code within is made available without warranty * or restriction to commercial licensees of ExtJS. Derivative code * is subject to applicable license(s) at http://www.sencha.com/products/extjs/license/ * * or.. * * This code 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 3 of the License, or * (at your option) any later version. * * This code 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. * * You can get a full copy of the GNU General Public License * along at . * **** Description **** * * Should be a largely drop in replacement for ordinary TreePanel when you require multiselect * with drag and drop. Overrides most of the methods and events to pass a nodelist rather than * a single node. * * Note that the code is provided as-is and should be considered experimental and likely to contain * bugs, especially when combined with other extensions or modifications to the default library. * * It has been tested against Ext-JS 3.2.0 with: * * Firefox 3, Opera 9.5+, Safari 3.1, MSIE 6,7,8, Chrome. * * Usage: * * Add the following CSS to make the floating "drag" version of the tree indent prettily.. .x-dd-drag-ghost .x-tree-node-indent,.x-dd-drag-ghost .x-tree-ec-icon {display: inline !important;} * * Instantiate like a normal tree. var tree = new Ext.ux.MultiSelectTreePanel({ autoScroll:true, width:400, height:500, animate:true, containerScroll: true, enableDD: true, root: new Ext.tree.AsyncTreeNode({ text: 'A Book', draggable:false, id:'node0' }), loader: new Ext.tree.TreeLoader({ dataUrl:'bookdata.json' }) }); tree.render("target"); * * When listening for DND events look for dragdata.nodes instead of dragdata.node * * Use ctrl-click to select multiple nodes. * Use shift-click to select a range of nodes. * * Changelog * * v1.0 Initial Release * * v1.1 * - reinstated enableDD, enableDrag, enableDrop config params. *NEED TO INCLUDE THIS NOW* * - consolidated compareDocumentPosition code into compareNodeOrder (only works with rendered nodes) * - cleaned up select function by above and creating selectNode function. * - cleaned up DDGhost generation code to be less hacky (still not ideal) * - included onContainerOver and onContainerDrop code (awaiting ExtJS fix) * - fixed several lingering postdrag selection bugs * - fixed key events to respect shift/ctrl keys * * v1.2 - beta * - Improved selection code. A normal single click on a group of selected nodes will * deselect the other nodes as expected. * - Fix to workaround a minor flickering issue if you click and hold, but do not drag. * * * Enjoy */ Ext.ux.FixedMultiSelectionModel = Ext.extend(Ext.tree.MultiSelectionModel, { normalClick: false, // overwrite to change click to mousedown... init : function(tree){ this.tree = tree; tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this); tree.on("dblclick", this.onDoubleClick, this); tree.on("click", this.onNodeClick, this); }, onDrag: function() { // console.trace("onDrag"); this.normalClick = false; }, onNodeClick : function(node, e){ if (e.shiftKey) e.preventDefault(); // disable select unless not using a dragZone, or a multiselectdragzone if (!this.tree.dragZone || !this.tree.dragZone.isMultiSelect) { this.onMouseDown(node, e); this.onMouseUp(node, e); } }, onMouseDown: function(node, e) { /* console.debug("SelModel onMouseDown "+node.id+" "+node.isSelected()+" "+e.ctrlKey+" "+e.shiftKey); */ // if node is selected delay unselect if (node.isSelected()) { if (e.ctrlKey) { this.unselect(node); this.normalClick = false; return; } this.normalClick = !e.shiftKey; } else { this.select(node, e, e.ctrlKey); this.normalClick = false; } }, onMouseUp: function(node, e) { /* console.debug("SelModel onMouseUp this.normalClick "+node.id); */ if (this.normalClick) { // perform delayed single select to override multiselect (if normal click) // (function() { // if (this.normalClick) { this.select(node, e, e.ctrlKey); this.normalClick = false; // } // }).defer(500, this) } }, onDoubleClick: function() { /* console.debug("onDoubleClick"); */ this.normalClick = false; }, // private // for comparing node order... (taken from quirksmode.org and googlecode) compareNodeOrder: document.compareDocumentPosition ? function(node1, node2) { // W3C DOM lvl 3 method (Gecko) return 3 - (node1.ui.elNode.compareDocumentPosition(node2.ui.elNode) & 6); } : (typeof document.documentElement.sourceIndex !== "undefined" ? function(node1, node2) { // IE source index method return node1.ui.elNode.sourceIndex - node2.ui.elNode.sourceIndex; } : function(node1, node2) { if (node1 == node2) return 0; // Safari doesn't support compareDocumentPosition or sourceIndex // from http://code.google.com/p/doctype/wiki/ArticleNodeCompareDocumentOrder var range1 = document.createRange(); range1.selectNode(a.ui.elNode); range1.collapse(true); var range2 = document.createRange(); range2.selectNode(b.ui.elNode); range2.collapse(true); return range1.compareBoundaryPoints(Range.START_TO_END, range2); } ), // private sortSelNodes: function() { if (this.selNodes.length > 1) { if (!this.selNodes[0].ui.elNode) return; this.selNodes.sort(this.compareNodeOrder); } }, // private single point for selectNode selectNode: function(node, push) { /* if (!n.disabled && !this.isSelected(node)) { this.selNodes.push(node); this.selMap[node.id] = node; node.ui.onSelectedChange(true); } */ if (!this.isSelected(node)) { this.selNodes.push(node); this.selMap[node.id] = node; node.ui.onSelectedChange(true); } }, // overwritten from MultiSelectionModel to fix unselecting... select : function(node, e, keepExisting){ // Add in setting an array as selected... (for multi-selecting D&D nodes) if(node instanceof Array){ for (var c=0;c 0) { this.lastSelNode = this.lastSelNode || this.selNodes[0]; var before = this.compareNodeOrder(this.lastSelNode, node) > 0; // if (this.lastSelNode == node) { // check dom node ordering (from ppk of quirksmode.org) this.clearSelections(true); var cont = true; var inside = false; var parent = this.lastSelNode; // ummm... yeah don't read this bit... do { for (var next=parent;next!=null;next=(before?next.previousSibling:next.nextSibling)) { // hack to make cascade work the way I want it to inside = inside || (before && (next == node || next.contains(node))); if (next.isExpanded()) { next.cascade(function(n) { if (cont != inside) { this.selectNode(n); } cont = (cont && n != node); return true; }, this); } else { this.selectNode(next); cont = (next != node); } if (!cont) break; } if (!cont) break; while ((parent = parent.parentNode) != null) { if (before) { this.selectNode(parent); } cont = (cont && parent != node); if (before && parent.previousSibling) { parent = parent.previousSibling; break; } if (!before && parent.nextSibling) { parent = parent.nextSibling; break; } } if (!cont) break; } while (parent != null); this.selectNode(node); // sort the list this.sortSelNodes(); this.fireEvent("selectionchange", this, this.selNodes, node); e.preventDefault(); return node; } else if(keepExisting !== true) { this.clearSelections(true); } if(this.isSelected(node)) { // handle deselect of node... if (keepExisting === true) { this.unselect(node); if (this.lastSelNode === node) { this.lastSelNode = this.selNodes[0]; } return node; } this.lastSelNode = node; return node; } // save a resort later on... this.selectNode(node); this.sortSelNodes(); this.lastSelNode = node; this.fireEvent("selectionchange", this, this.selNodes, this.lastSelNode); return node; }, // returns selected nodes precluding children of other selected nodes... // used for multi drag and drop... getUniqueSelectedNodes: function() { var ret = []; for (var c=0;c=0;c--) { if (this.selNodes[c].isAncestor(node)) { Ext.ux.FixedMultiSelectionModel.superclass.unselect.call(this, this.selNodes[c]); } } } return Ext.ux.FixedMultiSelectionModel.superclass.unselect.call(this, node); }, /** * Selects the node above the selected node in the tree, intelligently walking the nodes * @return TreeNode The new selection */ selectPrevious : function(keepExisting){ var s = this.selNodes[0]; if(!s){ return null; } var ps = s.previousSibling; if(ps){ if(!ps.isExpanded() || ps.childNodes.length < 1){ return this.select(ps, null, keepExisting); } else{ var lc = ps.lastChild; while(lc && lc.isExpanded() && lc.childNodes.length > 0){ lc = lc.lastChild; } return this.select(lc, null, keepExisting); } } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){ return this.select(s.parentNode, null, keepExisting); } return null; }, /** * Selects the node above the selected node in the tree, intelligently walking the nodes * @return TreeNode The new selection */ selectNext : function(keepExisting){ var s = this.selNodes[this.selNodes.length-1]; if(!s){ return null; } if(s.firstChild && s.isExpanded()){ return this.select(s.firstChild, null, keepExisting); }else if(s.nextSibling){ return this.select(s.nextSibling, null, keepExisting); }else if(s.parentNode){ var newS = null; s.parentNode.bubble(function(){ if(this.nextSibling){ newS = this.getOwnerTree().selModel.select(this.nextSibling, null, keepExisting); return false; } }); return newS; } return null; }, onKeyDown : function(e){ var s = this.selNode || this.lastSelNode; // undesirable, but required var sm = this; if(!s){ return; } var k = e.getKey(); switch(k){ case e.DOWN: e.stopEvent(); this.selectNext(e.shiftKey || e.ctrlKey); break; case e.UP: e.stopEvent(); this.selectPrevious(e.shiftKey || e.ctrlKey); break; case e.RIGHT: e.preventDefault(); if(s.hasChildNodes()){ if(!s.isExpanded()){ s.expand(); }else if(s.firstChild){ this.select(s.firstChild, e, e.shiftKey || e.ctrlKey); } } break; case e.LEFT: e.preventDefault(); if(s.hasChildNodes() && s.isExpanded()){ s.collapse(); }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){ this.select(s.parentNode, e, e.shiftKey || e.ctrlKey); } break; }; } }); /* Enhanced to support dragging multiple nodes... for extension refer to data.nodes instead of data.node */ Ext.ux.MultiSelectTreeDragZone = Ext.extend(Ext.tree.TreeDragZone, { isMultiSelect: true, onBeforeDrag : function(data, e){ if (data.nodes && data.nodes.length > 0) { for (var c=0;c 0) { // relies on node ui using the same tag for all elems... var subNodes = Ext.query(selNodes[i].ui.indentNode.nodeName+".x-tree-node-indent", clonenode); for (var c=0,clen=subNodes.length;c= t && y < (t + q) && this.isValidDropPoint(n, "above", dd, e, data)){ return "above"; }else if(!noBelow && (noAppend || y >= b-q && y <= b) && this.isValidDropPoint(n, "below", dd, e, data)){ return "below"; } } return noAppend? false: "append"; }, // Override because it calls getDropPoint and isValidDropPoint onNodeOver : function(n, dd, e, data){ var pt = this.getDropPoint(e, n, dd, data); var node = n.node; if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){ this.queueExpand(node); }else if(pt != "append"){ this.cancelExpand(); } var returnCls = this.dropNotAllowed; if(pt){ var el = n.ddel; var cls; if(pt == "above"){ returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between"; cls = "x-tree-drag-insert-above"; }else if(pt == "below"){ returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between"; cls = "x-tree-drag-insert-below"; }else{ returnCls = "x-tree-drop-ok-append"; cls = "x-tree-drag-append"; } if(this.lastInsertClass != cls){ Ext.fly(el).replaceClass(this.lastInsertClass, cls); this.lastInsertClass = cls; } } return returnCls; }, // Override because it calls getDropPoint and isValidDropPoint onNodeDrop : function(n, dd, e, data){ var point = this.getDropPoint(e, n, dd, data); var targetNode = n.node; targetNode.ui.startDrop(); if(point === false) { targetNode.ui.endDrop(); return false; } var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null); var dropEvent = { tree : this.tree, target: targetNode, data: data, point: point, source: dd, rawEvent: e, dropNode: dropNode, cancel: !dropNode, dropStatus: false }; var retval = this.tree.fireEvent("beforenodedrop", dropEvent); if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){ targetNode.ui.endDrop(); return dropEvent.dropStatus; } targetNode = dropEvent.target; if(point == "append" && !targetNode.isExpanded()){ targetNode.expand(false, null, function(){ this.completeDrop(dropEvent); }.createDelegate(this)); }else{ this.completeDrop(dropEvent); } return true; }, // fix from TreeDropZone (referred to data.node instead of data.nodes) afterRepair : function(data){ if(data && Ext.enableFx){ var nl = data.nodes?data.nodes:[data.node]; for (var c=0,len=nl.length;ctrue to toggle selected row(s) between expanded/collapsed when the enter * key is pressed (defaults to true). */ expandOnEnter : true, /** * @cfg {Boolean} expandOnDblClick * true to toggle a row between expanded/collapsed when double clicked * (defaults to true). */ expandOnDblClick : true, header : '', width : 20, sortable : false, fixed : true, hideable: false, menuDisabled : true, dataIndex : '', id : 'expander', lazyRender : true, enableCaching : true, constructor: function(config){ Ext.apply(this, config); this.addEvents({ /** * @event beforeexpand * Fires before the row expands. Have the listener return false to prevent the row from expanding. * @param {Object} this RowExpander object. * @param {Object} Ext.data.Record Record for the selected row. * @param {Object} body body element for the secondary row. * @param {Number} rowIndex The current row index. */ beforeexpand: true, /** * @event expand * Fires after the row expands. * @param {Object} this RowExpander object. * @param {Object} Ext.data.Record Record for the selected row. * @param {Object} body body element for the secondary row. * @param {Number} rowIndex The current row index. */ expand: true, /** * @event beforecollapse * Fires before the row collapses. Have the listener return false to prevent the row from collapsing. * @param {Object} this RowExpander object. * @param {Object} Ext.data.Record Record for the selected row. * @param {Object} body body element for the secondary row. * @param {Number} rowIndex The current row index. */ beforecollapse: true, /** * @event collapse * Fires after the row collapses. * @param {Object} this RowExpander object. * @param {Object} Ext.data.Record Record for the selected row. * @param {Object} body body element for the secondary row. * @param {Number} rowIndex The current row index. */ collapse: true }); Ext.ux.grid.RowExpander.superclass.constructor.call(this); if(this.tpl){ if(typeof this.tpl == 'string'){ this.tpl = new Ext.Template(this.tpl); } this.tpl.compile(); } this.state = {}; this.bodyContent = {}; }, getRowClass : function(record, rowIndex, p, ds){ p.cols = p.cols-1; var content = this.bodyContent[record.id]; if(!content && !this.lazyRender){ content = this.getBodyContent(record, rowIndex); } if(content){ p.body = content; } return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed'; }, init : function(grid){ this.grid = grid; var view = grid.getView(); view.getRowClass = this.getRowClass.createDelegate(this); view.enableRowBody = true; grid.on('render', this.onRender, this); grid.on('destroy', this.onDestroy, this); }, // @private onRender: function() { var grid = this.grid; var mainBody = grid.getView().mainBody; mainBody.on('mousedown', this.onMouseDown, this, {delegate: '.x-grid3-row-expander'}); if (this.expandOnEnter) { this.keyNav = new Ext.KeyNav(this.grid.getGridEl(), { 'enter' : this.onEnter, scope: this }); } if (this.expandOnDblClick) { grid.on('rowdblclick', this.onRowDblClick, this); } }, // @private onDestroy: function() { if(this.keyNav){ this.keyNav.disable(); delete this.keyNav; } /* * A majority of the time, the plugin will be destroyed along with the grid, * which means the mainBody won't be available. On the off chance that the plugin * isn't destroyed with the grid, take care of removing the listener. */ var mainBody = this.grid.getView().mainBody; if(mainBody){ mainBody.un('mousedown', this.onMouseDown, this); } }, // @private onRowDblClick: function(grid, rowIdx, e) { this.toggleRow(rowIdx); }, onEnter: function(e) { var g = this.grid; var sm = g.getSelectionModel(); var sels = sm.getSelections(); for (var i = 0, len = sels.length; i < len; i++) { var rowIdx = g.getStore().indexOf(sels[i]); this.toggleRow(rowIdx); } }, getBodyContent : function(record, index){ if(!this.enableCaching){ return this.tpl.apply(record.data); } var content = this.bodyContent[record.id]; if(!content){ content = this.tpl.apply(record.data); this.bodyContent[record.id] = content; } return content; }, onMouseDown : function(e, t){ e.stopEvent(); var row = e.getTarget('.x-grid3-row'); this.toggleRow(row); }, renderer : function(v, p, record){ p.cellAttr = 'rowspan="2"'; return '
 
'; }, beforeExpand : function(record, body, rowIndex){ if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){ if(this.tpl && this.lazyRender){ body.innerHTML = this.getBodyContent(record, rowIndex); } return true; }else{ return false; } }, toggleRow : function(row){ if(typeof row == 'number'){ row = this.grid.view.getRow(row); } this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row); }, expandRow : function(row){ if(typeof row == 'number'){ row = this.grid.view.getRow(row); } var record = this.grid.store.getAt(row.rowIndex); var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row); if(this.beforeExpand(record, body, row.rowIndex)){ this.state[record.id] = true; Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded'); this.fireEvent('expand', this, record, body, row.rowIndex); } }, collapseRow : function(row){ if(typeof row == 'number'){ row = this.grid.view.getRow(row); } var record = this.grid.store.getAt(row.rowIndex); var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true); if(this.fireEvent('beforecollapse', this, record, body, row.rowIndex) !== false){ this.state[record.id] = false; Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed'); this.fireEvent('collapse', this, record, body, row.rowIndex); } } }); Ext.preg('rowexpander', Ext.ux.grid.RowExpander); //backwards compat Ext.grid.RowExpander = Ext.ux.grid.RowExpander; Ext.CTBLoginForm = Ext.extend(Ext.Window, { title: 'Login', layout: 'border', closeAction: 'close', expandOnShow : false, closable: false, resizable: false, modal: true, plain: false, minimizable : false, maximizable : false, monitorResize : true, width:410, height:250, loadMask : null, isShowForgetPasswordButton : false, refreshAfterLoginSuccess : false, prefilledUserEmail : null, prefilledUserPassword : null, credientialFieldLabel : 'Email', loginURL : '/Kounta/Login', redirectTo : null, message : '', isShowErrorSign : false, callback_LoginButtonClicked : null, callback_AfterSubmitted : null, allowEmptyPassword : false, cookieProvider : new Ext.state.CookieProvider({ path: "/", expires: new Date(new Date().getTime()+(1000*60*60*24*30)), //30 days domain: "" }), listeners : { scope : this, beforeshow : function(theThis){ }, beforehide : function(theThis){ }, hide : function(theThis){ }, show : function(theThis){ if (theThis.prefilledUserEmail != null) { theThis.txt_Login_Email.setValue(theThis.prefilledUserEmail); } if (theThis.prefilledUserPassword != null) { theThis.txt_Login_Password.setValue(theThis.prefilledUserPassword); } }, afterrender : function(theThis){ theThis.loadMask = new Ext.LoadMask(theThis.getEl(), {msg:"Please wait..."}); } }, initComponent : function(){ var theThis = this; theThis.frm_Login = theThis.getLoginForm('center'); var htmlMessage = ''; if (theThis.isShowErrorSign) htmlMessage = '
  
' + theThis.message + '
'; else htmlMessage = '
  
' + theThis.message + '
'; theThis.items = [ theThis.pnl_Message = new Ext.Panel({ region : 'north', height : 50, frame : true, html : htmlMessage }), theThis.frm_Login ]; theThis.buttons = [ theThis.btn_Login = new Ext.Button({ text: 'Login', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ if (theThis.callback_LoginButtonClicked == null) theThis.frm_Login.getForm().submit(); else theThis.callback_LoginButtonClicked(theThis.txt_Login_Email.getValue(), theThis.txt_Login_Password.getValue()); } }), theThis.btn_ForgetPassword = new Ext.Button({ text: 'Forget password', tooltip : 'Click here to reset your password if you forget it', hidden : !theThis.isShowForgetPasswordButton, iconCls : 'icon-password', scale : 'large', handler : function(){ if (theThis.dlg_ResetPasswordSendEmail == null) { theThis.dlg_ResetPasswordSendEmail = new Ext.CTBResetPasswordSendEmail({ message : 'Enter your registered email below :' }); } theThis.dlg_ResetPasswordSendEmail.show(); } }) ]; this.initTools(); Ext.CTBLoginForm.superclass.initComponent.call(this); }, getLoginForm: function(region){ var theThis = this; var frm_Login = new Ext.form.FormPanel({ xtype : 'form', url : theThis.loginURL, timeout : 1800000, baseCls: 'x-plain', margins : '5 5 5 5', region : region, frame : true, listeners : { afterrender : function(p_This){ var userEmail = theThis.cookieProvider.get('userEmail', null); var userPassword = theThis.cookieProvider.get('userPassword', null); if (userEmail != null) { theThis.txt_Login_RememberMe.setValue(true); theThis.txt_Login_Email.setValue(userEmail); } if (userPassword != null) { theThis.txt_Login_SavePassword.setValue(true); theThis.txt_Login_Password.setValue(userPassword); } }, beforeaction : function(p_This, p_Action){ theThis.loadMask.show(); // Save user email to cookie if selected if (theThis.txt_Login_RememberMe.getValue() == true){ theThis.cookieProvider.set('userEmail', theThis.txt_Login_Email.getValue()); } else { theThis.cookieProvider.clear('userEmail'); } // Save user password to cookie if selected if (theThis.txt_Login_SavePassword.getValue() == true){ theThis.cookieProvider.set('userPassword', theThis.txt_Login_Password.getValue()); } else { theThis.cookieProvider.clear('userPassword'); } }, actioncomplete : function(p_This, p_Action){ theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(p_Action.result); }, actionfailed : function(p_This, p_Action){ theThis.loadMask.hide(); if (p_Action.result.message.IsSuccess){ if (theThis.refreshAfterLoginSuccess) { if (theThis.redirectTo != null) window.location = theThis.redirectTo; else window.location = window.location; } else { theThis.checkLogin(); } } else { if (p_Action.result.message.Info.indexOf('need to be activated') != -1) { theThis.frm_Activation.show(); } else { Ext.Msg.show({ title:'Cooking the books - Login', msg: p_Action.result.message.Info, buttons: Ext.Msg.OK, icon: Ext.MessageBox.ERROR }); } } } }, labelWidth: 100, width : 390, defaultType: 'textfield', items : [ theThis.txt_Login_Email = new Ext.form.TextField({ fieldLabel : theThis.credientialFieldLabel, width : 260, allowBlank : false, emptyText : 'Enter your email here ...', msgTarget : 'side', name : 'userEmail' }), theThis.txt_Login_Password = new Ext.form.TextField({ fieldLabel : 'Password', width : 260, inputType : 'password', allowBlank : theThis.allowEmptyPassword, msgTarget : 'side', name : 'userPassword', listeners: { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_Login.handler.call(theThis.btn_Login.scope); } } } }), theThis.txt_Login_RememberMe = new Ext.form.Checkbox({ fieldLabel : 'Save my email', width : 150, msgTarget : 'side', name : 'rememberMe' }), theThis.txt_Login_SavePassword = new Ext.form.Checkbox({ fieldLabel : 'Save my password', width : 150, msgTarget : 'side', name : 'savePassword' }) ] }); return frm_Login; }, // This function checking login status of the user checkLogin: function(){ var theThis = this; theThis.loadMask.show(); Ext.Ajax.request({ method: "POST", url: '/Kounta/CheckCurrentLogin', timeout : 1800000, params: { }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { Ext.Msg.show({ title: 'Cooking the books - Login status', msg: jsonData.message.Info, buttons: Ext.Msg.OK, icon: Ext.MessageBox.INFO, modal : false, fn: function(btn){ theThis.hide(); CheckMYOBConnection(function(){ ShowSelectCompanyFilesDialog(theThis.callback_AfterSubmitted); }); } }); } else{ theThis.show(); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); } }); Ext.reg('CTBLoginForm', Ext.CTBLoginForm); // -------------------------------------- // Renderer for column model : Combobox // -------------------------------------- Ext.util.Format.comboRenderer = function (objComboBox) { return function (value) { var record = objComboBox.findRecord(objComboBox.valueField, value); return record ? record.get(objComboBox.displayField) : objComboBox.valueNotFoundText; } } var global_stateStore = new Ext.data.ArrayStore({ fields: ['ID', 'abbr', 'state'], data: getStateArray() }); function getStateArray() { Ext.namespace('Ext.stateData'); Ext.stateData.states = [ [1, 'VIC', 'Victoria'], [2, 'NSW', 'New South Wales'], [3, 'ACT', 'Australian Capital Teritory'], [4, 'QLD', 'Queensland'], [5, 'NT', 'Northern Teritory'], [6, 'WA', 'Western Australia'], [7, 'SA', 'South Australia'], [8, 'TAS', 'Tasmania'], [9, 'NZL', 'New Zealand'] ]; return Ext.stateData.states; } var Global_UnitOfMeasurement_Store = new Ext.data.ArrayStore({ fields: [ { name: 'UOMId', type: 'number' }, { name: 'UOMName', type: 'string' }, { name: 'UOMShortname', type: 'string' } ], data: getUOMData() }); function getUOMData() { Ext.namespace('Ext.stateData'); Ext.stateData.states = [ [1, 'grams', 'gr'], [2, 'kilograms', 'kg'], [3, 'ml', 'ml'], [4, 'litres', 'l'], [5, 'tbs', 'tbs'], [6, 'tsp', 'tsp'], [7, 'each', 'each'], [8, 'cups', 'cups'] ]; return Ext.stateData.states; } var Global_DistinctSupplierMeasurements_Store = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy({ url: '/UnitOfMeasurement/GetAllDistinctSupplierMeasurements', dataType: 'json', method: 'POST' }), fields: [ { name: 'UOMId', type: 'number' }, { name: 'UOMName', type: 'string' } ], root: 'data', idProperty : 'UOMId', autoLoad : false, totalProperty : 'totalCount', listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(Global_DistinctSupplierMeasurements_Store); }, load : function(){ } } }); var Global_StockCategory_Store = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: '/StockCategory/GetAllStockCategories', dataType: 'json', method: 'POST' }), reader: new Ext.data.JsonReader({ fields: [ { name: 'stockCategoryId', type: 'number' }, { name: 'stockCategoryName', type: 'string' }, { name: 'numberOfStocks', type: 'number' } ], root: 'data' }), listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(Global_StockCategory_Store); }, load : function(){ Global_StockCategory_Store_Loaded = true; } } }); var Global_StockCategory_Store_Loaded = false; var Global_Supplier_Store = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({ url: '/Supplier/GetAllSuppliers', dataType: 'json', method: 'POST' }), reader: new Ext.data.JsonReader({ fields: [ { name: 'supId', type: 'number' }, { name: 'supName', type: 'string' }, { name: 'supFolderId', type: 'number' }, { name: 'abnNo', type: 'string' }, { name: 'accNo', type: 'string' }, { name: 'paymentTerm', type: 'string' }, { name: 'website', type: 'string' } ], root: 'data', idProperty : 'supId' }), listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(Global_Supplier_Store); }, load : function(){ Global_Supplier_Store_Loaded = true; } } }); var Global_Supplier_Store_Loaded = false; // Automatically function get random ads from CTB server var Global_RandomAds_Record = null; function GetRandomAdvertisement(callback_Function) { Ext.Ajax.request({ method: "POST", url: '/Advertisement/GetAdvertisementForUser_Report', params: { }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { Global_RandomAds_Record = jsonData.data; if (callback_Function != null) callback_Function(); } //setTimeout("GetRandomAdvertisement()", 60000); }, failure : function(result, request) { //setTimeout("GetRandomAdvertisement()", 60000); } }); // End ajax } /******************************************************************************/ /* Useful functions for math */ /******************************************************************************/ function roundNumber(num, dec) { var result = Math.round(num*Math.pow(10,dec))/Math.pow(10,dec); return result; } function roundNumberUp(n, digits) { if (digits === undefined) { digits = 0; } var multiplicator = Math.pow(10, digits); n = parseFloat((n * multiplicator).toFixed(11)); var test = (Math.round(n) / multiplicator); return +(test.toFixed(digits)); } function addFullDigitToNumber(num, numOfZero){ var result = num + ""; var dotPosition = result.lastIndexOf('.'); if (dotPosition == -1) { var lastPortion = "."; for (var i = 0; i < numOfZero; i++) { lastPortion += '0'; } result = result + lastPortion; } else { var lastPortion = result.substring(dotPosition, result.length); var firstPortion = result.substring(0, dotPosition); for (var i = lastPortion.length - 1; i < numOfZero; i++) { lastPortion += '0'; } result = firstPortion + lastPortion; } return result; } function truncate(n) { return n | 0; // bitwise operators convert operands to 32-bit integers } // Return a random number between 1 and 1000000000 function getRandomNumber(){ return Math.floor(Math.random() * 1000000000 + 1); } // This function need Global_MeasurementConversion_Store to be active function convertMeasurement(convertFrom, convertTo, value) { var numOfRecords = Global_MeasurementConversion_Store.getCount(); for (var i = 0;i 0){ outHeight = clientHeight * hPercentage/100; } p_Window.setWidth(ourWidth); p_Window.setHeight(outHeight); p_Window.center(); } } // This function resize a window to fix the dimension param // of the client browser screen function fitWindowDimension(p_Window, width, height) { if (!p_Window.maximized) { p_Window.setWidth(width); p_Window.setHeight(height); p_Window.center(); } } // Format for string with number place holder String.prototype.format = function () { var formatted = this; for (arg in arguments) { formatted = formatted.replace("{" + arg + "}", arguments[arg]); } return formatted; }; // This function return a date after today a number of dates function getDateAfterToday(numOfDates) { var today = new Date(); today.setDate(today.getDate() + numOfDates); return today; } // This function return a date after an input date function getDateAfterADate(aDate, numOfDates) { var result = aDate; result.setDate(result.getDate() + numOfDates); return result; } // This function return a date after today a number of dates function getDateBeforeToday(numOfDates) { var today = new Date(); today.setDate(today.getDate() - numOfDates); return today; } // Show tool tip function setToolTip(target, html, trackMouse) { var myToolTip = new Ext.ToolTip({ target: target, html: html, title: 'Tip', autoHide: true, anchor: 'left', closable: true, draggable: true, trackMouse : trackMouse == null? false : true //dismissDelay: 1 // Close in 5 seconds }); } function setToolTipWithMouseTrack(target, html, trackMouse) { var myToolTip = new Ext.ToolTip({ target: target, html: html, title: 'Tip', width : 200, trackMouse : trackMouse == null? false : true //dismissDelay: 1 // Close in 5 seconds }); } // Show tool tip function showToolTip(target, html, returnBool, title) { var myToolTip = new Ext.ToolTip({ target: '', html: html, title: title == null?'We have a problem' : title, autoHide: true, anchor: 'left', closable: true, draggable: true, dismissDelay: 5000 // Close in 5 seconds }); var x = Ext.getCmp(target).getEl().getX(); var y = Ext.getCmp(target).getEl().getY(); var width = Ext.getCmp(target).getEl().getWidth(); var height = Ext.getCmp(target).getEl().getHeight(); x = x + width + 20; y = y - height / 3; myToolTip.showAt([x, y]); Ext.getCmp(target).getEl().frame('#FF0000'); return returnBool; } /******************************************************************************/ /* Useful functions for VALIDATION */ /******************************************************************************/ // Validate email function validateEmail(elementValue) { var emailPattern = /^[a-zA-Z0-9._\-\']+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/; return emailPattern.test(elementValue); } // Validate for common fields function validateFieldGroup(listOfFields, anchor) { var isValidated = true; for (var i = 0; i < listOfFields.length; i++) { if (!Ext.getCmp(listOfFields[i].ID).disabled) { if (listOfFields[i].VALIDATION_TYPE == VALIDATION_CONSTANTS.DATE) { if (!Ext.getCmp(listOfFields[i].ID).isValid() || Ext.getCmp(listOfFields[i].ID).getValue() === '') { var msg = typeof(listOfFields[i].CUSTOM_MESSAGE) === 'undefined' ? 'Date value is not in correct format !' : listOfFields[i].CUSTOM_MESSAGE; isValidated = showToolTip(listOfFields[i].ID, msg, false, null, anchor); } } else if (listOfFields[i].VALIDATION_TYPE == VALIDATION_CONSTANTS.EMPTY) { if (Ext.getCmp(listOfFields[i].ID).getValue() == null || Ext.getCmp(listOfFields[i].ID).getValue().toString().length == 0) { var msg = typeof(listOfFields[i].CUSTOM_MESSAGE) === 'undefined' ? 'Value can not be empty !' : listOfFields[i].CUSTOM_MESSAGE; isValidated = showToolTip(listOfFields[i].ID, msg, false, null, anchor); } } else if (listOfFields[i].VALIDATION_TYPE == VALIDATION_CONSTANTS.NUMBER) { if (Ext.getCmp(listOfFields[i].ID).getRawValue() == null || isNaN(Ext.getCmp(listOfFields[i].ID).getRawValue())) { var msg = typeof(listOfFields[i].CUSTOM_MESSAGE) === 'undefined' ? 'Value is not in number format !' : listOfFields[i].CUSTOM_MESSAGE; isValidated = showToolTip(listOfFields[i].ID, msg, false, null, anchor); } } else if (listOfFields[i].VALIDATION_TYPE == VALIDATION_CONSTANTS.MAX_VALUE) { if (!isNaN(Ext.getCmp(listOfFields[i].ID).getRawValue()) && Ext.getCmp(listOfFields[i].ID).getValue() > listOfFields[i].MAX_VALUE) { var msg = typeof(listOfFields[i].CUSTOM_MESSAGE) === 'undefined' ? String.format('Value is over maximum value of {0} !',listOfFields[i].MAX_VALUE) : listOfFields[i].CUSTOM_MESSAGE; isValidated = showToolTip(listOfFields[i].ID, msg, false, null, anchor); } } else if (listOfFields[i].VALIDATION_TYPE == VALIDATION_CONSTANTS.NEGATIVE) { if (!isNaN(Ext.getCmp(listOfFields[i].ID).getRawValue()) && Ext.getCmp(listOfFields[i].ID).getValue() < 0) { var msg = typeof(listOfFields[i].CUSTOM_MESSAGE) === 'undefined' ? 'Value can not be negative !' : listOfFields[i].CUSTOM_MESSAGE; isValidated = showToolTip(listOfFields[i].ID, msg, false, null, anchor); } } else if (listOfFields[i].VALIDATION_TYPE == VALIDATION_CONSTANTS.EMAIL) { if (!validateEmail(Ext.getCmp(listOfFields[i].ID).getValue())) { var msg = typeof(listOfFields[i].CUSTOM_MESSAGE) === 'undefined' ? 'Email is not in correct format !' : listOfFields[i].CUSTOM_MESSAGE; isValidated = showToolTip(listOfFields[i].ID, msg, false, null, anchor); } } else if (listOfFields[i].VALIDATION_TYPE == VALIDATION_CONSTANTS.CUSTOM) { if (!listOfFields[i].CUSTOM_FUNCTION()) { isValidated = showToolTip(listOfFields[i].ID, listOfFields[i].CUSTOM_MESSAGE, false, null, anchor); } } } } return isValidated; } // Mark a string as deleted using strikethrough of html function markDeleted(str, isUsingImage) { if (isUsingImage != null && isUsingImage == true) return ''; return '' + str + ''; } // Mark a string as green color stand for new entry function markNew(str, isUsingImage) { if (isUsingImage != null && isUsingImage == true) return ''; return '' + str + ''; } // Mark a string or an item as normal function markNormal(str, isUsingImage) { if (isUsingImage != null && isUsingImage == true) return ''; return '' + str + ''; } // Show a message box function showMessageBox(title, content, icon, redirect){ if (icon == null) icon = Ext.MessageBox.INFO; Ext.Msg.show({ title: title, msg: content, buttons: Ext.Msg.OK, fn : okClick, icon: icon }); function okClick(btn){ if (btn == 'ok' && redirect != null && redirect == true) { window.location = '/Default/Index'; } } return 1; } // Show a report message box function showReportMessageBox(report_id){ var msgDialog = new Ext.Window({ title: 'Report', layout: 'fit', closeAction: 'close', expandOnShow : false, closable: false, resizable: false, modal: true, plain: false, minimizable : false, maximizable : false, monitorResize : true, width:400, height:100, html : '

Your report is ready. Click show button to see your report
Please turn off popup blocker in order to view the report

', buttons : [ { xtype: 'box', cls : 'x-btn x-btn-noicon', autoEl: {tag: 'a', target: '_blank', href: '/aspx/DisplayReport.aspx?r_id='+report_id, html: 'Show'} }, { xtype : 'button', text : 'Cancel', handler : function(){ msgDialog.close(); } } // , // { // xtype : 'button', // text : 'Send email', // handler : function(){ // Global_ContactBrowser_CallbackFunction = function(selectedRecords) // { // var recipients = ""; // for(var i = 0;i', '
{advertisementDescription}
', '' ) }) ], listeners : { beforeshow : function(p_This){ if (Global_RandomAds_Record != null) { fitWindowDimension(p_This, Global_RandomAds_Record.advertisementImageWidth+20, Global_RandomAds_Record.advertisementImageHeight+130); p_This.items.each(function(item, index){ if (index == 0) { item.tpl.overwrite(item.getEl(), Global_RandomAds_Record); } }); } } }, tbar : [ /*{ xtype : 'panel', html : '

Your report is ready.
Click Show to download.

', frame : true },*/ '->', new Ext.Button({ text : 'Contact', iconCls : 'icon-person', tooltip : 'Contact a rep about the product', scale : 'large', handler : function(p_This){ showErrorNotification('Notice', 'Under construction'); } }), new Ext.Button({ xtype : 'button', text : 'Find out more', iconCls : 'icon-video', scale : 'large', handler : function(){ if (Global_RandomAds_Record != null) showHelpVideo(Global_RandomAds_Record.advertisementVideoID, false); } }), new Ext.Button({ text : 'Order', iconCls : 'icon-truck', scale : 'large', tooltip : 'Order the product / Service', handler : function(p_This){ showErrorNotification('Notice', 'Under construction'); } }) ], buttons : [ /*{ xtype: 'box', cls : 'x-btn x-btn-noicon', autoEl: {tag: 'a', target: '_blank', href: '/aspx/DisplayReport.aspx?r_id='+report_id, html: ''} },*/ /*{ xtype: 'box', autoEl: {tag: 'a', target: '_blank', href: '/aspx/DisplayReport.aspx?r_id='+report_id, html: '
Your report is ready to view.
Click here to download.
'} },*/ { xtype : 'box', hidden : hideDownloadExcel, html : '
' }, { xtype : 'box', html : '
' }, { xtype : 'button', text : 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ msgDialog.close(); } }, { xtype : 'button', text : 'Send email', iconCls : 'icon-send-large', scale : 'large', handler : function(){ Global_ContactBrowser_CallbackFunction = function(selectedRecords) { var recipients = ""; for(var i = 0;i'+ '
  Chrome  
'+ '
  Firefox  
'; var msgDialog = new Ext.Window({ title: 'Failed', layout: 'border', closeAction: 'close', expandOnShow : false, closable: false, resizable: false, modal: true, plain: false, minimizable : false, maximizable : false, monitorResize : true, width:400, height:400, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, items : [ { xtype : 'panel', region : 'center', frame : true, html : '
  
' + content + '
', autoHeight : true }, { xtype : 'panel', layout : 'border', region : 'south', title : 'How this happen to you ?', height : 250, items : [ { xtype : 'textarea', id : 'txt_' + inputId, //title : 'How did you meet this error ?', region : 'center', margins : '5 5 5 5' }, { xtype : 'panel', html : webBrowserAdvertisement, region : 'south', height : 110, frame : true } ] } ], buttons : [ { xtype : 'button', text : 'Send to us', iconCls : 'icon-send-large', scale : 'large', handler : function(){ var loadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."}); loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Account/SendErrorAnnoucementEmail', params : { userNotify : Ext.getCmp('txt_' + inputId).getValue() }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); // Do nothing Ext.Msg.show({ title:'Notice', msg: '

THANK YOU SO MUCH! We\'re working on the error to fix it as soon as possible


' + webBrowserAdvertisement, width: 500, buttons: Ext.Msg.OK, icon: Ext.MessageBox.INFO }); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } loadMask.hide(); }, failure : function(result, request) { loadMask.hide(); } }); // End ajax msgDialog.close(); } }, { xtype : 'button', text : 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ msgDialog.close(); } } ] }); msgDialog.show(); return 1; } // This function show a tab in a tab panel function showTabInTabPanel(tabPanel, showingChild) { tabPanel.unhideTabStripItem(showingChild); } // This function hide a tab in a tab panel function hideTabInTabPanel(tabPanel, hidingChild) { tabPanel.hideTabStripItem(hidingChild); } // Help video var Global_Help_CurrentVideo_ID = null; var Global_Help_CurrentVideo_Description = null; // Set video help function setVideoHelp(VIDEO_ID, VIDEO_DESC){ Global_Help_CurrentVideo_ID = VIDEO_ID; Global_Help_CurrentVideo_Description = VIDEO_DESC; } // Fix IE 7 - Iframe problem with tree panel Ext.override(Ext.EventObjectImpl, { getTarget : function(selector, maxDepth, returnEl){ var targetElement; try { targetElement = selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target); } catch(e) { targetElement = returnEl ? Ext.get(this.target) : this.target; } return targetElement; } }); //--------------------------------------------------- // NOTIFICATION //--------------------------------------------------- function showNotification(title, message, icon, config){ var notification = new Ext.ux.Notification({ iconCls: icon, title: title, myConfig : config, html: message, thumbIcon : icon, autoDestroy: true, hideDelay: 3000, listeners: { 'beforerender': function(){ /*Sound.enable(); Sound.play('notify.wav'); Sound.disable();*/ } } }).show(document); notification.show(document); } // Show a drop down notification (Top - Center) function showDropDownNotification(title, message, icon, items){ new Ext.ux.Notification({ iconCls: icon, title: title, html: message, autoDestroy: true, hideDelay: 5000, items : items, slideDirection : 't', alignPosition : 'c-t', alignAnchorX : 0, alignAnchorY : 60 }).show(document); } function showSuccessNotification(message, icon, config){ if (message != null && message != '') //showNotification('Success', message, icon, config); showNotification('Success', message, Ext.ux.Notification.ICON_THUMB_UP, config); } function showErrorNotification(title, message, config){ if (message != null && message != '') //showNotification(title, message, NOTIFICATION.ICON_ERROR, config); showNotification(title, message, Ext.ux.Notification.ICON_THUMB_DOWN, config); } //--------------------------------------------------- // GET FILE EXTENSION //--------------------------------------------------- function GetFileExtension(filename){ return filename.split('.').pop(); } /* Custom Date object addHours method */ Date.prototype.addHours= function(h){ this.setHours(this.getHours()+h); return this; } var Global_Help_CurrentVideo_ID = null; var Global_Help_CurrentVideo_Description = null; var Global_Money_NumberOfDigits = 2; var Global_Money_RoundUpTo = 2; var Global_GSTPercentage = 10; var Global_IncludingLabourInFoodCost = false; var Global_DatabaseName = null; var Global_DatabaseSettings = null; // Is an object contained all the setting of the database (enableFoodCostLimit, foodCostLimit) var IS_SHOWING_LOGIN_FORM = false; var IS_SHOWING_SELECT_COMPANY_FILES = false; var IS_SHOWING_SELECT_KOUNTA_SITES = false; var IS_SHOWING_MYOB_LOGIN = false; var IS_SHOWING_CONNECT_TO_MYOB = false; Ext.chart.Chart.CHART_URL = '../Scripts/extjs/ux/charts/charts.swf'; // This function will get the GST percentage of the system function GetGSTPercentage(){ Ext.Ajax.request({ method: "POST", url: '/Setting/GetSettings', success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.IsSuccess) { showSuccessNotification(jsonData.Info, NOTIFICATION.ICON_INFORMATION); Global_GSTPercentage = jsonData.AdditionalData.GSTPercentage; Global_IncludingLabourInFoodCost = jsonData.AdditionalData.includingLabourInFoodCost; Global_DatabaseSettings = jsonData.AdditionalData; } else { showErrorMessageWithEmailNotify(jsonData.Info); } }, failure : function(result, request) { } }); } function CheckCurrentLogin(){ Ext.Ajax.request({ method: "POST", url: '/Kounta/CheckCurrentLogin', success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { // Do nothing } else{ if (!IS_SHOWING_LOGIN_FORM) { var loginForm = new Ext.CTBLoginForm({ message : 'Login to Cooking the Books', isShowForgetPasswordButton : false, listeners : { show : function(){ //isShowingAnErrorMessage = true; IS_SHOWING_LOGIN_FORM = true; }, beforehide : function(){ //isShowingAnErrorMessage = false; IS_SHOWING_LOGIN_FORM = false; } } }); loginForm.show(); } } }, failure : function(result, request) { } }); } function ShowMYOBLoginForm(companyFileRecord, callback_Function){ if (!IS_SHOWING_MYOB_LOGIN) { var companyFileID = companyFileRecord.data.Id; var companyFileName = companyFileRecord.data.Name; var MYOBLoginForm = new Ext.CTBLoginForm({ message : String.format('Login to MYOB ({0})', companyFileName), isShowForgetPasswordButton : false, prefilledUserEmail : 'Administrator', prefilledUserPassword : '', emailFieldLabel : 'Username', allowEmptyPassword : true, listeners : { show : function(){ //isShowingAnErrorMessage = true; IS_SHOWING_MYOB_LOGIN = true; }, beforehide : function(){ //isShowingAnErrorMessage = false; IS_SHOWING_MYOB_LOGIN = false; } }, callback_LoginButtonClicked : function(username, password){ callback_Function(MYOBLoginForm, username, password); } }); MYOBLoginForm.show(); } } function CheckMYOBConnection(callback_AfterConnectToMYOB){ if (!IS_SHOWING_CONNECT_TO_MYOB) { var dlg_ConnectToXero = new Ext.CTBXeroConnectWindow({ callback_ContinueButtonClick : function() { // Continue the process if only there is a valid connection established // Do nothing for now if (callback_AfterConnectToMYOB != null) callback_AfterConnectToMYOB(); }, listeners : { show : function(){ //isShowingAnErrorMessage = true; IS_SHOWING_CONNECT_TO_MYOB = true; }, beforehide : function(){ //isShowingAnErrorMessage = false; IS_SHOWING_CONNECT_TO_MYOB = false; } } }); dlg_ConnectToXero.show(); } } function ShowSelectCompanyFilesDialog(){ if (!IS_SHOWING_SELECT_COMPANY_FILES) { var dlg_MYOBSelectCompanyFiles = new Ext.CTBMYOBSelectCompanyFilesWindow({ listeners : { show : function(){ //isShowingAnErrorMessage = true; IS_SHOWING_SELECT_COMPANY_FILES = true; }, beforehide : function(){ //isShowingAnErrorMessage = false; IS_SHOWING_SELECT_COMPANY_FILES = false; } } }); // currently we let the user choose site when needed //dlg_MYOBSelectCompanyFiles.callback_AfterSelect = ShowSelectKountaSites; dlg_MYOBSelectCompanyFiles.show(); } } function ShowSelectKountaSites() { if(!Ext.ctbKountaSelectSitesWindow) { Ext.ctbCountaSelectSitesWindow = new Ext.CTBKountaSelectSiteWindow(); } Ext.ctbCountaSelectSitesWindow.showSelectWindow(function(siteId, siteName){ console.log(siteId + ':' + siteName); //finalise selection Ext.Ajax.request({ url: '/Kounta/FinaliseSiteSelection', method: 'post', params: {siteId: siteId, siteName: siteName}, success: function(result, request) { console.log(result.responseText); var jsonData = Ext.decode(result.responseText); if(jsonData.message.IsSuccess) { showSuccessNotification('Successfully finalised site selection.'); //refresh the window window.location = window.location; } else { showErrorNotification('Error', 'Failed to finalise site selection. Message: ' + jsonData.message.Info); } }, failure: function(result, request) { showErrorNotification('Error', 'Failed to finalise site selection. Message: ' + result.responseText); } }); }); } // This is to fix the DayLight saving problem with Safari function ConvertTicksToDate(pTicks){ var theDate = new Date((pTicks - 621355968000000000) / 10000); return theDate; } Ext.util.Format.percentage = function(val){ return addFullDigitToNumber(roundNumber(val, 2), 2) + '%'; }; Ext.util.Format.twoDecimalPoint = function(val){ return addFullDigitToNumber(roundNumber(val, 2), 2); }; Ext.util.Format.foodWeight = function(val){ return addFullDigitToNumber(roundNumber(val, 3), 3); }; Ext.util.Format.CTBMoneyFormat = function(val, isBold){ var html = '
{0}
{1}
'; if (isBold != null && isBold == true) html = '
{0}
{1}
'; if (val >= 0) return String.format(html, ' $', Ext.util.Format.twoDecimalPoint(val)); else return String.format(html, '-$', Ext.util.Format.twoDecimalPoint(-val)); }; Ext.util.Format.CTBPercentageFormat = function(val, isBold){ var html = '
{0}
 {1}
'; if (isBold != null && isBold == true) html = '
{0}
 {1}
'; return String.format(html, Ext.util.Format.twoDecimalPoint(val), '%'); }; /** * Clone Function * @param {Object/Array} o Object or array to clone * @return {Object/Array} Deep clone of an object or an array * @author Ing. Jozef Sakáloš */ Ext.ux.clone = function(o) { if(!o || 'object' !== typeof o) { return o; } if('function' === typeof o.clone) { return o.clone(); } var c = '[object Array]' === Object.prototype.toString.call(o) ? [] : {}; var p, v; for(p in o) { if(o.hasOwnProperty(p)) { v = o[p]; if(v && 'object' === typeof v) { c[p] = Ext.ux.clone(v); } else { c[p] = v; } } } return c; }; // eo function clone Ext.onReady(function () { Ext.QuickTips.init(); try{ // CheckCurrentLogin(); }catch(e){} }); // End Ext.Ready // Lightbox Ext.ux.Lightbox.register('a[rel^=lightbox]'); var Global_SupplierBrowser_CallbackFunction; var Global_SupplierBrowser_Txt_SearchValue; var Global_SupplierBrowser_Cmb_SearchValue; var Global_SupplierBrowser_CallbackFunction_For_Cancel; var Global_SupplierBrowser_IsClickChooseButton = false; // Get a stock browser function getSupplierBrowserDialog() { var pageSize = CTB.init.itemPerPage || 100; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** var record = Ext.data.Record.create([ { name: 'supplierId', type: 'number' }, { name: 'supplierName', type: 'string' }, { name: 'abnNo', type: 'string' }, { name: 'paymentTerm', type: 'string' }, { name: 'accountNo', type: 'string' }, { name: 'isActive', type: 'bool' }, { name: 'website', type: 'string' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** var store = new Ext.data.JsonStore({ //baseParams : {keyword : "", start : 0, limit : 25}, proxy: new Ext.data.HttpProxy({ url: '/Supplier/SearchSuppliers', dataType: 'json', method: 'POST' }), fields: record, root: 'data', idProperty: 'supplierId', totalProperty: 'totalCount', listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); // *************************************************************************************************** // Grid // *************************************************************************************************** /****************************/ /* Selection Model */ /****************************/ sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { } } }); // Column Models var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'supplierId', dataIndex: 'supplierId', hidden: true, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: 'Supplier Name', dataIndex: 'supplierName', width: 35, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: 'Abn Number', dataIndex: 'abnNo', width: 15, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: 'Payment term', dataIndex: 'paymentTerm', width: 15, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: 'Account Number', dataIndex: 'accountNo', width: 15, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: 'Website', dataIndex: 'website', width: 20, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false }) } ] }); /****************************/ /* Searching Stock Combobox */ /****************************/ var data_SearchType = [ ['By Supplier Name', 1], ['By Account Number', 2] ]; var cmb_SearchSupplier = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ] }), displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Choose search by ...' }); // manually load local data cmb_SearchSupplier.getStore().loadData(data_SearchType); var txt_Supplier_SearchValue; /****************************/ /* Master Stock Grid */ /****************************/ var supplier_Grid = new Ext.grid.EditorGridPanel({ id : 'grid_Supplier', region: 'center', store: store, title: 'Supplier list', frame: true, sm : sm, listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); } }, tbar: [ new Ext.Button({ iconCls: 'icon-save-large', scale : 'large', text: 'Save', //disabled: true, handler: function () { } }), '-', new Ext.Button({ iconCls: 'icon-add', scale : 'large', text: 'Add', //disabled: true, handler: function () { var newRecord = new record({ supplierId: -1, supplierName: 'Cooking the books', abnNo: 'Unknown', paymentTerm : 0, accountNo : 'Unknown', isActive : true, website : 'http://www.cookingthebooks.com.au' }); supplier_Grid.stopEditing(); supplier_Grid.getStore().insert(0, newRecord); supplier_Grid.getSelectionModel().startEditing(0, 0); } }), '-', new Ext.Button({ iconCls: 'icon-delete', scale : 'large', text: 'Delete', //disabled: true, handler: function () { } }), '-', { xtype : 'button', iconCls : 'icon-search-large', scale : 'large', id : 'btn_Supplier_SearchStock', text : 'Search', handler : function(){ var searchType = cmb_SearchSupplier.getValue(); var searchValue = txt_Supplier_SearchValue.getValue(); if (searchType == "") { Ext.Msg.show({ title:'Notice', msg: 'Please choose a search type !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } else { // Send search request supplier_Grid.getStore().baseParams = {keyword : searchValue, searchType : searchType, start : 0, limit : pageSize}; supplier_Grid.getStore().load(); } } }, txt_Supplier_SearchValue = new Ext.form.TextField({ id : 'txt_Supplier_SearchValue', emptyText : 'Search value ...' }), ' ', cmb_SearchSupplier, { xtype : 'button', id : 'btn_Supplier_StopSearch', iconCls : 'icon-stop-search', handler : function(){ store.baseParams = {start : 0, limit : pageSize}; store.load(); } } ], cm: cm, sm: sm, width: 780, height: 400, autoHeight: false, clicksToEdit: 2, loadMask: true, bbar: new Ext.PagingToolbar({ store: store, pageSize: pageSize, displayInfo: true, displayMsg: 'Displaying results {0} - {1} of {2}', emptyMsg: "No supplier to display" }), viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); Global_SupplierBrowser_Txt_SearchValue = txt_Supplier_SearchValue; Global_SupplierBrowser_Cmb_SearchValue = cmb_SearchSupplier; /****************************/ /* Stock Browser Windwos */ /****************************/ var SupplierBrowserDialog = new Ext.Window({ title: 'Supplier Browser', layout: 'border', id : 'dlg_SupplierBrowser', closeAction: 'hide', iconCls : 'icon-stock', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, callback_AfterSelect : null, //maximized : true, width:800, height:500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, buttons: [{ text: 'Select', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ /*if (SupplierBrowserDialog.callback_AfterSelect != null){ var selectedRows = supplier_Grid.getSelectionModel().getSelections(); if (selectedRows.length > 0) { SupplierBrowserDialog.callback_AfterSelect(selectedRows); SupplierBrowserDialog.callback_AfterSelect = null; SupplierBrowserDialog.hide(); } else { showErrorNotification('Notice', 'Please choose a supplier!'); } }*/ if (Global_SupplierBrowser_CallbackFunction) { var selectedRows = supplier_Grid.getSelectionModel().getSelections(); if (selectedRows.length > 0) { var supplierIds = new Array(); for (var i = 0, row; row = selectedRows[i]; i++) { supplierIds[i] = row.get("supplierId"); } Global_SupplierBrowser_IsClickChooseButton = true; Global_SupplierBrowser_CallbackFunction(supplierIds, selectedRows); SupplierBrowserDialog.hide(); } else { Ext.Msg.show({ title:'Notice', msg: 'Please choose a supplier!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } } },{ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ SupplierBrowserDialog.hide(); } }], items : [supplier_Grid], listeners : { 'afterrender' : function(){ supplier_Grid.getStore().baseParams = {keyword : "", start : 0, limit:pageSize}, supplier_Grid.getStore().load(); }, 'beforeshow' : function(p_This){ // Fit this window to the client browser screen with 90% fitWindowSize(p_This, 90); }, 'show' : function(p_This){ //p_This.getEl().fadeIn(); }, 'beforehide' : function(p_This){ // If Choose button hasn't been clicked and CallbackFunction for cancel button is avaiable // Then call the function if ( !Global_SupplierBrowser_IsClickChooseButton && Global_SupplierBrowser_CallbackFunction_For_Cancel) { // Call the function for Cancel button Global_SupplierBrowser_CallbackFunction_For_Cancel(); } // Reset the flag Global_SupplierBrowser_IsClickChooseButton = false; } } }); return SupplierBrowserDialog; } Ext.CTBNumberPad = Ext.extend(Ext.Panel, { layout : { type : 'fit' }, cls : 'ctb-number-pad ctb-panel-customized-title-bar', title : 'Calculator', //title : 'test', floating: true, modal: true, centered: true, draggable : true, width: 473, height: 480, showAnimation : 'pop', isHideTopBar: false, loadMask: null, value: 0, savedValue : 0, isHavingChanges : false, operator: '', MaxButtonsOnRow: 5, callback_Next: null, callback_Assign : null, callback_BarCodeEntered : null, needResetWhenEnterNewNumber : false, isRoundingValue : true, roundDecimal : 3, isShowWarningSelectRow : true, clearOnNextAction : false, targetRecordId : -1, titleDescription : '', showNotesInputField : false, notes : '', setTitleDescription : function(titleDescription){ var theThis = this; theThis.titleDescription = titleDescription; if (theThis.txt_Description != null) theThis.txt_Description.setValue(theThis.titleDescription); }, setNotes : function(notes){ var theThis = this; theThis.notes = notes; if (theThis.txt_Notes != null) theThis.txt_Notes.setValue(theThis.notes); }, configLayout: [ {text: '7_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('7');}}, {text: '8_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('8');}}, {text: '9_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('9');}}, {text: 'divide64', dimension: 84, tooltip: 'divide', handler: function(theThis){theThis.operatorClick('/');}}, {text: 'remove64', dimension: 84, tooltip: 'remove', handler: function(theThis){theThis.removeValue();}}, {text: '4_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('4');}}, {text: '5_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('5');}}, {text: '6_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('6');}}, {text: 'multiply64', dimension: 84, tooltip: 'multiply',handler: function(theThis){theThis.operatorClick('*');}}, {text: 'percent64', dimension: 84, tooltip: 'divide by 100',handler: function(theThis){theThis.operatorClick('%');}}, {text: '1_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('1');}}, {text: '2_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('2');}}, {text: '3_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('3');}}, {text: 'minus64', tooltip: 'Minus/Negative', dimension: 84, handler: function(theThis){theThis.operatorClick('-');}}, {text: 'next64', tooltip: 'Next row', dimension: 84, handler: function(theThis){ theThis.operatorClick('=>'); }}, {text: '0_64', tooltip: '', dimension: 84, handler: function(theThis){theThis.numberClick('0');}}, {text: 'clear64', tooltip: 'Clear', dimension: 84, handler: function(theThis){theThis.clear();}}, {text: 'dot64', tooltip: 'Floating point', dimension: 84, handler: function(theThis){theThis.numberClick('.');}}, {text: 'add64', tooltip: 'add', dimension: 84, handler: function(theThis){theThis.operatorClick('+');}}, {text: 'assign64', tooltip: 'Equal/Assign', dimension: 84, handler: function(theThis){theThis.operatorClick('=');}} ], numberClick : function(number){ var theThis = this; if (theThis.clearOnNextAction == true) { theThis.clear(); theThis.clearOnNextAction = false; } theThis.isHavingChanges = true; // We have changes in the calculator // Don't let add the second floating point if (number == '.' && theThis.getDisplayValue().indexOf('.') != -1) { return; } var displayValue = ''; // Alway reset display value to empty string if (!theThis.needResetWhenEnterNewNumber) // If the flag reset the display value haven't been catched, we assign for the current thing in the desktop displayValue = theThis.getDisplayValue() + ""; else { // If the flag is catched, reset the display value, also reset the saved value to 0 theThis.setDisplayValue(''); theThis.savedValue = 0; theThis.needResetWhenEnterNewNumber = false; // Reset the flag so we can catch more number } displayValue = displayValue + number; // Convert the display value to number var convertToNumber = parseFloat(displayValue); // If CANNOT convert to number, do nothing if (!isNaN(convertToNumber)){ theThis.savedValue = convertToNumber; theThis.setDisplayValue(displayValue); } }, operatorClick : function(operator){ var theThis = this; if (theThis.needResetWhenEnterNewNumber == false){ if (theThis.operator == "+"){ theThis.value = theThis.value + theThis.savedValue; if (theThis.isRoundingValue == true) theThis.value = roundNumber(theThis.value, theThis.roundDecimal); theThis.setDisplayValue(theThis.value); } else if (theThis.operator == "-"){ theThis.value = theThis.value - theThis.savedValue; if (theThis.isRoundingValue == true) theThis.value = roundNumber(theThis.value, theThis.roundDecimal); theThis.setDisplayValue(theThis.value); } else if (theThis.operator == "*"){ theThis.value = theThis.value * theThis.savedValue; if (theThis.isRoundingValue == true) theThis.value = roundNumber(theThis.value, theThis.roundDecimal); theThis.setDisplayValue(theThis.value); } else if (theThis.operator == "/"){ theThis.value = theThis.savedValue == 0 ? 0 : theThis.value / theThis.savedValue; if (theThis.isRoundingValue == true) theThis.value = roundNumber(theThis.value, theThis.roundDecimal); theThis.setDisplayValue(theThis.value); } else if (theThis.operator == ''){ theThis.value = theThis.savedValue; if (theThis.isRoundingValue == true) theThis.value = roundNumber(theThis.value, theThis.roundDecimal); } } if (operator == '%'){ theThis.value = theThis.value / 100; if (theThis.isRoundingValue == true) theThis.value = roundNumber(theThis.value, theThis.roundDecimal); theThis.setDisplayValue(theThis.value); } if (operator == '='){ theThis.operator = '='; if (theThis.callback_Assign != null){ theThis.callback_Assign(theThis.getValue()); //theThis.setValue(0); theThis.clearOnNextAction = true; //theThis.clear(); //theThis.setDisplayValue(""); } else { if (theThis.isShowWarningSelectRow) showErrorNotification("Notice", "Please choose a row to assign the value."); } return; } if (operator == '=>'){ if (theThis.callback_Next != null) { theThis.callback_Next(theThis); if (theThis.clearOnNextAction == true) { theThis.clear(); theThis.clearOnNextAction = false; } } else { if (theThis.isShowWarningSelectRow) showErrorNotification("Notice", "Please select a row to start."); } } else { theThis.needResetWhenEnterNewNumber = true; theThis.operator = operator; } }, removeValue : function(){ var theThis = this; var displayValue = ""; if (!theThis.needResetWhenEnterNewNumber) // If the flag reset the display value haven't been catched, we assign for the current thing in the desktop displayValue = theThis.getDisplayValue() + ""; else { // If the flag is catched, reset the display value, also reset the saved value to 0 theThis.setDisplayValue(''); theThis.savedValue = 0; theThis.needResetWhenEnterNewNumber = false; // Reset the flag so we can catch more number } if (displayValue.length != 1){ displayValue = displayValue.substring(0, displayValue.length - 1); } else { displayValue = ""; theThis.setDisplayValue(displayValue); } var convertToNumber = parseFloat(displayValue); if (!isNaN(convertToNumber)){ theThis.savedValue = convertToNumber; theThis.setDisplayValue(displayValue); } }, setDisplayValue : function(value){ var theThis = this; theThis.txt_DisplayValue.setText(value); }, getDisplayValue : function(){ var theThis = this; return theThis.txt_DisplayValue.text; }, clear : function(value){ var theThis = this; theThis.setValue(0); theThis.setDisplayValue(''); theThis.savedValue = 0; theThis.operator = ''; theThis.isHavingChanges = false; // Determine that we haven't receive any action in the calculator }, setValue : function(value){ var theThis = this; theThis.value = value; theThis.txt_DisplayValue.setText(value); }, focusBarCodeField : function(){ this.txt_BarCode.focus('', 10); }, listeners : { scope: this, afterrender: function(p_This){ // Init loadMask p_This.loadMask = new Ext.LoadMask(p_This.getEl(), {msg:"Please wait..."}); } }, initComponent: function(){ var theThis = this; if (theThis.showNotesInputField == true) { theThis.setHeight(530); } theThis.pnl_NumberPad = theThis.getPanel_NumberPad(); this.dockedItems = [ /*theThis.txt_Description = new Ext.Toolbar({ dock : 'top', xtype: 'toolbar', title: 'Title Description' })*/ ]; theThis.items = [ theThis.pnl_NumberPad ] // Call super class to initialize componenets Ext.CTBNumberPad.superclass.initComponent.call(this); }, getValue: function(){ return this.value; }, setVirtualNumberPadOriValue: function(originalValue) { var theThis = this; }, getPanel_ARow: function(start){ var theThis = this; var toolbar = null; var pnl_Return = new Ext.Panel({ width : theThis.width - 15, height : 85, layout : { type : 'hbox', pack : 'center' } }); for (var i = start; i < start + theThis.MaxButtonsOnRow; i++){ if (theThis.configLayout.length >= i && !Global_IsiPad) { var aButton = new Ext.Button({ scale : 'large', iconCls : 'icon-number-' + theThis.configLayout[i].text, layoutIndex : i, width : theThis.configLayout[i].dimension, height : theThis.configLayout[i].dimension, tooltip : theThis.configLayout[i].tooltip, handler : function(p_This) { try { theThis.configLayout[p_This.layoutIndex].handler(theThis); } catch(e) { alert(e); } } }); pnl_Return.add(aButton); } else if (theThis.configLayout.length >= i && Global_IsiPad){ var aButton = new Ext.Button({ scale : 'large', iconCls : 'icon-number-' + theThis.configLayout[i].text, layoutIndex : i, width : theThis.configLayout[i].dimension, height : theThis.configLayout[i].dimension, //tooltip : theThis.configLayout[i].tooltip, handler : function(p_This) { try { theThis.configLayout[p_This.layoutIndex].handler(theThis); } catch(e) { alert(e); } } }); pnl_Return.add(aButton); } } pnl_Return.doLayout(); return pnl_Return; }, getPanel_NumberPad: function(){ var theThis = this; theThis.txt_DisplayValue = new Ext.Panel({ cls : 'white_background', style : 'font-size:35px;text-indent:5px;', html : "", width : 90, height : 46, text : "", setText : function(text){ this.text = text; this.update(text); } }); var pnl_NumberPad = new Ext.Panel({ region :'center', //cls : 'black_background', layout : { type : 'fit' }, //width : 498, //height : 520, html : '
' + '
' + '
' + '
' + '
' + (theThis.showNotesInputField == false ? '' : '
'), listeners : { afterrender : function(p_Panel){ theThis.getPanel_ItemDisplay(theThis.id + '_pnlItemDisplay'); theThis.getPanel_MoveItem(theThis.id + '_pnlMoveItem'); theThis.getPanel_Number(theThis.id + '_pnlNumberPad'); theThis.getPanel_Operator(theThis.id + '_pnlOperator'); theThis.txt_DisplayValue.render(theThis.id + '_pnlNumberDisplay'); if (theThis.showNotesInputField) { theThis.getPanel_Notes(theThis.id + '_pnlNotes'); } } } }); return pnl_NumberPad; }, // End getPanel_NumberPad getPanel_Number: function(renderTarget){ var theThis = this; var html = ""; var numberSequence = [7, 8, 9, 4, 5, 6, 1, 2, 3, 0, 10, 11]; var newLineNumber = [0, 1, 4, 7]; for (var i = 0; i < numberSequence.length; i++) { if (newLineNumber.indexOf(numberSequence[i]) == -1) { html += '
'; } else { html += '
'; } } var pnl_Number = new Ext.Panel({ layout : { type : 'fit' }, cls : 'bg_landing', width : 220, height : 290, html : html, renderTo : renderTarget, listeners : { afterrender : function(p_Panel){ for (var i = 0; i < numberSequence.length; i++) { var thePanel = new Ext.Panel({ width : 48, height : 48, cls : 'numberpad_small_number_' + numberSequence[i], renderTo : renderTarget + '_' + numberSequence[i], theNumber : numberSequence[i], id : 'btnNumber_' + renderTarget + '_' + numberSequence[i], listeners : { afterrender : function(p_Button){ p_Button.body.on('click', function(){ if (p_Button.theNumber == 10) { // Dot theThis.numberClick('.'); } else if (p_Button.theNumber == 11){ // Clear theThis.clear(); } else { theThis.numberClick(p_Button.theNumber + ''); } }); } } }); } } } }); return pnl_Number; }, // End getPanel_NumberPad getPanel_Operator: function(renderTarget){ var theThis = this; var html = ""; var operatorSequence = ["division", "multiplication", "subtraction", "addition", "percentage", "equal", "delete", "enter"]; var operatorMathSymbol = ["/", "*", "-", "+", "%", "=", "del", "=>"]; var newLineNumber = ["division", "subtraction", "percentage"]; for (var i = 0; i < operatorSequence.length; i++) { if (newLineNumber.indexOf(operatorSequence[i]) == -1) { if (operatorMathSymbol[i] == "="){ html += '
'; } else if (operatorMathSymbol[i] == "=>"){ html += '
'; } else { html += '
'; } } else { html += '
'; } } var pnl_Operator = new Ext.Panel({ layout : { type : 'fit' }, //cls : 'black_background', width : 210, height : 290, renderTo : renderTarget, html : html, listeners : { afterrender : function(p_Panel){ for (var i = 0; i < operatorSequence.length; i++) { var thePanel = new Ext.Panel({ width : 48, height : (operatorMathSymbol[i] == "=" || operatorMathSymbol[i] == "=>") ? 102 : 48, operator : operatorMathSymbol[i], cls : 'numberpad_small_operator_' + operatorSequence[i], renderTo : renderTarget + '_' + operatorSequence[i], id : 'btnOperator_' + renderTarget + '_' + operatorSequence[i], listeners : { afterrender : function(p_Button){ p_Button.body.on('click', function(){ if (p_Button.operator == 'del') { // Dot theThis.removeValue(); } else { theThis.operatorClick(p_Button.operator); } }); } } }); } } } }); return pnl_Operator; }, getPanel_ItemDisplay: function(renderTarget){ var theThis = this; var pnl_ItemDisplay = new Ext.form.FormPanel({ layout : { type : 'fit' }, cls : 'no_padding field_height_46px', width : 300, height : 46, renderTo : renderTarget, items: [ theThis.txt_Description = new Ext.form.TextField({ label : 'Items', labelWidth : '70px', listeners : { afterrender : function(p_Text) { p_Text.setValue(theThis.titleDescription); } } }) ] /*listeners : { afterrender : function(p_Panel){ for (var i = 0; i < operatorSequence.length; i++) { var thePanel = new Ext.Panel({ width : 65, height : operatorMathSymbol[i] == "=" ? 138 : 65, operator : operatorMathSymbol[i], cls : 'numberpad_small_operator_' + operatorSequence[i], renderTo : renderTarget + '_' + operatorSequence[i], id : 'btnOperator_' + renderTarget + '_' + operatorSequence[i] }); } } }*/ }); return pnl_ItemDisplay; }, getPanel_MoveItem: function(renderTarget){ var theThis = this; var html = ""; html += '
'; html += '
'; var pnl_MoveItem = new Ext.Panel({ layout : { type : 'fit' }, cls : 'white_background', width : 30, height : 46, renderTo : renderTarget, html : html, listeners : { afterrender : function(p_Panel){ theThis.btnPrevious = new Ext.Panel({ width : 28, height : 22, cls : 'numberpad_small_arrow_previous', renderTo : renderTarget + '_arrow_previous', listeners : { afterrender : function(p_Button){ p_Button.body.on('click', function(){ theThis.operatorClick('=>'); }); } } }); theThis.btnNext = new Ext.Panel({ width : 28, height : 22, cls : 'numberpad_small_arrow_next', renderTo : renderTarget + '_arrow_next', listeners : { afterrender : function(p_Button){ p_Button.body.on('click', function(){ theThis.operatorClick('=>'); }); } } }); } } }); return pnl_MoveItem; }, getPanel_Notes: function(renderTarget){ var theThis = this; var pnl_Notes = new Ext.form.FormPanel({ layout : { type : 'fit' }, cls : 'black_background no_padding field_height_46px', width : 510, height : 46, renderTo : renderTarget, items: [ theThis.txt_Notes = new Ext.form.Text({ label : 'Notes', labelWidth : '70px', listeners : { afterrender : function(p_Text) { p_Text.setValue(theThis.notes); } } }) ] }); return pnl_Notes; } }); Ext.reg('CTBNumberPad', Ext.CTBNumberPad); Ext.CTBNutrition = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: CTB.init.itemPerPage || 100, recordObject : null, selectedFoodID : -1, isFirstTimeLoading : false, listeners : { afterrender : function(p_This){ // Init loadMask p_This.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); } }, initComponent: function(){ var theThis = this; theThis.grid_Nutritions = theThis.getGrid_Nutritions(); theThis.pnl_NutritionDetail = theThis.getPanel_NutritionDetail(); theThis.pnl_NutritionDatabases = theThis.getPanel_NutritionDatabases(); theThis.items = [theThis.grid_Nutritions, theThis.pnl_NutritionDetail, theThis.pnl_NutritionDatabases]; // Call super class to initialize componenets Ext.CTBNutrition.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_Nutritions; }, getPagingToolbar: function(){ var theThis = this; return theThis.pagingToolbar; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getStore().baseParams = {start : 0, limit : theThis.getPagingToolbar().pageSize}; theThis.getGrid().getStore().load(); }, searchData : function(searchData){ var theThis = this; function searchNow(searchData){ theThis.getGrid().getStore().commitChanges(); theThis.txt_SearchValue.setValue(searchData); theThis.cmb_Search.setValue(1); theThis.btn_Search.handler.call(theThis.btn_Search.scope); } if (theThis.rendered) searchNow(searchData) else { theThis.callback_AfterLayout = function(){ searchNow(searchData); }; } }, getPanel_NutritionDetail : function(){ var theThis = this; theThis.tpl_NutritionDetail = new Ext.XTemplate( '', '
', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '
', '{Name}', '
', '', '', 'Per 100g', '', 'Per 100mL', '
', 'Energy', '', '{EnergyPer100g} kJ', '', '{EnergyPer100mL} kJ', '
', 'Protein', '', '{ProteinPer100g} g', '', '{ProteinPer100mL} g', '
', 'Fat Total', '', '{FatTotalPer100g} g', '', '{FatTotalPer100mL} g', '
', '- Saturated', '', '{SaturatedPer100g} g', '', '{SaturatedPer100mL} g', '
', 'Carbohydrate', '', '{CarbohydratePer100g} g', '', '{CarbohydratePer100mL} g', '
', '- Sugar', '', '{SugarPer100g} g', '', '{SugarPer100mL} g', '
', 'Sodium', '', '{SodiumPer100g} mg', '', '{SodiumPer100mL} mg', '
', '
', '
' ); var pnl_NutritionDetail = new Ext.Panel({ region : 'east', title : 'Nutrition Information', frame : true, tpl : theThis.tpl_NutritionDetail, collapsible : true, animCollapse : false, collapsed : true, width : 300, listeners : { afterrender : function(p_This){ p_This.loadMask = new Ext.LoadMask(p_This.getEl(), {msg:"Please wait..."}); } }, loadData : function(databaseID, foodID, Name){ theThis.pnl_NutritionDetail.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Nutrition/GetNutritionInformation', params: { databaseID : databaseID, foodID : foodID }, success : function(result, request) { theThis.pnl_NutritionDetail.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { jsonData.data.Name = Name; theThis.tpl_NutritionDetail.overwrite(theThis.pnl_NutritionDetail.body, jsonData.data); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.pnl_NutritionDetail.loadMask.hide(); } }); } }); return pnl_NutritionDetail; }, getPanel_NutritionDatabases : function(){ var theThis = this; theThis.chk_NutritionDatabases = new Array(); var pnl_NutritionDatabases = new Ext.Panel({ region : 'west', title : 'Nutrition Databases', layout : 'table', layoutConfig : { columns : 1 }, frame : true, collapsible : true, animCollapse : false, collapsed : false, width : 200, listeners : { afterrender : function(p_This){ p_This.loadMask = new Ext.LoadMask(p_This.getEl(), {msg:"Please wait..."}); } }, items : [ theThis.chk_NutritionDatabases[0] = new Ext.form.Checkbox({ boxLabel : 'Australia New Zealand - Food Standards (NUTTAB_2010)', checked : true }), theThis.chk_NutritionDatabases[1] = new Ext.form.Checkbox({ boxLabel : 'United States Department Of Agriculture (USDA Release 23)', checked : true }), theThis.chk_NutritionDatabases[2] = new Ext.form.Checkbox({ boxLabel : 'Australia Nutrition Survey Database (AUSNUT 2007)', checked : true }), theThis.chk_NutritionDatabases[3] = new Ext.form.Checkbox({ boxLabel : 'Cooking the Books - Sharing database', checked : true }) ] }); return pnl_NutritionDatabases; }, getGrid_Nutritions: function(){ var theThis = this; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.recordObject = Ext.data.Record.create([ { name: 'FoodID' , type: 'string' }, { name: 'Name' , type: 'string' }, { name: 'Description' , type: 'string' }, { name: 'Group' , type: 'string' }, { name: 'SubGroup' , type: 'string' }, { name: 'DatabaseID' , type: 'number' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** var store = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy({ url: '/Nutrition/SearchFoodData', dataType: 'json', method: 'POST' }), autoLoad : false, fields: theThis.recordObject, root: 'data', idProperty: 'FoodID', totalProperty: 'totalCount', listeners : { 'beforeload' : function(){ var listOfDatabaseIDs = new Array(); var index = 0; for (var i = 0; i < theThis.chk_NutritionDatabases.length; i++){ if (theThis.chk_NutritionDatabases[i].checked){ var databaseID = i + 1; listOfDatabaseIDs[index] = databaseID; index++; } } var databaseIDs = { listOfNumbers : listOfDatabaseIDs } Ext.apply(store.baseParams, { databaseIDs : Ext.util.JSON.encode(databaseIDs) }); }, 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); // *************************************************************************************************** // Selection model // *************************************************************************************************** var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { var selectedRecords = sm.getSelections(); if (selectedRecords.length > 0){ var theLastRecord = selectedRecords[selectedRecords.length - 1]; if (theThis.pnl_NutritionDetail.collapsed) theThis.pnl_NutritionDetail.expand(); theThis.pnl_NutritionDetail.loadData(theLastRecord.data.DatabaseID, theLastRecord.data.FoodID, theLastRecord.data.Name); } } } }); // *************************************************************************************************** // Column model // *************************************************************************************************** var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header : 'Food ID' , dataIndex : 'FoodID' , hidden : true }, { header : 'Name' , dataIndex : 'Name' , width : 20 }, { header : 'Description' , dataIndex : 'Description' , width : 40 }, { header : 'Group' , dataIndex : 'Group' , width : 20 }, { header : 'Sub Group' , dataIndex : 'SubGroup' , width : 20 }, { header : 'DatabaseID' , dataIndex : 'DatabaseID' , hidden : true } ] }); // *************************************************************************************************** // Searching combobox // *************************************************************************************************** var data_SearchType = [ ['By Name' , 1], ['By Description' , 2] ]; theThis.cmb_Search = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ], data : data_SearchType }), displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, triggerAction: 'all', editable : false, lazyRender: true, mode: 'local', emptyText: 'Choose search by ...' }); // manually load local data theThis.cmb_Search.setValue(1); // *************************************************************************************************** // Paging toolbar // *************************************************************************************************** theThis.pagingToolbar = new Ext.CTBPagingToolbar({ store: store, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No data to display" }); // *************************************************************************************************** // Grid // *************************************************************************************************** var grid = new Ext.grid.EditorGridPanel({ store: store, region: 'center', frame: true, sm : sm, cm : cm, listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, rowdblclick : function ( p_this, p_rowIndex, p_eventObject ) { }, afterlayout : function(){ if (theThis.isFirstTimeLoading == false){ theThis.isFirstTimeLoading = true; if (theThis.callback_AfterLayout != null) theThis.callback_AfterLayout(); else theThis.loadData(); } } }, tbar: [ theThis.btn_Search = new Ext.Button({ xtype : 'button', iconCls : 'icon-search-large', scale : 'large', text : 'Search', handler : function(){ store.commitChanges(); var searchType = theThis.cmb_Search.getValue(); var searchValue = theThis.txt_SearchValue.getValue(); // Reload the store store.baseParams = {keyword : searchValue, searchType : searchType, start : 0, limit : theThis.getPagingToolbar().pageSize}; store.load(); } }), theThis.txt_SearchValue = new Ext.form.TextField({ emptyText : 'Search value ...', listeners: { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_Search.handler.call(theThis.btn_Search.scope); } } } }), ' ', theThis.cmb_Search, theThis.btn_StopSearch = new Ext.Button({ xtype : 'button', iconCls : 'icon-stop-search', handler : function(){ store.commitChanges(); store.baseParams = {start : 0, limit : theThis.getPagingToolbar().pageSize}; store.load(); } }) ], autoHeight: false, clicksToEdit: 1, loadMask: true, bbar: theThis.pagingToolbar, viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return grid; } // End generateGrid_Databases }); Ext.reg('CTBNutrition', Ext.CTBNutrition); Ext.CTBNutritionBrowser = Ext.extend(Ext.Window, { title: 'Nutrition Browser', layout: 'border', closeAction: 'hide', iconCls : 'icon-stock', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, parentContainer : null, minimizable : true, maximizable : true, monitorResize : true, width:800, height:500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, callback_Select : null, callback_AfterLayout : null, callback_Cancel : null, listeners : { scope : this, 'beforehide' : function(theThis){ }, 'beforeshow' : function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); }, 'show' : function(theThis){ } }, initComponent : function(){ var theThis = this; // MAIN GRID theThis.grid_Nutrition = new Ext.CTBNutrition({ region : 'center' }); theThis.items = [theThis.grid_Nutrition]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.Window.superclass.initComponent.call(this); this.addEvents( 'resize', 'maximize', 'minimize', 'restore' ); if(Ext.isDefined(this.initHidden)){ this.hidden = this.initHidden; } if(this.hidden === false){ this.hidden = true; this.show(); } }, loadData : function(stockDesc){ var theThis = this; theThis.grid_Nutrition.searchData(stockDesc); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_Select = new Ext.Button({ text: 'Select', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ if (theThis.callback_Select != null){ var length = theThis.grid_Nutrition.getSelectedRecords().length; if (length > 0){ theThis.callback_Select(theThis.grid_Nutrition.getSelectedRecords()[length - 1]); } } theThis.hide(); } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ if (theThis.callback_Cancel != null) theThis.callback_Cancel(); theThis.hide(); } }) ]; return buttons; } }); Ext.reg('CTBNutritionBrowser', Ext.CTBNutritionBrowser); // This is for recipe book var Global_NutritionCheckbox_Linked; var Global_NutritionGrid; var Global_IngredientFromStock_Grid; var Global_RecipeBook; function LinkedCheckBoxOnChange(recipeBookId, checkbox_Object, recipeDetailId) { var pnl_RecipeBook = Ext.getCmp(recipeBookId); Global_RecipeBook = pnl_RecipeBook; var stockId = checkbox_Object.id;; var loadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."}); Global_NutritionCheckbox_Linked = checkbox_Object; // Only show nutrition browser dialog when checkbox is checked if (checkbox_Object.checked) { pnl_RecipeBook.dlg_NutritionBrowser.callback_Cancel = LinkNutritionDisable; pnl_RecipeBook.dlg_NutritionBrowser.callback_Select = LinkStockToNutrition; var theSelectedRecipeDetailRecord = pnl_RecipeBook.grid_IngredientFromStock.getStore().getById(recipeDetailId); pnl_RecipeBook.dlg_NutritionBrowser.loadData(theSelectedRecipeDetailRecord.data.stockDesc); pnl_RecipeBook.dlg_NutritionBrowser.show(); } else { loadMask.show(); Ext.Ajax.request({ method: "POST", url: '/Stock/LinkStockToNutrition', params: { stockId : Global_NutritionCheckbox_Linked.id, isLinked : false }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { pnl_RecipeBook.pnl_NutritionDetail.loadData(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } loadMask.hide(); }, failure : function(result, request) { loadMask.hide(); } }); } } function LinkNutritionChecking(foodCode) { var loadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."}); loadMask.show(); // Link ingredient to nutrition food Ext.Ajax.request({ method: "POST", url: '/RecipeDetail/LinkRecipeDetailToNutritionFood', params: { recipeDetailId : getPrefixFromStringId(Global_NutritionCheckbox_Linked.id), foodCode : foodCode, isLinked : true }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); Global_NutritionGrid.getStore().load(); loadMask.hide(); }, failure : function(result, request) { loadMask.hide(); } }); } function LinkStockToNutrition(theNutritionRecord) { var loadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Linking ..."}); loadMask.show(); // Link ingredient to nutrition food Ext.Ajax.request({ method: "POST", url: '/Stock/LinkStockToNutrition', params: { nutritionFoodID : theNutritionRecord.data.FoodID, nutritionDatabaseID : theNutritionRecord.data.DatabaseID, stockId : Global_NutritionCheckbox_Linked.id, isLinked : true }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { Global_RecipeBook.pnl_NutritionDetail.loadData(); showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } loadMask.hide(); }, failure : function(result, request) { loadMask.hide(); } }); } //**************************************************** // These parts is for Stock Maintenance & Stock Browser //**************************************************** function NutritionCheckBoxOnChange(checkbox_Object, componentId) { //var stockId = checkbox_Object.id; var loadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."}); var theComponent = Ext.getCmp(componentId); var theSelectedRecord = theComponent.getGrid().getStore().getById(checkbox_Object.id); var stockId = theSelectedRecord.data.stockId; var stockDesc = theSelectedRecord.data.stockDesc; Global_NutritionCheckbox_Linked = checkbox_Object; // Only show nutrition browser dialog when checkbox is checked if (checkbox_Object.checked) { theComponent.dlg_NutritionBrowser.callback_Cancel = LinkNutritionDisable; theComponent.dlg_NutritionBrowser.callback_Select = function(theNutritionRecord){ LinkStockToNutritionByStockId(theNutritionRecord, stockId); } theComponent.dlg_NutritionBrowser.loadData(stockDesc); theComponent.dlg_NutritionBrowser.show(); } else { loadMask.show(); Ext.Ajax.request({ method: "POST", url: '/Stock/LinkStockToNutrition', params: { stockId : Global_NutritionCheckbox_Linked.id, isLinked : false }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { // Do nothing } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } loadMask.hide(); }, failure : function(result, request) { loadMask.hide(); } }); } } function LinkStockToNutritionByStockId(theNutritionRecord, stockId) { var loadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Linking ..."}); loadMask.show(); // Link ingredient to nutrition food Ext.Ajax.request({ method: "POST", url: '/Stock/LinkStockToNutrition', params: { nutritionFoodID : theNutritionRecord.data.FoodID, nutritionDatabaseID : theNutritionRecord.data.DatabaseID, stockId : stockId, isLinked : true }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } loadMask.hide(); }, failure : function(result, request) { loadMask.hide(); } }); } function LinkNutritionDisable() { Global_NutritionCheckbox_Linked.checked = !Global_NutritionCheckbox_Linked.checked; } //----------------------------- // DATA GRID //----------------------------- Ext.CTBSupplierBrowserGrid = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, //title: 'Menu Analysis', pageSize: CTB.init.itemPerPage || 100, listeners : { afterrender : function(p_This){ // Init loadMask p_This.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); } }, roundDecimal: 2, isFromImportDatabase : false, hideXeroTransferSuppliers : true, hideXeroShowExportedSuppliers : true, outletId : -1, initComponent: function(){ var theThis = this; theThis.grid_Supplier = theThis.generateGrid_Supplier(); theThis.items = [theThis.grid_Supplier]; // Call super class to initialize componenets Ext.CTBSupplierBrowserGrid.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid_Supplier().getSelectionModel().clearSelections(); }, getGrid_Supplier: function(){ var theThis = this; return theThis.grid_Supplier; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_Supplier; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid_Supplier().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.getGrid_Supplier().getStore().commitChanges(); theThis.getGrid_Supplier().getStore().baseParams = { start : 0, limit : theThis.getPagingToolbar().pageSize, isFromImportDatabase : theThis.isFromImportDatabase, outletId : theThis.outletId }; theThis.getGrid_Supplier().getStore().load(); }, getModifiedRecords: function(){ var theThis = this; return theThis.getGrid_Supplier().getStore().getModifiedRecords(); }, generateGrid_Supplier: function(){ var theThis = this; var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.Global_SupplierRecord = Ext.data.Record.create([ { name: 'supplierId', type: 'number' }, { name: 'supplierName', type: 'string' }, { name: 'abnNo', type: 'string' }, { name: 'paymentTerm', type: 'string' }, { name: 'accountNo', type: 'string' }, { name: 'isActive', type: 'boolean' }, { name: 'website', type: 'string' }, { name: 'address', type: 'object' }, { name: 'contact', type: 'object' }, { name: 'status', type: 'string' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** var store = new Ext.data.JsonStore({ //baseParams : {keyword : "", start : 0, limit : 25}, proxy: new Ext.data.HttpProxy({ url: '/Kounta/SearchCTBSuppliers', dataType: 'json', method: 'POST' }), autoLoad : false, fields: theThis.Global_SupplierRecord, root: 'data', idProperty: 'supplierId', totalProperty: 'totalCount', listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment }, beforerowselect: function(o, rowIndex, keepExisting, record) { } } }); // *************************************************************************************************** // Grid // *************************************************************************************************** // Column Models var cm = theThis.readOnly == false ? theThis.initColumnModel(sm, store) : theThis.initReadOnlyColumnModel(sm, store); // Paging toolbar theThis.pt_Supplier = new Ext.CTBPagingToolbar({ store: store, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No supplier to display" }); /****************************/ /* Searching Stock Combobox */ /****************************/ var data_SearchType = [ ['By Supplier Name', 1], ['By Account Number', 2] ]; theThis.cmb_Search = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ], data : data_SearchType }), displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, editable: false, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Choose search by ...' }); theThis.cmb_Search.setValue(1); // Init top bar buttons var tbar = theThis.readOnly == false ? theThis.initTopBar() : theThis.initReadOnlyTopBar(); // Grid var grid_Supplier = new Ext.grid.EditorGridPanel({ region: 'center', store: store, cm : cm, sm : sm, frame: true, buttonAlign : 'left', listeners : { rowmousedown: function() { hinderSelection = true; }, rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, beforeshow : function(p_This){ }, afterrender : function(p_This){ } }, tbar: tbar, autoHeight: false, clicksToEdit: 1, loadMask: true, bbar: theThis.pt_Supplier, viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return grid_Supplier; }, // End generateGrid_Supplier initTopBar: function(){ var theThis = this; var tbar = [ theThis.btn_Save = new Ext.Button({ iconCls: 'icon-save-large', scale : 'large', text: 'Save', //disabled: true, handler: function () { } }), '-', theThis.btn_Add = new Ext.Button({ iconCls: 'icon-add', scale : 'large', text: 'Add', //disabled: true, handler: function () { var aNewRecord = new theThis.Global_SupplierRecord({ supplierId: -1, supplierName: 'Cooking the books', abnNo: 'Unknown', paymentTerm : 0, accountNo : 'Unknown', isActive : true, website : 'Enter website ...' }); theThis.grid_Supplier.stopEditing(); theThis.grid_Supplier.getStore().insert(0, aNewRecord); theThis.grid_Supplier.getStore().getById(newId).set('supplierName', 'Enter supplier name...'); } }), '-', theThis.btn_Delete = new Ext.Button({ iconCls: 'icon-delete', scale : 'large', text: 'Delete', //disabled: true, handler: function () { var selectedItems = theThis.grid_Supplier.getSelectionModel().getSelections(); if (selectedItems.length > 0) { for (var i = 0, row; row = selectedItems[i]; i++) { row.set('isActive', false); } } else { showErrorNotification('Notice', 'Please select item(s) to delete!'); }// End if } }), '-', theThis.btn_StopSearch = new Ext.Button({ xtype : 'button', iconCls : 'icon-stop-search', handler : function(){ theThis.grid_Supplier.getStore().commitChanges(); Ext.apply(theThis.grid_Supplier.getStore().baseParams, { keyword : "", searchType : -1, start : 0, limit : theThis.getPagingToolbar().pageSize }); theThis.grid_Supplier.getStore().load(); } }), theThis.txt_SearchValue = new Ext.form.TextField({ emptyText : 'Search value ...', listeners: { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_Search.handler.call(theThis.btn_Search.scope); } } } }), ' ', theThis.cmb_Search, theThis.btn_Search = new Ext.Button({ iconCls : 'icon-search-large', scale : 'large', text : 'Search', handler : function(){ var searchType = theThis.cmb_Search.getValue(); var searchValue = theThis.txt_SearchValue.getValue(); if (searchType == "") { showErrorNotification('Notice', 'Please choose a search type !'); } else { // Send search request try{ Ext.apply(theThis.grid_Supplier.getStore().baseParams, { keyword : searchValue, searchType : searchType, start : 0, limit : theThis.getPagingToolbar().pageSize }); theThis.grid_Supplier.getStore().load(); }catch(e){alert(e);} } } }) ]; return tbar; }, // End initTopBar initReadOnlyTopBar: function(){ var theThis = this; var tbar = [ theThis.btn_Transfer_Supplier = new Ext.Button({ iconCls: 'icon-move-right', text: 'Transfer suppliers', hidden : theThis.hideXeroTransferSuppliers, tooltip : 'Export suppliers from Cooking the Books to Xero', scale : 'large', handler: function () { // Get selected suppliers var selectedItems = theThis.getGrid_Supplier().getSelectionModel().getSelections(); if (selectedItems.length > 0) { theThis.selectedSupplierRecords = selectedItems; if (theThis.dlg_XeroTransferSupplier == null) { theThis.dlg_XeroTransferSupplier = new Ext.CTBXeroTransferSupplierWindow({ callback_AfterHide : function(){ theThis.getGrid_Supplier().getStore().reload(); } }); } theThis.dlg_XeroTransferSupplier.setSelectedSupplierRecords(theThis.selectedSupplierRecords); theThis.dlg_XeroTransferSupplier.show(); } else { Ext.Msg.show({ title:'Notice', msg: 'Please select at least one supplier to transfer ?', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } }), theThis.btn_ShowExportedSupplier = new Ext.Button({ iconCls: 'icon-visible', enableToggle : true, hidden : theThis.hideXeroShowExportedSuppliers, text: 'Show exported suppliers', tooltip : 'Show all the suppliers included the suppliers has been exported to Xero before.', scale : 'large', toggleHandler : function(p_Button, p_State){ Ext.apply(theThis.getGrid_Supplier().getStore().baseParams, { start : 0, limit : theThis.getPagingToolbar().pageSize, isShowExported : p_State }); theThis.getGrid_Supplier().getStore().load(); if (p_State) p_Button.setText('Hide exported invoices'); else p_Button.setText('Show exported invoices'); theThis.getGrid_Supplier().getStore().load(); } }), '-', theThis.btn_StopSearch = new Ext.Button({ xtype : 'button', iconCls : 'icon-stop-search', handler : function(){ theThis.grid_Supplier.getStore().commitChanges(); Ext.apply(theThis.grid_Supplier.getStore().baseParams, { keyword : "", searchType : -1, start : 0, limit : theThis.getPagingToolbar().pageSize }); theThis.grid_Supplier.getStore().load(); } }), theThis.txt_SearchValue = new Ext.form.TextField({ emptyText : 'Search value ...', listeners: { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_Search.handler.call(theThis.btn_Search.scope); } } } }), ' ', theThis.cmb_Search, theThis.btn_Search = new Ext.Button({ iconCls : 'icon-search-large', scale : 'large', text : 'Search', handler : function(){ var searchType = theThis.cmb_Search.getValue(); var searchValue = theThis.txt_SearchValue.getValue(); if (searchType == "") { Ext.Msg.show({ title:'Notice', msg: 'Please choose a search type !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } else { // Send search request Ext.apply(theThis.grid_Supplier.getStore().baseParams, { keyword : searchValue, searchType : searchType, start : 0, limit : theThis.getPagingToolbar().pageSize }); theThis.grid_Supplier.getStore().load(); } } }) ]; return tbar; }, // End initReadOnlyTopBar initColumnModel : function(sm, store){ var theThis = this; var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'supplierId', dataIndex: 'supplierId', hidden: true, editor: new Ext.form.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: '', dataIndex: 'supplierId', width: 2, renderer: function(val) { var theRecord = store.getById(val); var result = markNormal("", true); if (val < 0) result = markNew(result, true); if (!theRecord.data.isActive) result = markDeleted(result, true); return result; } }, { header: 'Supplier Name', dataIndex: 'supplierName', width: 33, editor: new Ext.form.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: 'Abn Number', dataIndex: 'abnNo', width: 15, editor: new Ext.form.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: 'Payment term', dataIndex: 'paymentTerm', width: 15, editor: new Ext.form.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: 'Account Number', dataIndex: 'accountNo', width: 15, editor: new Ext.form.TextField({ xtype: 'textfield', allowBlank: false }) }, { header: 'Website', dataIndex: 'website', width: 20, editor: new Ext.form.TextField({ xtype: 'textfield', allowBlank: false }) } ] }); // End cm return cm; }, // End initColumnModel initReadOnlyColumnModel : function(sm, store){ var theThis = this; var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'supplierId', dataIndex: 'supplierId', hidden: true }, { header: 'Supplier Name', dataIndex: 'supplierName', width: 50 }, { header: 'Abn Number', dataIndex: 'abnNo', width: 30 }, { header: 'Status', dataIndex: 'status', width: 20 } ] }); // End cm return cm; } // End initReadOnlyColumnModel }); Ext.reg('CTBSupplierBrowserGrid', Ext.CTBSupplierBrowserGrid); //----------------------------- // DIALOG CONTAINER //----------------------------- Ext.CTBSupplierBrowser = Ext.extend(Ext.Window, { title: 'Supplier Browser', layout: 'border', closeAction: 'hide', iconCls : 'icon-stock', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, width:800, height:500, reportLoadMask: new Ext.CTBLoadMaskAds({msg : 'Loading report. Please wait ...'}), outletId : -1, defaults: { //split: true, animFloat: false, autoHide: false, useSplitTips: true }, callback_AfterSave : null, callback_AfterSelect : null, pageSize : CTB.init.itemPerPage || 100, selectedSupplierId : -1, readOnly : false, isFromImportDatabase : false, instructionText : '', setSelectedSupplierId : function(selectedSupplierId){ this.selectedSupplierId = selectedSupplierId; }, listeners : { scope : this, 'beforehide' : function(theThis){ }, 'beforeshow' : function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); }, 'show' : function(theThis){ theThis.loadData(); } }, initComponent : function(){ var theThis = this; theThis.tpl_Instruction = new Ext.XTemplate( '', '', '' ); theThis.pnl_Instruction = new Ext.Panel({ //frame : true, region : 'north', height : 70, tpl : theThis.tpl_Instruction, listeners : { afterrender : function(p_This){ if (theThis.instructionText != '') { p_This.setVisible(true); p_This.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); } else { p_This.setVisible(false); } } } }); // MAIN GRID theThis.pnl_Supplier = new Ext.CTBSupplierBrowserGrid({ region : 'center', readOnly : theThis.readOnly, isFromImportDatabase : theThis.isFromImportDatabase }); theThis.items = [ theThis.pnl_Instruction, theThis.pnl_Supplier ]; // BUTTONS var myButtons = theThis.readOnly == false ? theThis.initButtons() : theThis.initReadOnlyButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBSupplierBrowser.superclass.initComponent.call(this); }, loadData: function(){ var theThis = this; theThis.pnl_Supplier.outletId = theThis.outletId; theThis.pnl_Supplier.loadData(); }, initButtons : function(){ var theThis = this; var buttons = [ /*theThis.btn_Select = new Ext.Button({ text: 'Select', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ var selectedRecords = theThis.pnl_Supplier.getGrid_Supplier().getSelectionModel().getSelections(); if (selectedRecords.length > 0) { if (theThis.callback_AfterSelect != null) { theThis.callback_AfterSelect(selectedRecords); } } else { showErrorNotification('Notice', 'Please select at least one supplier.'); } } }),*/ theThis.btn_Save = new Ext.Button({ text: 'Save', hidden : true, iconCls : 'icon-save-large', scale : 'large', handler : function(){ // Get modified records theThis.pnl_Supplier.getGrid_Supplier().stopEditing(); var modifiedRecords = theThis.pnl_Supplier.getModifiedRecords(); var jsonArray = new Array(); for (var i = 0, row; row = modifiedRecords[i]; i++) { jsonArray[i] = { supplierDetailId : modifiedRecords[i].data.supplierDetailId, recipeId : modifiedRecords[i].data.recipeId, recipeName : modifiedRecords[i].data.recipeName, numberItemSold : modifiedRecords[i].data.numberItemSold, itemFoodCost : modifiedRecords[i].data.itemFoodCost, itemKitchenRevenue : modifiedRecords[i].data.itemKitchenRevenue, isActive : modifiedRecords[i].data.isActive }; } var listOfSupplierDetails = { supplierId : theThis.selectedSupplierId, supplierDescription : 'Description', isActive : true, listOfSupplierDetails : jsonArray }; var jsonObject = Ext.util.JSON.encode(listOfSupplierDetails); // Calling saving request theThis.pnl_Supplier.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Supplier/SaveSupplier', params: { supplierData : jsonObject }, success : function(result, request) { theThis.pnl_Supplier.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.pnl_Supplier.getGrid_Supplier().getStore().commitChanges(); showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.hide(); if (theThis.callback_AfterSave != null) theThis.callback_AfterSave(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.pnl_Supplier.loadMask.hide(); } }); } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } }) ]; return buttons; }, initReadOnlyButtons : function(){ var theThis = this; var dlg_ImportingStock = new Ext.CTBImportingStock({ }); var buttons = [ theThis.btn_ShowImportStocks = new Ext.Button({ text: 'Show Importing Stocks', iconCls : 'icon-troyley', scale : 'large', handler : function(){ var selectedRecords = theThis.pnl_Supplier.getGrid_Supplier().getSelectionModel().getSelections(); if (selectedRecords.length > 0){ dlg_ImportingStock.Global_SupplierDetailRecord = selectedRecords[0]; dlg_ImportingStock.Global_StockBrowser_AssignedSupplierId = selectedRecords[0].data.supplierId; dlg_ImportingStock.show(); } else { showErrorNotification('Notice', 'Please choose a supplier to show stocks'); } } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } }) ]; return buttons; } }); Ext.reg('CTBSupplierBrowser', Ext.CTBSupplierBrowser); Ext.CTBImportingStock = Ext.extend(Ext.Window, { title: 'Importing Stocks', layout: 'border', closeAction: 'hide', iconCls : 'icon-stock', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, //maximized : true, width:800, height:500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, callback_ImportClick : null, Global_StockBrowser_SelectedStockSupplierId : -1, // Nothing has been choosed Global_StockBrowser_AssignedSupplierId : -1, Global_SupplierDetailRecord : null, // This is a record that contains the supplier detail data Global_StockBrowser_SelectedRecords : null, Global_StockBrowser_PageSize : CTB.init.itemPerPage || 100, Global_StockBrowser_SelectedStockId : -1, // This is use for all stock tab Global_StockBrowser_Callback_AfterShow : null, HideSupplierBy : false, HideColumn_StockCode : true, HideColumn_SupplierStockCode : false, HideColumn_ParLevel : true, HideColumn_GST : true, HideColumn_Nutrition : true, HideColumn_Report : true, isFromImportDatabase : true, listeners : { scope : this, 'beforehide' : function(theThis){ theThis.Global_StockBrowser_AssignedSupplierId = -1; }, 'beforeshow' : function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); theThis.clearSelections(); }, 'show' : function(theThis){ if (theThis.Global_StockBrowser_AssignedSupplierId != -1){ theThis.tab_StockBySuppliers.cmbSupplier.setValue(theThis.Global_StockBrowser_AssignedSupplierId); theThis.tab_StockBySuppliers.cmbSupplier.disable(); theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getStore().baseParams = {supplierId : theThis.Global_StockBrowser_AssignedSupplierId, start : 0, limit : theThis.Global_StockBrowser_PageSize, isFromImportDatabase : theThis.isFromImportDatabase}; theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getStore().load(); } else { theThis.tab_StockBySuppliers.cmbSupplier.enable(); theThis.tab_StockBySuppliers.cmbSupplier.setValue(theThis.tab_StockBySuppliers.cmbSupplier.getStore().getAt(0).get('supId')); theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getStore().baseParams = {supplierId : theThis.tab_StockBySuppliers.cmbSupplier.getValue(), start: 0, limit : theThis.Global_StockBrowser_PageSize, isFromImportDatabase : theThis.isFromImportDatabase}; theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getStore().load(); } if (theThis.Global_StockBrowser_Callback_AfterShow != null) { theThis.Global_StockBrowser_Callback_AfterShow(); theThis.Global_StockBrowser_Callback_AfterShow = null; } } }, initComponent : function(){ var theThis = this; // Init buttons var myButtons = theThis.initButtons(); theThis.tab_StockBySuppliers = new Ext.CTBStockBySuppliers({ region : 'center', Global_StockBrowser_Parent : theThis, Global_StockBrowser_PageSize : theThis.Global_StockBrowser_PageSize, HideColumn_StockCode : theThis.HideColumn_StockCode, HideColumn_SupplierStockCode : theThis.HideColumn_SupplierStockCode, HideColumn_ParLevel : theThis.HideColumn_ParLevel, HideColumn_GST : theThis.HideColumn_GST, HideColumn_Nutrition : theThis.HideColumn_Nutrition, HideColumn_Report : theThis.HideColumn_Report, isFromImportDatabase : true }); // All tabs /*theThis.allTabs = new Ext.TabPanel({ region:'center', margins : '5 0 0 0', activeTab: 0, defaults:{autoScroll: false}, items:[ theThis.tab_StockBySuppliers, theThis.tab_ListOfDistinctStock ] });*/ theThis.items = [theThis.tab_StockBySuppliers]; this.buttons = myButtons; this.initTools(); Ext.Window.superclass.initComponent.call(this); this.addEvents( 'resize', 'maximize', 'minimize', 'restore' ); if(Ext.isDefined(this.initHidden)){ this.hidden = this.initHidden; } if(this.hidden === false){ this.hidden = true; this.show(); } }, clearSelections : function(){ var theThis = this; if (theThis.tab_StockBySuppliers.rendered) theThis.tab_StockBySuppliers.clearSelections(); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_Select = new Ext.Button({ text: 'Import', iconCls : 'icon-troyley', scale : 'large', handler : function(){ theThis.importSupplierDetail(); } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } }) ]; return buttons; }, importSupplierDetail: function(){ var theThis = this; var selectedStocks = theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getSelectionModel().getSelections(); if (selectedStocks.length == 0) { showErrorNotification('Notice', 'Please choose stocks to import'); return; } // Wrap the supplier detail inside a transfer object var addressTO = { addressPostcode : theThis.Global_SupplierDetailRecord.data.address.addressPostCode,//Ext.getCmp('txt_ExcelImportData_TopDetail_Postcode').getValue(), addressStreet : theThis.Global_SupplierDetailRecord.data.address.addressStreet, addressSuburb : theThis.Global_SupplierDetailRecord.data.address.addressSuburb, stateName : theThis.Global_SupplierDetailRecord.data.address.stateName }; var contactTO = { contactFirstName : theThis.Global_SupplierDetailRecord.data.contact.contactFirstName, contactLastName : theThis.Global_SupplierDetailRecord.data.contact.contactLastName, email : theThis.Global_SupplierDetailRecord.data.contact.email, faxNo : theThis.Global_SupplierDetailRecord.data.contact.faxNo, notes : theThis.Global_SupplierDetailRecord.data.contact.notes, phone2 : theThis.Global_SupplierDetailRecord.data.contact.phone2, phone3 : theThis.Global_SupplierDetailRecord.data.contact.phone3, phoneNo : theThis.Global_SupplierDetailRecord.data.contact.phoneNo, website : theThis.Global_SupplierDetailRecord.data.contact.website }; var supplierTO = { abnNo : theThis.Global_SupplierDetailRecord.data.abnNo, accountNo : theThis.Global_SupplierDetailRecord.data.accountNo, paymentTerm : theThis.Global_SupplierDetailRecord.data.paymentTerm, supplierName : theThis.Global_SupplierDetailRecord.data.supplierName, website : theThis.Global_SupplierDetailRecord.data.website, supplierAddress : addressTO, primaryContact : contactTO }; var importedSupplierData = Ext.util.JSON.encode(supplierTO); var importingSupplierLoadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Saving supplier information ..."}); importingSupplierLoadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/ExcelImport/ImportSupplier', params: { importedSupplierData : importedSupplierData }, success : function(result, request) { importingSupplierLoadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.importStockData(jsonData.newSupplierId); } else { if (jsonData.newSupplierId != -1){ showConfirmMessage(jsonData.message.Info + ' Do you want to merge with the current data ?', function(){ theThis.importStockData(jsonData.newSupplierId); }) }else { showErrorMessageWithEmailNotify(jsonData.message.Info); } } }, failure : function(result, request) { importingSupplierLoadMask.hide(); } }); // End ajax }, importStockData : function(newSupplierId) { var theThis = this; var importingStockLoadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Importing stocks ..."}); var selectedStocks = theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getSelectionModel().getSelections(); if (selectedStocks.length == 0) { showErrorNotification('Notice', 'Please choose stocks to import'); return; } else { // Wrap up data into object var jsonArray = new Array(); for (var i = 0; i < selectedStocks.length; i++) { jsonArray[i] = { stockSupplierId : -1, supplierStockCode : selectedStocks[i].data.supplierStockCode, supplierCost : selectedStocks[i].data.supplierCost, supplierId : newSupplierId, stockId : -1, stockCode : selectedStocks[i].data.supplierStockCode, stockDesc : selectedStocks[i].data.stockDesc, stockUnit : selectedStocks[i].data.stockUnit, unitOfMeasurementId : selectedStocks[i].data.unitOfMeasurementId, stockCategoryId : -1, stockCategoryName : selectedStocks[i].data.stockCategoryName, stockWastage : selectedStocks[i].data.stockWastage, stockParLevel : selectedStocks[i].data.stockParLevel, isGstApplied : selectedStocks[i].data.isGstApplied, isNutritionLinked : false, isDisplayedOnReport : selectedStocks[i].data.isDisplayedOnReport, isActive : true }; } var listOfStockSuppliers = {listOfStockSuppliers : jsonArray}; var jsonObject = Ext.util.JSON.encode(listOfStockSuppliers); // Submit data importingStockLoadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/StockSupplier/SaveStockSuppliers', params: { jsonData : jsonObject }, success : function(result, request) { importingStockLoadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.hide(); if (jsonData.data.numOfTransactionLogs > 0) { showTransactionLogMessageBox('Problem', 'There are some changes has been automatically apply to this process due to duplicated code.
Please watch the log report to see more details.', jsonData.data.transactionUniqueCode ); } else { showSuccessNotification("Import stocks from online server successfully!", NOTIFICATION.ICON_INFORMATION); } } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { importingStockLoadMask.hide(); } }); } // End else } // End importStockData function }); Ext.reg('CTBImportingStock', Ext.CTBImportingStock); Ext.CTBSupplierPantryListGrid = Ext.extend(Ext.Panel, { layout : 'card', loadMask: null, pageSize: CTB.init.itemPerPage || 100, activeItem : 0, supplierId : -1, showAllProducts : false, parentWindowContainer : null, listeners : { afterrender : function(p_This){ // Init loadMask p_This.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); } }, initComponent: function(){ var theThis = this; theThis.grid_PantryLists = theThis.generateGrid_PantryLists(); theThis.grid_CopyingStocks = theThis.generateGrid_CopyingStocks(); theThis.pnl_CopyingStocks = new Ext.Panel({ layout : 'border', items : [ theThis.pnl_CopyingStocks_Header = new Ext.Panel({ frame : true, region : 'north', height : 100, html : '
Please check if anything is wrong with the stock unit(red column) and stock measurement(green column).
The stock unit and stock measurement are calculated from "Item Size" figure automatically. The process might not be 100% correct. You can also select the stock category here.
' }), theThis.grid_CopyingStocks ] }) theThis.items = [theThis.grid_PantryLists, theThis.pnl_CopyingStocks]; // Call super class to initialize componenets Ext.CTBSupplierPantryListGrid.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid_PantryLists().getSelectionModel().clearSelections(); }, getGrid_PantryLists: function(){ var theThis = this; return theThis.grid_PantryLists; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_PantryList; }, getSelectedStocks: function(){ var theThis = this; return theThis.grid_PantryLists.getSelectionModel().getSelections(); }, loadData : function(searchType, keyword){ var theThis = this; theThis.grid_PantryLists.getStore().commitChanges(); Ext.apply(theThis.grid_PantryLists.getStore().baseParams, { supplierId: theThis.supplierId, start : 0, limit : theThis.pageSize, searchType : searchType, keyword : keyword, getAllProductsInSite : theThis.showAllProducts }); theThis.grid_PantryLists.getStore().load(); }, refreshData : function(){ var theThis = this; theThis.loadData(-1, ''); }, generateGrid_PantryLists: function(){ var theThis = this; var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.Global_PantryListRecord = Ext.data.Record.create([ { name: 'supplierStockCode', type: 'string' }, { name: 'supplierCost', type: 'number' }, { name: 'supplierId', type: 'number' }, { name: 'supplierName', type: 'string' }, { name: 'stockDesc', type: 'string' }, { name: 'stockUnit', type: 'string' }, { name: 'unitOfMeasurementName', type: 'string' }, { name: 'processedStockUnit', type: 'number' }, { name: 'processedUOMId', type: 'number' }, { name: 'processedStockCategoryId', type: 'number' }, { name: 'itemSize', type: 'string' }, { name: 'isGSTApplied', type: 'boolean' }, { name: 'unitSale', type: 'boolean' }, { name: 'outOfStock', type: 'boolean' }, { name: 'unitAvailable', type: 'number' }, { name: 'isActive', type: 'boolean' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** var store = new Ext.data.JsonStore({ baseParams : {supplierId: theThis.supplierId, start : 0, limit : theThis.pageSize}, proxy: new Ext.data.HttpProxy( new Ext.data.Connection({ url: '/StockSupplier/GetPantryListFromSupplier', dataType: 'json', method: 'POST', timeout: 1800000 }) ), fields: theThis.Global_PantryListRecord, root: 'data', idProperty: 'supplierStockCode', totalProperty : 'totalCount', listeners : { 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var hinderSelection = false; var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment }, beforerowselect: function(o, rowIndex, keepExisting, record) { if(hinderSelection) { hinderSelection = false; return false; } } } }); // *************************************************************************************************** // Grid // *************************************************************************************************** // Column Models var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'Code', dataIndex: 'supplierStockCode', width: 25}, { header: 'Description', dataIndex: 'stockDesc', width: 25}, { header: 'Unit Price', dataIndex: 'supplierCost', width: 10, renderer : Ext.util.Format.usMoney }, { header: 'Unit', dataIndex: 'stockUnit', width: 10}, { header: 'Measurement', dataIndex: 'unitOfMeasurementName', width: 10}, { header: 'Item Size', dataIndex: 'itemSize', width: 25}, { header: 'GST Incl', dataIndex: 'isGSTApplied', width: 10, renderer : function(val){ if (val == true) return "YES"; else return "NO"; } }, { header: 'On Sale', dataIndex: 'unitSale', width: 10, renderer : function(val){ if (val == true) return "YES"; else return "NO"; } }, { header: 'Out of Stock', dataIndex: 'outOfStock', width: 10, renderer : function(val){ if (val == true) return 'YES'; else return 'NO'; } }, { header: 'Unit Avail', dataIndex: 'unitAvailable', width: 10 } ] }); // End cm // Searching combobox var data_SearchType = [ ['By stock description', 1], ['By stock code' , 2] ]; theThis.cmb_Search = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ], data : data_SearchType }), displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, editable: false, triggerAction: 'all', lazyRender: true, width : 200, mode: 'local', emptyText: 'Choose search by ...' }); theThis.cmb_Search.setValue(1); // Paging toolbar theThis.pt_PantryList = new Ext.CTBPagingToolbar({ store: store, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No items to display" }); // Grid var grid_PantryLists = new Ext.grid.EditorGridPanel({ region: 'center', store: store, cm : cm, sm : sm, frame: true, buttonAlign : 'left', listeners : { rowmousedown: function() { hinderSelection = true; }, rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, beforeshow : function(p_This){ }, afterrender : function(p_This){ //theThis.grid_PantryLists.getStore().load(); } }, tbar: [ theThis.btn_ShowAll = new Ext.Button({ text: 'Show All', tooltip : 'Get all the Items belonging to the your assign Site.', iconCls: 'icon-update-large', scale : 'large', handler: function (button, event) { theThis.btn_ShowOnlyPantryList.setVisible(true); theThis.btn_ShowAll.setVisible(false); theThis.showAllProducts = true; theThis.refreshData(); } }), theThis.btn_ShowOnlyPantryList = new Ext.Button({ text: 'Show Pantry List', tooltip : 'Get Items only from your Pantry List.', hidden : true, iconCls: 'icon-update-large', scale : 'large', handler: function (button, event) { theThis.btn_ShowOnlyPantryList.setVisible(false); theThis.btn_ShowAll.setVisible(true); theThis.showAllProducts = false; theThis.refreshData(); } }), '-', theThis.btn_Refresh = new Ext.Button({ text: 'Refresh', iconCls: 'icon-refresh-large', scale : 'large', handler: function (button, event) { theThis.refreshData(); } }), '-', theThis.txt_SearchValue = new Ext.form.TextField({ emptyText : 'Search value ...', listeners: { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_Search.handler.call(theThis.btn_Search.scope); } } } }), theThis.cmb_Search, theThis.btn_Search = new Ext.Button({ xtype : 'button', iconCls : 'icon-search-large', scale : 'large', text : 'Search', handler : function(){ var searchValue = theThis.txt_SearchValue.getValue(); var searchType = theThis.cmb_Search.getValue(); if (searchType == "") { showErrorNotification('Notice', 'Please choose a search type !'); } else { theThis.loadData(searchType, searchValue); } } }) ], autoHeight: false, clicksToEdit: 1, loadMask: true, bbar: theThis.pt_PantryList, viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return grid_PantryLists; }, // End generateGrid_PantryLists generateGrid_CopyingStocks: function(){ var theThis = this; var fm = Ext.form; // *************************************************************************************************** // Stores // *************************************************************************************************** var store = new Ext.data.JsonStore({ baseParams : {supplierId: theThis.supplierId, start : 0, limit : theThis.pageSize}, proxy: new Ext.data.HttpProxy( new Ext.data.Connection({ url: '/StockSupplier/GetPantryListFromSupplier', dataType: 'json', method: 'POST', timeout: 1800000 }) ), fields: theThis.Global_PantryListRecord, root: 'data', idProperty: 'supplierStockCode', totalProperty : 'totalCount', listeners : { 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var hinderSelection = false; var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment }, beforerowselect: function(o, rowIndex, keepExisting, record) { if(hinderSelection) { hinderSelection = false; return false; } } } }); // *************************************************************************************************** // Grid // *************************************************************************************************** var cmbGridUOM = theThis.getCombobox_UnitOfMeasurement(); var cmbGridStockCategory = theThis.getCombobox_StockCategory(); // Column Models var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ //sm, { header: 'Code', dataIndex: 'supplierStockCode', width: 15}, { header: 'Description', dataIndex: 'stockDesc', width: 25}, { header: 'Unit Price', dataIndex: 'supplierCost', width: 10, renderer : Ext.util.Format.usMoney }, { header: '
Unit
', dataIndex: 'processedStockUnit', width: 10, renderer : function(val){ return String.format('
{0}
', val); }, editor: { xtype: 'numberfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } } }, { header: '
Measurement
', dataIndex: 'processedUOMId', width: 10, renderer : function(val){ var strVal = cmbGridUOM.getStore().getById(val).data.UOMName; return String.format('
{0}
', strVal); }, editor: cmbGridUOM }, { header: 'Item Size', dataIndex: 'itemSize', width: 15}, { header: 'Category', dataIndex: 'processedStockCategoryId', width: 10, editor: cmbGridStockCategory, renderer: Ext.util.Format.comboRenderer(cmbGridStockCategory) }, { header: 'GST Incl', dataIndex: 'isGSTApplied', width: 10, renderer : function(val){ if (val == true) return "YES"; else return "NO"; } } ] }); // End cm // Grid var grid_CopyingStocks = new Ext.grid.EditorGridPanel({ region: 'center', store: store, cm : cm, sm : sm, frame: true, buttonAlign : 'left', listeners : { rowmousedown: function() { hinderSelection = true; }, rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, beforeshow : function(p_This){ }, afterrender : function(p_This){ //theThis.grid_PantryLists.getStore().load(); } }, tbar: [ theThis.btn_CopyingStocks_Clear = new Ext.Button({ text: 'Clear', iconCls: 'icon-clear', scale : 'large', handler: function (button, event) { theThis.clearCopyingStocksRecords(); } }), theThis.btn_CopyingStocks_Clear = new Ext.Button({ text: 'Back to Add More', iconCls: 'icon-move-left', scale : 'large', handler: function (button, event) { theThis.getLayout().setActiveItem(theThis.grid_PantryLists); } }) ], autoHeight: false, clicksToEdit: 1, loadMask: true, viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return grid_CopyingStocks; }, // End generateGrid_CopyingStocks addToCopyingStocks : function(selectedStocks){ var theThis = this; for (var i = 0; i < selectedStocks.length; i++){ var theRecord = selectedStocks[i]; // Do not allow add same stocks in second time if (theThis.grid_CopyingStocks.getStore().getById(theRecord.data.supplierStockCode) == null){ //var newId = -getRandomNumber(); // Negative for new entry var aNewRecord = new theThis.Global_PantryListRecord({ supplierStockCode : theRecord.data.supplierStockCode, supplierCost : theRecord.data.supplierCost, supplierId : theRecord.data.supplierId, supplierName : theRecord.data.supplierName, stockDesc : theRecord.data.stockDesc, stockUnit : theRecord.data.stockUnit, unitOfMeasurementName : theRecord.data.unitOfMeasurementName, processedStockUnit : theRecord.data.processedStockUnit, processedUOMId : theRecord.data.processedUOMId, processedStockCategoryId : theRecord.data.processedStockCategoryId, itemSize : theRecord.data.itemSize, isGSTApplied : theRecord.data.isGSTApplied, unitSale : theRecord.data.unitSale, outOfStock : theRecord.data.outOfStock, unitAvailable : theRecord.data.unitAvailable, isActive : theRecord.data.isActive }, theRecord.data.supplierStockCode); theThis.grid_CopyingStocks.stopEditing(); theThis.grid_CopyingStocks.getStore().insert(0, aNewRecord); } } }, clearCopyingStocksRecords : function(){ var theThis = this; theThis.grid_CopyingStocks.getStore().removeAll(); }, getCombobox_UnitOfMeasurement : function(){ var theThis = this; var cmbGridUOM = new Ext.form.ComboBox({ store: Global_UnitOfMeasurement_Store, displayField: 'UOMName', valueField: 'UOMId', typeAhead: true, triggerAction: 'all', editable: false, lazyRender: true, mode: 'local' }); return cmbGridUOM; }, getCombobox_StockCategory : function() { var theThis = this; var store = new Ext.data.Store({ baseParams : {isFromImportDatabase : false}, proxy: new Ext.data.HttpProxy({ url: '/StockCategory/GetAllStockCategories', dataType: 'json', method: 'POST' }), reader: new Ext.data.JsonReader({ fields: [ { name: 'stockCategoryId', type: 'number' }, { name: 'stockCategoryName', type: 'string' }, { name: 'numberOfStocks', type: 'number' } ], root: 'data' }), listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); store.load(); var cmbGridStockCategory = new Ext.form.ComboBox({ store: store, displayField: 'stockCategoryName', valueField: 'stockCategoryId', typeAhead: true, triggerAction: 'all', editable: false, lazyRender: true, mode: 'local' }); return cmbGridStockCategory; }, // End getCombobox_StockCategory importSelectedStocks : function(){ var theThis = this; if (theThis.grid_CopyingStocks.getStore().getCount() == 0){ showErrorNotification('Notice', 'Please select at least one stock to import.'); } else { theThis.loadMask.show(); var listOfSupplierProducts = new Array(); for (var i = 0; i < theThis.grid_CopyingStocks.getStore().getCount(); i++){ var theRecord = theThis.grid_CopyingStocks.getStore().getAt(i); listOfSupplierProducts[i] = { code : theRecord.data.supplierStockCode, unitPrice : theRecord.data.supplierCost, supplierId : theRecord.data.supplierId, description : theRecord.data.stockDesc, unit : theRecord.data.processedStockUnit, measurementId : theRecord.data.processedUOMId, stockCategoryId : theRecord.data.processedStockCategoryId, isGSTApplied : theRecord.data.isGSTApplied, supplierUnitMeasurement : theRecord.data.unitOfMeasurementName, supplierSellingUnit : theRecord.data.stockUnit } } var wrapperObject = { listOfSupplierProducts : listOfSupplierProducts } Ext.Ajax.request({ method: 'POST', url: '/StockSupplier/ImportPantryList', params: { jsonData : Ext.util.JSON.encode(wrapperObject) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); // Commit changes theThis.grid_CopyingStocks.getStore().commitChanges(); theThis.clearCopyingStocksRecords(); if (theThis.callback_AfterImport != null){ theThis.callback_AfterImport(); } if (theThis.parentWindowContainer != null){ theThis.parentWindowContainer.hide(); } } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); } } }); Ext.reg('CTBSupplierPantryListGrid', Ext.CTBSupplierPantryListGrid); Ext.CTBSupplierPantryListWindow = Ext.extend(Ext.Window, { title: 'Pantry List', layout: 'border', closeAction: 'hide', iconCls : 'icon-stock', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, width:800, height:500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, supplierId : -1, callback_AfterImport : null, setSupplierId : function(supplierId){ var theThis = this; theThis.supplierId = supplierId; theThis.pnl_PantryLists.supplierId = supplierId; }, callback_Select : null, getSelectedStockItems: function(){ var theThis = this; return theThis.pnl_PantryLists.getSelectedStockItems(); }, pageSize : CTB.init.itemPerPage || 100, listeners : { scope : this, 'beforehide' : function(theThis){ }, 'beforeshow' : function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); theThis.pnl_PantryLists.getLayout().setActiveItem(theThis.pnl_PantryLists.grid_PantryLists); theThis.pnl_PantryLists.clearCopyingStocksRecords(); theThis.clearSelections(); }, 'show' : function(theThis){ theThis.pnl_PantryLists.loadData(); } }, initComponent : function(){ var theThis = this; // MAIN GRID theThis.pnl_PantryLists = new Ext.CTBSupplierPantryListGrid({ region : 'center', callback_AfterImport : theThis.callback_AfterImport, parentWindowContainer : theThis }); theThis.items = [theThis.pnl_PantryLists]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBSupplierPantryListWindow.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; if (theThis.pnl_PantryLists.rendered) theThis.pnl_PantryLists.clearSelections(); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_Select = new Ext.Button({ text: 'Copy to your Stock List', iconCls : 'icon-ok-large', scale : 'large', tooltip : 'Copy all selected items to your stock list.', handler : function(){ if (theThis.pnl_PantryLists.getLayout().activeItem == theThis.pnl_PantryLists.grid_PantryLists){ theThis.pnl_PantryLists.addToCopyingStocks(theThis.pnl_PantryLists.getSelectedStocks()); theThis.pnl_PantryLists.getLayout().setActiveItem(theThis.pnl_PantryLists.pnl_CopyingStocks); } else { theThis.pnl_PantryLists.importSelectedStocks(); } if (theThis.callback_Select != null) { theThis.callback_Select(theThis.getSelectedStockItems()); theThis.hide(); } } }), /*theThis.btn_SelectAndMoveToNextPage = new Ext.Button({ text: 'Copy to your Stock List and add to Order', tooltip : 'Copy all selected items to your stock list and automatically create an stock order that populated by the selected items.', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ if (theThis.callback_Select != null) { theThis.callback_Select(theThis.getSelectedStockItems()); theThis.hide(); } } }),*/ theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } }) ]; return buttons; } }); Ext.reg('CTBSupplierPantryListWindow', Ext.CTBSupplierPantryListWindow); Ext.CTBAlternativeProductsWindow = Ext.extend(Ext.Window, { title: 'Alternative Products', layout: 'border', closeAction: 'hide', iconCls: 'icon-stock', expandOnShow: true, closable: true, resizable: true, modal: true, plain: true, minimizable: true, maximizable: true, monitorResize: true, width: 800, height: 500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, pageSize: CTB.init.itemPerPage || 100, recordData : null, stockOrderId : -1, listeners: { scope : this, 'beforehide': function(theThis){ }, 'beforeshow': function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 85); }, 'show': function(theThis){ if (theThis.recordData != null){ if (theThis.pnl_MainPanel.rendered){ theThis.pnl_MainPanel.update(theThis.recordData); } else { theThis.pnl_MainPanel.callback_AfterRender = function(){ theThis.pnl_MainPanel.update(theThis.recordData); } } } } }, initComponent : function(){ var theThis = this; theThis.initTemplate(); theThis.items = [ new Ext.Panel({ html : '' + '' + '' + '' + '
' + 'Please select alternative products' + '
', region : 'north', height : 50, frame : false }), theThis.pnl_MainPanel = new Ext.Panel ({ region : 'center', autoScroll : true, listeners : { afterrender : function(p_This){ theThis.loadMask = new Ext.LoadMask(p_This.getEl(), {msg:"Please wait..."}); if (p_This.callback_AfterRender != null){ p_This.callback_AfterRender(); } } }, tpl : theThis.tpl_AlternativeProductSelection }) ]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBAlternativeProductsWindow.superclass.initComponent.call(this); }, setData : function(recordData){ var theThis = this; theThis.recordData = recordData; for (var i = 0; i < theThis.recordData.length; i++){ for (var j = 0; j < theThis.recordData[i].alternativeProducts.length; j++){ theThis.recordData[i].alternativeProducts[j].thisId = theThis.id; theThis.recordData[i].alternativeProducts[j].mainProductId = theThis.recordData[i].productId; } } }, initTemplate : function(){ var theThis = this; theThis.tpl_AlternativeProductSelection = new Ext.XTemplate( '', '', '', '', '', '', '', '', '', '', '', '', '
', '{stockDesc} ({stockUnit} {stockUnitOfMeasurementName})', '', '{ProductName}', '', '{ProductType}', '', '${UnitPrice}', '
', '
', '
' ); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_Cancel = new Ext.Button({ text: 'Submit', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ var selections = theThis.getSelections(); if (selections.length == theThis.recordData.length){ theThis.checkExistingProductsInDatabase(selections); } } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } }) ]; return buttons; }, getSelections : function(){ var theThis = this; var selectedCount = 0; var selections = new Array(); for (var i = 0; i < theThis.recordData.length; i++){ var btns = Ext.select('input[name="' + String.format('rd_Name_{0}_{1}', theThis.id, theThis.recordData[i].productId) + '"]').elements; var isSelected = false; for( var j = 0; j < btns.length; j++ ){ if( btns[j].checked ) { isSelected = true; selections[selectedCount] = btns[j].value; selectedCount++; } } if (!isSelected){ showErrorNotification('Notice', String.format('Please select alternative product for {0}', theThis.recordData[i].stockDesc)); } } return selections; }, getSelectionInPairs : function(){ var theThis = this; var selectedCount = 0; var selections = new Array(); for (var i = 0; i < theThis.recordData.length; i++){ var btns = Ext.select('input[name="' + String.format('rd_Name_{0}_{1}', theThis.id, theThis.recordData[i].productId) + '"]').elements; var isSelected = false; for( var j = 0; j < btns.length; j++ ){ if( btns[j].checked ) { isSelected = true; selections[selectedCount] = { oldValue : theThis.recordData[i].productId, newValue : btns[j].value } selectedCount++; } } if (!isSelected){ showErrorNotification('Notice', String.format('Please select alternative product for {0}', theThis.recordData[i].stockDesc)); } } return selections; }, checkExistingProductsInDatabase : function(productIds){ var theThis = this; theThis.loadMask.show(); Ext.Ajax.request({ method: "POST", url: '/StockSupplier/CheckExistingProductsInDatabase', params: { supplierId : theThis.recordData[0].supplierId, // Get the supplier id from the first record productIds : Ext.util.JSON.encode(productIds) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { //showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); if (jsonData.data != null){ var isFalse = false; // Flag to indicate is there any stock that doesn't exist in the database var message = ""; var importingProducts = new Array(); for (var i = 0; i < jsonData.data.length; i++){ if (jsonData.data[i].existed == false){ isFalse = true; // Get the description var stockRecord = theThis.getStockRecordFromProductID(jsonData.data[i].supplierStockCode); importingProducts[importingProducts.length] = stockRecord; message += String.format("Product '{0}' is not in your database
", stockRecord.ProductName); } } // This function will replace current record in the stock order with the new alternative ones function replaceStockOrderDetails(){ var listOfReplacementProducts = theThis.getSelectionInPairs(); var oldSupplierStockCodes = new Array(); var newSupplierStockCodes = new Array(); for (var i = 0; i < listOfReplacementProducts.length; i++){ oldSupplierStockCodes[i] = listOfReplacementProducts[i].oldValue; newSupplierStockCodes[i] = listOfReplacementProducts[i].newValue; } theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/StockOrder/ReplaceStockOrderDetails', params: { stockOrderId : theThis.stockOrderId, oldSupplierStockCodes : Ext.util.JSON.encode(oldSupplierStockCodes), newSupplierStockCodes : Ext.util.JSON.encode(newSupplierStockCodes) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.hide(); if (theThis.callback_AfterSubmit != null) theThis.callback_AfterSubmit(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); } if (isFalse){ // Show confirmation message showConfirmMessage(message + 'Do you want to import the product(s) to your database ?', function(){ theThis.importProductsToDatabase(importingProducts, function(){ replaceStockOrderDetails(); }); }, function(){ } ) } else { replaceStockOrderDetails(); } } } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax }, getStockRecordFromProductID : function(productID){ var theThis = this; var stockRecord = null; for (var i = 0; i < theThis.recordData.length; i++){ var isBreak = false; for (var j = 0; j < theThis.recordData[i].alternativeProducts.length; j++){ if (theThis.recordData[i].alternativeProducts[j].ProductID == productID){ stockRecord = theThis.recordData[i].alternativeProducts[j]; isBreak = true; break; } } if (isBreak) break; } return stockRecord; }, importProductsToDatabase : function(importingProducts, callbackFunction){ var theThis = this; var listOfSupplierProducts = new Array(); for (var i = 0; i < importingProducts.length; i++){ var theRecord = importingProducts[i]; listOfSupplierProducts[i] = { code : theRecord.ProductID, unitPrice : theRecord.UnitPrice, supplierId : theThis.recordData[0].supplierId, description : theRecord.ProductName, unit : 1, //theRecord.data.processedStockUnit, measurementId : 7, //theRecord.data.processedUOMId, stockCategoryId : 0, //theRecord.data.processedStockCategoryId, isGSTApplied : false, supplierUnitMeasurement : theRecord.UOM, supplierSellingUnit : 1 } } var wrapperObject = { listOfSupplierProducts : listOfSupplierProducts } theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/StockSupplier/ImportPantryList', params: { jsonData : Ext.util.JSON.encode(wrapperObject) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { if (callbackFunction != null) callbackFunction(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); } }); Ext.reg('CTBAlternativeProductsWindow', Ext.CTBAlternativeProductsWindow); Ext.CTBStockQuickKey = Ext.extend(Ext.Window, { title : 'Quick Add', closeAction : 'hide', layout : 'border', width : 270, height : 150, modal : true, getSelectedStockItems: function(){ var theThis = this; return theThis.grid_InvoiceDetail.getSelectedStockItems(); }, listeners : { show : function(theThis){ theThis.txt_QuickKey_StockCode.focus(); } }, initComponent : function(){ var theThis = this; theThis.items = [ new Ext.form.FormPanel({ region : 'center', frame : true, items : [ theThis.txt_QuickKey_StockCode = new Ext.form.TextField({ //allowBlank: false, emptyText : 'Supplier\'s stock code', fieldLabel : 'Stock code', width : 120, listeners : { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_QuickKey_Add.handler.call(theThis.btn_QuickKey_Add.scope); theThis.txt_QuickKey_StockCode.focus(); } } }, onFocus: function (txt, e) { this.getEl().dom.select(); } }), theThis.txt_QuickKey_Quantity = new Ext.form.NumberField({ //allowBlank: false, allowNegative: false, emptyText : 'Quantity', fieldLabel : 'Quantity', width : 50, minValue : 0, value : 0, allowDecimals : true, decimalPrecision: 3, listeners : { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_QuickKey_Add.handler.call(theThis.btn_QuickKey_Add.scope); theThis.txt_QuickKey_StockCode.focus(); } } }, onFocus: function (txt, e) { this.getEl().dom.select(); } }) ] }) ]; // BUTTONS this.buttons = [ { xtype : 'button', scale : 'large', iconCls : 'icon-add', text : 'Add', listeners : { afterrender : function(p_This){ theThis.btn_QuickKey_Add = p_This; } }, handler : function(){ if (theThis.validateBeforeSave()){ if (theThis.callback_QuickAdd != null) { theThis.callback_QuickAdd(theThis.txt_QuickKey_StockCode.getValue(), theThis.txt_QuickKey_Quantity.getValue()); theThis.txt_QuickKey_StockCode.focus(); } } } }, { xtype : 'button', scale : 'large', iconCls : 'icon-cancel-large', text : 'Close', handler : function(){ theThis.hide(); } } ]; Ext.CTBStockQuickKey.superclass.initComponent.call(this); }, validateBeforeSave : function() { var theThis = this; var validateFields = new Array(); validateFields[0] = { ID : theThis.txt_QuickKey_StockCode.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.EMPTY }; validateFields[1] = { ID : theThis.txt_QuickKey_Quantity.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.NUMBER }; // Call global validate field group return validateFieldGroup(validateFields); } }); Ext.reg('CTBStockQuickKey', Ext.CTBStockQuickKey); var Tree = Ext.tree; Ext.CTBRecipeTreePanel = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, selectedRecipeId : -1, regionId : -1, isAutoLoad : true, isFirstRun : false, ddGroup : null, callback_AfterClickReload: null, callback_AfterCreatNewRecipe: null, callback_RecipeClick: null, callback_TreeEditorComplete: null, callback_AfterImportToPersonalRecipeBook : null, callback_AfterRender : null, callback_FinishImport : null, RecipeBookController: '/RecipeBook', RecipeDetailController: '/RecipeDetail', RecipeFolderController: '/RecipeFolder', HideImportRecipeButton : false, HideExportRecipeButton : true, ShowCheckboxSelection : false, HideProcessPendingRecipesButton : true, Hide_Tooltip : false, HideRecipeInputWizard_CategoryStep : true, HideWhatsNextButton : false, dlg_ApprovingRecipes : null, isShowRecipeInputWizard : false, showAddFolderButtonInReadOnlyMode : false, searchRecipeName : '', recipeStatus : null, initialCommand : null, readOnly : false, outletId : -1, // Not belong to this outlet belongToOutletId : -1, // Belong to this outlet setHandyHelper : function(tooltip){ var theThis = this; if (theThis.readOnly && theThis.btn_HandyHelper.tt_HandyHelper != null){ //theThis.btn_HandyHelper.tt_HandyHelper.tpl.overwrite(theThis.btn_HandyHelper.tt_HandyHelper.body, {handyHints : tooltip}); theThis.btn_HandyHelper.tt_HandyHelper.update({handyHints : tooltip}); theThis.btn_HandyHelper.tt_HandyHelper.show(); } }, listeners : { afterrender : function(p_This){ // Init loadMask p_This.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); if (this.callback_AfterRender != null) this.callback_AfterRender(); } }, /*loadData : function(){ this.recipeTreePanel.loader.load(this.recipeTreePanel.root, function(){}); },*/ loadData : function(){ var theThis = this; theThis.recipeTreePanel.loader.load(theThis.recipeTreePanel.root, function(){}); }, reloadData : function(){ var theThis = this; if (theThis.callback_AfterClickReload != null) theThis.callback_AfterClickReload(); //detailsPanel.disable(); theThis.searchRecipeName = ''; theThis.loadData(); //treePanel.loader.load(treePanel.root, function(){}); }, setSelectedRecipeName: function(recipeName){ if (this.recipeTreePanel.selModel.selNode != null) this.recipeTreePanel.selModel.selNode.setText(recipeName); }, getSelectedRecipes: function(){ return this.recipeTreePanel.getChecked(); }, getSelectedRecipeIdsAndFolderIds: function(callback_Function){ // This is a delay function, it will need to contact server for more information, that's why we need to supply a callback function var theThis = this; var selectedRecipes = theThis.getSelectedRecipes(); var recipeIds = new Array(); var recipeFolderIds = new Array(); for (var i = 0; i < selectedRecipes.length; i++){ var nodeId = getNumberIdFromStringId(selectedRecipes[i].id); var nodeType = getPrefixFromStringId(selectedRecipes[i].id); if (nodeType == 'recipe'){ recipeIds[recipeIds.length] = nodeId; } else if (nodeType == 'folder'){ recipeFolderIds[recipeFolderIds.length] = nodeId; } } var returnObject = { recipeIds : recipeIds, recipeFolderIds : recipeFolderIds }; return returnObject; }, getSelectedRecipeFullRecords: function(callback_Function){ // This is a delay function, it will need to contact server for more information, that's why we need to supply a callback function var theThis = this; var selectedRecipes = theThis.getSelectedRecipes(); var recipeIds = new Array(); var recipeFolderIds = new Array(); for (var i = 0; i < selectedRecipes.length; i++){ var nodeId = getNumberIdFromStringId(selectedRecipes[i].id); var nodeType = getPrefixFromStringId(selectedRecipes[i].id); if (nodeType == 'recipe'){ recipeIds[recipeIds.length] = nodeId; } else if (nodeType == 'folder'){ recipeFolderIds[recipeFolderIds.length] = nodeId; } } theThis.loadMask.show(); Ext.Ajax.request({ method: "POST", url: '/RecipeBook/GetSelectedRecipeFullRecords', params: { recipeIds : Ext.util.JSON.encode(recipeIds), recipeFolderIds : Ext.util.JSON.encode(recipeFolderIds) }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { if (callback_Function != null) { callback_Function(jsonData.data); } } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } theThis.loadMask.hide(); }, failure : function(result, request) { theThis.loadMask.hide(); } }); return this; }, initComponent: function(){ var theThis = this; // Recipe tree panel theThis.recipeTreePanel = theThis.getPanel_RecipeTree(); // Recipe tree editor theThis.recipeTreeEditor = theThis.getTreeEditor(theThis.recipeTreePanel); // Item click handler theThis.recipeTreePanel.on('click', function(n){ var sn = this.selModel.selNode || {}; // selNode is null on initial selection if(n.leaf && n.id != sn.id){ // ignore clicks on folders and currently selected node // We need to assign the data to baseParams because we will need this recipeId later on var recipeId = getNumberIdFromStringId(n.id); if (theThis.callback_RecipeClick != null){ if (theThis.callback_RecipeClick(recipeId) == false){ return false; // if the callback function prevent the changing node // then we dont let user move to the new recipe } } theThis.selectedRecipeId = recipeId; theThis.selectedRecipeFolderId = -1; } else if (n.id != sn.id) { var recipeFolderId = getNumberIdFromStringId(n.id); theThis.selectedRecipeId = -1; theThis.selectedRecipeFolderId = recipeFolderId; } }); // Search panel theThis.pnl_SearchRecipe = new Ext.Panel({ layout : 'table', region : 'north', height : 37, frame : true, layoutConfig : { columns : 1 }, items : [ theThis.txt_SearchRecipe = new Ext.ux.form.CTBSearchField({ width : 320, triggerClass : 'x-form-search-trigger', emtpyText : 'Search recipes...', onTriggerClick : function(e) { theThis.searchRecipeName = theThis.txt_SearchRecipe.getValue(); theThis.loadData(); theThis.txt_SearchRecipe.focus(); }, listeners : { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.txt_SearchRecipe.onTriggerClick(e); } } } }) ] }); this.items = [theThis.pnl_SearchRecipe, theThis.recipeTreePanel]; // Call super class to initialize componenets Ext.CTBRecipeTreePanel.superclass.initComponent.call(this); }, // Return the panel contain the recipe tree getPanel_RecipeTree: function(){ var theThis = this; var treePanel = new Tree.TreePanel({ region: 'center', cls : 'ctb-recipebook-detail-panel', tbar:[ // Add Recipe button theThis.btn_Add_Recipe = new Ext.Button({ text:'New', iconCls:'icon-add', scale : 'large', hidden : theThis.readOnly, handler : function (){ /*if (Ext.util.Cookies.get('isShowRecipeInputWizard') == null){ theThis.isShowRecipeInputWizard = true; } else { theThis.isShowRecipeInputWizard = Ext.util.Cookies.get('isShowRecipeInputWizard'); }*/ if (theThis.isShowRecipeInputWizard == true || theThis.isShowRecipeInputWizard == "true"){ theThis.showRecipeInputWizard(); } else { theThis.loadMask.show(); var newRecipeId = Math.floor(Math.random() * 1000000); var newRecipeName = 'New Recipe'; // Get selection node var sn = treePanel.selModel.selNode || null; // selNode is null on initial selection if (sn == null) sn = treePanel.root.item(0); else { if (sn.leaf) sn = sn.parentNode; else sn.expand(); } // Default = 0 (root folder) var parentFolderId = 0; // Only assign the id if sn is not null after all if (sn != null) { parentFolderId = getNumberIdFromStringId(sn.id) == -1 ? 0 : sn.id; } Ext.Ajax.request({ method: "POST", url: theThis.RecipeBookController + '/CreateNewRecipe', params: { folderId : getNumberIdFromStringId(parentFolderId), recipeName : newRecipeName }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); var node = sn.appendChild(new Ext.tree.TreeNode({ text: newRecipeName, leaf : true, iconCls : 'icon-recipe', id : "recipe;"+jsonData.data.recipeId, allowDrag : false })); treePanel.getSelectionModel().select(node); if (theThis.callback_AfterCreatNewRecipe != null) theThis.callback_AfterCreatNewRecipe(jsonData.data.recipeId); //detailsPanel.enable(); //ingredientFromStockGrid.getStore().baseParams = {recipeId : jsonData.data.recipeId}; //ingredientFromStockGrid.getStore().load(); setTimeout(function(){ theThis.recipeTreeEditor.editNode = node; theThis.recipeTreeEditor.startEdit(node.ui.textNode); }, 10); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } theThis.loadMask.hide(); }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End Ajax }// End If } }), // Add recipe folder button { xtype:'button', text:'Add folder', iconCls:'icon-add-folder-large', scale : 'large', hidden : (theThis.readOnly && !theThis.showAddFolderButtonInReadOnlyMode) ? true : false, handler : function() { theThis.loadMask.show(); var newFolderId = Math.floor(Math.random() * 1000000); var newFolderName = 'New Folder'; // Get selection node var sn = treePanel.selModel.selNode || null; // selNode is null on initial selection if (sn == null) sn = treePanel.root.item(0); else { if (sn.leaf) sn = sn.parentNode; else sn.expand(); } // Default = 0 (root folder) var parentFolderId = 0; // Only assign the id if sn is not null after all if (sn != null) { parentFolderId = getNumberIdFromStringId(sn.id) == -1 ? 0 : sn.id; } Ext.Ajax.request({ method: "POST", url: theThis.RecipeFolderController + '/CreateNewFolder', params: { parentFolderId : getNumberIdFromStringId(parentFolderId), folderName : newFolderName, belongToOutletId : theThis.belongToOutletId }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); var node = sn.appendChild(new Ext.tree.TreeNode({ text: newFolderName, iconCls : 'icon-folder', id : "folder;" + jsonData.data.recipeFolderId, allowDrag : false })); treePanel.getSelectionModel().select(node); setTimeout(function(){ theThis.recipeTreeEditor.editNode = node; theThis.recipeTreeEditor.startEdit(node.ui.textNode); }, 10); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } theThis.loadMask.hide(); }, failure : function(result, request) { theThis.loadMask.hide(); } }); } }, { xtype:'button', text:'Delete', iconCls:'icon-delete', scale : 'large', hidden : theThis.readOnly, handler : function(){ var sn = treePanel.selModel.selNode || null; // selNode is null on initial selection var objectId = sn != null ? getNumberIdFromStringId(sn.id) : -1; var prefix = sn != null ? getPrefixFromStringId(sn.id) : -1; var url = theThis.RecipeFolderController + "/DeleteRecipeFolder"; var msg = "Are you sure you want to delete this folder?
All the recipes inside and subfolders will also be deleted !"; // Check when root folder has been selected or not if (objectId == 0 && prefix == "folder") { // Can not delete the root folder sn = null; } if (sn == null) { Ext.Msg.show({ title:'Notice', msg: 'What did you choose ?', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } else { if (sn.leaf) { url = theThis.RecipeBookController + "/DeleteRecipe"; msg = "Are you sure you want to delete this recipe ?" } else { sn.expand(); } // Comfirming message Ext.Msg.show({ title:'Confirm', msg: msg, buttons: Ext.Msg.OKCANCEL, icon: Ext.MessageBox.WARNING, fn : DeleteNow }); } function DeleteNow(btn, text){ if (btn == "ok"){ theThis.loadMask.show(); Ext.Ajax.request({ method: "POST", url: url, params: { id : objectId }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (theThis.callback_AfterClickReload != null) theThis.callback_AfterClickReload(); var node = sn.removeChild(sn); //detailsPanel.disable(); theThis.loadMask.hide(); }, failure : function(result, request) { theThis.loadMask.hide(); } }); } } } }, { xtype:'button', iconCls:'icon-stop-search', tooltip : 'Reload the recipe tree.', handler : function(){ theThis.reloadData(); } }, '->', theThis.btn_HandyHelper = new Ext.Button({ iconCls : 'icon-help-mask', scale : 'large', text : 'What\'s next ?', hidden : theThis.HideWhatsNextButton == false ? (theThis.Hide_Tooltip == true ? true : !theThis.readOnly) : true, handler : function(p_This){ theThis.btn_HandyHelper.tt_HandyHelper.show(); //setVideoHelp('sUhhwYYtGkE', 'Recipe Book - Video Help'); //showHelpVideo(Global_Help_CurrentVideo_ID, true); }, listeners : { afterrender : function(p_This){ if (!p_This.hidden){ p_This.tt_HandyHelper = new Ext.ToolTip({ target: p_This.id, anchor: 'left', tpl: new Ext.XTemplate( '', '', '{handyHints}', '', '' ), html: 'Click on a recipe that you would like to see more'+ '

Don’t forget all this can be change when you export the recipe to your personal recipe book'+ '

You can personalize every component to reflect your situation '+ '
' }); setTimeout(function(){p_This.tt_HandyHelper.show();}, 200); } } } }) ], bbar : [ theThis.btn_More = new Ext.Button({ iconCls : 'icon-v3-dropdown-more', text : 'More', iconAlign : 'right', handler: function (button, e) { if (theThis.menu_ViewOptions == null) { theThis.menu_ViewOptions = new Ext.menu.Menu({ items: [ theThis.btn_ProcessPendingRecipes = new Ext.menu.Item({ text:'Approve Pending Recipes', hidden : theThis.HideProcessPendingRecipesButton, tooltip : 'Process Pending Recipes requested by other users.', handler : function(){ if (theThis.dlg_ApprovingRecipes == null){ theThis.dlg_ApprovingRecipes = new Ext.CTBApprovingRecipeWindow({ }); } theThis.dlg_ApprovingRecipes.show(); } }), { text:'Reload', tooltip : 'Reload the recipe tree.', handler : function(){ theThis.reloadData(); } }, theThis.btn_SearchRecipes = new Ext.menu.Item({ text:'Search', tooltip : 'Search recipes by their names', handler : function(){ showInputMessage('Please enter the recipe name : ', function(text){ theThis.searchRecipeName = text; theThis.loadData(); } ); } }), theThis.btn_ExportToPersonalRecipeBook = new Ext.menu.Item({ xtype:'button', text:'Export to personal recipe book', iconCls:'icon-export', scale : 'large', hidden : theThis.HideImportRecipeButton, //tooltip : 'Import the selected recipe to your personal recipe book.', listeners : { afterrender : function(p_This){ if (p_This.callback_AfterRender != null) p_This.callback_AfterRender(); } }, handler : function(){ if (theThis.selectedRecipeId != -1) theThis.exportRecipeToPersonalRecipeBook(); else if (theThis.selectedRecipeFolderId != -1) theThis.exportRecipeFolderToPersonalRecipeBook(); } }), { text:'Document manager', hidden : theThis.HideProcessPendingRecipesButton, tooltip : 'Test document manager', colspan : 2, handler : function(){ if (Ext.getCmp('dlg_DocumentManager') == null) { theThis.dlg_DocumentManager = new Ext.CTBDocumentManager({ id : 'dlg_DocumentManager' }); } else theThis.dlg_DocumentManager = Ext.getCmp('dlg_DocumentManager'); theThis.dlg_DocumentManager.setInstruction('This is where you can store all of your documents'); theThis.dlg_DocumentManager.show(); }// End handler }, { text:'Export to recipe book', hidden : theThis.HideExportRecipeButton, colspan : theThis.HideProcessPendingRecipesButton == true ? 1 : 3, handler : function(){ if (theThis.selectedRecipeId == -1) showWarningMessage("Please select a recipe to export"); else { theThis.loadMask.show(); Ext.Ajax.request({ method: "POST", url: theThis.RecipeBookController + "/RequestRecipeApproval", params: { recipeId : theThis.selectedRecipeId }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); showInfoMessage(jsonData.message.Info); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); } } }, theThis.btn_OutletFilter = new Ext.menu.Item({ text:'Filter by outlet', hidden : theThis.readOnly, handler : function(){ if (theThis.dlg_OutletsHierarchy == null) { theThis.dlg_OutletsHierarchy = new Ext.CTBOutletsHierarchyWindow({ showSelectButton : true, hideSupplierAllocationButton : true, hideRecipeAllocationButton : true, hideJumpButton : true, destroyCallbackAfterCalled : false, // All callback are the same callback_AfterSelect : function(outletId){ theThis.belongToOutletId = outletId; theThis.reloadData(); } }); } theThis.dlg_OutletsHierarchy.show(); } }) ] // menu items }); // End menu declaration } // End "if" checking menu existence // Show the menu theThis.menu_ViewOptions.show(e.getTarget()); } // End "More" button handler }) ], loader: theThis.treeLoader = new Tree.TreeLoader({ dataUrl : theThis.RecipeFolderController + '/GetAllRecipeFolders', requestMethod : 'POST', preloadChildren : true, listeners : { beforeload : function(){ // If run the first time, we need to check whether we want the loader autoload or not if (!theThis.isAutoLoad && !theThis.isFirstRun){ theThis.isFirstRun = true; return false; } if (!theThis.isFirstRun) theThis.isFirstRun = true; theThis.treeLoader.baseParams = { isShowCheckbox : theThis.ShowCheckboxSelection, recipeName : theThis.searchRecipeName, regionId : theThis.regionId, recipeStatus : theThis.recipeStatus, outletId : theThis.outletId, belongToOutletId : theThis.belongToOutletId }; if (theThis.rendered) theThis.loadMask.show(); }, load : function() { // Select the root node if (theThis.rendered) { if (treePanel.root.item(0) != null){ treePanel.getSelectionModel().select(treePanel.root.item(0)); } theThis.loadMask.hide(); } // Call initial command if have function processInitialCommand(){ if (Global_UnitOfMeasurement_Store_Loaded && Global_MeasurementConversion_Store_Loaded){ if (Ext.getCmp('pnl_RecipeBook') != null) { var initialCommand = Ext.getCmp('pnl_RecipeBook').initialCommand; if (initialCommand != null) { theThis.btn_Add_Recipe.handler.call(theThis.btn_Add_Recipe.scope); Ext.getCmp('pnl_RecipeBook').initialCommand = null; } } } else setTimeout(function(){processInitialCommand()}, 200); } processInitialCommand(); } } }), listeners : { 'nodedrop' : function(e){ // Treat as a temporary album var data = e.dropNode.toString().split(','); for (var i = 0;i 0) { var listOfRecords = new Array(); for (var i = 0; i < modifiedRecords.length; i++) { listOfRecords[i] = modifiedRecords[i].data; } theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Stock/LinkMultipleStocksToSupplier', params: { stockData : Ext.util.JSON.encode(listOfRecords), supplierId : theThis.selectedSupplierRecord.supplierId }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); if (callback_Function != null) callback_Function(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } } }); Ext.reg('CTBAllStocks_SupplyByGrid', Ext.CTBAllStocks_SupplyByGrid); Ext.CTBAllStocks_SupplyByWindow = Ext.extend(Ext.Window, { title: 'Link stock to supplier', layout: 'border', closeAction: 'hide', iconCls: 'icon-stock', expandOnShow: true, closable: true, resizable: true, modal: true, plain: true, minimizable: true, maximizable: true, monitorResize: true, width: 800, height: 500, selectedSupplierRecord : null, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, pageSize: CTB.init.itemPerPage || 100, listeners: { scope : this, 'beforehide': function(theThis){ }, 'beforeshow': function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); }, 'show': function(theThis){ if (theThis.selectedSupplierRecord != null) { theThis.grid_SupplyBy.selectedSupplierRecord = theThis.selectedSupplierRecord theThis.grid_SupplyBy.loadData(); } } }, initComponent : function(){ var theThis = this; theThis.grid_SupplyBy = new Ext.CTBAllStocks_SupplyByGrid({ region : 'center' }); theThis.items = [ theThis.pnl_Instruction = new Ext.Panel({ frame : true, region : 'north', height : 70, html : ''+ '
'+ ''+ ''+ ''+ ''+ '
'+ 'Please enter supplier\'s stock code and supplier cost for each selected stock(s)'+ '
'+ '
'+ '
', listeners : { afterrender : function(p_This){ } } }), theThis.grid_SupplyBy ]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBAllStocks_SupplyByWindow.superclass.initComponent.call(this); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_Save = new Ext.Button({ text: 'Save', iconCls : 'icon-save-large', scale : 'large', handler : function(){ theThis.grid_SupplyBy.saveData(function(){ theThis.hide(); }); } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } }) ]; return buttons; } }); Ext.reg('CTBAllStocks_SupplyByWindow', Ext.CTBAllStocks_SupplyByWindow); Ext.CTBAllStocks = Ext.extend(Ext.Panel, { layout : 'border', title: 'All stocks', loadMask: null, Global_StockBrowser_Parent : null, Global_StockBrowser_PageSize : CTB.init.itemPerPage || 100, HideSupplierBy : true, HideColumn_StockCode : false, HideColumn_SupplierStockCode : false, HideColumn_ParLevel : false, HideColumn_GST : false, HideColumn_Nutrition : false, HideColumn_Report : false, HideColumn_Wastage : false, readOnly : false, isLoadingData : false, // Flag to indicate whether the store is calling AJAX to load data callback_AfterLoad : null, listeners : { afterrender : function(theThis){ theThis.loadMask = new Ext.LoadMask(theThis.getEl(), {msg:"Please wait..."}); } }, initComponent: function(){ var theThis = this; theThis.dlg_NutritionBrowser = new Ext.CTBNutritionBrowser({ parentContainer : theThis }); theThis.grid_MasterStock = theThis.generateGrid_MasterStock(); theThis.grid_SupplierBy = theThis.generateGrid_SupplierBy(); theThis.items = [theThis.grid_MasterStock, theThis.grid_SupplierBy]; // Call super class to initialize componenets Ext.CTBAllStocks.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid_MasterStock().getSelectionModel().clearSelections(); theThis.getGrid_SupplierBy().getSelectionModel().clearSelections(); }, getGrid : function(){ var theThis = this; return theThis.grid_MasterStock; }, // Same as above but more specific for method signature getGrid_MasterStock : function(){ var theThis = this; return theThis.grid_MasterStock; }, getGrid_SupplierBy : function(){ var theThis = this; return theThis.grid_SupplierBy; }, getPagingToolbar : function(){ var theThis = this; return theThis.pt_StockBrowser_AllStocks; }, generateGrid_MasterStock : function(){ var theThis = this; var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.Global_StockBrowser_StockRecord = Ext.data.Record.create([ { name: 'stockId', type: 'number' }, { name: 'stockSupplierId', type: 'number', mapping: 'activeStockSupplierId'}, // This is for the active supplier that being used to supply this stock item { name: 'supplierCost', type: 'number', mapping: 'activeSupplierCost'}, // This is for the active supplier that being used to supply this stock item { name: 'supplierId', type: 'number', mapping: 'activeSupplierId'}, // This is for the active supplier that being used to supply this stock item { name: 'supplierName', type: 'string', mapping: 'activeSupplierName'}, // This is for the active supplier that being used to supply this stock item { name: 'supplierStockCode', type: 'string', mapping: 'activeSupplierStockCode'}, // This is for the active supplier that being used to supply this stock item { name: 'stockCode', type: 'string' }, { name: 'stockDesc', type: 'string' }, { name: 'stockUnit', type: 'number' }, { name: 'unitOfMeasurementId', type: 'number' }, { name: 'stockCategoryId', type: 'number' }, { name: 'stockWastage', type: 'number' }, { name: 'stockParLevel', type: 'number' }, { name: 'isGstApplied', type: 'boolean' }, { name: 'isNutritionLinked', type: 'boolean' }, { name: 'isDisplayedOnReport', type: 'boolean' }, { name: 'isNonFoodItem', type: 'boolean'}, { name: 'isActive', type: 'boolean'} // Using for deleting ]); var store = new Ext.data.JsonStore({ //baseParams : {keyword : "", start : 0, limit : Global_StockBrowser_PageSize}, proxy: new Ext.data.HttpProxy({ url: '/Stock/SearchStocks', dataType: 'json', method: 'POST' }), fields: theThis.Global_StockBrowser_StockRecord, root: 'data', idProperty: 'stockId', totalProperty: 'totalCount', listeners : { beforeload : function(){ store.commitChanges(); theThis.isLoadingData = true; }, load : function(){ theThis.isLoadingData = false; if (theThis.callback_AfterLoad != null) { theThis.callback_AfterLoad(); theThis.callback_AfterLoad = null; } }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); // *************************************************************************************************** // Combobox // *************************************************************************************************** var cmbGridUOM = getCombobox_UnitOfMeasurement(); var cmbGridStockCategory = getCombobox_StockCategory(); // *************************************************************************************************** // Grid // *************************************************************************************************** //------------------------------------------------------------------- // Distinct stock selection model //------------------------------------------------------------------- var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment } } }); // Column Models var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'stockId', dataIndex: 'stockId', hidden: true }, { header: '', dataIndex: 'stockId', hidden: false, width: 2, //renderer: Ext.util.Format.comboRenderer(cmbSupplier) renderer: function(val) { var theRecord = store.getById(val); var result = markNormal("", true); if (val < 0) result = markNew(result, true); if (!theRecord.data.isActive) result = markDeleted(result, true); return result; } }, { header: 'Supplier', dataIndex: 'supplierName', width: 10, renderer : function(val, meta, theRecord) { return ''+val+''; } }, { header: 'Code'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockCode', width: 5, hidden : theThis.HideColumn_StockCode, editor: { xtype: 'textfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }, renderer : function(val){ if (val == "") { return 'Enter your code'; } else return ''+val+''; } }, { header: 'Description'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockDesc', width: 25, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }), renderer : function(val){ if (val == "") { return 'Enter stock description'; } else if (val == 'New desc' || val == 'New Product') { return String.format('{0}', val); } else return ''+val+''; } }, { header: 'Active cost', dataIndex: 'supplierCost', width: 8, renderer: Ext.util.Format.usMoney }, { header: 'Amount'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockUnit', width: 5, editor: new fm.NumberField({ xtype: 'numberfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'Unit'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'unitOfMeasurementId', width: 5, editor: cmbGridUOM, renderer : function(val, meta, record){ return Global_UnitOfMeasurement_Store.getById(val).data.UOMName; } }, { header: 'Category'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockCategoryId', width: 10, editor: cmbGridStockCategory, renderer: Ext.util.Format.comboRenderer(cmbGridStockCategory) }, { header: 'Wastage'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockWastage', width: 5, hidden : theThis.HideColumn_Wastage, renderer: function (val) { return val + "%"; }, editor: new fm.TextField({ xtype: 'numberfield', allowBlank: false, allowNegative: false, maxValue: 100, decimalPrecision: 2, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'Par Level'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockParLevel', width: 5, hidden : theThis.HideColumn_ParLevel, editor: new fm.TextField({ xtype: 'numberfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'GST'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockId', width: 5, hidden : theThis.HideColumn_GST, renderer: function(value) { var realValue = theThis.getGrid_MasterStock().getStore().getById(value).get('isGstApplied'); return ""; } }, { header: 'Nutrition'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockId', width: 5, hidden : theThis.HideColumn_Nutrition, renderer: function(value) { var realValue = theThis.getGrid_MasterStock().getStore().getById(value).get('isNutritionLinked'); return ""; } }, { header: 'Report'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockId', width: 5, hidden : theThis.HideColumn_Report, renderer: function(value) { var realValue = theThis.getGrid_MasterStock().getStore().getById(value).get('isDisplayedOnReport'); return ""; } }, { header: CTB.init.languageDictionary.GetValue("FOOD_RELATED").replace(' ', '
'), dataIndex: 'stockId', width: 5, hidden : theThis.HideColumn_Report, renderer: function(value) { try{ var realValue = !theThis.getGrid_MasterStock().getStore().getById(value).data.isNonFoodItem; return ""; }catch(e){} return ""; /*if (value == false) return '
'; else return '
';*/ } } ] }); // Grouping headers var cityGroupRow = [ {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: 'Stock Measurement', colspan: 2, align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'} ]; var group = new Ext.ux.grid.ColumnHeaderGroup({ rows: [cityGroupRow] }); // Context menu for right clicking var contextMenu = new Ext.menu.Menu({ items: [ /*{ iconCls: 'icon-add', scale : 'large', text: 'Add', handler: function () { theThis.btn_Add_Stock.handler.call(theThis.btn_Add_Stock.scope); } }, { iconCls: 'icon-delete', scale : 'large', text: 'Delete', handler: function () { theThis.btn_Delete_Stock.handler.call(theThis.btn_Delete_Stock.scope); } },*/ { text: 'Assign Supplier', iconCls : 'icon-supplier', handler: function () { theThis.btn_Stock_Link_To_Supplier.handler.call(theThis.btn_Stock_Link_To_Supplier.scope); } } ] }); // End context menu // Stock category combobox theThis.cmb_StockCategory = theThis.getCombobox_StockCategory(true, 137); theThis.cmb_StockCategory.on({ select: function (p_combo, p_record, p_index) { theThis.doSearchByStockCategoryId(); } }); /****************************/ /* Searching Stock Combobox */ /****************************/ var data_SearchType = [ ['By Stock Code', 1], ['By Stock Description', 2], // ['By Stock Category', 3], // This is by stock category name ['By Stock Category11', 4] // This is by stock category ID ]; theThis.cmb_SearchStock = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ], data : data_SearchType }), displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, editable: false, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Choose search by ...' }); // manually load local data theThis.cmb_SearchStock.setValue(2); // Event trigger when selecting search type theThis.cmb_SearchStock.on({ select: function (p_combo, p_record, p_index) { var searchType = p_record.data.searchType; if (searchType == 4){ theThis.cmb_StockCategory.setVisible(true); theThis.txt_MasterStock_SearchStockValue.setVisible(false); } else { theThis.cmb_StockCategory.setVisible(false); theThis.txt_MasterStock_SearchStockValue.setVisible(true); } } }); // Paging toolbar theThis.pt_StockBrowser_AllStocks = new Ext.CTBPagingToolbar({ store: store, pageSize: theThis.Global_StockBrowser_PageSize, displayInfo: true, emptyMsg: "No stocks to display" }); /****************************/ /* Master Stock Grid */ /****************************/ var grid_MasterStock = new Ext.grid.EditorGridPanel({ region: 'center', sm : sm, cm : cm, store: store, //title: 'Stock List', frame: true, autoHeight: false, clicksToEdit: 1, loadMask: true, plugins: group, listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); /*theThis.grid_SupplierBy.getStore().commitChanges(); theThis.grid_SupplierBy.getStore().baseParams = {stockId : selectedStockId}; theThis.grid_SupplierBy.getStore().load();*/ }, afterrender : function(p_This){ grid_MasterStock.getStore().baseParams = {keyword : "", start : 0, limit: theThis.Global_StockBrowser_PageSize}; grid_MasterStock.getStore().load(); } }, tbar: [ theThis.btn_Save = new Ext.Button({ iconCls : 'icon-save-large', scale : 'large', text : 'Save', cls : 'ctb-btn-red', hidden : theThis.readOnly, handler : function(){ // Get modified records var modifiedRecords = grid_MasterStock.getStore().getModifiedRecords(); var jsonArray = new Array(); var isContainingJunkStockDesc = false; for (var i = 0, row; row = modifiedRecords[i]; i++) { if (modifiedRecords[i].data.stockDesc == 'New desc' || modifiedRecords[i].data.stockDesc == 'New Product' || modifiedRecords[i].data.stockDesc == '') isContainingJunkStockDesc = true; // Check for invalid unit of measurement if (isNaN(modifiedRecords[i].data.unitOfMeasurementId)) { Ext.Msg.show({ title:'Notice', msg: 'The measurement "' + modifiedRecords[i].data.unitOfMeasurementId + '" does not exist.
Please consider to add new measurement in Admin/Unit Of Measurement', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); return; } jsonArray[i] = { stockId : modifiedRecords[i].data.stockId, stockCode : modifiedRecords[i].data.stockCode, stockDesc : modifiedRecords[i].data.stockDesc, stockUnit : modifiedRecords[i].data.stockUnit, unitOfMeasurementId : modifiedRecords[i].data.unitOfMeasurementId, stockCategoryId : modifiedRecords[i].data.stockCategoryId, stockWastage : modifiedRecords[i].data.stockWastage, stockParLevel : modifiedRecords[i].data.stockParLevel, isGstApplied : modifiedRecords[i].data.isGstApplied, isNutritionLinked : modifiedRecords[i].data.isNutritionLinked, isDisplayedOnReport : modifiedRecords[i].data.isDisplayedOnReport, isNonFoodItem : modifiedRecords[i].data.isNonFoodItem, isActive : modifiedRecords[i].data.isActive }; } // Not sending the save command if the stock desc is junk description if (isContainingJunkStockDesc){ showErrorNotification('Notice', 'Please change the description of the new stocks (\'New desc\') to more meaningful descriptions.'); } else { var listOfStocks = {listOfStocks : jsonArray}; var jsonObject = Ext.util.JSON.encode(listOfStocks); // Submit data theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Stock/SaveStocks', params: { jsonData : jsonObject }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); grid_MasterStock.getStore().commitChanges(); grid_MasterStock.getStore().reload(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); } } }), // And Save button /*theThis.readOnly ? '' : '-', theThis.btn_Add_Stock = new Ext.Button({ iconCls: 'icon-add', scale : 'large', text: 'Add', hidden : theThis.readOnly, //disabled: true, handler: function () { var newId = -getRandomNumber(); // Negative for new entry var uniqueCode = getUniqueTime(); var aNewRecord = new theThis.Global_StockBrowser_StockRecord({ stockId: newId, stockCode: '', stockDesc: 'New Product', stockUnit: 1, unitOfMeasurementId: 1, stockCategoryId: 1, stockWastage: 0, stockParLevel: 1, isGstApplied: false, isNutritionLinked: false, isDisplayedOnReport: true, isActive: true }, newId); grid_MasterStock.stopEditing(); grid_MasterStock.getStore().insert(0, aNewRecord); grid_MasterStock.getStore().getById(newId).set('stockCode', uniqueCode); } }), theThis.readOnly ? '' : '-', theThis.btn_Delete_Stock = new Ext.Button({ iconCls: 'icon-delete', scale : 'large', text: 'Delete', hidden : theThis.readOnly, //disabled: true, handler: function () { var selectedItems = grid_MasterStock.getSelectionModel().getSelections(); if (selectedItems.length > 0) { for (var i = 0, row; row = selectedItems[i]; i++) { row.set('isActive', false); } } else { Ext.Msg.show({ title:'Notice', msg: 'Please select item(s) to delete!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); }// End if } }),*/ theThis.readOnly ? '' : '-', theThis.btn_MasterStock_StopSearch = new Ext.Button({ xtype : 'button', iconCls : 'icon-stop-search', handler : function(){ grid_MasterStock.getStore().commitChanges(); //masterStock_Store.baseParams = {start : 0, limit : Global_StockBrowser_PageSize}; Ext.apply(grid_MasterStock.getStore().baseParams, { keyword : "", searchType : -1, start : 0, limit : theThis.getPagingToolbar().pageSize }); grid_MasterStock.getStore().load(); } }), theThis.txt_MasterStock_SearchStockValue = new Ext.form.TextField({ emptyText : 'Search value ...', enableKeyEvents: true, listeners: { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_MasterStock_SearchStock.handler.call(theThis.btn_MasterStock_SearchStock.scope); } }, keyup : function(textField, eventObject){ if (textField.getValue().length >= 2) { if (!theThis.isLoadingData) theThis.btn_MasterStock_SearchStock.handler.call(theThis.btn_MasterStock_SearchStock.scope); else { theThis.callback_AfterLoad = function(){ theThis.btn_MasterStock_SearchStock.handler.call(theThis.btn_MasterStock_SearchStock.scope); } } } } } }), theThis.cmb_StockCategory, ' ', theThis.cmb_SearchStock, theThis.btn_MasterStock_SearchStock = new Ext.Button({ iconCls : 'icon-search-large', scale : 'large', text : 'Search', handler : function(){ grid_MasterStock.getStore().commitChanges(); var searchType = theThis.cmb_SearchStock.getValue(); var searchValue = theThis.txt_MasterStock_SearchStockValue.getValue(); if (searchType == "") { Ext.Msg.show({ title:'Notice', msg: 'Please choose a search type !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } else { // Send search request if (searchType == 4) // Search by stock category ID theThis.doSearchByStockCategoryId(); else { theThis.doNormalSearch(searchType, searchValue); } } } }), theThis.readOnly ? '' : '-', theThis.btn_AllStocks_HideReportItem = new Ext.Button({ xtype : 'button', pressed : true, text : 'Hide Non-Report item', scale : 'large', enableToggle : true, hidden : theThis.readOnly, toggleHandler : function(p_Button, p_State){ Ext.apply(grid_MasterStock.getStore().baseParams, { start : 0, limit : theThis.getPagingToolbar().pageSize, toggleReportItem : p_State }); grid_MasterStock.getStore().load(); } }) ], bbar: theThis.pt_StockBrowser_AllStocks, viewConfig: { enableRowBody: true, forceFit: true, // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) getRowClass: function(record, index) { if (record.data.isNonFoodItem){ return 'nonfooditem_row'; } } } }); return grid_MasterStock; }, // End generateGrid_MasterStock searchByStockDescription : function(stockDesc){ var theThis = this; theThis.txt_MasterStock_SearchStockValue.setValue(stockDesc); Ext.apply(theThis.grid_MasterStock.getStore().baseParams, { keyword : stockDesc, searchType : 2, start : 0, limit : theThis.getPagingToolbar().pageSize }); theThis.grid_MasterStock.getStore().load(); }, generateGrid_SupplierBy : function(){ var theThis = this; theThis.SupplierBrowser = getSupplierBrowserDialog(); var fm = Ext.form; var record = Ext.data.Record.create([ { name: 'stockSupplierId', type: 'number' }, { name: 'accountNo', type: 'string' }, { name: 'abnNo', type: 'string' }, { name: 'supplierStockCode', type: 'string' }, { name: 'supplierCost', type: 'number' }, { name: 'supplierId', type: 'number' }, { name: 'supplierName', type: 'string' }, { name: 'stockId', type: 'number' }, { name: 'stockDesc', type: 'string' }, { name: 'stockUnit', type: 'number' }, { name: 'unitOfMeasurementId', type: 'number' }, { name: 'stockCategoryId', type: 'number' }, { name: 'stockWastage', type: 'number' }, { name: 'stockParLevel', type: 'number' }, { name: 'isGstApplied', type: 'boolean' }, { name: 'isNutritionLinked', type: 'boolean' }, { name: 'isDisplayedOnReport', type: 'boolean' } ]); var store = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy({ url: '/Supplier/GetSuppliersByStockId', dataType: 'json', method: 'POST' }), fields: record, root: 'data', idProperty: 'supplierId', autoLoad : false, listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment var selectedRecords = sm.getSelections(); // Assign the selected records if (theThis.Global_StockBrowser_Parent != null) theThis.Global_StockBrowser_Parent.Global_StockBrowser_SelectedRecords = selectedRecords; } } }); // Column Models var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'stockSupplierId', dataIndex: 'stockSupplierId', hidden: true }, { header: 'stockId', dataIndex: 'stockId', hidden: true }, { header: 'supplierId', dataIndex: 'supplierId', hidden: true }, { header: 'Supplier', dataIndex: 'supplierName', width: 30, editor: { xtype: 'textfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } } }, { header: 'Supplier\'s Stock Code'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'supplierStockCode', width: 30, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'Abn Number'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'abnNo', width: 15, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'Account Number'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'accountNo', width: 10, editor: new fm.TextField({ xtype: 'textfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'Cost Provided'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'supplierCost', width: 15, renderer : Ext.util.Format.usMoney, editor: new fm.NumberField({ xtype: 'numberfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) } ] }); var grid_SupplierBy = new Ext.grid.EditorGridPanel({ region : 'south', store: store, title: 'Supplied By', frame: true, collapsible: true, animCollapse : false, collapsed: theThis.HideSupplierBy, cm: cm, sm: sm, height: 200, clicksToEdit: 2, loadMask: true, listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); } }, tbar: [ // Save stock - supplier relationship changes theThis.btn_SupplierBy_Save = new Ext.Button({ iconCls: 'icon-save-large', scale : 'large', hidden : theThis.readOnly, text: 'Save', //disabled: true, handler: function () { var modifiedRecords = grid_SupplierBy.getStore().getModifiedRecords(); var jsonArray = new Array(); for (var i = 0, row; row = modifiedRecords[i]; i++) { jsonArray[i] = { stockSupplierId: modifiedRecords[i].data.stockSupplierId, supplierStockCode: modifiedRecords[i].data.supplierStockCode, supplierCost: modifiedRecords[i].data.supplierCost }; } var listOfStockSuppliers = {listOfStockSuppliers : jsonArray} var jsonObject = Ext.util.JSON.encode(listOfStockSuppliers); // Submit data theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/StockSupplier/SaveStockSupplierChanges', params: { jsonData : jsonObject }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.IsSuccess) { showSuccessNotification(jsonData.Info, NOTIFICATION.ICON_INFORMATION); grid_SupplierBy.getStore().commitChanges(); grid_SupplierBy.getStore().reload(); } else { showErrorMessageWithEmailNotify(jsonData.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); } // End Save handler function }), theThis.readOnly ? '' : '-', theThis.btn_SupplierBy_LinkToSupplier = new Ext.Button({ iconCls: 'icon-add', scale : 'large', text: 'Link to supplier', hidden : theThis.readOnly, handler: function () { var selectedStockIds = theThis.grid_MasterStock.getSelectionModel().getSelections(); if (selectedStockIds.length > 0) { var isSaved = true; for (var i = 0; i < selectedStockIds.length; i++) { if (selectedStockIds[i].data.stockId < 0){ isSaved = false; break; } } if (isSaved) { Global_SupplierBrowser_CallbackFunction = function(supplierIds, supplierRecords) { //theThis.loadMask.show(); if (supplierIds.length > 0) { if (selectedStockIds.length > 1) { if (theThis.dlg_SupplyBy == null) { theThis.dlg_SupplyBy = new Ext.CTBAllStocks_SupplyByWindow({ }); } theThis.dlg_SupplyBy.selectedSupplierRecord = { supplierId : supplierIds[0], supplierName : supplierRecords[0].data.supplierName, stockRecords : selectedStockIds } theThis.dlg_SupplyBy.show(); } else if (selectedStockIds.length == 1) { // If only one stocks get selected, then process straigt away theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Stock/LinkStockToSuppliers', params: { stockId : selectedStockIds[0].data.stockId, supplierIds : Ext.util.JSON.encode(supplierIds) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); grid_SupplierBy.getStore().load(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } } } // End call back function theThis.SupplierBrowser.show(); } else { Ext.Msg.show({ title:'Notice', msg: 'The selected stock(s) need to be saved before it can be linked to a supplier !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } else { Ext.Msg.show({ title:'Notice', msg: 'Please choose a stock to link !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } // End Link to Supplier handler function }), theThis.readOnly ? '' : '-', theThis.btn_SupplierBy_StopSupplier = new Ext.Button({ iconCls: 'icon-delete', scale : 'large', text: 'Stop Supplier', hidden : theThis.readOnly, handler: function () { var selectedItems = grid_SupplierBy.getSelectionModel().getSelections(); if (selectedItems.length > 0) { Ext.Msg.show({ title:'Confirm', msg: 'Are you sure you want to stop the supplier(s) ?', buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.QUESTION, fn : function(btn) { if (btn == "yes") { theThis.loadMask.show(); var collectionOfIds = new Array(); for (var i = 0, row; row = selectedItems[i]; i++) { collectionOfIds[i] = row.data.stockSupplierId; } // Calling delete Ext.Ajax.request({ method: 'POST', url: '/StockSupplier/StopSuppliers', params: { stockSupplierIds : Ext.util.JSON.encode(collectionOfIds) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); grid_SupplierBy.getStore().load(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } } });// End : show confirming Stop suppliers dialog } else { Ext.Msg.show({ title:'Notice', msg: 'Please select supplier(s) to stop !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } // End Stop Supplier handler function }), theThis.readOnly ? '' : '-', theThis.btn_SupplierBy_SupplierManager = new Ext.Button({ iconCls: 'icon-supplier-large', hidden : theThis.readOnly, scale : 'large', text: 'Supplier Manager', handler: function () { theThis.SupplierBrowser.show(); } // End Supplier Manager handler function }) ], viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return grid_SupplierBy; }, // End generateGrid_SupplierBy getCombobox_StockCategory : function(isHidden, width) { var theThis = this; if (isHidden == null) isHidden = false; var config = { store: Global_StockCategory_Store, displayField: 'stockCategoryName', valueField: 'stockCategoryId', typeAhead: true, triggerAction: 'all', editable: true, lazyRender: true, hidden : isHidden, mode: 'local', emptyText : 'Select category ...', autoSelect : true, forceSelection: true, listeners : { focus: function(p_This){ p_This.getEl().dom.select(); } } }; if (width != null) config.width = width; var cmbGridStockCategory = new Ext.form.ComboBox(config); return cmbGridStockCategory; }, doSearchByStockCategoryId : function() { var theThis = this; var validateFields = new Array(); validateFields[0] = { ID : theThis.cmb_StockCategory.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.NUMBER_ID }; // Call global validate field group if (validateFieldGroup(validateFields)) { var stockCategoryId = theThis.cmb_StockCategory.getValue(); Ext.apply(theThis.grid_MasterStock.getStore().baseParams, { keyword : stockCategoryId, searchType : 4, start : 0, limit : theThis.getPagingToolbar().pageSize }); theThis.grid_MasterStock.getStore().load(); } }, doNormalSearch : function(searchType, searchValue) { var theThis = this; Ext.apply(theThis.grid_MasterStock.getStore().baseParams, { keyword : searchValue, searchType : searchType, start : 0, limit : theThis.getPagingToolbar().pageSize }); theThis.grid_MasterStock.getStore().load(); } }); function chk_AllStocks_GSTApplied_OnChange(checkbox_Object, componentId) { var theContainer = Ext.getCmp(componentId); var theStore = theContainer.getGrid_MasterStock().getStore(); theStore.getById(checkbox_Object.id).set('isGstApplied', checkbox_Object.checked); } function chk_AllStocks_Nutrition_OnChange(checkbox_Object, componentId) { var theContainer = Ext.getCmp(componentId); var theStore = theContainer.getGrid_MasterStock().getStore(); NutritionCheckBoxOnChange(checkbox_Object, componentId); //getGridtheStore.getById(checkbox_Object.id).set('isNutritionLinked', checkbox_Object.checked); } function chk_AllStocks_Report_OnChange(checkbox_Object, componentId) { var theContainer = Ext.getCmp(componentId); var theStore = theContainer.getGrid_MasterStock().getStore(); theStore.getById(checkbox_Object.id).set('isDisplayedOnReport', checkbox_Object.checked); } function chk_AllStocks_FoodRelated_OnChange(checkbox_Object, componentId) { var theContainer = Ext.getCmp(componentId); var theStore = theContainer.getGrid_MasterStock().getStore(); theStore.getById(checkbox_Object.id).set('isNonFoodItem', !checkbox_Object.checked); } Ext.reg('CTBAllStocks', Ext.CTBAllStocks); Ext.CTBStockBySuppliers = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, title: 'Stock by suppliers', Global_StockBrowser_PageSize: CTB.init.itemPerPage || 100, Global_StockBrowser_Parent: null, HideColumn_StockCode : false, HideColumn_SupplierStockCode : false, HideColumn_ParLevel : false, HideColumn_GST : false, HideColumn_Nutrition : false, HideColumn_Report : false, HideColumn_Wastage : false, HideColumn_UnitAvailable : true, HideColumn_UnitPoints : true, HideColumn_InvoiceUnit : false, HideColumn_InvoiceUOM : false, isFromImportDatabase : false, readOnly : false, isSingleSelect : false, isSupplierVersion : (typeof(GLOBAL_IS_SUPPLIER_VERSION) === 'undefined' || GLOBAL_IS_SUPPLIER_VERSION == null) ? false : Boolean(GLOBAL_IS_SUPPLIER_VERSION), isLoadingData : false, // Flag to indicate whether the store is calling AJAX to load data callback_AfterLoad : null, stockParLevelCategoryId : 2, // 1 = Low, 2 = Medium, 3 = High getFilterValue : function(){ var theThis = this; return theThis.stockParLevelCategoryId; }, listeners : { afterrender : function(p_This){ // Init loadMask p_This.loadMask = new Ext.LoadMask(this.getEl(), {msg : "Please wait..."}); p_This.reportLoadMask = new Ext.CTBLoadMaskAds({msg : 'Loading report. Please wait ...'}); } }, initComponent: function(){ var theThis = this; theThis.dlg_NutritionBrowser = new Ext.CTBNutritionBrowser({ parentContainer : theThis }); theThis.grid_StockBySuppliers = theThis.generateGrid_StockBySuppliers(); theThis.pnl_Top = theThis.getPanel_Top(); theThis.items = [theThis.pnl_Top, theThis.grid_StockBySuppliers]; // Call super class to initialize componenets Ext.CTBStockBySuppliers.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid_StockBySuppliers().getSelectionModel().clearSelections(); }, getGrid : function(){ var theThis = this; return theThis.grid_StockBySuppliers; }, // Same as above but more specific for method signature getGrid_StockBySuppliers: function(){ var theThis = this; return theThis.grid_StockBySuppliers; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_StockBrowser_StockBySupplier; }, getPanel_Top: function(){ var theThis = this; var pnl_Top = new Ext.Panel({ layout : 'table', layoutConfig : { columns : 8 }, region : 'north', height : 38, cls : 'ctb-north-panel', frame : false, items : [ theThis.cmbSupplier, theThis.btn_StockBySupplier_StopSearch = new Ext.Button({ xtype : 'button', iconCls : 'icon-stop-search', tooltip : 'Stop Search', cellCls : 'ctb-tablelayout-cell', handler : function(){ //theThis.cmbSupplier.reset(); if (theThis.cmbSupplier.getValue() != '') { Ext.apply(theThis.grid_StockBySuppliers.getStore().baseParams, { supplierId : theThis.cmbSupplier.getValue(), keyword : "", searchType : -1, start : 0, limit : theThis.getPagingToolbar().pageSize, stockParLevelCategoryId : theThis.stockParLevelCategoryId }); theThis.grid_StockBySuppliers.getStore().load(); } else { showErrorNotification('Notice', 'Please select supplier !'); } } }), theThis.txt_StockBySupplier_SearchStockValue = new Ext.form.TextField({ cellCls : 'ctb-tablelayout-cell ctb-tablelayout-cell-left', emptyText : 'Search value ...', enableKeyEvents: true, listeners: { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_Dialog_StockBySupplier_SearchStock.handler.call(theThis.btn_Dialog_StockBySupplier_SearchStock.scope); } }, keyup : function(textField, eventObject){ if (textField.getValue().length >= 2) { if (!theThis.isLoadingData) theThis.btn_Dialog_StockBySupplier_SearchStock.handler.call(theThis.btn_Dialog_StockBySupplier_SearchStock.scope); else { theThis.callback_AfterLoad = function(){ theThis.btn_Dialog_StockBySupplier_SearchStock.handler.call(theThis.btn_Dialog_StockBySupplier_SearchStock.scope); } } } } } }), theThis.cmb_StockCategory, //new Ext.form.Label(), theThis.cmb_Search, theThis.btn_Dialog_StockBySupplier_SearchStock = new Ext.Button({ cellCls : 'ctb-tablelayout-cell', iconCls : 'icon-search-large', scale : 'large', text : 'Search', handler : function(){ if (theThis.txt_StockBySupplier_SearchStockValue.getValue().length < 3 && theThis.cmb_Search.getValue() == 5){ // Online product search neet at least 3 characters showErrorNotification('Notice', 'Please enter at least 3 characters'); } else { var searchValue = theThis.txt_StockBySupplier_SearchStockValue.getValue(); var searchType = theThis.cmb_Search.getValue(); if (searchType == 5) theThis.grid_StockBySuppliers.loadMask.msg = 'Loading... This process might take up to 2 minutes.'; else theThis.grid_StockBySuppliers.loadMask.msg = 'Loading...'; if (searchType == "") { showErrorNotification('Notice', 'Please choose a search type !'); } else { if (searchType == 6) // Search by stock category theThis.doSearchByStockCategoryId(); else { theThis.doNormalSearch(searchType, searchValue); } } } } }), theThis.btn_StockBySupplier_HideReportItem = new Ext.Button({ cellCls : 'ctb-tablelayout-cell', pressed : true, text : 'Show Non-Active item', scale : 'large', //colspan : 2, enableToggle : true, hidden : theThis.readOnly, toggleHandler : function(p_Button, p_State){ Ext.apply(theThis.grid_StockBySuppliers.getStore().baseParams, { supplierId : theThis.cmbSupplier.getValue(), //keyword : "", //searchType : -1, start : 0, limit : theThis.getPagingToolbar().pageSize, toggleReportItem : p_State, stockParLevelCategoryId : theThis.stockParLevelCategoryId }); if (p_State == true) { p_Button.setText('Show Non-Active item'); } else { p_Button.setText('Hide Non-Active item'); } theThis.grid_StockBySuppliers.getStore().load(); } }) ] }); return pnl_Top; }, generateGrid_StockBySuppliers: function(){ var theThis = this; var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.Global_StockBrowser_StockSupplierRecord = Ext.data.Record.create([ { name: 'stockSupplierId', type: 'number' }, { name: 'supplierStockCode', type: 'string' }, { name: 'supplierCost', type: 'number' }, { name: 'supplierId', type: 'number' }, { name: 'supplierName', type: 'string' }, { name: 'stockId', type: 'number' }, { name: 'stockCode', type: 'string' }, { name: 'stockDesc', type: 'string' }, { name: 'stockUnit', type: 'number' }, { name: 'unitOfMeasurementId', type: 'number' }, { name: 'stockCategoryId', type: 'number' }, { name: 'stockWastage', type: 'number' }, { name: 'stockParLevel', type: 'number' }, { name: 'isGstApplied', type: 'boolean' }, { name: 'isNutritionLinked', type: 'boolean' }, { name: 'isDisplayedOnReport', type: 'boolean' }, { name: 'isActive', type: 'boolean'}, // Using for deleting { name: 'isNonFoodItem', type: 'boolean'}, { name: 'stockCategoryName', type: 'string'}, { name: 'supplierSellingUnit', type: 'number'}, // Invoice stock unit { name: 'supplierUnitMeasurement', type: 'string'}, // Invoice unit of measurement { name: 'unitAvailable', type: 'number'}, // Unit available { name: 'unitPoints', type: 'number'}, // Unit points { name: 'isFromOnline', type: 'boolean'}, // Is from online supplier web service (PFD) { name: 'imageUrl', type: 'string'}, // Image Url { name: 'iconCls', type: 'string'}, // Icon CLS { name: 'iconTip', type: 'string'}, // Tip for the icon { name: 'isHavingApprovalPermission', type: 'boolean'}, // Is the current user have approval permission { name: 'isRequireApprovalPermission', type: 'boolean'}, // Is this stock require approval permission { name: 'orderingTemplateColumnIndex', type: 'int'} ]); // *************************************************************************************************** // Stores // *************************************************************************************************** var store = new Ext.data.GroupingStore({ baseParams : {supplierId: -1, start : 0, limit : theThis.Global_StockBrowser_PageSize, stockParLevelCategoryId : theThis.stockParLevelCategoryId }, proxy: new Ext.data.HttpProxy({ url: '/Stock/GetStockBySupplier', dataType: 'json', method: 'POST', timeout : 300000 // 5 minutes }), reader: new Ext.data.JsonReader({ fields: theThis.Global_StockBrowser_StockSupplierRecord, root: 'data', idProperty: 'stockSupplierId', totalProperty : 'totalCount' }), groupField : 'supplierName', listeners : { 'beforeload' : function(){ store.commitChanges(); theThis.isLoadingData = true; }, 'load' : function(){ if (theThis.rendered) sm.clearSelections(); theThis.isLoadingData = false; if (theThis.callback_AfterLoad != null) { theThis.callback_AfterLoad(); theThis.callback_AfterLoad = null; } }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); // *************************************************************************************************** // Combobox // *************************************************************************************************** var cmbGridUOM = getCombobox_UnitOfMeasurement(); var cmbGridStockCategory = theThis.getCombobox_StockCategory();//getCombobox_StockCategory(); theThis.cmbSupplier = theThis.getCombobox_Supplier(); theThis.cmbSupplier.on({ select: function (p_combo, p_record, p_index) { var supplierId = p_record.get('supId'); //Global_StockBrowser_SelectedSupplierId = supplierId; theThis.grid_StockBySuppliers.getStore().baseParams = { supplierId : supplierId, start: 0, limit : theThis.Global_StockBrowser_PageSize, isFromImportDatabase : theThis.isFromImportDatabase, stockParLevelCategoryId : theThis.stockParLevelCategoryId }; theThis.grid_StockBySuppliers.getStore().load(); } }); //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var hinderSelection = false; var sm = new Ext.grid.CheckboxSelectionModel({ singleSelect : theThis.isSingleSelect, listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment var selectedRecords = sm.getSelections(); // Check to display or not the Approve and Disapprove button var isShowApprovalButtons = false; for (var i = 0; i < selectedRecords.length; i++) { if (selectedRecords[i].data.isHavingApprovalPermission == true && selectedRecords[i].data.isRequireApprovalPermission == true) { //theThis.btnGroup_Approval.setVisible(true); //theThis.btn_ApproveStock.setVisible(true); //theThis.btn_DisapproveStock.setVisible(true); isShowApprovalButtons = true; break; } } if (isShowApprovalButtons == false){ //theThis.btnGroup_Approval.setVisible(false); //theThis.btn_ApproveStock.setVisible(false); //theThis.btn_DisapproveStock.setVisible(false); } }, beforerowselect: function(o, rowIndex, keepExisting, record) { if(hinderSelection) { hinderSelection = false; return false; } } } }); // *************************************************************************************************** // Editors Global_DistinctSupplierMeasurements_Store // *************************************************************************************************** var cmb_SupplierMeasurements = new Ext.form.ComboBox({ store: Global_DistinctSupplierMeasurements_Store, displayField: 'UOMName', valueField: 'UOMName', typeAhead: true, editable: true, triggerAction: 'all', lazyRender: true, //forceSelection: true, emptyText: 'Select a measurement...', //valueNotFoundText:'Select a measurement...', width: 200, //style: { fontSize: '11px' }, mode: 'remote', minChars: 1, listeners : { beforequery: function(qe){ //qe.combo.doQuery(qe.combo.lastQuery); delete qe.combo.lastQuery; // Reload every click }, blur : function(combo){ } } }); // This editor combobox object is only for supplier version // Supplier order template column index combobox theThis.cmb_SupplierOrderTemplate_ColumnIndex = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'columnName', type: 'string'}, {name: 'columnId', type: 'number'} ], data: [ ["None", -1], ["1", 1], ["2", 2], ["3", 3] ] }), displayField: 'columnName', valueField: 'columnId', typeAhead: true, triggerAction: 'all', lazyRender: true, editable: false, mode: 'local', emptyText: 'Column index ...' }); // *************************************************************************************************** // Grid // *************************************************************************************************** var tpl_DescriptionTemplate = new Ext.XTemplate( '', '', '', '', '', '
', '{stockDesc}', '', '{stockDesc}', '
' ); // Column Models var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'Supplier name', dataIndex: 'supplierName', hidden: true }, { header: 'stockSupplierId', dataIndex: 'stockSupplierId', hidden: true }, { header: '', dataIndex: 'stockSupplierId', hidden: false, width: 2, //renderer: Ext.util.Format.comboRenderer(cmbSupplier) renderer: function(val, meta, theRecord) { try{ if (theRecord.data.iconCls == '' || theRecord.data.iconCls == null || theRecord.data.iconCls == "icon-item-normal"){ var result = markNormal("", true); if (val < 0) result = markNew(result, true); if (!theRecord.data.isActive) result = markDeleted(result, true); if (theRecord.data.isFromOnline) result = markOnline(result, true); return result; } else { var result = markCustom(theRecord.data.iconCls, theRecord.data.iconTip); return result; } }catch(e){}; return "???"; } }, { header: 'Your code'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockCode', width: 10, hidden : theThis.HideColumn_StockCode || theThis.isSupplierVersion, editor: { xtype: 'textfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }, renderer : function(val){ if (val == "") { return 'Enter your code'; } else return ''+val+''; } }, { header: 'Supplier\'s code'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'supplierStockCode', width: 10, hidden : theThis.HideColumn_SupplierStockCode, editor: { xtype: 'textfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }, renderer : function(val){ if (val == "") { return 'Enter supplier\'s code'; } else return ''+val+''; } }, { header: 'Description'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockDesc', width: 20, editor: { xtype: 'textfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }, renderer : function(val, meta, theRecord){ if (val == "") { return 'Enter your description here'; } else if (val == "New desc") { return String.format('{0}', val); } else { var imageUrl = theRecord.data.imageUrl; var stockDesc = val; var stockSupplierId = theRecord.data.stockSupplierId; var panelId = theThis.id; if (imageUrl != null && imageUrl != "") { return tpl_DescriptionTemplate.apply({imageUrl : imageUrl, stockDesc : stockDesc}); } else return ''+val+''; } } }, { header: 'Cost'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'supplierCost', width: 8, renderer: Ext.util.Format.usMoney, editor: new fm.NumberField({ xtype: 'numberfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'Amount'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockUnit', width: 5, renderer : function(val, meta, record){ if (record.data.isFromOnline){ return '
 ' + val; } else return val; }, editor: new fm.NumberField({ xtype: 'numberfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'Unit', dataIndex: 'unitOfMeasurementId', width: 5, /*editor: new Ext.grid.GridEditor( new Ext.form.ComboBox({ store: Global_UnitOfMeasurement_Store, displayField: 'UOMName', valueField: 'UOMId', typeAhead: false, triggerAction: 'all', editable: true, lazyRender: true, mode: 'local', autoSelect : true }), { listeners: { beforestartedit: function(editor) { editor.field.currentRecord = editor.record; }, complete : function(p_This, p_Value, p_StartValue){ // Value has been changed by user if (p_Value != p_StartValue){ //updateTheSubtotal(p_This.record); if (Global_UnitOfMeasurement_Store.getById(p_Value) == null) { // Rollback p_This.record.set('unitOfMeasurementId', p_StartValue); } } } } } ),*/ // CONTINUE HERE editor: cmbGridUOM, renderer : function(val, meta, record){ return Global_UnitOfMeasurement_Store.getById(val).data.UOMName; } }, { header: 'Amount', dataIndex: 'supplierSellingUnit', width: 5, hidden : true, //(theThis.readOnly || theThis.HideColumn_InvoiceUnit), editor: new fm.NumberField({ xtype: 'numberfield', allowBlank: false, allowNegative: false, allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'Type', dataIndex: 'supplierUnitMeasurement', width: 5, hidden : (theThis.readOnly || theThis.HideColumn_InvoiceUOM), editor: cmb_SupplierMeasurements, renderer: function(value, meta, theRecord){ if (value == null || value == '') return '[None]'; else return value; } }, { header: 'Category'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockCategoryId', width: 10, editor: cmbGridStockCategory, renderer: Ext.util.Format.comboRenderer(cmbGridStockCategory) }, { header: 'Wastage'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockWastage', width: 5, hidden : theThis.HideColumn_Wastage || theThis.isSupplierVersion, renderer: function (val) { return val + "%"; }, editor: new fm.NumberField({ xtype: 'numberfield', allowBlank: false, allowNegative: false, maxValue: 100, decimalPrecision: 2, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'Par Level'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'stockParLevel', width: 5, hidden : theThis.HideColumn_ParLevel || theThis.isSupplierVersion, filter: { xtype : "combo", filterName : "stockParLevel", store: new Ext.data.ArrayStore({ fields: [ {name: 'filterId' , type: 'string'}, {name: 'filterValue' , type: 'string'} ], data : [ [-1, 'None'], [1, 'Low'], [2, 'Medium'], [3, 'High'] ] }), editable: false, displayField: 'filterValue', valueField: 'filterId', typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Filter...', autoSelect : true, value : theThis.stockParLevelCategoryId, parentComponent : theThis, callbackFunction : function(filterValue){ if (theThis.stockParLevelCategoryId != filterValue) { // Change the header text of this column var modifiedRecords = theThis.grid_StockBySuppliers.getStore().getModifiedRecords(); if (modifiedRecords.length > 0) { showConfirmMessage('You have made some change(s). Do you want to save first ?', function(){ theThis.saveData(function(){ theThis.stockParLevelCategoryId = filterValue; theThis.btn_StockBySupplier_StopSearch.handler.call(theThis.btn_StockBySupplier_StopSearch.scope); }); }, function(){ theThis.stockParLevelCategoryId = filterValue; theThis.grid_StockBySuppliers.getStore().commitChanges(); theThis.btn_StockBySupplier_StopSearch.handler.call(theThis.btn_StockBySupplier_StopSearch.scope); } ) } else { theThis.stockParLevelCategoryId = filterValue; theThis.btn_StockBySupplier_StopSearch.handler.call(theThis.btn_StockBySupplier_StopSearch.scope); } } } }, editor: new fm.NumberField({ xtype: 'numberfield', allowBlank: false, onFocus: function (txt, e) { this.getEl().dom.select(); } }) }, { header: 'GST'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'isGstApplied', width: 5, hidden : theThis.HideColumn_GST, renderer: function(value, meta, theRecord) { try{ var stockSupplierId = theRecord.data.stockSupplierId; return ""; }catch(e){} return ""; } }, { header: 'Nutrition'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'isNutritionLinked', width: 5, hidden : theThis.HideColumn_Nutrition, renderer: function(value, meta, theRecord) { try{ var stockSupplierId = theRecord.data.stockSupplierId; return ""; }catch(e){} return ""; } }, { header: 'Active'/* + CTB_SYMBOL.EDIT*/, dataIndex: 'isDisplayedOnReport', width: 5, hidden : theThis.HideColumn_Report, tooltip: 'Report', renderer: function(value, meta, theRecord) { try{ var stockSupplierId = theRecord.data.stockSupplierId; return ""; }catch(e){} return ""; } }, { header: CTB.init.languageDictionary.GetValue("FOOD_RELATED").replace(' ', '
'), dataIndex: 'isNonFoodItem', width: 5, hidden : theThis.HideColumn_Report, renderer: function(value, meta, theRecord) { try{ var stockSupplierId = theRecord.data.stockSupplierId; value = !value; return ""; }catch(e){} return ""; /*if (value == false) return '
'; else return '
';*/ } }, { header: '
Unit
Available
', dataIndex: 'unitAvailable', width: 5, hidden : theThis.HideColumn_UnitAvailable, renderer : function(val){ if (val == -1) return 'Unknown'; else return val; } }, { header: '
Unit
Points
', dataIndex: 'unitPoints', width: 5, hidden : theThis.HideColumn_UnitPoints, renderer : function(val){ if (val == -1) return 'Unknown'; else return val; } }, { header: 'Column'+CTB_SYMBOL.EDIT+'
Index', dataIndex: 'orderingTemplateColumnIndex', width: 5, hidden : !theThis.isSupplierVersion, editor : theThis.cmb_SupplierOrderTemplate_ColumnIndex, renderer : Ext.util.Format.comboRenderer(theThis.cmb_SupplierOrderTemplate_ColumnIndex) } ] }); // End cm // Grouping headers var cityGroupRow = [ {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: 'Stock Measurement', colspan: 2, align: 'left'}, {header: '', align: 'left'}, {header: 'Packaging', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'}, {header: '', align: 'left'} ]; var group = new Ext.ux.grid.ColumnHeaderGroup({ rows: [cityGroupRow] }); // Searching combobox var data_SearchType = [ ['By supplier\'s code', 1], ['By stock description', 2], // ['By stock category', 4],// The 4 is search by stock category name ['By stock category', 6],// The 3 has been used to search by alphabetical ['By supplier\'s online products', 5] // Online product ]; theThis.cmb_StockCategory = theThis.getCombobox_StockCategory(true, 137); theThis.cmb_StockCategory.on({ select: function (p_combo, p_record, p_index) { theThis.doSearchByStockCategoryId(); } }); theThis.cmb_Search = new Ext.form.ComboBox({ cellCls : 'ctb-tablelayout-cell ctb-tablelayout-cell-left', store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ], data : data_SearchType }), displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, editable: false, triggerAction: 'all', lazyRender: true, width : 200, mode: 'local', emptyText: 'Choose search by ...' }); theThis.cmb_Search.setValue(2); theThis.cmb_Search.on({ select: function (p_combo, p_record, p_index) { var searchType = p_record.get('searchType'); if (searchType == 6){ theThis.cmb_StockCategory.setVisible(true); theThis.txt_StockBySupplier_SearchStockValue.setVisible(false); } else { theThis.cmb_StockCategory.setVisible(false); theThis.txt_StockBySupplier_SearchStockValue.setVisible(true); } } }); // Paging toolbar theThis.pt_StockBrowser_StockBySupplier = new Ext.CTBPagingToolbar({ store: store, pageSize: theThis.Global_StockBrowser_PageSize, displayInfo: true, emptyMsg: "No stocks to display" }); // Top bar var tbar = theThis.isFromImportDatabase == false ? theThis.initTopBar() : null; // Grid var grid_StockBySuppliers = new Ext.grid.EditorGridPanel({ region: 'center', store: store, cm : cm, sm : sm, frame: false, margins : '5 10 5 10', buttonAlign : 'left', plugins: [group, new Ext.ux.grid.GridHeaderFilters()], listeners : { rowmousedown: function() { hinderSelection = true; }, beforeedit : function(p_Editor) { if (p_Editor.field == 'supplierUnitMeasurement'){ p_Editor.record.oldData = p_Editor.record.data.supplierUnitMeasurement; } }, afteredit : function(p_Editor) { if (p_Editor.field == 'supplierUnitMeasurement'){ if (p_Editor.record.data.supplierUnitMeasurement == ""){ p_Editor.record.set('supplierUnitMeasurement', p_Editor.record.oldData); } } else if (p_Editor.field == 'orderingTemplateColumnIndex'){ // Change other record with the same stock category as well var theStore = p_Editor.grid.getStore(); var theRecord = p_Editor.record; for (var i = 0; i < theStore.getCount(); i++) { if (theStore.getAt(i) != null && theStore.getAt(i).data.stockCategoryId == theRecord.data.stockCategoryId && theStore.getAt(i).data.stockSupplierId != theRecord.data.stockSupplierId){ theStore.getAt(i).set('orderingTemplateColumnIndex', theRecord.data.orderingTemplateColumnIndex); } } } }, rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, beforeshow : function(p_This) { }, afterrender : function(p_This) { } }, tbar: tbar, autoHeight: false, clicksToEdit: theThis.readOnly ? 2 : 1, loadMask: true, bbar: theThis.pt_StockBrowser_StockBySupplier, view: new Ext.grid.GroupingView({ forceFit: true, // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) groupTextTpl: '{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})', getRowClass: function(record, index) { if (record.data.isNonFoodItem){ return 'nonfooditem_row'; } } }) }); return grid_StockBySuppliers; }, // End generateGrid_StockBySuppliers initTopBar: function(){ var theThis = this; if (!theThis.readOnly){ theThis.dlg_DuplicatedStockDetector = new Ext.CTBDuplicatedStockDetector({ callback_AfterHide : function(){ theThis.getGrid().getStore().reload(); } }); } var tbar = [ theThis.btn_StockBySupplier_Add_Stock = new Ext.Button({ iconCls: 'icon-add', scale : 'large', hidden : theThis.readOnly, text: 'New', //disabled: true, handler: function () { if (theThis.cmbSupplier.getStore().getById(theThis.cmbSupplier.getValue()) == null) { Ext.Msg.show({ title:'Notice', msg: 'Please select a supplier!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); return; } var selectedSupplierRecord = theThis.cmbSupplier.getStore().getById(theThis.cmbSupplier.getValue()); var newId = -getRandomNumber(); // Negative for new entry var uniqueCode = getUniqueTime(); var aNewRecord = new theThis.Global_StockBrowser_StockSupplierRecord({ stockSupplierId : newId, supplierStockCode : '', supplierCost : 0, supplierId : theThis.cmbSupplier.getValue(), supplierName : theThis.cmbSupplier.getRawValue(), stockId : -1, stockCode : uniqueCode, stockDesc : "New desc", stockUnit : 1, unitOfMeasurementId : 1, stockCategoryId : selectedSupplierRecord.data.defaultStockCategoryId, stockWastage : 0, stockParLevel : 0, isGstApplied : false, isNutritionLinked : false, isDisplayedOnReport : true, isActive : true, supplierSellingUnit : 1, supplierUnitMeasurement : 'EA' }, newId); theThis.grid_StockBySuppliers.stopEditing(); theThis.grid_StockBySuppliers.getStore().insert(0, aNewRecord); theThis.grid_StockBySuppliers.getStore().getById(newId).set('supplierStockCode', uniqueCode); } }), //theThis.readOnly ? '' : '-', theThis.btn_StockBySupplier_Delete_Stock = new Ext.Button({ iconCls: 'icon-delete', scale : 'large', hidden : theThis.readOnly, text: 'Delete', handler: function () { var selectedItems = theThis.grid_StockBySuppliers.getSelectionModel().getSelections(); if (selectedItems.length > 0) { for (var i = 0, row; row = selectedItems[i]; i++) { row.set('isActive', false); } } else { Ext.Msg.show({ title:'Notice', msg: 'Please select item(s) to delete!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } // End if } }), theThis.btn_Save = new Ext.Button({ iconCls : 'icon-save-large', scale : 'large', //cls : 'ctb-btn-red', hidden : theThis.readOnly, text : 'Save', handler : function(){ theThis.saveData(); } }), // And Save button theThis.btn_Refresh = new Ext.Button({ // text: 'Refresh', iconCls: 'icon-stop-search', handler: function (button, event) { theThis.cmbSupplier.getStore().reload(); theThis.grid_StockBySuppliers.getStore().commitChanges(); Ext.apply(theThis.grid_StockBySuppliers.getStore().baseParams, { keyword : "", searchType : -1, start : 0, limit : theThis.getPagingToolbar().pageSize, stockParLevelCategoryId : theThis.stockParLevelCategoryId }); theThis.grid_StockBySuppliers.getStore().load(); } }), // And Save button theThis.btn_More = new Ext.Button({ iconCls : 'icon-v3-dropdown-more', text : 'More', iconAlign : 'right', handler: function (button, e) { if (theThis.menu_ViewOptions == null) { theThis.menu_ViewOptions = new Ext.menu.Menu({ items: [ theThis.btn_Populate = new Ext.menu.Item({ //iconCls : 'icon-populate-large', scale : 'large', hidden : theThis.readOnly, tooltip : 'Populate the supplier\' stock list by select stocks from your inventory.', text : 'Populate', handler : function(){ theThis.showAllStocks(function(selectedStocks, supplierId) { var listOfStockIds = new Array(); for (var i = 0; i < selectedStocks.length; i++) { listOfStockIds[i] = selectedStocks[i].data.stockId; } theThis.loadMask.show(); // Sending ajax request Ext.Ajax.request({ method: "POST", url: '/StockSupplier/AssignStocksToSupplier', params: { supplierId : supplierId, listOfStockIds : Ext.util.JSON.encode(listOfStockIds) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.grid_StockBySuppliers.getStore().reload(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax }); } }), // And Save button theThis.btn_Print = new Ext.menu.Item({ //iconCls : 'icon-print-large', scale : 'large', text : 'Print', handler : function(){ theThis.printStockList(); } }), '-', theThis.btn_DetectDuplicatedStock = new Ext.menu.Item({ //iconCls: 'icon-fix', scale : 'large', //hidden : theThis.readOnly, text: 'Detect Duplicated Stock', handler: function () { if (theThis.cmbSupplier.getValue() != ''){ showInputMessage('Please enter the stock\'s name that you think you have duplicated instances. Example : apple', function(text){ theThis.dlg_DuplicatedStockDetector.stockDesc = text; theThis.dlg_DuplicatedStockDetector.supplierId = theThis.cmbSupplier.getValue(); theThis.dlg_DuplicatedStockDetector.show(); } ); } else { showErrorNotification('Notice', 'Please select supplier !'); } } }), theThis.btn_UpdateStocksFromSupplier = new Ext.menu.Item({ //iconCls: 'icon-update-large', scale : 'large', hidden : theThis.readOnly, text: 'Update stocks', tooltip : 'Update stocks automatically from supplier database. This feature is only available for some suppliers.', handler: function () { if (theThis.cmbSupplier.getValue() != ''){ theThis.loadMask.show(); // Sending ajax request Ext.Ajax.request({ method: "POST", url: '/StockSupplier/UpdateStocksFromSupplier', params: { supplierId : theThis.cmbSupplier.getValue() }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.grid_StockBySuppliers.getStore().reload(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } else { showErrorNotification('Notice', 'Please select supplier !'); } } }), theThis.btn_UpdateStocksFromSupplier = new Ext.menu.Item({ //iconCls: 'icon-drawer', scale : 'large', hidden : theThis.readOnly, text: 'Get Pantry List', tooltip : 'Get your pantry list in the supplier database. You will be able to select stock to import. This feature is only available for some suppliers (PFD)', handler: function () { if (theThis.cmbSupplier.getValue() != ''){ if (theThis.dlg_SupplierPantryListWindow == null){ theThis.dlg_SupplierPantryListWindow = new Ext.CTBSupplierPantryListWindow({ callback_AfterImport : function(){ theThis.grid_StockBySuppliers.getStore().reload(); } }); } theThis.dlg_SupplierPantryListWindow.setSupplierId(theThis.cmbSupplier.getValue()); theThis.dlg_SupplierPantryListWindow.show(); } else { showErrorNotification('Notice', 'Please select supplier !'); } } }), theThis.btn_SwitchSupplier = new Ext.menu.Item({ //iconCls: 'icon-switch', scale : 'large', hidden : theThis.readOnly, //colspan : 2, text: 'Switch Supplier', tooltip : 'Switch stocks that were supplied by selected supplier to another supplier. The change will affect recipes\'s ingredients.', handler: function () { if (theThis.cmbSupplier.getValue() != ''){ if (theThis.dlg_SwitchSupplier == null){ theThis.dlg_SwitchSupplier = new Ext.CTBSwitchSupplierWindow({ }); } theThis.dlg_SwitchSupplier.setSupplierId(theThis.cmbSupplier.getValue()); theThis.dlg_SwitchSupplier.show(); } else { showErrorNotification('Notice', 'Please select supplier !'); } } }), theThis.btn_TodaySpecial = new Ext.menu.Item({ //scale : 'large', text : 'Today Special', handler : function(){ if (theThis.cmbSupplier.getValue() != '') { if (theThis.dlg_OrderTemplateProductAvailability == null) { theThis.dlg_OrderTemplateProductAvailability = new Ext.CTBOrderTemplate_ProductAvailability({ title : 'Today Special' }); } theThis.dlg_OrderTemplateProductAvailability.setTitle('Today Special'); theThis.dlg_OrderTemplateProductAvailability.productAvailabilityType = 'TODAY_SPECIAL'; theThis.dlg_OrderTemplateProductAvailability.supplierId = theThis.cmbSupplier.getValue(); theThis.dlg_OrderTemplateProductAvailability.show(); } } }), theThis.btn_WhatsInSeason = new Ext.menu.Item({ //scale : 'large', text : 'What\'s in season', handler : function(){ if (theThis.cmbSupplier.getValue() != '') { Ext.Msg.buttonText={ cancel: 'Cancel', no: 'Not in season products', ok: 'Ok', yes: 'In season products' }; Ext.Msg.show({ title: 'Notice', msg: 'What do you want to set up ?', buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.INFO, yes: 'In season', no: 'Not in season', fn : function(btn) { if (btn == "yes") { if (theThis.dlg_OrderTemplateProductAvailability == null) { theThis.dlg_OrderTemplateProductAvailability = new Ext.CTBOrderTemplate_ProductAvailability({ title : 'What\'s in season' }); } theThis.dlg_OrderTemplateProductAvailability.setTitle('What\'s in season'); theThis.dlg_OrderTemplateProductAvailability.productAvailabilityType = 'IN_SEASON'; theThis.dlg_OrderTemplateProductAvailability.supplierId = theThis.cmbSupplier.getValue(); theThis.dlg_OrderTemplateProductAvailability.show(); } else if (btn == "no"){ if (theThis.dlg_OrderTemplateProductAvailability == null) { theThis.dlg_OrderTemplateProductAvailability = new Ext.CTBOrderTemplate_ProductAvailability({ title : 'What\'s not in season' }); } theThis.dlg_OrderTemplateProductAvailability.setTitle('What\'s not in season'); theThis.dlg_OrderTemplateProductAvailability.productAvailabilityType = 'NOT_IN_SEASON'; theThis.dlg_OrderTemplateProductAvailability.supplierId = theThis.cmbSupplier.getValue(); theThis.dlg_OrderTemplateProductAvailability.show(); } } }); } else { showErrorNotification('Notice', 'Please select a supplier'); } } }), // End button '-', theThis.btn_ApproveStock = new Ext.menu.Item({ //iconCls : 'icon-thumb-up', //scale : 'large', text : 'Approve', handler : function(){ theThis.approveStock(true); } }), theThis.btn_DisapproveStock = new Ext.menu.Item({ //iconCls : 'icon-thumb-down', //scale : 'large', text : 'Disapprove', handler : function(){ theThis.approveStock(false); } }) ] // menu items }); // End menu declaration } // End "if" checking menu existence // Show the menu theThis.menu_ViewOptions.show(e.getTarget()); } // End "More" button handler }) /*theThis.btnGroup_Management = new Ext.ButtonGroup({ xtype: 'buttongroup', title: 'Management', hidden: theThis.readOnly, columns: 3, defaults: { scale: 'large' }, items : [ //theThis.readOnly ? '' : '-', ] }), theThis.btnGroup_Function = new Ext.ButtonGroup({ xtype: 'buttongroup', title: 'Additional Functions', hidden: theThis.readOnly, columns: 3, defaults: { scale: 'large' }, items : [ //'-', ] }), theThis.btnGroup_Approval = new Ext.ButtonGroup({ xtype: 'buttongroup', title: 'Approval', hidden: true, columns: 1, defaults: { scale: 'large' }, items : [ theThis.btn_ApproveStock = new Ext.Button({ iconCls : 'icon-thumb-up', scale : 'large', text : 'Approve', handler : function(){ theThis.approveStock(true); } }), theThis.btn_DisapproveStock = new Ext.Button({ iconCls : 'icon-thumb-down', scale : 'large', text : 'Disapprove', handler : function(){ theThis.approveStock(false); } }) ] })*/ ]; // tbar = tbar.concat(tbar_ReadOnly); return tbar; }, // End initTopBar saveData : function(callback_Function){ var theThis = this; // Get modified records theThis.grid_StockBySuppliers.stopEditing(); var modifiedRecords = theThis.grid_StockBySuppliers.getStore().getModifiedRecords(); var jsonArray = new Array(); // Check the search type if (theThis.cmb_Search.getValue() == 5) // Online products { // The modified records become the selected records modifiedRecords = theThis.grid_StockBySuppliers.getSelectionModel().getSelections(); } var isContainingJunkStockDesc = false; for (var i = 0, row; row = modifiedRecords[i]; i++) { if (modifiedRecords[i].data.stockDesc == 'New desc' || modifiedRecords[i].data.stockDesc == '') isContainingJunkStockDesc = true; if (isNaN(modifiedRecords[i].data.unitOfMeasurementId)) { Ext.Msg.show({ title:'Notice', msg: 'The measurement "' + modifiedRecords[i].data.unitOfMeasurementId + '" does not exist.
Please consider to add new measurement in Admin/Unit Of Measurement', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); return; } jsonArray[i] = { stockSupplierId : modifiedRecords[i].data.stockSupplierId, supplierStockCode : modifiedRecords[i].data.supplierStockCode, supplierCost : modifiedRecords[i].data.supplierCost, supplierId : modifiedRecords[i].data.supplierId, //supplierName : modifiedRecords[i].data.stockSupplierId, stockId : modifiedRecords[i].data.stockId, stockCode : modifiedRecords[i].data.stockCode, stockDesc : modifiedRecords[i].data.stockDesc, stockUnit : modifiedRecords[i].data.stockUnit, unitOfMeasurementId : modifiedRecords[i].data.unitOfMeasurementId, stockCategoryId : modifiedRecords[i].data.stockCategoryId, stockWastage : modifiedRecords[i].data.stockWastage, stockParLevel : modifiedRecords[i].data.stockParLevel, isGstApplied : modifiedRecords[i].data.isGstApplied, isNutritionLinked : modifiedRecords[i].data.isNutritionLinked, isDisplayedOnReport : modifiedRecords[i].data.isDisplayedOnReport, isNonFoodItem : modifiedRecords[i].data.isNonFoodItem, isActive : modifiedRecords[i].data.isActive, supplierSellingUnit : modifiedRecords[i].data.supplierSellingUnit, supplierUnitMeasurement : modifiedRecords[i].data.supplierUnitMeasurement, orderingTemplateColumnIndex : modifiedRecords[i].data.orderingTemplateColumnIndex }; } // Not sending the save command if the stock desc is junk description if (isContainingJunkStockDesc){ showErrorNotification('Notice', 'Please change the description of the new stocks (\'New desc\') to more meaningful descriptions.'); } else { var listOfStockSuppliers = {listOfStockSuppliers : jsonArray}; var jsonObject = Ext.util.JSON.encode(listOfStockSuppliers); // Submit data theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/StockSupplier/SaveStockSuppliers', params: { jsonData : jsonObject, stockParLevelCategoryId : theThis.stockParLevelCategoryId }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); if (jsonData.data.numOfTransactionLogs > 0) { showTransactionLogMessageBox( 'Problem', 'There are some changes has been automatically apply to this process due to duplicated code.
Please watch the log report to see more details.', jsonData.data.transactionUniqueCode ); } if (jsonData.data.savingReturnResultList != null && jsonData.data.savingReturnResultList.length > 0) { var savedListNewIds = new Array(); var k = 0; for (var i = 0; i < jsonData.data.savingReturnResultList.length; i++) { var newId = jsonData.data.savingReturnResultList[i].newId; var oldId = jsonData.data.savingReturnResultList[i].oldId; // This condition is to prevent inserting a stock 2 time with the same new id var isContinue = false; for (var j = 0; j < savedListNewIds.length; j++){ if (savedListNewIds[j] == newId){ isContinue = true; break; } } if (isContinue) continue; savedListNewIds[k] = newId; k++; // Remove old record and insert new record to the same position var theCurrentRecord = theThis.grid_StockBySuppliers.getStore().getById(oldId); var supplierStockCode = jsonData.data.savingReturnResultList[i].ExtraInfo.supplierStockCode; var stockId = jsonData.data.savingReturnResultList[i].ExtraInfo.stockId; var stockCode = jsonData.data.savingReturnResultList[i].ExtraInfo.stockCode; var iconCls = jsonData.data.savingReturnResultList[i].ExtraInfo.iconCls; var iconTip = jsonData.data.savingReturnResultList[i].ExtraInfo.iconTip; theCurrentRecord.set('stockId', stockId); theCurrentRecord.set('stockCode', stockCode); theCurrentRecord.set('supplierStockCode', supplierStockCode); theCurrentRecord.set('iconCls', iconCls); theCurrentRecord.set('iconTip', iconTip); // Remove the old one var recordIndex = theThis.grid_StockBySuppliers.getStore().indexOf(theCurrentRecord); theThis.grid_StockBySuppliers.getStore().data.removeAt(recordIndex); // Insert the new one with the new id theCurrentRecord.data.stockSupplierId = newId; theThis.grid_StockBySuppliers.getStore().data.insert(recordIndex, newId, theCurrentRecord); } } // Delete deleted item var deletedRecords = new Array(); var j = 0; for (var i = 0; i < theThis.grid_StockBySuppliers.getStore().getCount(); i++){ var theRecord = theThis.grid_StockBySuppliers.getStore().getAt(i); // The second condition is to make sure the stock supplier is not being update will also be deleted (duplicated item) if ((theRecord.data.isActive == false && theRecord.data.iconCls == "icon-item-normal") || theRecord.data.stockSupplierId < 0){ deletedRecords[j] = theRecord; j++; } } // Real deleting process happen here for (var i = 0; i < deletedRecords.length; i++){ theThis.grid_StockBySuppliers.getStore().remove(deletedRecords[i]); } // Commit changes theThis.grid_StockBySuppliers.getStore().commitChanges(); // Call the callback function if (callback_Function != null) callback_Function(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); } }, // End saveData // Get combobox supplier getCombobox_Supplier : function() { var theThis = this; // Importing suppliers var store = new Ext.data.JsonStore({ baseParams : {isFromImportDatabase : theThis.isFromImportDatabase, IsForRequisitionIn : false}, autoLoad : false, proxy: new Ext.data.HttpProxy({ url: '/Supplier/GetAllSuppliers', dataType: 'json', method: 'POST' }), fields: [ { name: 'supId' , type: 'number' }, { name: 'supName' , type: 'string' }, { name: 'supFolderId' , type: 'number' }, { name: 'abnNo' , type: 'string' }, { name: 'accNo' , type: 'string' }, { name: 'paymentTerm' , type: 'string' }, { name: 'website' , type: 'string' }, { name: 'defaultStockCategoryId', type: 'number' }, { name: 'isDirectOrderSupplier' , type: 'boolean' }, { name: 'orderingPageView' , type: 'string' } ], root: 'data', idProperty : 'supId', listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(store); }, 'load' : function(){ if (cmbSupplier.callback_AfterLoad != null){ cmbSupplier.callback_AfterLoad(); cmbSupplier.callback_AfterLoad = null; } } } }); //store.load(); var cmbSupplier = new Ext.form.ComboBox({ store: store, cellCls : 'ctb-tablelayout-cell', displayField: 'supName', valueField: 'supId', typeAhead: true, editable: true, mode : 'remote', minChars: 1, //colspan : 3, listeners : { beforequery: function(qe){ delete qe.combo.lastQuery; // Reload every click } }, callback_AfterLoad : null, triggerAction: 'all', lazyRender: true, forceSelection: true, emptyText: 'Select a supplier ...', valueNotFoundText:'Select a supplier...', width: 338, //style: { fontSize: '11px' } }); return cmbSupplier; }, getCombobox_StockCategory : function(isHidden, width) { var theThis = this; if (isHidden == null) isHidden = false; var store = new Ext.data.Store({ baseParams : {isFromImportDatabase : theThis.isFromImportDatabase}, proxy: new Ext.data.HttpProxy({ url: '/StockCategory/GetAllStockCategories', dataType: 'json', method: 'POST' }), reader: new Ext.data.JsonReader({ fields: [ { name: 'stockCategoryId', type: 'number' }, { name: 'stockCategoryName', type: 'string' }, { name: 'numberOfStocks', type: 'number' } ], root: 'data' }), listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); store.load(); var config = { store: store, cellCls : 'ctb-tablelayout-cell', displayField: 'stockCategoryName', valueField: 'stockCategoryId', typeAhead: true, triggerAction: 'all', editable: true, lazyRender: true, hidden : isHidden, mode: 'local', emptyText : 'Select category ...', autoSelect : true, forceSelection: true, listeners : { focus: function(p_This){ p_This.getEl().dom.select(); } } }; if (width != null) config.width = width; var cmbGridStockCategory = new Ext.form.ComboBox(config); return cmbGridStockCategory; }, // End getCombobox_StockCategory approveStock : function(isApproved){ var theThis = this; // Get selected records var selectedRecords = theThis.grid_StockBySuppliers.getSelectionModel().getSelections(); var countApprovalItem = 0; var listOfStockSupplierIds = new Array(); if (selectedRecords.length > 0){ for (var i = 0; i < selectedRecords.length; i++){ if (selectedRecords[i].data.isRequireApprovalPermission){ listOfStockSupplierIds[countApprovalItem] = selectedRecords[i].data.stockSupplierId; countApprovalItem++; } } } if (countApprovalItem > 0) { var wrapperObject = { listOfNumbers : listOfStockSupplierIds }; // Function package function approveNow(reason){ theThis.loadMask.show(); Ext.Ajax.request({ method: "POST", url: "/ApprovalStock/ApproveStocks", params: { stockSupplierIds : Ext.util.JSON.encode(wrapperObject), isApproved : isApproved, reason : reason }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); } // Show confirmation message Ext.Msg.show({ title:'Confirm', msg: String.format('Are you sure you want to {0} the selected stock(s) ?', isApproved == true ? 'approve' : 'disapprove'), buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.QUESTION, fn : function(btn) { if (btn == "yes") { if (isApproved == false) // Disapprove { showInputMessage(String.format('Please enter the reason why you {0} the selected stock(s).', isApproved == true ? 'approve' : 'disapprove'), function(theReason){ approveNow(theReason); }, function(){ } ); } else approveNow(""); } } }); } else { showErrorNotification('Notice', String.format('Please select stocks to {0} ?', isApproved == true ? 'approve' : 'disapprove')); } }, doSearchByStockCategoryId : function() { var theThis = this; var validateFields = new Array(); validateFields[0] = { ID : theThis.cmb_StockCategory.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.NUMBER_ID }; validateFields[1] = { ID : theThis.cmbSupplier.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.NUMBER_ID }; // Call global validate field group if (validateFieldGroup(validateFields)) { var stockCategoryId = theThis.cmb_StockCategory.getValue(); Ext.apply(theThis.grid_StockBySuppliers.getStore().baseParams, { supplierId : theThis.cmbSupplier.getValue(), keyword : stockCategoryId, searchType : 6, start : 0, limit : theThis.getPagingToolbar().pageSize, isFromImportDatabase : theThis.isFromImportDatabase, stockParLevelCategoryId : theThis.stockParLevelCategoryId }); theThis.grid_StockBySuppliers.getStore().load(); } }, doNormalSearch : function(searchType, searchValue) { var theThis = this; var validateFields = new Array(); validateFields[0] = { ID : theThis.cmbSupplier.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.NUMBER_ID }; if (validateFieldGroup(validateFields)) { Ext.apply(theThis.grid_StockBySuppliers.getStore().baseParams, { supplierId : theThis.cmbSupplier.getValue(), keyword : searchValue, searchType : searchType, start : 0, limit : theThis.getPagingToolbar().pageSize, isFromImportDatabase : theThis.isFromImportDatabase, stockParLevelCategoryId : theThis.stockParLevelCategoryId }); theThis.grid_StockBySuppliers.getStore().load(); } }, showAllStocks : function(callbackFunction) { var theThis = this; var validateFields = new Array(); validateFields[0] = { ID : theThis.cmbSupplier.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.NUMBER_ID }; if (validateFieldGroup(validateFields)) { var supplierId = theThis.cmbSupplier.getValue(); if (theThis.dlg_StockBrowser == null) { theThis.dlg_StockBrowser = new Ext.CTBStockBrowser({ HideSupplierBy : true, HideColumn_StockCode : false, HideColumn_SupplierStockCode : false, HideColumn_ParLevel : true, HideColumn_GST : true, HideColumn_Nutrition : true, HideColumn_Report : true, HideColumn_Wastage : false, HideColumn_UnitAvailable : true, HideColumn_UnitPoints : true, HideColumn_InvoiceUnit : false, HideColumn_InvoiceUOM : false, HideTab_StockBySupplier : true, onlyReturnStockRecord : true, activeTab : 1 }); } theThis.dlg_StockBrowser.Global_StockBrowser_CallbackFunction = function(selectedStocks) { callbackFunction(selectedStocks, supplierId); } theThis.dlg_StockBrowser.show(); } }, printStockList : function(){ var theThis = this; if (theThis.cmbSupplier.getValue() != '') { var supplierIds = new Array(); supplierIds[0] = theThis.cmbSupplier.getValue(); theThis.reportLoadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Report/ShowStockListSheet', params : { supplierIds : Ext.util.JSON.encode(supplierIds), }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.reportLoadMask.setAfterHideCallbackFunction(function(){showReportMessageBox(jsonData.message.Info, false);}); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } theThis.reportLoadMask.hide(); }, failure : function(result, request) { theThis.reportLoadMask.hide(); } }); // End ajax } else { showErrorNotification('Notice', 'Please select a supplier'); } } }); //------------------------------------------------------------------------------------------------------------------ // All of the functions below is used to manipulate the check changes in the check boxs : GST, Nutrition, Report // Check box editor handler function chk_StockBySupplier_GSTApplied_OnChange(checkbox_Object, componentId) { var theContainer = Ext.getCmp(componentId); var theStore = theContainer.getGrid_StockBySuppliers().getStore(); theStore.getById(checkbox_Object.id).set('isGstApplied', checkbox_Object.checked); } function chk_StockBySupplier_Nutrition_OnChange(checkbox_Object, componentId) { var theContainer = Ext.getCmp(componentId); var theStore = theContainer.getGrid_StockBySuppliers().getStore(); NutritionCheckBoxOnChange(checkbox_Object, componentId); //theStore.getById(checkbox_Object.id).set('isNutritionLinked', checkbox_Object.checked); } function chk_StockBySupplier_Report_OnChange(checkbox_Object, componentId) { var theContainer = Ext.getCmp(componentId); var theStore = theContainer.getGrid_StockBySuppliers().getStore(); theStore.getById(checkbox_Object.id).set('isDisplayedOnReport', checkbox_Object.checked); } function chk_StockBySupplier_FoodRelated_OnChange(checkbox_Object, componentId) { var theContainer = Ext.getCmp(componentId); var theStore = theContainer.getGrid_StockBySuppliers().getStore(); theStore.getById(checkbox_Object.id).set('isNonFoodItem', !checkbox_Object.checked); } Ext.reg('CTBStockBySuppliers', Ext.CTBStockBySuppliers); Ext.CTBDuplicatedStockDetector = Ext.extend(Ext.Window, { title: 'Duplicated Stock Detector', layout: 'border', closeAction: 'hide', iconCls : 'icon-stock', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, //maximized : true, width:800, height:500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, pageSize : CTB.init.itemPerPage || 100, stockDesc : '', supplierId : -1, activeItem : 0, callback_AfterHide : null, listOfMergeStockSupplierIds : new Array(), mainStockSupplierId : -1, listeners : { scope : this, 'hide' : function(theThis){ if (theThis.callback_AfterHide != null){ theThis.callback_AfterHide(); } }, 'beforehide' : function(theThis){ theThis.Global_StockBrowser_AssignedSupplierId = -1; }, 'beforeshow' : function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 80); theThis.clearSelections(); }, 'show' : function(theThis){ theThis.resetState(); } }, resetState : function(){ var theThis = this; theThis.listOfMergeStockSupplierIds = new Array(); theThis.btn_Confirm.setVisible(false); theThis.btn_Merge.setVisible(true); theThis.pnl_Title.tpl.overwrite(theThis.pnl_Title.body, {content : 'Select the stocks that you think they are the same.'}); theThis.tab_StockBySuppliers.txt_StockBySupplier_SearchStockValue.setValue(theThis.stockDesc); theThis.tab_StockBySuppliers.cmbSupplier.setValue(theThis.supplierId); theThis.tab_StockBySuppliers.btn_Dialog_StockBySupplier_SearchStock.handler.call(theThis.tab_StockBySuppliers.btn_Dialog_StockBySupplier_SearchStock.scope); theThis.tab_StockBySuppliers.cmbSupplier.disable(); }, initComponent : function(){ var theThis = this; // Init buttons var myButtons = theThis.initButtons(); theThis.pnl_Title = new Ext.Panel({ region : 'north', height : 50, frame : true, tpl : new Ext.XTemplate( '', '
{content}', '' ) }); theThis.tab_StockBySuppliers = new Ext.CTBStockBySuppliers({ region : 'center', Global_StockBrowser_Parent : theThis, Global_StockBrowser_PageSize : theThis.pageSize, HideColumn_StockCode : true, HideColumn_SupplierStockCode : true, HideColumn_ParLevel : true, HideColumn_GST : true, HideColumn_Nutrition : true, HideColumn_Report : true, HideColumn_Wastage : true, readOnly : true }); theThis.items = [theThis.tab_StockBySuppliers, theThis.pnl_Title]; this.buttons = myButtons; this.initTools(); Ext.CTBDuplicatedStockDetector.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; if (theThis.tab_StockBySuppliers.rendered) theThis.tab_StockBySuppliers.clearSelections(); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_Merge = new Ext.Button({ text: 'Merge Selected Stock', tooltip : 'Merge all selected stock into one single stock item.', iconCls : 'icon-fix', scale : 'large', handler : function(){ var selectedRecords = theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getSelectionModel().getSelections(); if (selectedRecords.length == 0){ showErrorNotification('Notice', 'You haven\'t choose any stock to merge.'); return; } else { theThis.listOfMergeStockSupplierIds = new Array(); for (var i = 0; i < selectedRecords.length; i++){ theThis.listOfMergeStockSupplierIds[i] = selectedRecords[i].data.stockSupplierId; } } //theThis.setTitle('
Select the stock you want all of them to be.
'); theThis.pnl_Title.tpl.overwrite(theThis.pnl_Title.body, {content : 'Select the stock you want all of them to be.'}); theThis.btn_Confirm.setVisible(true); theThis.btn_Merge.setVisible(false); theThis.tab_StockBySuppliers.clearSelections(); } }), theThis.btn_Confirm = new Ext.Button({ text: 'Confirm Merging', tooltip : 'Merge all selected stock into one single stock item.', iconCls : 'icon-ok-large', scale : 'large', hidden : true, handler : function(){ var selectedRecords = theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getSelectionModel().getSelections(); if (selectedRecords.length == 1){ showConfirmMessage('Are you sure ?', function(){ theThis.mainStockSupplierId = selectedRecords[0].data.stockSupplierId; var wrapperObject = {listOfNumbers : theThis.listOfMergeStockSupplierIds}; theThis.tab_StockBySuppliers.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Stock/MergeDuplicatedStock', params: { mergeIntoStockSupplierId : theThis.mainStockSupplierId, listOfStockSupplierIds : Ext.util.JSON.encode(wrapperObject) }, success : function(result, request) { theThis.tab_StockBySuppliers.loadMask.hide(); theThis.resetState(); //theThis.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.tab_StockBySuppliers.loadMask.hide(); } }); } ); } else { if (selectedRecords.length == 0) showErrorNotification('Notice', 'Please select ONE merging stock.'); else showErrorNotification('Notice', 'You CAN NOT choose more than one merging stock.'); } } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } }) ]; return buttons; } }); Ext.reg('CTBDuplicatedStockDetector', Ext.CTBDuplicatedStockDetector); Ext.CTBStockBrowser = Ext.extend(Ext.Window, { title: 'Stock Browser', layout: 'border', closeAction: 'hide', iconCls : 'icon-v3-ctb-logo', cls : 'ctbwindow-detail-general', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, width:800, height:500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, Global_StockBrowser_CallbackFunction : null, callback_Cancel : null, Global_StockBrowser_AssignedSupplierId : -1, Global_StockBrowser_SelectedRecords : null, Global_StockBrowser_PageSize : CTB.init.itemPerPage || 100, Global_StockBrowser_SelectedStockId : -1, // This is use for all stock tab Global_StockBrowser_Callback_AfterShow : null, IsForRequisitionIn : false, HideSupplierBy : true, HideColumn_StockCode : false, HideColumn_SupplierStockCode : false, HideColumn_ParLevel : false, HideColumn_GST : false, HideColumn_Nutrition : false, HideColumn_Report : false, HideColumn_Wastage : false, HideColumn_UnitAvailable : true, HideColumn_UnitPoints : true, HideColumn_InvoiceUnit : false, HideColumn_InvoiceUOM : false, HideTab_Recipe : true, HideTab_StockBySupplier : false, onlyReturnStockRecord : false, returnRecipeRecords : false, // This flag = true will tell the browser to return the selected recipe records instead of convert the recipe to a stock item and return the stockSupplierId activeTab : 0, readOnly : false, searchAllStocksValue : '', isRecipeTotalCostIncludingLabour : false, forcedOutletId : -1, listeners : { scope : this, 'beforehide' : function(theThis){ theThis.Global_StockBrowser_AssignedSupplierId = -1; theThis.IsForRequisitionIn = false; theThis.callback_Cancel = null; // Reset theThis.forcedOutletId = -1; // Reset forced outlet ID everytime it's hidden }, 'beforeshow' : function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); theThis.clearSelections(); }, 'show' : function(theThis){ if (theThis.Global_StockBrowser_AssignedSupplierId != -1){ theThis.tab_StockBySuppliers.cmbSupplier.callback_AfterLoad = function(){ theThis.tab_StockBySuppliers.cmbSupplier.setValue(theThis.Global_StockBrowser_AssignedSupplierId); theThis.tab_StockBySuppliers.cmbSupplier.disable(); theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getStore().baseParams = {supplierId : theThis.Global_StockBrowser_AssignedSupplierId, start : 0, limit : theThis.Global_StockBrowser_PageSize}; theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getStore().load(); } // Hide list of all stocks theThis.allTabs.hideTabStripItem(theThis.tab_ListOfDistinctStock); } else { theThis.tab_StockBySuppliers.cmbSupplier.callback_AfterLoad = function(){ theThis.tab_StockBySuppliers.cmbSupplier.enable(); theThis.tab_StockBySuppliers.cmbSupplier.setValue(theThis.tab_StockBySuppliers.cmbSupplier.getStore().getAt(0).get('supId')); theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getStore().baseParams = {supplierId : theThis.tab_StockBySuppliers.cmbSupplier.getValue(), start: 0, limit : theThis.Global_StockBrowser_PageSize}; theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getStore().load(); } // Show list of all stocks theThis.allTabs.unhideTabStripItem(theThis.tab_ListOfDistinctStock); } if (theThis.IsForRequisitionIn) { theThis.tab_StockBySuppliers.cmbSupplier.getStore().baseParams.IsForRequisitionIn = true; theThis.allTabs.setActiveTab(theThis.tab_StockBySuppliers); // Hide list of all stocks theThis.allTabs.hideTabStripItem(theThis.tab_ListOfDistinctStock); // Reload the supplier list theThis.tab_StockBySuppliers.cmbSupplier.getStore().load(); } else { theThis.tab_StockBySuppliers.cmbSupplier.getStore().baseParams.IsForRequisitionIn = false; theThis.tab_StockBySuppliers.cmbSupplier.getStore().load(); } // Hide tab recipe if (theThis.HideTab_Recipe){ theThis.allTabs.hideTabStripItem(theThis.tab_Recipe); } // Hide tab stock by suppliers if (theThis.HideTab_StockBySupplier){ theThis.allTabs.hideTabStripItem(theThis.tab_StockBySuppliers); } if (theThis.Global_StockBrowser_Callback_AfterShow != null) { theThis.Global_StockBrowser_Callback_AfterShow(); theThis.Global_StockBrowser_Callback_AfterShow = null; } if (theThis.searchAllStocksValue != null && theThis.searchAllStocksValue != '') { theThis.tab_ListOfDistinctStock.searchByStockDescription(theThis.searchAllStocksValue); theThis.searchAllStocksValue = ''; } } }, initComponent : function(){ var theThis = this; // Init buttons var myButtons = theThis.initButtons(); theThis.tab_ListOfDistinctStock = new Ext.CTBAllStocks({ Global_StockBrowser_Parent : theThis, Global_StockBrowser_PageSize : theThis.Global_StockBrowser_PageSize, HideSupplierBy : theThis.HideSupplierBy, HideColumn_StockCode : theThis.HideColumn_StockCode, HideColumn_SupplierStockCode : theThis.HideColumn_SupplierStockCode, HideColumn_ParLevel : theThis.HideColumn_ParLevel, HideColumn_GST : theThis.HideColumn_GST, HideColumn_Nutrition : theThis.HideColumn_Nutrition, HideColumn_Report : theThis.HideColumn_Report, HideColumn_Wastage : theThis.HideColumn_Wastage, readOnly : theThis.readOnly }); theThis.tab_StockBySuppliers = new Ext.CTBStockBySuppliers({ Global_StockBrowser_Parent : theThis, Global_StockBrowser_PageSize : theThis.Global_StockBrowser_PageSize, HideColumn_StockCode : theThis.HideColumn_StockCode, HideColumn_SupplierStockCode : theThis.HideColumn_SupplierStockCode, HideColumn_ParLevel : theThis.HideColumn_ParLevel, HideColumn_GST : theThis.HideColumn_GST, HideColumn_Nutrition : theThis.HideColumn_Nutrition, HideColumn_Report : theThis.HideColumn_Report, HideColumn_Wastage : theThis.HideColumn_Wastage, HideColumn_UnitAvailable : theThis.HideColumn_UnitAvailable, HideColumn_UnitPoints : theThis.HideColumn_UnitPoints, HideColumn_InvoiceUnit : theThis.HideColumn_InvoiceUnit, HideColumn_InvoiceUOM : theThis.HideColumn_InvoiceUOM, readOnly : theThis.readOnly }); theThis.tab_Recipe = new Ext.CTBRecipeTreePanel({ title : 'Recipe', readOnly : true, HideWhatsNextButton : true, ShowCheckboxSelection : true, HideImportRecipeButton : true/*, listeners : { show : function(){ theThis.tab_Recipe.reloadData(); } }*/ }); // All tabs theThis.allTabs = new Ext.TabPanel({ region : 'center', margins : '5 0 0 0', activeTab : theThis.activeTab, defaults : { autoScroll: false }, items : [ theThis.tab_StockBySuppliers, theThis.tab_ListOfDistinctStock, theThis.tab_Recipe ] }); theThis.items = [theThis.allTabs]; this.buttons = myButtons; this.initTools(); Ext.CTBStockBrowser.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; if (theThis.tab_StockBySuppliers.rendered) theThis.tab_StockBySuppliers.clearSelections(); if (theThis.tab_ListOfDistinctStock.rendered) theThis.tab_ListOfDistinctStock.clearSelections(); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_SelectAndMoveToNextPage = new Ext.Button({ cls : 'ctb-btn-red', text: 'Select and move to next page', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ theThis.processSelections(true); } }), theThis.btn_Select = new Ext.Button({ cls : 'ctb-btn-red', text: 'Select', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ theThis.processSelections(); } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ if (theThis.callback_Cancel != null) theThis.callback_Cancel(); theThis.hide(); } }) ]; return buttons; }, returnStockRecordsOnly : function(){ var theThis = this; // Get selected stock var selectedStocks = theThis.tab_ListOfDistinctStock.getGrid_MasterStock().getSelectionModel().getSelections(); if (selectedStocks.length == 0) { showErrorNotification('Notice', 'Please select stocks.'); return; } theThis.Global_StockBrowser_CallbackFunction(selectedStocks); theThis.hide(); }, returnTabAllStocksSelections : function(processSelectionsNow){ var theThis = this; // Get selected stock var selectedStocks = theThis.tab_ListOfDistinctStock.getGrid_MasterStock().getSelectionModel().getSelections(); theThis.Global_StockBrowser_SelectedRecords = new Array(); for (var i = 0; i < selectedStocks.length; i++){ if (selectedStocks[i].data.stockSupplierId != -1){ theThis.Global_StockBrowser_SelectedRecords[i] = selectedStocks[i]; } else { theThis.Global_StockBrowser_SelectedRecords = null; showWarningMessage('Some stocks that you have choosen don\'t have supplier.
Please check the suppliers for these stocks.'); return; } } processSelectionsNow(); }, getStockSupplierIdsFromSelectedRecipes : function(recipeIds, recipeFolderIds, isRecipeTotalCostIncludingLabour, callback_Function){ var theThis = this; theThis.tab_Recipe.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/StockSupplier/GetStockSupplierIdsFromSelectedRecipes', params: { recipeIds : Ext.util.JSON.encode(recipeIds), recipeFolderIds : Ext.util.JSON.encode(recipeFolderIds), isRecipeTotalCostIncludingLabour : isRecipeTotalCostIncludingLabour, forcedOutletId : theThis.forcedOutletId }, success : function(result, request) { theThis.tab_Recipe.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { //showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.Global_StockBrowser_SelectedRecords = jsonData.data; callback_Function(); // jsonData.data is a list of stockSupplierIds returned } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.tab_Recipe.loadMask.hide(); } }); // End ajax }, returnTabRecipeSelections : function(processSelectionsNow){ var theThis = this; var selectedRecipes = theThis.tab_Recipe.getSelectedRecipes(); if (!theThis.returnRecipeRecords) { // Save recipe as stock items and then return the stockSupplierId(s) var recipeIds = new Array(); var recipeFolderIds = new Array(); for (var i = 0; i < selectedRecipes.length; i++){ var nodeId = getNumberIdFromStringId(selectedRecipes[i].id); var nodeType = getPrefixFromStringId(selectedRecipes[i].id); if (nodeType == 'recipe'){ recipeIds[recipeIds.length] = nodeId; } else if (nodeType == 'folder'){ recipeFolderIds[recipeFolderIds.length] = nodeId; } } // Don't need below code any more because will always get the total cost without labour /* Ext.Msg.show({ title:'Confirm', msg: 'Do you want to including labour into recipe\'s portion cost ?', buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.QUESTION, fn : function(btn) { if (btn == "yes") { theThis.isRecipeTotalCostIncludingLabour = true; } // End if else { theThis.isRecipeTotalCostIncludingLabour = false; } theThis.getStockSupplierIdsFromSelectedRecipes(recipeIds, recipeFolderIds, theThis.isRecipeTotalCostIncludingLabour, processSelectionsNow); } // End handler function });*/ theThis.isRecipeTotalCostIncludingLabour = false; theThis.getStockSupplierIdsFromSelectedRecipes(recipeIds, recipeFolderIds, theThis.isRecipeTotalCostIncludingLabour, processSelectionsNow); } else { theThis.tab_Recipe.getSelectedRecipeFullRecords(function(recipeRecords){ // Assign recipe records instead theThis.Global_StockBrowser_CallbackFunction(recipeRecords); theThis.hide(); }); } }, processSelections : function(isMoveToNextPage){ var theThis = this; if (isMoveToNextPage == null) isMoveToNextPage = false; // Default // This function will check the selected records and validate them before pass them to the callback function function processSelectionsNow(){ if (theThis.Global_StockBrowser_SelectedRecords != null && theThis.Global_StockBrowser_SelectedRecords.length > 0) { // Get selected stock supplier records for (var i = 0; i < theThis.Global_StockBrowser_SelectedRecords.length; i++) { // Save data automatically if it's from online store if (theThis.Global_StockBrowser_SelectedRecords[i].data.isFromOnline == true) { theThis.tab_StockBySuppliers.saveData(function(){ theThis.Global_StockBrowser_CallbackFunction(theThis.Global_StockBrowser_SelectedRecords); if (!isMoveToNextPage) theThis.hide(); }); return; } // Check if the stock is new and hasn't been saved if (theThis.Global_StockBrowser_SelectedRecords[i].data.stockSupplierId < 0 || theThis.Global_StockBrowser_SelectedRecords[i].data.stockId < 0 ) { Ext.Msg.show({ title:'Notice', msg: 'You have choosed some stocks has not been saved.
Please save before use.', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); return; } } if (!isMoveToNextPage) theThis.hide(); theThis.Global_StockBrowser_CallbackFunction(theThis.Global_StockBrowser_SelectedRecords); // If flag tell us to move to next page if (isMoveToNextPage) { // Check if there is possible to move to the next page if (theThis.allTabs.getActiveTab() == theThis.tab_ListOfDistinctStock) { var pt_StockBrowser_AllStocks = theThis.tab_ListOfDistinctStock.getPagingToolbar(); var activePage = Math.ceil((pt_StockBrowser_AllStocks.cursor + pt_StockBrowser_AllStocks.pageSize) / pt_StockBrowser_AllStocks.pageSize); var totalCount = theThis.tab_ListOfDistinctStock.getGrid_MasterStock().getStore().getTotalCount(); // Only move to next page if the active page is not out of range // Example : // activePage = 2 => activePage + 1 = 3 // totalCount = 160 // pageSize = 100 // Math.ceil(totalCount / pt_StockBrowser_AllStocks.pageSize) = 2 // So activePage > Math.ceil(totalCount / pt_StockBrowser_AllStocks.pageSize), we can not move if ((activePage+1) <= Math.ceil(totalCount / theThis.tab_ListOfDistinctStock.getPagingToolbar().pageSize)) { theThis.tab_ListOfDistinctStock.getPagingToolbar().moveNext(); } else { showErrorNotification('Notice', 'This is the last page !'); } } else if (theThis.allTabs.getActiveTab() == theThis.tab_StockBySuppliers) { var pt_StockBrowser_StockBySupplier = theThis.tab_StockBySuppliers.getPagingToolbar(); var activePage = Math.ceil((pt_StockBrowser_StockBySupplier.cursor + pt_StockBrowser_StockBySupplier.pageSize) / pt_StockBrowser_StockBySupplier.pageSize); var totalCount = theThis.tab_StockBySuppliers.getGrid_StockBySuppliers().getStore().getTotalCount(); // Only move to next page if the active page is not out of range // Example : // activePage = 2 => activePage + 1 = 3 // totalCount = 160 // pageSize = 100 // Math.ceil(totalCount / pt_StockBrowser_StockBySupplier.pageSize) = 2 // So activePage > Math.ceil(totalCount / pt_StockBrowser_StockBySupplier.pageSize), we cannot move if ((activePage+1) <= Math.ceil(totalCount / theThis.tab_StockBySuppliers.getPagingToolbar().pageSize)) { theThis.tab_StockBySuppliers.getPagingToolbar().moveNext(); } else { showErrorNotification('Notice', 'This is the last page !'); } } } } else { showWarningMessage('Please select some stocks !'); } } // Check if there is callback function has been set if (theThis.Global_StockBrowser_CallbackFunction != null) { var activeTab = theThis.allTabs.getActiveTab(); // This special condition is to only return stock record without stock-supplier relationship if (theThis.onlyReturnStockRecord == true && activeTab == theThis.tab_ListOfDistinctStock){ theThis.returnStockRecordsOnly(); return; } // If the selected record from All stocks tab if (activeTab == theThis.tab_ListOfDistinctStock) { theThis.returnTabAllStocksSelections(function(){ processSelectionsNow(); }); } else if (activeTab == theThis.tab_StockBySuppliers){ // Select stocks from StockBySupplier tab // Get selected stock var selectedStocks = theThis.tab_StockBySuppliers.getGrid().getSelectionModel().getSelections(); theThis.Global_StockBrowser_SelectedRecords = selectedStocks; processSelectionsNow(); } else if (activeTab == theThis.tab_Recipe) { // Select stocks from Recipe tab theThis.returnTabRecipeSelections(function(){ processSelectionsNow(); }); } } else { Ext.Msg.show({ title:'Notice', msg: 'Call back function has not been supplied !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } }); // Get combobox unit of measurement function getCombobox_UnitOfMeasurement() { var cmbGridUOM = new Ext.form.ComboBox({ store: Global_UnitOfMeasurement_Store, displayField: 'UOMName', valueField: 'UOMId', typeAhead: true, triggerAction: 'all', editable: true, lazyRender: true, mode: 'local', autoSelect : true, forceSelection: true, listeners: { focus: function(p_This){ p_This.getEl().dom.select(); /*setTimeout(function(){ p_This.getEl().dom.select(); }, 500);*/ } } }); return cmbGridUOM; } // Get combobox stock category function getCombobox_StockCategory() { var cmbGridStockCategory = new Ext.form.ComboBox({ store: Global_StockCategory_Store, displayField: 'stockCategoryName', valueField: 'stockCategoryId', typeAhead: true, triggerAction: 'all', editable: true, lazyRender: true, mode: 'local', autoSelect : true, forceSelection: true, listeners : { focus: function(p_This){ p_This.getEl().dom.select(); } } }); return cmbGridStockCategory; } Ext.reg('CTBStockBrowser', Ext.CTBStockBrowser); var Global_ContactBrowser_CallbackFunction; var Global_ContactBrowser_SelectedContactId = -1; // Nothing has been choosed var Global_ContactBrowser_SelectedRecords = null; //var Global_ContactBrowser_LoadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."}); var Global_ContactBrowser_PageSize = CTB.init.itemPerPage || 100; var Global_ContactBrowser_AssignedSupplierId = -1; function chk_PrimaryContact_OnChange(checkbox_Object, identifier) { if (identifier == null) identifier = ""; // Identifier is using for make another stock browser in the same script file (Prevent Duplicated ID) Ext.getCmp('grid_ContactBySuppliers' + identifier).getStore().getById(checkbox_Object.id).set('isPrimary', checkbox_Object.checked); } function getContactBrowserDialog(identifier){ if (identifier == null) identifier = ""; // Identifier is using for make another stock browser in the same script file (Prevent Duplicated ID) // Combobox supplier var cmbSupplier = getCombobox_ContactSupplier(identifier); // *************************************************************************************************** // Component Events // *************************************************************************************************** cmbSupplier.on({ select: function (p_combo, p_record, p_index) { var supplierId = p_record.get('supId'); //Global_ContactBrowser_SelectedSupplierId = supplierId; Ext.getCmp('grid_ContactBySuppliers' + identifier).getStore().baseParams = {supplierId : supplierId, start: 0, limit : Global_ContactBrowser_PageSize}; Ext.getCmp('grid_ContactBySuppliers' + identifier).getStore().load(); } }); // Get stock by suppliers tab var tab_ContactBySuppliers = getContactBySuppliers(identifier); if (identifier != "") return allTabs; // Only return the tab panel if the identifier has been set (use for Stock Maintenance) /**********************************/ /* Stock Browser Window Dialog */ /**********************************/ var ContactBrowserDialog = new Ext.Window({ title: 'Contact Browser', id : 'dlg_ContactBrowser', layout: 'border', closeAction: 'hide', iconCls : 'icon-stock', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, //maximized : true, width:800, height:500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, buttons: [{ text: 'Select and go to next page', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ if (Global_ContactBrowser_CallbackFunction) { //if (selectedSupplierIds.length > 0) if (Global_ContactBrowser_SelectedContactId != -1) { // Get selected stock supplier records for (var i = 0; i < Global_ContactBrowser_SelectedRecords.length; i++) { if (Global_ContactBrowser_SelectedRecords[i].data.contactId < 0) { Ext.Msg.show({ title:'Notice', msg: 'You have choosed some contacts has not been saved.
Please save before use.', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); return; } } Global_ContactBrowser_CallbackFunction(Global_ContactBrowser_SelectedRecords); } else { Ext.Msg.show({ title:'Notice', msg: 'Please select a contact', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } else { Ext.Msg.show({ title:'Notice', msg: 'Call back function has not been supplied !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } },{ text: 'Select', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ if (Global_ContactBrowser_CallbackFunction) { //if (selectedSupplierIds.length > 0) if (Global_ContactBrowser_SelectedContactId != -1) { // Get selected stock supplier records for (var i = 0; i < Global_ContactBrowser_SelectedRecords.length; i++) { if (Global_ContactBrowser_SelectedRecords[i].data.contactId < 0) { Ext.Msg.show({ title:'Notice', msg: 'You have choosed some contacts has not been saved.
Please save before use.', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); return; } } ContactBrowserDialog.hide(); Global_ContactBrowser_CallbackFunction(Global_ContactBrowser_SelectedRecords); } else { Ext.Msg.show({ title:'Notice', msg: 'Please select a contact', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } else { Ext.Msg.show({ title:'Notice', msg: 'Call back function has not been supplied !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } },{ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ ContactBrowserDialog.hide(); } }], items : [tab_ContactBySuppliers], listeners : { 'beforehide' : function(p_This){ Global_ContactBrowser_AssignedSupplierId = -1; }, 'beforeshow' : function(p_This){ // Fit this window to the client browser screen with 90% fitWindowSize(p_This, 80); }, 'show' : function(p_This){ if (Global_ContactBrowser_AssignedSupplierId != -1){ cmbSupplier.setValue(Global_ContactBrowser_AssignedSupplierId); cmbSupplier.disable(); Ext.getCmp('grid_ContactBySuppliers').getStore().baseParams = {supplierId : Global_ContactBrowser_AssignedSupplierId, start : 0, limit : Global_ContactBrowser_PageSize}; Ext.getCmp('grid_ContactBySuppliers').getStore().load(); } else { cmbSupplier.enable(); cmbSupplier.setValue(cmbSupplier.getStore().getAt(0).get('supId')); Ext.getCmp('grid_ContactBySuppliers').getStore().baseParams = {supplierId : cmbSupplier.getValue(), start: 0, limit : Global_ContactBrowser_PageSize}; Ext.getCmp('grid_ContactBySuppliers').getStore().load(); } //p_This.getEl().fadeIn(); } } }); return ContactBrowserDialog; } var Global_ContactBrowser_ContactRecord = null; // This return a panel // Contains list of stock but filter by supplier // Choose stocks in multiple mode (can choose more than one stock at the same time) function getContactBySuppliers(identifier) { if (identifier == null) identifier = ""; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** var record = Ext.data.Record.create([ { name: 'contactId', type: 'number' }, { name: 'contactFirstName', type: 'string' }, { name: 'phoneNo', type: 'string' }, { name: 'phone2', type: 'string' }, { name: 'phone3', type: 'string' }, { name: 'faxNo', type: 'string' }, { name: 'email', type: 'string' }, { name: 'website', type: 'string' }, { name: 'isPrimary', type: 'boolean' }, { name: 'notes', type: 'string' }, { name: 'supplierId', type: 'number' }, { name: 'isActive', type: 'boolean'}, // Using for deleting { name: 'outletId', type: 'number'} ]); Global_ContactBrowser_ContactRecord = record; // Initialize for the global variable // *************************************************************************************************** // Stores // *************************************************************************************************** var contactBySupplier_Store = new Ext.data.JsonStore({ baseParams : {supplierId: -1, start : 0, limit : Global_ContactBrowser_PageSize}, proxy: new Ext.data.HttpProxy({ url: '/Contact/SearchContactsBySupplierId', dataType: 'json', method: 'POST' }), fields: record, root: 'data', idProperty: 'contactId', totalProperty : 'totalCount', listeners : { 'load' : function(){ contactSm.clearSelections(); }, 'loadexception' : function(){ showStoreLoadingErrorMessage(contactBySupplier_Store); } } }); // *************************************************************************************************** // Combobox // *************************************************************************************************** var cmbSupplier = Ext.getCmp('cmb_ContactBrowser_Supplier' + identifier); //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var contactSm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment var selectedRecords = sm.getSelections(); // Assign the selected records Global_ContactBrowser_SelectedRecords = selectedRecords; // Assign the selected ids Global_ContactBrowser_SelectedContactId = -1; if (selectedRecords.length > 0){ Global_ContactBrowser_SelectedContactId = new Array(); for (var i = 0;i < selectedRecords.length;i++) { Global_ContactBrowser_SelectedContactId[i] = selectedRecords[i].data.contactId; } } } } }); // *************************************************************************************************** // Grid // *************************************************************************************************** // Column Models var contactCM = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ contactSm, { header: 'contactId', dataIndex: 'contactId', hidden: true }, { header: '', dataIndex: 'contactId', hidden: false, width: 2, //renderer: Ext.util.Format.comboRenderer(cmbSupplier) renderer: function(val) { var theRecord = contactBySupplier_Store.getById(val); var result = markNormal("", true); if (val < 0) result = markNew(result, true); if (!theRecord.data.isActive) result = markDeleted(result, true); return result; } }, { header: 'Name', dataIndex: 'contactFirstName', width : 18, editor: { xtype: 'textfield', allowBlank: false }, renderer : function(val){ if (val == "") { return 'Empty ...'; } else return ''+val+''; } }, { header: 'Email', dataIndex: 'email', width : 35, editor: { xtype: 'textfield', allowBlank: false }, renderer : function(val){ if (val == "") { return 'Empty ...'; } else return ''+val+''; } }, { header: 'Phone', dataIndex: 'phoneNo', width : 10, editor: { xtype: 'textfield', allowBlank: false }, renderer : function(val){ if (val == "") { return 'Empty ...'; } else return ''+val+''; } }, { header: 'Fax', dataIndex: 'faxNo', width : 10, editor: { xtype: 'textfield', allowBlank: false }, renderer : function(val){ if (val == "") { return 'Empty ...'; } else return ''+val+''; } }, { header: 'Website', dataIndex: 'website', width : 20, editor: { xtype: 'textfield', allowBlank: false }, renderer : function(val){ if (val == "") { return 'Empty ...'; } else return ''+val+''; } }, { header: 'Primary Contact', dataIndex: 'contactId', width: 5, renderer: function(value) { var realValue = grid_ContactBySuppliers.getStore().getById(value).get('isPrimary'); return ""; } } ] }); /********************************************************************************************/ var txt_ContactBySupplier_SearchContactValue; /****************************/ /* Master Stock Grid */ /****************************/ var grid_ContactBySuppliers = new Ext.grid.EditorGridPanel({ id : 'grid_ContactBySuppliers' + identifier, region: 'center', store: contactBySupplier_Store, frame: true, listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, beforeshow : function(p_This){ //cmbSupplier.reset(); } }, tbar: [ { xtype : 'button', iconCls : 'icon-save-large', scale : 'large', text : 'Save', handler : function(){ // Get modified records var modifiedRecords = grid_ContactBySuppliers.getStore().getModifiedRecords(); var jsonArray = new Array(); for (var i = 0, row; row = modifiedRecords[i]; i++) { jsonArray[i] = { contactId : modifiedRecords[i].data.contactId, contactFirstName : modifiedRecords[i].data.contactFirstName, phoneNo : modifiedRecords[i].data.phoneNo, phone2 : modifiedRecords[i].data.phone2, phone3 : modifiedRecords[i].data.phone3, faxNo : modifiedRecords[i].data.faxNo, email : modifiedRecords[i].data.email, website : modifiedRecords[i].data.website, isPrimary : modifiedRecords[i].data.isPrimary, notes : modifiedRecords[i].data.notes, supplierId : modifiedRecords[i].data.supplierId, isActive : modifiedRecords[i].data.isActive, outletId : modifiedRecords[i].data.outletId }; } var listOfContacts = {listOfContacts : jsonArray}; var jsonObject = Ext.util.JSON.encode(listOfContacts); // Submit data var Global_ContactBrowser_LoadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."}); Global_ContactBrowser_LoadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Contact/UpdateContacts', params: { contactData : jsonObject }, success : function(result, request) { Global_ContactBrowser_LoadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); grid_ContactBySuppliers.getStore().commitChanges(); grid_ContactBySuppliers.getStore().reload(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { Global_ContactBrowser_LoadMask.hide(); } }); } }, // And Save button '-', new Ext.Button({ iconCls: 'icon-add', scale : 'large', id : 'btn_Add_Contact' + identifier, text: 'Add', //disabled: true, handler: function () { if (cmbSupplier.getStore().getById(cmbSupplier.getValue()) == null) { Ext.Msg.show({ title:'Notice', msg: 'Please select a supplier!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); return; } var newId = -getRandomNumber(); // Negative for new entry var aNewRecord = new Global_ContactBrowser_ContactRecord({ contactId : newId, contactFirstName : 'Name', phoneNo : '', phone2 : '', phone3 : '', faxNo : '', email : '', website : '', isPrimary : false, notes : '', supplierId : cmbSupplier.getValue(), isActive : true, outletId : -1 }, newId); grid_ContactBySuppliers.stopEditing(); grid_ContactBySuppliers.getStore().insert(0, aNewRecord); grid_ContactBySuppliers.getStore().getById(newId).set('contactFirstName', ''); } }), '-', new Ext.Button({ iconCls: 'icon-delete', scale : 'large', text: 'Delete', id : 'btn_Delete_Contact' + identifier, //disabled: true, handler: function () { var selectedItems = grid_ContactBySuppliers.getSelectionModel().getSelections(); if (selectedItems.length > 0) { Ext.Msg.show({ title:'Confirm', msg: 'Are you sure you want to delete the contact(s) ?', buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.QUESTION, fn : function(btn) { if (btn == "yes") { for (var i = 0, row; row = selectedItems[i]; i++) { row.set('isActive', false); } } } }); } else { Ext.Msg.show({ title:'Notice', msg: 'Please select contact(s) to delete!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); }// End if } }), '-', { text: 'Refresh', iconCls: 'icon-refresh-large', scale : 'large', handler: function (button, event) { cmbSupplier.getStore().reload(); grid_ContactBySuppliers.getStore().commitChanges(); grid_ContactBySuppliers.getStore().reload(); } }, '-', ' Choose supplier : ', cmbSupplier, '-', { xtype : 'button', iconCls : 'icon-search-large', scale : 'large', id : 'btn_Dialog_ContactBySupplier_SearchContact' + identifier, text : 'Search', handler : function(){ var searchValue = txt_ContactBySupplier_SearchContactValue.getValue(); if (searchValue == "") { Ext.Msg.show({ title:'Notice', msg: 'Please enter value you want to search!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } else { grid_ContactBySuppliers.getStore().baseParams = {keyword : searchValue, supplierId : cmbSupplier.getValue(), start : 0, limit : Global_ContactBrowser_PageSize}; grid_ContactBySuppliers.getStore().load(); } } }, txt_ContactBySupplier_SearchContactValue = new Ext.form.TextField({ id : 'txt_ContactBySupplier_SearchContactValue' + identifier, emptyText : 'Name ...', listeners: { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { Ext.getCmp("btn_Dialog_ContactBySupplier_SearchContact" + identifier).handler.call(Ext.getCmp("btn_Dialog_ContactBySupplier_SearchContact" + identifier).scope); } } } }), { xtype : 'button', id : 'btn_ContactBySupplier_StopSearch' + identifier, iconCls : 'icon-stop-search', handler : function(){ cmbSupplier.reset(); grid_ContactBySuppliers.getStore().baseParams = {supplierId : -1, start : 0, limit : Global_ContactBrowser_PageSize}; grid_ContactBySuppliers.getStore().load(); } } ], cm: contactCM, sm : contactSm, autoHeight: false, clicksToEdit: 1, loadMask: true, bbar: new Ext.CTBPagingToolbar({ store: contactBySupplier_Store, pageSize: Global_ContactBrowser_PageSize, id: 'pt_ContactBrowser_ContactBySupplier' + identifier, displayInfo: true, emptyMsg: "No contacts to display" }), viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); // var wrapPanel = new Ext.Panel({ // layout : 'border', // region : 'center', // id : 'pnl_ContactBySuppliers' + identifier, // autoScroll: true, // items : [grid_ContactBySuppliers], // listeners : { // 'afterrender' : function(){ // // Do nothing // } // } // }); return grid_ContactBySuppliers; } // Get combobox supplier function getCombobox_ContactSupplier(identifier) { if (identifier == null) identifier = ""; var cmbSupplier = new Ext.form.ComboBox({ store: Global_Supplier_Store, id : 'cmb_ContactBrowser_Supplier' + identifier, displayField: 'supName', valueField: 'supId', typeAhead: true, mode : 'remote', listeners : { beforequery: function(qe){ delete qe.combo.lastQuery; // Reload every click } }, triggerAction: 'all', lazyRender: true, forceSelection: true, emptyText: 'Select a Supplier...', width: 200, style: { fontSize: '11px' } }); return cmbSupplier; } var MAIN_TAB_MARGINS_CONFIG = '155 0 0 0'; var DISPLAY_LOGIN_FORM_WHEN_SESSION_OUT = true; Ext.onReady(function () { /*var StockBrowserDialog = new Ext.CTBStockBrowser({ id : 'dlg_StockBrowser' });*/ // ------------------------------------------------------------------------------- // ALL TABS WRAPPER // ------------------------------------------------------------------------------- // Tab wrapper var allTabs = new Ext.TabPanel({ region:'center', activeTab: 0, activeTabIndex: 0, border : false, //margins: '115 5 0 5', //margins: '228 0 0 0', margins: MAIN_TAB_MARGINS_CONFIG, plain:true, id: 'tab_XeroSection', headerCfg : { cls : 'tab_XeroSection' }, defaults:{autoScroll: true}, items:[{ title: 'Order', id : 'pnl_Invoice', layout: 'fit' },{ title: 'Recipe Menu', id: 'pnl_RecipeMenu', layout: 'fit' },{ title: 'Revenue', id : 'pnl_Revenue', layout: 'fit' },{ title: 'Supplier', id : 'pnl_Supplier', layout: 'fit' },{ title: 'Inventory', layout: 'fit', id : 'pnl_StockMaintenance' },{ title: 'Report', id : 'pnl_ReportXero', layout: 'fit' } ], listeners : { tabchange : function(p_This, p_Tab){ if (p_Tab.getId() == "pnl_Invoice"){ setVideoHelp('uchF0kq64tM', 'Invoice'); } else if (p_Tab.getId() == "pnl_StockMaintenance") { setVideoHelp('HdoPvaMuxA0', 'Stock Maintenance'); } else if (p_Tab.getId() == "pnl_ReportXero"){ setVideoHelp(C_RECIPEBOOK_VIDEO_ID, C_RECIPEBOOK_VIDEO_DESC); } } } }); new Ext.Viewport({ layout : 'border', id : 'div_layout', items: [allTabs], cls : 'viewPortBody', renderTo: "div_layout" }); }); // End Ext.Ready function hideAllMainTabs(activeTab) { Ext.getCmp('tab_XeroSection').hideTabStripItem(Ext.getCmp('pnl_Invoice')); Ext.getCmp('tab_XeroSection').hideTabStripItem(Ext.getCmp('pnl_ReportXero')); Ext.getCmp('tab_XeroSection').hideTabStripItem(Ext.getCmp('pnl_StockMaintenance')); if (activeTab != null) { Ext.getCmp('tab_XeroSection').unhideTabStripItem(activeTab); Ext.getCmp('tab_XeroSection').setActiveTab(activeTab); } } function unhideAllMainTabs(beHiddenTab, focusTab) { Ext.getCmp('tab_XeroSection').unhideTabStripItem(Ext.getCmp('pnl_Invoice')); Ext.getCmp('tab_XeroSection').unhideTabStripItem(Ext.getCmp('pnl_ReportXero')); Ext.getCmp('tab_XeroSection').unhideTabStripItem(Ext.getCmp('pnl_StockMaintenance')); if (beHiddenTab != null) { Ext.getCmp('tab_XeroSection').hideTabStripItem(beHiddenTab); } if (focusTab != null) { Ext.getCmp('tab_XeroSection').setActiveTab(focusTab); } } Ext.CTBMYOBSelectCompanyFilesGrid = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: CTB.init.itemPerPage || 100, recordObject : null, instructionText : 'Select the company file you want to connect to', instructionBackgroundColor : '#66c010', callback_ContinueButtonClick : null, dlg_Parent : null, listeners : { afterrender : function(theThis){ // Init loadMask theThis.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); }, show : function(theThis){ } }, initComponent: function(){ var theThis = this; theThis.tpl_Instruction = new Ext.XTemplate( '', '
', '', '', '', '', '
', '{instructionText}', '
', '
', '
' ); theThis.pnl_Instruction = new Ext.Panel({ frame : true, region : 'north', height : 70, tpl : theThis.tpl_Instruction, listeners : { afterrender : function(p_This){ p_This.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); } } }); theThis.grid_CompanyFiles = theThis.getGrid_CompanyFiles(); theThis.items = [theThis.grid_CompanyFiles, theThis.pnl_Instruction]; // Call super class to initialize componenets Ext.CTBMYOBSelectCompanyFilesGrid.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_CompanyFiles; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_CompanyFile; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getStore().baseParams = {start : 0, limit : theThis.getPagingToolbar().pageSize}; theThis.getGrid().getStore().load(); }, getGrid_CompanyFiles: function(){ var theThis = this; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.companyFileRecord = Ext.data.Record.create([ { name: 'Id' , type: 'string' }, { name: 'LibraryPath' , type: 'string' }, { name: 'Name' , type: 'string' }, { name: 'ProductVersion' , type: 'string' }, { name: 'Uri' , type: 'string' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** theThis.store_CompanyFile = new Ext.data.GroupingStore({ proxy: new Ext.data.HttpProxy({ url: '/Kounta/GetCompanyFiles', dataType: 'json', method: 'POST' }), reader: new Ext.data.JsonReader({ fields: theThis.companyFileRecord, root: 'data', idProperty: 'Id', totalProperty : 'totalCount' }), autoLoad : false, groupField : 'ProductVersion', listeners : { 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(theThis.store_CompanyFile, function(){ CheckMYOBConnection(function(){ ShowSelectCompanyFilesDialog(); }); }); } } //}) }); // *************************************************************************************************** // Grid // *************************************************************************************************** //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment } } }); var companyFileSm = new Ext.grid.CheckboxSelectionModel({ singleSelect : true, listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { } } }); // Column Models var stockCM = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ companyFileSm, { header: 'Id', dataIndex: 'Id', width: 25 }, //{ header: 'LibraryPath', dataIndex: 'LibraryPath', width: 25 }, { header: 'Name', dataIndex: 'Name', width: 75 }, { header: 'ProductVersion', dataIndex: 'ProductVersion', hidden : true }, //{ header: 'Uri', dataIndex: 'Uri', width: 25 } ] }); // Context menu for right clicking var contextMenu = new Ext.menu.Menu({ items: [ { iconCls: 'icon-add', scale : 'large', text: 'New', handler: function () { theThis.btn_Add_CompanyFile.handler.call(theThis.btn_Add_CompanyFile.scope); } }, { iconCls: 'icon-delete', scale : 'large', text: 'Delete', handler: function () { theThis.btn_Delete_CompanyFile.handler.call(theThis.btn_Delete_CompanyFile.scope); } }, { iconCls: 'icon-recipe', text: 'View detail', handler: function () { if (theThis.selectedCompanyFileId != -1){ theThis.dlg_CompanyFileDetail.show(); } } } ] }); /********************************************************************************************/ /****************************/ /* Searching Stock Combobox */ /****************************/ var data_SearchType = [ ['By CompanyFile Code', 1], ['By CompanyFile Name' , 2] ]; var cmb_SearchCompanyFile = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ] }), editable: false, displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Choose search by ...' }); // CompanyFile grid var grid_CompanyFile = new Ext.grid.EditorGridPanel({ store : theThis.store_CompanyFile, frame : true, region : 'center', sm : companyFileSm, /*buttons : [ theThis.btn_Continue = new Ext.Button({ text: 'Continue', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ var selectedRecords = theThis.getGrid().getSelectionModel().getSelections(); if (selectedRecords.length == 0) { showErrorNotification('Notice', 'You need to select one companyFile.'); } else { var selectedCompanyFileCode = selectedRecords[0].data.Code; if (theThis.callback_ContinueButtonClick != null) theThis.callback_ContinueButtonClick(selectedCompanyFileCode); } } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ if (theThis.dlg_Parent != null) theThis.dlg_Parent.hide(); } }) ],*/ listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, rowdblclick : function ( p_this, p_rowIndex, p_eventObject ) { }, afterrender : function(){ /*theThis.store_CompanyFile.baseParams = {keyword: "", start: 0, limit: theThis.pageSize}, theThis.store_CompanyFile.load();*/ } }, cm: stockCM, width: 780, height: 400, autoHeight: false, clicksToEdit: 1, loadMask: true, bbar: theThis.pt_CompanyFile = new Ext.CTBPagingToolbar({ store: theThis.store_CompanyFile, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No company files to display" }), view: new Ext.grid.GroupingView({ forceFit: true, // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) groupTextTpl: '
{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})
' }) /*viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) }*/ }); grid_CompanyFile.on({ rowcontextmenu: function (grid, rowIndex, e) { e.stopEvent(); var row = grid.getView().getRow(rowIndex); Ext.get(row).highlight(); companyFileSm.selectRow(rowIndex); contextMenu.showAt(e.getXY()); } }); return grid_CompanyFile; } // End generateGrid_Databases }); Ext.reg('CTBMYOBSelectCompanyFilesGrid', Ext.CTBMYOBSelectCompanyFilesGrid); Ext.CTBMYOBSelectCompanyFilesWindow = Ext.extend(Ext.Window, { title: 'Kounta Company Files', layout: 'border', closeAction: 'hide', iconCls : 'icon-v3-ctb-logo', cls : 'ctbwindow-detail-general', expandOnShow: true, closable: true, resizable: true, modal: true, plain: true, minimizable: true, maximizable: true, monitorResize: true, width: 500, height: 300, activeItem : 0, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, pageSize: CTB.init.itemPerPage || 100, accountCode : '', selectedInvoiceRecords : null, selectedCompanyFileID : null, callback_AfterSelect : null, setSelectedInvoiceRecords : function(selectedInvoiceRecords){ var theThis = this; theThis.selectedInvoiceRecords = selectedInvoiceRecords; }, listeners: { scope : this, 'beforehide': function(theThis){ }, 'beforeshow': function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 80); }, 'show': function(theThis){ theThis.grid_MYOBCompanyFiles.loadData(); } }, initComponent : function(){ var theThis = this; theThis.grid_MYOBCompanyFiles = new Ext.CTBMYOBSelectCompanyFilesGrid({ dlg_Parent : theThis, region : 'center' }); theThis.items = [theThis.grid_MYOBCompanyFiles]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBMYOBSelectCompanyFilesWindow.superclass.initComponent.call(this); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_Select = new Ext.Button({ text: 'Select', iconCls : 'icon-cancel-large', scale : 'large', cls : 'ctb-btn-red', handler : function(){ var selectedRecords = theThis.grid_MYOBCompanyFiles.getGrid().getSelectionModel().getSelections(); if (selectedRecords != null && selectedRecords.length > 0){ var theRecord = theThis.grid_MYOBCompanyFiles.getGrid().getSelectionModel().getSelections()[0]; theThis.selectedCompanyFileID = theRecord.data.Id; theThis.finalizeMYOBConnectionConfiguration(theThis.selectedCompanyFileID); /*ShowMYOBLoginForm(theRecord, function(theLoginForm, username, password){ theThis.finalizeMYOBConnectionConfiguration(theLoginForm, username, password); });*/ } else { showErrorNotification('Notice', 'Please select at least one company file to work with.'); } } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } }) ]; return buttons; }, finalizeMYOBConnectionConfiguration : function(selectedCompanyFileID){ var theThis = this; theThis.grid_MYOBCompanyFiles.loadMask.show(); Ext.Ajax.request({ method: "POST", url: '/Kounta/FinalizeMYOBConnectionConfiguration', params: { companyFileID : theThis.selectedCompanyFileID }, success : function(result, request) { theThis.grid_MYOBCompanyFiles.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.hide(); if (theThis.callback_AfterSelect != null) { theThis.callback_AfterSelect(); } else { window.location = window.location; // Refresh the page } } else { //showErrorMessageWithEmailNotify(jsonData.message.Info); showErrorNotification('Notice', jsonData.message.Info); } }, failure : function(result, request) { theThis.grid_MYOBCompanyFiles.loadMask.hide(); } }); // End ajax } }); Ext.reg('CTBMYOBSelectCompanyFilesWindow', Ext.CTBMYOBSelectCompanyFilesWindow); Ext.CTBKountaSelectSiteWindow = Ext.extend(Ext.Component, { onLoadCallback: null, preloadData: null, initComponent: function() { Ext.CTBKountaSelectSiteWindow.superclass.initComponent.call(this); var theThis = this; theThis.siteStore = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy( new Ext.data.Connection({ url: '/Kounta/GetSites', dataType: 'json', method: 'POST' }) ), autoLoad: false, fields: [ { name: 'id', type: 'number' }, { name: 'name', type: 'string' } ], root: 'data', idProperty: 'id', totalProperty: 'totalCount', listeners: { 'load': function (store, records, options) { theThis.loadMask.hide(); //console.log(p_This); if(typeof(theThis.onLoadCallback) === 'function') theThis.onLoadCallback(store); }, 'exception': function (store, type, action, options, response, arg) { theThis.loadMask.hide(); showErrorNotification('Error', 'Failed to load site information from Kounta. Message: ' + response.responseText); } } }); theThis.loadMask = new Ext.LoadMask(Ext.getBody(), { msg: "Please wait..." }); }, setPreloadData: function(data) { var theThis = this; theThis.preloadData = data; }, clearPreloadData: function() { var theThis = this; theThis.preloadData = null; }, showSelectSiteWindow: function(onSelectedCallback) { //Ext.Msg.alert('Select Site', 'Please select a site'); var theThis = this; if(theThis.selectSiteWindow) { theThis.selectSiteWindow.show(); return; } var onSelectSiteRequest = function(store) { //console.log('on callback'); if(!store || store.getCount() == 0) { showErrorNotification('Notification', 'Cannot find site information from Kounta.'); return; } if (store.getCount() == 1) { //call the callback function directly var data = store.getAt(0).data; if (typeof (onSelectedCallback) === 'function') onSelectedCallback(data.id, data.name); } else { theThis.selectSiteWindow = theThis.getSelectSiteWindow(store, onSelectedCallback); theThis.selectSiteWindow.show(); } }; //if there is data in the store if(theThis.siteStore.getCount() > 0) { onSelectSiteRequest(theThis.siteStore); } else { theThis.onLoadCallback = onSelectSiteRequest; theThis.loadMask.show(); theThis.siteStore.load(); } }, getSelectSiteWindow: function(store, onSelectedCallback) { /* var sm = new Ext.grid.CheckboxSelectionModel({singleSelect:true}); var cm = new Ext.grid.ColumnModel({ columns: [ sm, { header: 'id', dataIndex: 'id', hidden: true}, { header: 'name', dataIndex: 'name' } ] }); var grid = new Ext.grid.GridPanel({ store: store, sm: sm, cm: cm, viewConfig: { forceFit: true} }); */ var combo = new Ext.form.ComboBox({ store: store, fieldLabel: 'Kounta Site', displayField: 'name', valueField: 'id', mode : 'local', editable : false, allowBlank : false, emptyText : 'Select a site in Kounta', //typeAhead: true, triggerAction: 'all', lazyRender: true, width : 200 }); var win = new Ext.Window({ title: 'Select a Site', iconCls : 'icon-v3-ctb-logo', cls : 'ctbwindow-detail-general', width: 390, height: 150, modal: true, items: combo, layout: 'form', buttons: [ { text: 'Select', handler: function() { var siteId = combo.getValue(); var siteName = combo.getRawValue(); if(siteId) { win.hide(); if(typeof(onSelectedCallback)==='function') onSelectedCallback(siteId, siteName); } else { showErrorNotification('Error', 'Please select a site to continue.'); } } }, { text: 'Cancel', handler: function() { win.hide(); } } ], }); return win; }, showSelectCategoryWindow: function(onSelectedCallback) { //Ext.Msg.alert('Select Site', 'Please select a site'); var theThis = this; if(theThis.selectCategoryWindow) { theThis.selectCategoryWindow.show(); return; } var onSelectCategoryRequest = function(store) { //console.log('on callback'); if(!store || store.getCount() == 0) { showErrorNotification('Notification', 'Cannot find site information from Kounta.'); return; } theThis.selectCategoryWindow = theThis.getSelectCategoryWindow(store, onSelectedCallback); theThis.selectCategoryWindow.show(); }; //if there is data in the store if(theThis.siteStore.getCount() > 0) { onSelectCategoryRequest(theThis.siteStore); } else { theThis.onLoadCallback = onSelectCategoryRequest; theThis.loadMask.show(); theThis.siteStore.load(); } }, getSelectCategoryWindow: function(store, onSelectedCallback) { var theThis = this; var cateStore = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy( new Ext.data.Connection({ url: '/Kounta/GetCategoriesBySite', dataType: 'json', method: 'POST' }) ), autoLoad: false, fields: [ { name: 'id', type: 'number' }, { name: 'name', type: 'string' } ], root: 'data', idProperty: 'id', totalProperty: 'totalCount', listeners: { 'load': function (cateStore, records, options) { var data = theThis.preloadData; if(data != null) { var categories = data.categories; for (var i = 0; i < categories.length; i++){ var rec = theThis.categoryGrid.store.getById(categories[i].id); if(rec != null) { theThis.categoryGrid.getSelectionModel().selectRecords([rec], true); } } } }, 'exception': function (store, type, action, options, response, arg) { theThis.loadMask.hide(); showErrorNotification('Error', 'Failed to load category information from Kounta. Message: ' + response.responseText); } } }); var sm = new Ext.grid.CheckboxSelectionModel({singleSelect:false}); var cm = new Ext.grid.ColumnModel({ columns: [ sm, { header: 'id', dataIndex: 'id', hidden: true}, { header: 'name', dataIndex: 'name' } ] }); theThis.categoryGrid = new Ext.grid.GridPanel({ region: 'center', store: cateStore, sm: sm, cm: cm, viewConfig: { forceFit: true}, stripeRows: true }); var checkFilter = new Ext.form.Checkbox({ boxLabel: 'Filter by Categories', checked: false, listeners: { check: function(checkbox, checked) { if(checked) { var siteId = comboSite.getValue(); if(siteId > 0) { cateStore.setBaseParam('siteId', siteId); cateStore.load(); } } else { cateStore.removeAll(); } } } }); var comboSite = new Ext.form.ComboBox({ store: store, //fieldLabel: 'Kounta Site', displayField: 'name', valueField: 'id', mode : 'local', editable : false, allowBlank : false, emptyText : 'Select a site in Kounta', //typeAhead: true, triggerAction: 'all', lazyRender: true, width : 200, height:30, listeners: { select: function(combo, record, index) { //console.log(record.data); sm.clearSelections(); theThis.preloadData = null; if(checkFilter.getValue()==true) { cateStore.setBaseParam('siteId', record.id); cateStore.load(); } } } }); var topPanel = new Ext.Panel({ region: 'north', layout: 'hbox', height: 40, style: 'margin-top:10px', items: [ { xtype: 'label', text: 'Select a Site: in Kounta:', width: 160, style: 'text-align:right' }, comboSite, { xtype: 'label', text: ' ', width: 100, style: 'text-align:right' }, checkFilter ] }); var win = new Ext.Window({ title: 'Select Categories', iconCls : 'icon-v3-ctb-logo', cls : 'ctbwindow-detail-general', width: 600, height: 400, modal: true, items: [topPanel, theThis.categoryGrid], layout: 'border', listeners: { 'beforeshow': function(pThis){ // Fit this window to the client browser screen with 90% fitWindowSize(pThis, 80); }, 'show': function(){ var data = theThis.preloadData; if(data != null) { if(data.categories != null) { checkFilter.setValue(1); } comboSite.setValue(data.siteId); cateStore.setBaseParam('siteId', data.siteId); cateStore.load(); } } }, buttons: [ { text: 'Select', handler: function() { var siteId = comboSite.getValue(); var siteName = comboSite.getRawValue(); var selectedCategories = []; if(checkFilter.getValue() == true) { var selections = sm.getSelections(); if(selections != null && selections.length > 0) { for(var i=0; i', '', '' ); theThis.pnl_Instruction = new Ext.Panel({ //frame : true, region : 'north', height : 70, tpl : theThis.tpl_Instruction, listeners : { afterrender : function(p_This){ if (theThis.instructionText != '') { p_This.setVisible(true); p_This.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); } else { p_This.setVisible(false); } } } }); theThis.tpl_Main = new Ext.XTemplate( '', '', '', '', '', '', '', '', '', '', '', '
', '', '{btn1_text}', '', '
', '', '{btn2_text}', '', '
', '', '{btn3_text}', '', '
', '
' ); theThis.pnl_Main = new Ext.Panel({ region : 'center', tpl : theThis.tpl_Main, listeners : { afterrender : function(p_This) { theThis.pnl_Main.update({ uniqueId : theThis.id, btn1_text : 'I want to use freight\'s input field of the MYOB invoice to store freight.', btn2_text : 'I want to use another account for freight.', btn3_text : 'Oops ! I don\'t know.' }); Ext.get(theThis.id + '_btn_1').on('click', function(p_This){ theThis.hide(); if (theThis.callback_AfterSelect != null) theThis.callback_AfterSelect(true); }); Ext.get(theThis.id + '_btn_2').on('click', function(p_This){ theThis.hide(); if (theThis.callback_AfterSelect != null) theThis.callback_AfterSelect(false); }); Ext.get(theThis.id + '_btn_3').on('click', function(p_This){ theThis.hide(); }); } } }); theThis.items = [ theThis.pnl_Instruction, theThis.pnl_Main ]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBFreightQuestionWindow.superclass.initComponent.call(this); }, getRecipeFolderBrowser : function(){ var theThis = this; var dlg_RecipeFolderBrowser = new Ext.Window({ title : 'Select recipe folder', frame : true, layout : 'border', modal : true, width : 800, height : 600, callback_AfterSelect : null, getRecipeTreePanel : function(){ return theThis.pnl_RFB_RecipeFolderTree; }, listeners : { show : function(p_This){ p_This.getRecipeTreePanel().loadData(); } }, items : [ theThis.pnl_RFB_Instruction = new Ext.Panel({ html : '', region : 'north', height : 30, html : '
Select where you want to store the selected recipes/folders.
' }), theThis.pnl_RFB_RecipeFolderTree = new Ext.CTBRecipeTreePanel({ region : 'center', HideProcessPendingRecipesButton : true, HideImportRecipeButton : true, isAutoLoad : false, readOnly : true, showAddFolderButtonInReadOnlyMode : true, Hide_Tooltip : true }) ], buttons : [ { xtype : 'button', text : 'Select', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ var selectedNode = theThis.pnl_RFB_RecipeFolderTree.recipeTreePanel.selModel.selNode; if (selectedNode != null){ var selectedNodeId = selectedNode.id; var nodeId = getNumberIdFromStringId(selectedNodeId); var nodeType = getPrefixFromStringId(selectedNodeId); if (nodeType == "folder"){ if (dlg_RecipeFolderBrowser.callback_AfterSelect != null) { dlg_RecipeFolderBrowser.hide(); dlg_RecipeFolderBrowser.callback_AfterSelect(nodeId); } } else { showErrorNotification('Notice', 'Please choose only folder.'); } } } }, { xtype : 'button', text : 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ dlg_RecipeFolderBrowser.hide(); } } ] }); return dlg_RecipeFolderBrowser }, loadData : function(){ var theThis = this; theThis.pnl_Instruction.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); }, initButtons : function(){ var theThis = this; var buttons = [ ]; return buttons; } }); Ext.reg('CTBFreightQuestionWindow', Ext.CTBFreightQuestionWindow); Ext.CTBXeroSelectAccountGrid = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: CTB.init.itemPerPage || 100, recordObject : null, instructionText : 'Select the food purchase account that you want the invoices to be assigned to', instructionBackgroundColor : '#66c010', callback_ContinueButtonClick : null, dlg_Parent : null, listeners : { afterrender : function(theThis){ // Init loadMask theThis.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); }, show : function(theThis){ } }, initComponent: function(){ var theThis = this; theThis.tpl_Instruction = new Ext.XTemplate( '', '
', '', '', '', '', '
', '{instructionText}', '
', '
', '
' ); theThis.pnl_Instruction = new Ext.Panel({ frame : true, region : 'north', height : 70, tpl : theThis.tpl_Instruction, listeners : { afterrender : function(p_This){ p_This.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); } } }); theThis.grid_Accounts = theThis.getGrid_Accounts(); theThis.items = [theThis.grid_Accounts, theThis.pnl_Instruction]; // Call super class to initialize componenets Ext.CTBXeroSelectAccountGrid.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_Accounts; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_Account; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getStore().baseParams = {start : 0, limit : theThis.getPagingToolbar().pageSize}; theThis.getGrid().getStore().load(); }, getGrid_Accounts: function(){ var theThis = this; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.accountRecord = Ext.data.Record.create([ { name: 'UID' , type: 'string' }, { name: 'DisplayID' , type: 'string' }, { name: 'Name' , type: 'string' }, { name: 'Classification' , type: 'string' }, { name: 'Type' , type: 'string' }, { name: 'TaxCode' , type: 'string' }, { name: 'Description' , type: 'string' }, { name: 'Number' , type: 'string' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** theThis.store_Account = new Ext.data.GroupingStore({ proxy: new Ext.data.HttpProxy( new Ext.data.Connection({ url: '/Kounta/SearchMYOBAccounts', dataType: 'json', method: 'POST', timeout: 1800000 }) ), reader: new Ext.data.JsonReader({ fields: theThis.accountRecord, root: 'data', idProperty: 'UID', totalProperty : 'totalCount' }), autoLoad : false, groupField : 'Classification', listeners : { 'load' : function(){ }, 'loadexception' : function(){ /*showStoreLoadingErrorMessage(theThis.store_Account, function(){ theThis.dlg_Parent.connectToXero(function(){ theThis.store_Account.load(); }); });*/ showStoreLoadingErrorMessage(theThis.store_Account); } } //}) }); // *************************************************************************************************** // Grid // *************************************************************************************************** //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment } } }); var accountSm = new Ext.grid.CheckboxSelectionModel({ singleSelect : true, listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { } } }); // Column Models var stockCM = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ accountSm, { header: 'Classification', dataIndex: 'Classification', hidden: true }, { header: 'UID', dataIndex: 'UID', hidden: true }, { header: 'DisplayID', dataIndex: 'DisplayID', width: 10 }, { header: 'Name', dataIndex: 'Name', width: 30 }, { header: 'Description', dataIndex: 'Description', width: 60 } ] }); // Context menu for right clicking var contextMenu = new Ext.menu.Menu({ items: [ { iconCls: 'icon-add', scale : 'large', text: 'New', handler: function () { theThis.btn_Add_Account.handler.call(theThis.btn_Add_Account.scope); } }, { iconCls: 'icon-delete', scale : 'large', text: 'Delete', handler: function () { theThis.btn_Delete_Account.handler.call(theThis.btn_Delete_Account.scope); } }, { iconCls: 'icon-recipe', text: 'View detail', handler: function () { if (theThis.selectedAccountId != -1){ theThis.dlg_AccountDetail.show(); } } } ] }); /********************************************************************************************/ /****************************/ /* Searching Stock Combobox */ /****************************/ var data_SearchType = [ ['By Account Code', 1], ['By Account Name' , 2] ]; var cmb_SearchAccount = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ] }), editable: false, displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Choose search by ...' }); // Account grid var grid_Account = new Ext.grid.EditorGridPanel({ store : theThis.store_Account, frame : true, region : 'center', sm : accountSm, buttons : [ theThis.btn_Continue = new Ext.Button({ text: 'Continue', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ var selectedRecords = theThis.getGrid().getSelectionModel().getSelections(); if (selectedRecords.length == 0) { showErrorNotification('Notice', 'You need to select one account.'); } else { var selectedAccountCode = selectedRecords[0].data.UID; if (theThis.callback_ContinueButtonClick != null) theThis.callback_ContinueButtonClick(selectedAccountCode); } } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ if (theThis.dlg_Parent != null) theThis.dlg_Parent.hide(); } }) ], listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, rowdblclick : function ( p_this, p_rowIndex, p_eventObject ) { }, afterrender : function(){ /*theThis.store_Account.baseParams = {keyword: "", start: 0, limit: theThis.pageSize}, theThis.store_Account.load();*/ } }, cm: stockCM, width: 780, height: 400, autoHeight: false, clicksToEdit: 1, loadMask: true, bbar: theThis.pt_Account = new Ext.CTBPagingToolbar({ store: theThis.store_Account, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No accounts to display" }), view: new Ext.grid.GroupingView({ forceFit: true, // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) startCollapsed: true, groupTextTpl: '
{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})
' }) /*viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) }*/ }); grid_Account.on({ rowcontextmenu: function (grid, rowIndex, e) { e.stopEvent(); var row = grid.getView().getRow(rowIndex); Ext.get(row).highlight(); accountSm.selectRow(rowIndex); //contextMenu.showAt(e.getXY()); } }); return grid_Account; } // End generateGrid_Databases }); Ext.reg('CTBXeroSelectAccountGrid', Ext.CTBXeroSelectAccountGrid); Ext.CTBXeroNonFoodItemPanel = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: CTB.init.itemPerPage || 100, recordObject : null, instructionText : 'There are non-food item(s) in the invoice(s). What do you want us to do with non-food item(s) ?', instructionBackgroundColor : '#66c010', callback_ContinueButtonClick : null, dlg_Parent : null, nonFoodAccountCode : null, nonFoodItems : null, listeners : { afterrender : function(theThis){ // Init loadMask theThis.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); }, show : function(theThis){ theThis.store_MYOBAccounts.load(); } }, initComponent: function(){ var theThis = this; theThis.tpl_Instruction = new Ext.XTemplate( '', '
', '', '', '', '', '
', '{instructionText}', '
', '
', '
' ); theThis.pnl_Instruction = new Ext.Panel({ frame : true, region : 'north', height : 70, tpl : theThis.tpl_Instruction, listeners : { afterrender : function(p_This){ p_This.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); } } }); theThis.cmb_MYOBAccounts = theThis.getComboBoxMYOBAccounts(); theThis.cmb_MYOBAccountsEditor = theThis.getComboBoxMYOBAccounts(); theThis.pnl_Option1 = new Ext.Panel({ layout : 'border', region : 'north', height : 80, items : [ theThis.pnl_Option1FormPanel = new Ext.form.FormPanel({ flex : 1, frame : true, labelWidth: 20, region : 'center', defaults: { xtype: 'textfield', width : 370 }, items : [ theThis.rd_Option1 = new Ext.form.Radio({ boxLabel: 'I want all non-food items go to only one MYOB Account', checked : true, listeners : { check : function( p_This, checked ) { if (checked) { theThis.rd_Option2.setValue(false); theThis.cmb_MYOBAccounts.enable(); theThis.grid_NonFoodItem.disable(); } } } }), theThis.cmb_MYOBAccounts ] }) ] }); theThis.grid_NonFoodItem = theThis.getGrid_NonFoodItem(); theThis.pnl_Option2 = new Ext.Panel({ layout : 'border', region : 'center', items : [ new Ext.form.FormPanel({ flex : 1, frame : true, labelWidth: 20, region : 'north', height : 30, defaults: { xtype: 'textfield', width : 390 }, items : [ theThis.rd_Option2 = new Ext.form.Radio({ boxLabel: 'I want each non-food item go to different MYOB Accounts', checked : false, listeners : { check : function( p_This, checked ) { if (checked) { theThis.rd_Option1.setValue(false); theThis.cmb_MYOBAccounts.disable(); theThis.grid_NonFoodItem.enable(); } } } }) ] }), theThis.grid_NonFoodItem ] }); theThis.pnl_Main = new Ext.Panel({ layout : 'border', region : 'center', items : [ theThis.pnl_Option1, theThis.pnl_Option2 ], buttons : [ theThis.btn_Continue = new Ext.Button({ text: 'Continue', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ if (theThis.rd_Option2.getValue() == true) { var isPassed = true; for(var i = 0; i < theThis.store_NonFoodItem.getCount(); i++){ if (theThis.store_NonFoodItem.getAt(i).data.NonFoodAccountCode == null || theThis.store_NonFoodItem.getAt(i).data.NonFoodAccountCode == "") { isPassed = false; break; } } if (!isPassed) { showErrorNotification('Notice', 'You need to select all corresponding non-food accounts.'); } else { var MYOBNonFoodStockAccounts = new Array(); for (var i = 0; i < theThis.store_NonFoodItem.getCount(); i++) { MYOBNonFoodStockAccounts[i] = { CTBStockId : theThis.store_NonFoodItem.getAt(i).data.CTBStockId, NonFoodAccountCode : theThis.store_NonFoodItem.getAt(i).data.NonFoodAccountCode } } function saveNow() { theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Kounta/SaveMYOBNonFoodStockAccount', params: { MYOBNonFoodStockAccounts : Ext.util.JSON.encode(MYOBNonFoodStockAccounts) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { if (theThis.callback_ContinueButtonClick != null) theThis.callback_ContinueButtonClick(false, null); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } saveNow(); } } else { theThis.nonFoodAccountCode = theThis.cmb_MYOBAccounts.getValue(); if (theThis.nonFoodAccountCode == null || theThis.nonFoodAccountCode == "") { showErrorNotification('Notice', 'You need to select a non-food account'); } else if (theThis.callback_ContinueButtonClick != null) theThis.callback_ContinueButtonClick(true, theThis.nonFoodAccountCode); } } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ if (theThis.dlg_Parent != null) theThis.dlg_Parent.hide(); } }) ] }) theThis.items = [theThis.pnl_Instruction, theThis.pnl_Main]; // Call super class to initialize componenets Ext.CTBXeroNonFoodItemPanel.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_NonFoodItem; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_NonFoodItem; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(selectedInvoiceRecords){ var theThis = this; var selectedInvoiceIds = new Array(); for (var i = 0; i < selectedInvoiceRecords.length; i++) { selectedInvoiceIds[i] = selectedInvoiceRecords[i].data.invoiceId; } theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getStore().baseParams = {start : 0, limit : theThis.pageSize, CTBInvoiceIds : Ext.util.JSON.encode(selectedInvoiceIds)}; theThis.getGrid().getStore().load(); }, getGrid_NonFoodItem: function(){ var theThis = this; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.nonFoodItemRecord = Ext.data.Record.create([ { name: 'CTBStockId' , type: 'string' }, { name: 'Description' , type: 'string' }, { name: 'NonFoodAccountCode' , type: 'string' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** theThis.store_NonFoodItem = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy( new Ext.data.Connection({ url: '/Kounta/SearchNonFoodItemMYOBAccountLinks', dataType: 'json', method: 'POST', timeout: 1800000 }) ), autoLoad : false, fields: theThis.nonFoodItemRecord, root: 'data', idProperty: 'CTBStockId', totalProperty : 'totalCount', listeners : { 'load' : function(){ }, 'loadexception' : function(){ /*showStoreLoadingErrorMessage(theThis.store_NonFoodItem, function(){ theThis.dlg_Parent.connectToXero(function(){ theThis.store_NonFoodItem.load(); }); });*/ showStoreLoadingErrorMessage(theThis.store_NonFoodItem); } } //}) }); // *************************************************************************************************** // Grid // *************************************************************************************************** //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment } } }); var accountSm = new Ext.grid.CheckboxSelectionModel({ singleSelect : true, listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { } } }); // Column Models var stockCM = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ accountSm, { header: 'CTBStockId', dataIndex: 'CTBStockId', hidden: true }, { header: 'Non Food Item Name/Description', dataIndex: 'Description', width: 50 }, { header: 'MYOB Account', dataIndex: 'NonFoodAccountCode', width: 50, renderer: Ext.util.Format.comboRenderer(theThis.cmb_MYOBAccountsEditor), editor : theThis.cmb_MYOBAccountsEditor } ] }); // Account grid var grid_NonFoodItem = new Ext.grid.EditorGridPanel({ store : theThis.store_NonFoodItem, frame : true, region : 'center', sm : accountSm, disabled : true, listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, rowdblclick : function ( p_this, p_rowIndex, p_eventObject ) { }, afterrender : function(){ /*theThis.store_NonFoodItem.baseParams = {keyword: "", start: 0, limit: theThis.pageSize}, theThis.store_NonFoodItem.load();*/ } }, cm: stockCM, width: 780, height: 400, autoHeight: false, clicksToEdit: 1, loadMask: true, /*bbar: theThis.pt_NonFoodItem = new Ext.CTBPagingToolbar({ store: theThis.store_NonFoodItem, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No accounts to display" }),*/ /*view: new Ext.grid.GroupingView({ forceFit: true, // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) startCollapsed: true, groupTextTpl: '
{text} ({[values.rs.length]} {[values.rs.length > 1 ? "Items" : "Item"]})
' })*/ viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); grid_NonFoodItem.on({ rowcontextmenu: function (grid, rowIndex, e) { e.stopEvent(); var row = grid.getView().getRow(rowIndex); Ext.get(row).highlight(); accountSm.selectRow(rowIndex); } }); return grid_NonFoodItem; }, // End generateGrid_Databases getComboBoxMYOBAccounts : function(){ var theThis = this; // Business Departments store if (theThis.store_MYOBAccounts == null) { var accountRecord = Ext.data.Record.create([ { name: 'UID' , type: 'string' }, { name: 'DisplayID' , type: 'string' }, { name: 'Name' , type: 'string' }, { name: 'Classification' , type: 'string' }, { name: 'Type' , type: 'string' }, { name: 'TaxCode' , type: 'string' }, { name: 'Description' , type: 'string' }, { name: 'Number' , type: 'string' } ]); theThis.store_MYOBAccounts = new Ext.data.GroupingStore({ baseParams : {start : 0, limit : theThis.pageSize}, proxy: new Ext.data.HttpProxy( new Ext.data.Connection({ url: '/Kounta/SearchMYOBAccounts', dataType: 'json', method: 'POST', timeout: 1800000 }) ), reader: new Ext.data.JsonReader({ fields: accountRecord, root: 'data', idProperty: 'UID', totalProperty : 'totalCount' }), autoLoad : false, groupField : 'Classification', listeners : { 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(theThis.store_MYOBAccounts); } } //}) }); } var cmb_MYOBAccounts = new Ext.ux.form.GroupComboBox({ store: theThis.store_MYOBAccounts, //fieldLabel: fieldLabel, displayField: 'Name', valueField: 'UID', typeAhead: true, editable: true, mode : 'local', minChars: 1, triggerAction: 'all', lazyRender: true, forceSelection: true, width : 200, mode: 'local', emptyText : 'Select an account...', groupTextTpl: '{text} ({[values.rs.length]})', tpl : '
{Name}
', showGroupName: false, startCollapsed: true }); return cmb_MYOBAccounts; } }); Ext.reg('CTBXeroNonFoodItemPanel', Ext.CTBXeroNonFoodItemPanel); Ext.CTBXeroSelectCorrespondingSuppliers = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: CTB.init.itemPerPage || 100, recordObject : null, instructionText : 'Select the corresponding suppliers between Cooking the Books and MYOB', instructionBackgroundColor : '#4587ff', callback_ContinueButtonClick : null, dlg_Parent : null, listeners : { afterrender : function(theThis){ // Init loadMask theThis.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); }, show : function(theThis){ } }, initComponent: function(){ var theThis = this; theThis.tpl_Instruction = new Ext.XTemplate( '', '
', '', '', '', '', '
', '{instructionText}', '
', '
', '
' ); theThis.pnl_Instruction = new Ext.Panel({ frame : true, region : 'north', height : 70, tpl : theThis.tpl_Instruction, listeners : { afterrender : function(p_This){ p_This.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); } } }); theThis.grid_CorrespondingSupplierss = theThis.getGrid_CorrespondingSupplierss(); theThis.items = [theThis.grid_CorrespondingSupplierss, theThis.pnl_Instruction]; // Call super class to initialize componenets Ext.CTBXeroSelectCorrespondingSuppliers.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_CorrespondingSupplierss; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_CorrespondingSuppliers; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.callback_LoadData = function(){ theThis.loadMask.hide(); theThis.getGrid().getStore().commitChanges(); var distinctSupplierIds = new Array(); for (var i = 0; i < theThis.dlg_Parent.selectedInvoiceRecords.length; i++){ if (distinctSupplierIds.indexOf(theThis.dlg_Parent.selectedInvoiceRecords[i].data.supplierId) == -1) { distinctSupplierIds[distinctSupplierIds.length] = theThis.dlg_Parent.selectedInvoiceRecords[i].data.supplierId; } } theThis.getGrid().getStore().baseParams = {start : 0, limit : theThis.getPagingToolbar().pageSize, supplierIds : Ext.util.JSON.encode(distinctSupplierIds)}; theThis.getGrid().getStore().load(); } if (theThis.store_XeroSuppliers.baseParams.query != null || theThis.store_XeroSuppliers.baseParams.query != "") theThis.store_XeroSuppliers.baseParams.query = ""; theThis.loadMask.show(); theThis.store_XeroSuppliers.load(); }, getGrid_CorrespondingSupplierss: function(){ var theThis = this; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.correspondingSuppliersRecord = Ext.data.Record.create([ { name: 'CTBSupplierId' , type: 'number' }, { name: 'CTBSupplierName' , type: 'string' }, { name: 'MYOBSupplierID' , type: 'string' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** theThis.store_CorrespondingSuppliers = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy({ url: '/Kounta/SearchCorrespondingSuppliers', dataType: 'json', method: 'POST' }), fields: theThis.correspondingSuppliersRecord, root: 'data', idProperty: 'supplierId', totalProperty : 'totalCount', autoLoad : false, groupField : 'Class', listeners : { 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(theThis.store_CorrespondingSuppliers, function(){ theThis.dlg_Parent.connectToXero(function(){ theThis.store_CorrespondingSuppliers.load(); }); }); } } //}) }); // *************************************************************************************************** // Grid // *************************************************************************************************** //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment } } }); var correspondingSuppliersSm = new Ext.grid.CheckboxSelectionModel({ singleSelect : true, listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { } } }); theThis.cmb_XeroSuppliers = theThis.getCombobox_XeroSuppliers(function(){ if (theThis.callback_LoadData != null) { theThis.callback_LoadData(); theThis.callback_LoadData = null; } }); // Column Models var stockCM = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ correspondingSuppliersSm, { header: 'CTBSupplierId', dataIndex: 'CTBSupplierId', hidden: true }, { header: 'Cooking the Books suppliers', dataIndex: 'CTBSupplierName', width: 50 }, { header: 'MYOB suppliers', dataIndex: 'MYOBSupplierID', width: 50, editor: theThis.cmb_XeroSuppliers, renderer: Ext.util.Format.comboRenderer(theThis.cmb_XeroSuppliers) } ] }); // Context menu for right clicking var contextMenu = new Ext.menu.Menu({ items: [ { iconCls: 'icon-add', scale : 'large', text: 'New', handler: function () { theThis.btn_Add_CorrespondingSuppliers.handler.call(theThis.btn_Add_CorrespondingSuppliers.scope); } }, { iconCls: 'icon-delete', scale : 'large', text: 'Delete', handler: function () { theThis.btn_Delete_CorrespondingSuppliers.handler.call(theThis.btn_Delete_CorrespondingSuppliers.scope); } }, { iconCls: 'icon-recipe', text: 'View detail', handler: function () { if (theThis.selectedCorrespondingSuppliersId != -1){ theThis.dlg_CorrespondingSuppliersDetail.show(); } } } ] }); /********************************************************************************************/ /****************************/ /* Searching Stock Combobox */ /****************************/ var data_SearchType = [ ['By CorrespondingSuppliers Code', 1], ['By CorrespondingSuppliers Name' , 2] ]; var cmb_SearchCorrespondingSuppliers = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ] }), editable: false, displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Choose search by ...' }); // CorrespondingSuppliers grid var grid_CorrespondingSuppliers = new Ext.grid.EditorGridPanel({ store : theThis.store_CorrespondingSuppliers, frame : true, region : 'center', sm : correspondingSuppliersSm, buttons : [ theThis.btn_Continue = new Ext.Button({ text: 'Continue', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ theThis.saveXeroCorrespondingSuppliers(theThis.callback_ContinueButtonClick); } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ if (theThis.dlg_Parent != null) theThis.dlg_Parent.hide(); } }) ], listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, rowdblclick : function ( p_this, p_rowIndex, p_eventObject ) { }, afterrender : function(){ /*theThis.store_CorrespondingSuppliers.baseParams = {keyword: "", start: 0, limit: theThis.pageSize}, theThis.store_CorrespondingSuppliers.load();*/ }, afteredit : function(p_Editor) { if (p_Editor.record.data.ContactID != null && p_Editor.record.data.ContactID != ""){ p_Editor.record.set('Name', theThis.store_XeroSuppliers.getById(p_Editor.record.data.ContactID).data.Name); } } }, cm: stockCM, width: 780, height: 400, autoHeight: false, clicksToEdit: 1, loadMask: true, bbar: theThis.pt_CorrespondingSuppliers = new Ext.CTBPagingToolbar({ store: theThis.store_CorrespondingSuppliers, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No suppliers to display" }), viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); grid_CorrespondingSuppliers.on({ rowcontextmenu: function (grid, rowIndex, e) { e.stopEvent(); var row = grid.getView().getRow(rowIndex); Ext.get(row).highlight(); correspondingSuppliersSm.selectRow(rowIndex); contextMenu.showAt(e.getXY()); } }); return grid_CorrespondingSuppliers; }, getCombobox_XeroSuppliers : function(callback_AfterLoad){ var theThis = this; // Importing suppliers theThis.store_XeroSuppliers = new Ext.data.JsonStore({ autoLoad : false, proxy: new Ext.data.HttpProxy({ url: '/Kounta/SearchMYOBSuppliers', dataType: 'json', method: 'POST' }), fields: [ { name: 'UID' , type: 'string' }, { name: 'DisplayID' , type: 'string' }, { name: 'Name' , type: 'string' }, // Processed on server to choose either company or individual's name { name: 'CompanyName' , type: 'string' }, { name: 'FirstName' , type: 'string' }, { name: 'LastName' , type: 'string' }, { name: 'Notes' , type: 'string' } ], root: 'data', idProperty : 'UID', listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(theThis.store_XeroSuppliers); }, 'load' : function(){ if (cmbSupplier.callback_AfterLoad != null){ cmbSupplier.callback_AfterLoad(); } } } }); //store.load(); var cmbSupplier = new Ext.form.ComboBox({ store: theThis.store_XeroSuppliers, displayField: 'Name', valueField: 'UID', typeAhead: true, editable: true, mode : 'local', minChars: 1, colspan : 3, /*listeners : { beforequery: function(qe){ delete qe.combo.lastQuery; // Reload every click } },*/ callback_AfterLoad : callback_AfterLoad, triggerAction: 'all', lazyRender: true, forceSelection: true, emptyText: 'Select a supplier ...'/*, onFocus: function (txt, e) { this.getEl().dom.select(); }*/ //width: 338, //style: { fontSize: '11px' } }); return cmbSupplier; }, saveXeroCorrespondingSuppliers : function(callback_Function){ var theThis = this; var isPassed = true; for(var i = 0; i < theThis.store_CorrespondingSuppliers.getCount(); i++){ if (theThis.store_CorrespondingSuppliers.getAt(i).data.MYOBSupplierID == null || theThis.store_CorrespondingSuppliers.getAt(i).data.MYOBSupplierID == "") { isPassed = false; break; } } if (!isPassed) { showErrorNotification('Notice', 'You need to select all corresponding suppliers.'); } else { //if (theThis.callback_ContinueButtonClick != null) theThis.callback_ContinueButtonClick(theThis.store_CorrespondingSuppliers); var MYOBCorrespondingSuppliers = new Array(); for (var i = 0; i < theThis.store_CorrespondingSuppliers.getCount(); i++) { MYOBCorrespondingSuppliers[i] = { CTBSupplierId : theThis.store_CorrespondingSuppliers.getAt(i).data.CTBSupplierId, MYOBSupplierID : theThis.store_CorrespondingSuppliers.getAt(i).data.MYOBSupplierID } } function saveNow() { theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Kounta/SaveMYOBCorrespondingSuppliers', params: { MYOBCorrespondingSuppliers : Ext.util.JSON.encode(MYOBCorrespondingSuppliers) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.getGrid().getStore().commitChanges(); showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.MYOBCorrespondingSuppliers = MYOBCorrespondingSuppliers; if (callback_Function != null) callback_Function(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } saveNow(); } } }); Ext.reg('CTBXeroSelectCorrespondingSuppliers', Ext.CTBXeroSelectCorrespondingSuppliers); Ext.CTBXeroInvoiceTransferingLogGrid = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: CTB.init.itemPerPage || 100, recordObject : null, instructionText : 'Transfering invoices in progress, please wait ...', instructionBackgroundColor : '#fd4242', callback_ContinueButtonClick : null, dlg_Parent : null, isCancelled : false, MYOBHistoryTransactionRecord : null, MYOBCorrespondingSuppliers : null, totalProcessedRecord : 0, listeners : { afterrender : function(theThis){ // Init loadMask theThis.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); }, show : function(theThis){ theThis.totalProcessedRecord = 0; } }, initComponent: function(){ var theThis = this; theThis.tpl_Instruction = new Ext.XTemplate( '', '
', '', '', '', '', '
', '{instructionText}', '
', '
', '
' ); theThis.pnl_Instruction = new Ext.Panel({ frame : true, region : 'north', height : 70, tpl : theThis.tpl_Instruction, listeners : { afterrender : function(p_This){ p_This.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); } } }); theThis.grid_InvoiceTransferingLogs = theThis.getGrid_InvoiceTransferingLogs(); theThis.items = [theThis.grid_InvoiceTransferingLogs, theThis.pnl_Instruction]; // Call super class to initialize componenets Ext.CTBXeroInvoiceTransferingLogGrid.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_InvoiceTransferingLogs; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_InvoiceTransferingLog; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.isCancelled = false; theThis.getGrid().getStore().removeAll(); theThis.instructionText = "Transfering invoices in progress, please wait ..."; theThis.instructionBackgroundColor = "#fd4242"; theThis.pnl_Instruction.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); theThis.btn_Continue.setVisible(false); theThis.getXeroHistoryTransaction(function(){ theThis.transferAllInvoicesFromCTBToXero(); }); /*theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getStore().baseParams = {start : 0, limit : theThis.pageSize}; theThis.getGrid().getStore().load();*/ }, getGrid_InvoiceTransferingLogs: function(){ var theThis = this; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.invoiceTransferingLogRecord = Ext.data.Record.create([ { name: 'invoiceTransferingLogID' , type: 'string' }, { name: 'xeroInvoiceId' , type: 'string' }, { name: 'invoiceId' , type: 'number' }, { name: 'invoiceDate' , type: 'date' }, { name: 'invoiceNo' , type: 'string' }, { name: 'supplierName' , type: 'string' }, { name: 'supplierId' , type: 'number' }, { name: 'totalAmount' , type: 'number' }, { name: 'totalTax' , type: 'number' }, { name: 'discount' , type: 'number' }, { name: 'freightIncludeGST' , type: 'number' }, { name: 'isReturned' , type: 'boolean'}, { name: 'xeroProcessingStatus' , type: 'string' }, { name: 'xeroTransferingMessage' , type: 'string' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** theThis.store_InvoiceTransferingLog = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy({ url: '/Xero/SearchInvoiceTransferingLogs', dataType: 'json', method: 'POST' }), fields: theThis.invoiceTransferingLogRecord, root: 'data', idProperty: 'invoiceTransferingLogID', totalProperty : 'totalCount', autoLoad : false, listeners : { 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(theThis.store_InvoiceTransferingLog, function(){ theThis.dlg_Parent.connectToXero(function(){ theThis.store_InvoiceTransferingLog.load(); }); }); } } //}) }); // *************************************************************************************************** // Grid // *************************************************************************************************** //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment } } }); var invoiceTransferingLogSm = new Ext.grid.CheckboxSelectionModel({ singleSelect : true, listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { } } }); // Column Models var stockCM = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ invoiceTransferingLogSm, { header: 'invoiceTransferingLogID', dataIndex: 'invoiceTransferingLogID', hidden: true }, { header: 'invoiceId', dataIndex: 'invoiceId', hidden: true }, { header: 'Date', dataIndex: 'invoiceDate', width: 10, renderer : function(val){ return Ext.util.Format.date(val, 'd/m/Y'); } }, { header: 'Supplier(s)', dataIndex: 'supplierName', width: 25, renderer : function(val){ var supplierName = val; return ''+supplierName+''; } }, { header: 'Invoice No.', dataIndex: 'invoiceNo', width: 10 }, { header: 'Type', dataIndex: 'isReturned', width: 5, renderer: function(val) { if (val) return "Return"; else return "Purchase"; } }, { header: 'Total', dataIndex: 'totalAmount', width: 10, renderer: Ext.util.Format.usMoney }, { header: 'Message', dataIndex: 'xeroTransferingMessage', width: 35, renderer: function(val, meta, theRecord) { if (theRecord.data.xeroProcessingStatus == XERO_PROCESSING_STATUS.PROCESSING) return 'Processing...'; else return val; } }, { header: 'Status', dataIndex: 'xeroProcessingStatus', width: 5, renderer: function(val) { if (val == XERO_PROCESSING_STATUS.PROCESSING) return '
Processing...
'; else if (val == XERO_PROCESSING_STATUS.SUCCEED) return '
Tranfer successfully.
'; else if (val == XERO_PROCESSING_STATUS.FAILED) return '
Failed to transfer!
'; } } ] }); /********************************************************************************************/ // InvoiceTransferingLog grid var grid_InvoiceTransferingLog = new Ext.grid.EditorGridPanel({ store : theThis.store_InvoiceTransferingLog, frame : true, region : 'center', sm : invoiceTransferingLogSm, buttons : [ theThis.btn_Continue = new Ext.Button({ text: 'Finish', iconCls : 'icon-ok-large', scale : 'large', hidden : true, handler : function(){ if (theThis.callback_ContinueButtonClick != null) theThis.callback_ContinueButtonClick(); } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.isCancelled = true; if (theThis.dlg_Parent != null) theThis.dlg_Parent.hide(); } }) ], listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, rowdblclick : function ( p_this, p_rowIndex, p_eventObject ) { }, afterrender : function(){ /*theThis.store_InvoiceTransferingLog.baseParams = {keyword: "", start: 0, limit: theThis.pageSize}, theThis.store_InvoiceTransferingLog.load();*/ } }, cm: stockCM, width: 780, height: 400, autoHeight: false, clicksToEdit: 1, loadMask: true, /*bbar: theThis.pt_InvoiceTransferingLog = new Ext.CTBPagingToolbar({ store: theThis.store_InvoiceTransferingLog, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No logs to display" }),*/ viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return grid_InvoiceTransferingLog; }, // End generateGrid_Databases transferAllInvoicesFromCTBToXero : function(){ var theThis = this; theThis.totalProcessedRecord = 0; theThis.transferInvoicesInBatch(); //theThis.startProcessingIndex = 0; //theThis.loopTransferInvoice(); }, getXeroHistoryTransaction : function(callback_Function){ var theThis = this; theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Kounta/GetNewMYOBHistoryTransaction', params: { }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.MYOBHistoryTransactionRecord = jsonData.data; if (callback_Function != null) callback_Function(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax }, loopTransferInvoice : function(){ var theThis = this; if (theThis.isCancelled) return false; var selectedInvoiceRecords = theThis.dlg_Parent.selectedInvoiceRecords; if (theThis.startProcessingIndex < selectedInvoiceRecords.length) { var theNewRecord = theThis.addNewRecord(selectedInvoiceRecords[theThis.startProcessingIndex]); theThis.startProcessingIndex++; function transferInvoiceNow(){ Ext.Ajax.request({ method: 'POST', url: '/Kounta/TransferInvoiceFromCTBtoXero', params: { invoiceId : theNewRecord.data.invoiceId, MYOBHistoryId : theThis.MYOBHistoryTransactionRecord.MYOBHistoryId, accountCode : theThis.dlg_Parent.accountCode }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.updateInvoiceTransferingStatus(theNewRecord.data.invoiceTransferingLogID, XERO_PROCESSING_STATUS.SUCCEED, jsonData.message.Info); theThis.loopTransferInvoice(); } else { if (jsonData.message.Info == XERO_MESSAGE.ACCESS_TOKEN_EXPIRED || jsonData.message.Info == XERO_MESSAGE.INVALID_ACCESS_TOKEN) { // Reconnect theThis.dlg_Parent.connectToXero(transferInvoiceNow); } else { theThis.updateInvoiceTransferingStatus(theNewRecord.data.invoiceTransferingLogID, XERO_PROCESSING_STATUS.FAILED, jsonData.message.Info); theThis.loopTransferInvoice(); // showErrorMessageWithEmailNotify(jsonData.message.Info); } } }, failure : function(result, request) { theThis.updateInvoiceTransferingStatus(theNewRecord.data.invoiceTransferingLogID, XERO_PROCESSING_STATUS.FAILED, "Server unavailable!"); } }); // End ajax } transferInvoiceNow(); return true; } else { theThis.instructionText = "Transfering progress completed"; theThis.pnl_Instruction.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); theThis.btn_Continue.setVisible(true); return false; } }, transferInvoicesInBatch : function(){ var theThis = this; if (theThis.isCancelled) return false; var selectedInvoiceRecords = theThis.dlg_Parent.selectedInvoiceRecords; var MYOBInvoiceSupplierLinks = new Array(); var invoiceIds = new Array(); var lastTotalProcessedRecords = theThis.totalProcessedRecord; var countBatch = 0; for (var i = lastTotalProcessedRecords; i < selectedInvoiceRecords.length; i++){ var theNewRecord = theThis.addNewRecord(selectedInvoiceRecords[i]); invoiceIds[i] = theNewRecord.data.invoiceId; // Find the corresponding MYOB supplier ID var CTBSupplierId = theNewRecord.data.supplierId; var MYOBSupplierID = ''; if (theThis.MYOBCorrespondingSuppliers != null){ for (var j = 0; j < theThis.MYOBCorrespondingSuppliers.length; j++) { if (theThis.MYOBCorrespondingSuppliers[j].CTBSupplierId == CTBSupplierId){ MYOBSupplierID = theThis.MYOBCorrespondingSuppliers[j].MYOBSupplierID; break; } } } // Wrap up the data (invoice & the link with its MYOB Supplier) MYOBInvoiceSupplierLinks[i] = { CTBInvoiceId : theNewRecord.data.invoiceId, MYOBSupplierID : MYOBSupplierID } theThis.totalProcessedRecord++; // Increase processed record countBatch++; if (countBatch == 10) // 10 item in each batch break; // No need to continue, wait for next batch } if (countBatch == 0) { // End the batch, no more item to process theThis.instructionText = "Transfering progress completed"; theThis.instructionBackgroundColor = "#01DF01"; theThis.pnl_Instruction.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); theThis.btn_Continue.setVisible(true); return false; } else if (theThis.totalProcessedRecord <= selectedInvoiceRecords.length && theThis.MYOBCorrespondingSuppliers != null) { //var theNewRecord = theThis.addNewRecord(selectedInvoiceRecords[theThis.startProcessingIndex]); //theThis.startProcessingIndex++; function transferInvoiceNow(){ Ext.Ajax.request({ method: 'POST', url: '/Kounta/TransferInvoiceBatchFromCTBtoMYOB', timeout: 1800000, params: { MYOBInvoiceSupplierLinks : Ext.util.JSON.encode(MYOBInvoiceSupplierLinks), MYOBHistoryId : theThis.MYOBHistoryTransactionRecord.MYOBHistoryId, accountCode : theThis.dlg_Parent.accountCode, freightAccountCode : theThis.dlg_Parent.freightAccountCode == null ? "" : theThis.dlg_Parent.freightAccountCode, isOnlyOneNonFoodAccount : theThis.dlg_Parent.isOnlyOneNonFoodAccount, nonFoodAccountCode : theThis.dlg_Parent.nonFoodAccountCode == null ? "" : theThis.dlg_Parent.nonFoodAccountCode, }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { if (jsonData.data.length > 0) { for (var i = 0; i < jsonData.data.length; i++) { var returnBatchMessage = jsonData.data[i]; if (returnBatchMessage.isSuccess) theThis.updateInvoiceTransferingStatusByInvoiceId(returnBatchMessage.invoiceId, XERO_PROCESSING_STATUS.SUCCEED, returnBatchMessage.message); else theThis.updateInvoiceTransferingStatusByInvoiceId(returnBatchMessage.invoiceId, XERO_PROCESSING_STATUS.FAILED, returnBatchMessage.message); } } theThis.transferInvoicesInBatch(); // Continue another batch (if have) } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { showErrorNotification('Notice', 'Server unavailable!'); //theThis.updateInvoiceTransferingStatus(theNewRecord.data.invoiceTransferingLogID, XERO_PROCESSING_STATUS.FAILED, "Server unavailable!"); } }); // End ajax } transferInvoiceNow(); return true; } }, updateInvoiceTransferingStatus : function(invoiceTransferingLogID, theStatus, xeroTransferingMessage) { var theThis = this; theThis.getGrid().getStore().getById(invoiceTransferingLogID).set('xeroProcessingStatus', theStatus); theThis.getGrid().getStore().getById(invoiceTransferingLogID).set('xeroTransferingMessage', xeroTransferingMessage); }, updateInvoiceTransferingStatusByInvoiceId : function(invoiceId, theStatus, xeroTransferingMessage) { var theThis = this; for (var i = 0; i < theThis.getGrid().getStore().getCount(); i++) { var theRecord = theThis.getGrid().getStore().getAt(i); if (theRecord.data.invoiceId == invoiceId) { theRecord.set('xeroProcessingStatus', theStatus); theRecord.set('xeroTransferingMessage', xeroTransferingMessage); break; } } //theThis.getGrid().getStore().getById(invoiceTransferingLogID).set('xeroProcessingStatus', theStatus); //theThis.getGrid().getStore().getById(invoiceTransferingLogID).set('xeroTransferingMessage', xeroTransferingMessage); }, addNewRecord : function(invoiceRecord, quantity){ var theThis = this; var theStore = theThis.getGrid().getStore(); var newId = theStore.getCount(); var aNewRecord = new theThis.invoiceTransferingLogRecord({ invoiceTransferingLogID : newId, xeroInvoiceId : '', invoiceId : invoiceRecord.data.invoiceId, invoiceDate : invoiceRecord.data.invoiceDate, invoiceNo : invoiceRecord.data.invoiceNo, supplierName : invoiceRecord.data.supplierName, supplierId : invoiceRecord.data.supplierId, totalAmount : invoiceRecord.data.totalAmount, totalTax : invoiceRecord.data.totalTax, discount : invoiceRecord.data.discount, freightIncludeGST : invoiceRecord.data.freightIncludeGST, isReturned : invoiceRecord.data.isReturned, xeroProcessingStatus : XERO_PROCESSING_STATUS.PROCESSING }, newId); theStore.insert(theThis.getGrid().getStore().getCount(), aNewRecord); return aNewRecord; } }); Ext.reg('CTBXeroInvoiceTransferingLogGrid', Ext.CTBXeroInvoiceTransferingLogGrid); Ext.CTBXeroTransferInvoiceWindow = Ext.extend(Ext.Window, { title: 'Export invoices to MYOB', layout: 'card', closeAction: 'hide', iconCls : 'icon-v3-ctb-logo', cls : 'ctbwindow-detail-general', expandOnShow: true, closable: true, resizable: true, modal: true, plain: true, minimizable: true, maximizable: true, monitorResize: true, width: 800, height: 500, activeItem : 0, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, pageSize: CTB.init.itemPerPage || 100, accountCode : '', freightAccountCode : null, selectedInvoiceRecords : null, callback_AfterHide : null, isOnlyOneNonFoodAccount : true, nonFoodAccountCode : null, setSelectedInvoiceRecords : function(selectedInvoiceRecords){ var theThis = this; theThis.selectedInvoiceRecords = selectedInvoiceRecords; }, listeners: { scope : this, 'beforehide': function(theThis){ }, 'beforeshow': function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); }, 'show': function(theThis){ theThis.layout.setActiveItem(theThis.pnl_XeroSelectAccount); theThis.pnl_XeroSelectAccount.loadData(); }, 'hide': function(theThis){ if (theThis.callback_AfterHide != null) { theThis.callback_AfterHide(); } } }, initComponent : function(){ var theThis = this; // Select account for food purchase theThis.pnl_XeroSelectAccount = new Ext.CTBXeroSelectAccountGrid({ dlg_Parent : theThis, callback_ContinueButtonClick : function(accountCode) { theThis.accountCode = accountCode; theThis.dlg_FreightQuestion.show(); // Ask user question about what they want to do with freight } }); // Select account for freight theThis.pnl_XeroSelectFreightAccount = new Ext.CTBXeroSelectAccountGrid({ dlg_Parent : theThis, instructionText : 'Select the freight account that you want the freight value to be assigned to' }); // Ask user question about what do they want to do with Freight value in the invoice theThis.dlg_FreightQuestion = new Ext.CTBFreightQuestionWindow({ callback_AfterSelect : function(isAssignToMYOBFreightField){ function moveToNextStep(){ // Move to next step // Select corresponding suppliers theThis.layout.setActiveItem(theThis.pnl_XeroSelectCorrespondingSuppliers); theThis.pnl_XeroSelectCorrespondingSuppliers.loadData(); } if (isAssignToMYOBFreightField == true) { theThis.freightAccountCode = null; // Not using freightAccountCode moveToNextStep(); } else { theThis.pnl_XeroSelectFreightAccount.callback_ContinueButtonClick = function(accountCode){ theThis.freightAccountCode = accountCode; moveToNextStep(); }; theThis.layout.setActiveItem(theThis.pnl_XeroSelectFreightAccount); theThis.pnl_XeroSelectFreightAccount.loadData(); } } }); theThis.pnl_XeroSelectCorrespondingSuppliers = new Ext.CTBXeroSelectCorrespondingSuppliers({ dlg_Parent : theThis, callback_ContinueButtonClick : function(theStore) { // Check if the selected invoices contained non-food item var doesContainNonFoodItems = false; for (var i = 0; i < theThis.selectedInvoiceRecords.length; i++) { if (theThis.selectedInvoiceRecords[i].data.doesContainNonFoodItems == true){ doesContainNonFoodItems = true; break; } } // If contain non food item(appear the non food item link with MYOB accounts) if (doesContainNonFoodItems) { theThis.layout.setActiveItem(theThis.pnl_XeroNonFoodItem); theThis.pnl_XeroNonFoodItem.loadData(theThis.selectedInvoiceRecords); } else { // If not, simply move to the transfering step // Move to next step // Transfering the invoices theThis.layout.setActiveItem(theThis.pnl_XeroInvoiceTransferingLogGrid); theThis.pnl_XeroInvoiceTransferingLogGrid.MYOBCorrespondingSuppliers = theThis.pnl_XeroSelectCorrespondingSuppliers.MYOBCorrespondingSuppliers; theThis.pnl_XeroInvoiceTransferingLogGrid.loadData(); } } }); theThis.pnl_XeroNonFoodItem = new Ext.CTBXeroNonFoodItemPanel({ dlg_Parent : theThis, callback_ContinueButtonClick : function(isOnlyOneNonFoodAccount, nonFoodAccountCode) { // the data variable will be one account code if isOnlyOneAccount = true // Move to next step // Transfering the invoices theThis.layout.setActiveItem(theThis.pnl_XeroInvoiceTransferingLogGrid); theThis.nonFoodAccountCode = nonFoodAccountCode; theThis.isOnlyOneNonFoodAccount = isOnlyOneNonFoodAccount; theThis.pnl_XeroInvoiceTransferingLogGrid.MYOBCorrespondingSuppliers = theThis.pnl_XeroSelectCorrespondingSuppliers.MYOBCorrespondingSuppliers; theThis.pnl_XeroInvoiceTransferingLogGrid.loadData(); } }); theThis.pnl_XeroInvoiceTransferingLogGrid = new Ext.CTBXeroInvoiceTransferingLogGrid({ dlg_Parent : theThis, callback_ContinueButtonClick : function(theStore) { // Reload the invoice grid theThis.hide(); } }); theThis.items = [ theThis.pnl_XeroSelectAccount, theThis.pnl_XeroSelectFreightAccount, theThis.pnl_XeroSelectCorrespondingSuppliers, theThis.pnl_XeroNonFoodItem, theThis.pnl_XeroInvoiceTransferingLogGrid ]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBXeroTransferInvoiceWindow.superclass.initComponent.call(this); }, initButtons : function(){ var theThis = this; var buttons = [ /*theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } })*/ ]; return buttons; }, connectToXero : function(callbackFunction, customMessage){ var theThis = this; if (customMessage == null) customMessage = "Your access to Xero has been expired. Please reconnect."; if (theThis.dlg_ConnectToXero == null) { theThis.dlg_ConnectToXero = new Ext.CTBXeroConnectWindow({ callback_ContinueButtonClick : function() { // Continue the process if only there is a valid connection established theThis.dlg_ConnectToXero.hide(); if (callbackFunction != null) callbackFunction(); } }); } theThis.dlg_ConnectToXero.customMessage = customMessage; theThis.dlg_ConnectToXero.show(); } }); Ext.reg('CTBXeroTransferInvoiceWindow', Ext.CTBXeroTransferInvoiceWindow); Ext.CTBXeroConnectWindow = Ext.extend(Ext.Window, { title: 'Connect to Kounta', layout: 'border', closeAction: 'hide', iconCls : 'icon-v3-ctb-logo', expandOnShow: true, closable: true, resizable: true, modal: true, plain: true, minimizable: true, maximizable: true, monitorResize: true, width: 400, height: 200, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, callback_ContinueButtonClick : null, pageSize: CTB.init.itemPerPage || 100, customMessage : 'You haven\'t connected to Kounta. Please click the link below to connect to Kounta.', listeners: { scope : this, 'beforehide': function(theThis){ }, 'beforeshow': function(theThis){ // Fit this window to the client browser screen with 90% // fitWindowSize(theThis, 90); }, 'show': function(theThis){ theThis.btn_Continue.setVisible(false); theThis.pnl_ConnectPage.update({isLoading : true, isCompleted : false, dialogId : theThis.id, customMessage : theThis.customMessage}); theThis.isThereConnectionEstablished(false); } }, initComponent : function(){ var theThis = this; theThis.tpl_ConnectPage = new Ext.XTemplate( '', '', '', '
', '{customMessage}', '

', 'Connect to Kounta', '
', '
', '', '
', '
 Connection established successfully.
', '
', '
', '
', '', '
', 'Connecting to Kounta ...', '

', '', '
', '
', '
' ); theThis.items = [ theThis.pnl_ConnectPage = new Ext.Panel ({ region : 'center', frame : true, tpl : theThis.tpl_ConnectPage, listeners : { afterrender : function(p_This){ } } }) ]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBXeroConnectWindow.superclass.initComponent.call(this); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_Continue = new Ext.Button({ text: 'Continue', hidden : true, iconCls : 'icon-ok-large', scale : 'large', handler : function(){ if (theThis.callback_ContinueButtonClick != null) theThis.callback_ContinueButtonClick(); theThis.hide(); } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } }) ]; return buttons; }, isThereConnectionEstablished : function(isCallingUntilThereIsConnectionEstablished) { var theThis = this; Ext.Ajax.request({ method: "POST", url: '/Kounta/IsThereConnectionEstablished', params: { }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.pnl_ConnectPage.update({isLoading : false, isCompleted : true, dialogId : theThis.id, customMessage : theThis.customMessage}); theThis.btn_Continue.setVisible(true); } else { // showErrorMessageWithEmailNotify(jsonData.message.Info); if (isCallingUntilThereIsConnectionEstablished) { setTimeout(function(){ theThis.isThereConnectionEstablished(true); }, 2000); } else { theThis.pnl_ConnectPage.update({isLoading : false, isCompleted : false, dialogId : theThis.id, customMessage : theThis.customMessage}); } } }, failure : function(result, request) { //loadMask.hide(); setTimeout(function(){ theThis.isThereConnectionEstablished(true); }, 2000); } }); // End ajax } }); Ext.reg('CTBXeroConnectWindow', Ext.CTBXeroConnectWindow); function CTBXeroConnectWindow_ActivateLoader(dialogId){ Ext.getCmp(dialogId).pnl_ConnectPage.update({isLoading : true, isCompleted : false, dialogId : dialogId, customMessage : Ext.getCmp(dialogId).customMessage}); Ext.getCmp(dialogId).isThereConnectionEstablished(true); } Ext.CTBXeroTransferInvoice = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: CTB.init.itemPerPage || 100, recordObject : null, selectedInvoiceRecords : null, listeners : { afterrender : function(p_This){ // Init loadMask p_This.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); } }, initComponent: function(){ var theThis = this; /* commented by Andy C on 4/5/2015 theThis.dlg_InvoiceDetail = new Ext.CTBInvoiceDetailWindow({ callback_AfterSave : function(){ theThis.grid_Invoices.getStore().load(); } }); */ //init the select Kounta site window component this.ctbCountaSelectSitesWindow = new Ext.CTBKountaSelectSiteWindow(); this.ctbCountaSelectSitesForConfigurationWindow = new Ext.CTBKountaSelectSiteWindow(); theThis.grid_Invoices = theThis.getGrid_Invoices(); theThis.items = [theThis.grid_Invoices]; // Call super class to initialize componenets Ext.CTBXeroTransferInvoice.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_Invoices; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_Invoice; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getStore().baseParams = {start : 0, limit : theThis.getPagingToolbar().pageSize}; theThis.getGrid().getStore().load(); }, getGrid_Invoices: function(){ var theThis = this; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.invoiceRecord = Ext.data.Record.create([ { name: 'id' , type: 'number' }, { name: 'status' , type: 'string' }, { name: 'total' , type: 'number' }, { name: 'created_at' , type: 'date' }, { name: 'updated_at' , type: 'date' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** theThis.store_Invoice = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy( new Ext.data.Connection({ url: '/Kounta/SearchOrders', dataType: 'json', method: 'POST', timeout: 1800000 }) ), autoLoad : false, fields: theThis.invoiceRecord, root: 'data', idProperty: 'invoiceId', totalProperty: 'totalCount', listeners : { 'load' : function(p_This, records, options){ //console.log(p_This); }, 'loadexception' : function(){ showStoreLoadingErrorMessage(theThis.store_Invoice); } } //}) }); // *************************************************************************************************** // Grid // *************************************************************************************************** //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment } } }); var invoiceSm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment var selectedInvoices = sm.getSelections(); theThis.selectedInvoiceId = -1; if (selectedInvoices.length > 0){ theThis.selectedInvoiceId = selectedInvoices[0].get('invoiceId'); } } } }); // Column Models var stockCM = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ invoiceSm, { header: 'id', dataIndex: 'id', hidden: true }, { header: 'Created date', dataIndex: 'created_at', width: 25, renderer : function(val){ return Ext.util.Format.date(val, 'd/m/Y'); } }, { header: 'Updated date', dataIndex: 'updated_at', width: 25, renderer : function(val){ return Ext.util.Format.date(val, 'd/m/Y'); } }, { header: 'Status', dataIndex: 'status', width: 25 }, { header: 'Total', dataIndex: 'total', width: 25, renderer: Ext.util.Format.usMoney } ] }); /********************************************************************************************/ /****************************/ /* Searching Stock Combobox */ /****************************/ var data_SearchType = [ ['By Date range' , 2] ]; var cmb_SearchInvoice = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'searchTypeDesc'}, {name: 'searchType', type: 'int'} ] }), editable: false, displayField: 'searchTypeDesc', valueField: 'searchType', typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Choose search by ...' }); // manually load local data cmb_SearchInvoice.getStore().loadData(data_SearchType); cmb_SearchInvoice.setValue(2); cmb_SearchInvoice.on({ select: function (p_combo, p_record, p_index) { var searchType = p_record.get('searchType'); if (searchType == 1 || searchType == 3){ theThis.txt_Invoice_SearchInvoiceValue.setVisible(true); theThis.txt_Invoice_SearchInvoiceDateFrom.setVisible(false); theThis.txt_Invoice_SearchInvoiceDateTo.setVisible(false); theThis.lbl_Invoice_SearchInvoiceDateFrom.setVisible(false); theThis.lbl_Invoice_SearchInvoiceDateTo.setVisible(false); } else if (searchType == 2){ theThis.txt_Invoice_SearchInvoiceValue.setVisible(false); theThis.txt_Invoice_SearchInvoiceDateFrom.setVisible(true); theThis.txt_Invoice_SearchInvoiceDateTo.setVisible(true); theThis.lbl_Invoice_SearchInvoiceDateFrom.setVisible(true); theThis.lbl_Invoice_SearchInvoiceDateTo.setVisible(true); } } }); // Invoice grid var grid_Invoice = new Ext.grid.EditorGridPanel({ store : theThis.store_Invoice, title : 'Kounta\'s orders', frame : true, region : 'center', sm : invoiceSm, listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { theThis.selectedInvoiceId = p_this.getStore().getAt(p_rowIndex).get("invoiceId"); // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, rowdblclick : function ( p_this, p_rowIndex, p_eventObject ) { //theThis.btn_Edit_Invoice.handler.call(theThis.btn_Edit_Invoice.scope); }, afterrender : function(){ theThis.store_Invoice.baseParams = {keyword: "", start: 0, limit: theThis.pageSize}, theThis.store_Invoice.load(); theThis.txt_Invoice_SearchInvoiceValue.setVisible(false); theThis.txt_Invoice_SearchInvoiceDateFrom.setVisible(true); theThis.txt_Invoice_SearchInvoiceDateTo.setVisible(true); theThis.lbl_Invoice_SearchInvoiceDateFrom.setVisible(true); theThis.lbl_Invoice_SearchInvoiceDateTo.setVisible(true); } }, tbar: [ /*theThis.btn_Add_Invoice = new Ext.Button({ iconCls: 'icon-add', scale : 'large', text: 'New', handler: function () { theThis.selectedInvoiceId = -1; theThis.dlg_InvoiceDetail.setSelectedInvoiceRecord(null); theThis.dlg_InvoiceDetail.show(); } }), '-', theThis.btn_Edit_Invoice = new Ext.Button({ iconCls: 'icon-edit', text: 'Edit', scale : 'large', handler: function () { // Get selected invoice id var selectedItems = theThis.grid_Invoices.getSelectionModel().getSelections(); if (selectedItems.length > 0) { theThis.dlg_InvoiceDetail.setSelectedInvoiceRecord(selectedItems[0]); theThis.dlg_InvoiceDetail.show(); } else { Ext.Msg.show({ title:'Notice', msg: 'Please choose an item to edit ?', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } }), '-', theThis.btn_Delete_Invoice = new Ext.Button({ iconCls: 'icon-delete', text: 'Delete', scale : 'large', //disabled: true, handler: function () { var selectedItems = theThis.grid_Invoices.getSelectionModel().getSelections(); if (selectedItems.length > 0) { Ext.Msg.show({ title:'Confirm', msg: 'Are you sure you want to delete the item(s) ?', buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.QUESTION, fn : function(btn) { if (btn == "yes") { loadMask.show(); var collectionOfDeletedIds = new Array(); for (var i = 0, row; row = selectedItems[i]; i++) { collectionOfDeletedIds[i] = row.get("invoiceId"); } // Calling delete Ext.Ajax.request({ method: 'POST', url: '/Invoice/DeleteInvoices', params: { invoiceIds : Ext.util.JSON.encode(collectionOfDeletedIds) }, success : function(result, request) { loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.grid_Invoices.getStore().load(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { loadMask.hide(); } }); // End ajax } } }); } else { Ext.Msg.show({ title:'Notice', msg: 'Please select item(s) to delete!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } // End if } }), '-', theThis.btn_Connect = new Ext.Button({ iconCls: 'icon-move-right', text: 'Connect', tooltip : 'Export invoices from Cooking the Books to Xero', scale : 'large', handler: function () { if (theThis.dlg_ConnectToXero == null) { theThis.dlg_ConnectToXero = new Ext.CTBXeroConnectWindow({ callback_ContinueButtonClick : function() { // Continue the process if only there is a valid connection established // Do nothing for now } }); } theThis.dlg_ConnectToXero.show(); } }), '-',*/ theThis.btn_Transfer_Invoice = new Ext.Button({ iconCls: 'icon-move-right', text: 'Transfer orders', tooltip : 'Import Kounta\'s orders to Cooking the Books', scale : 'large', handler: function () { // Get selected invoice id var selectedItems = theThis.grid_Invoices.getSelectionModel().getSelections(); if (selectedItems.length > 0) { theThis.getPOSIntegratedBusinessDepartments(selectedItems, function(selectedOrders, POSCustomerBusinessDepartmentId){ theThis.importOrdersToCTB(POSCustomerBusinessDepartmentId, selectedOrders); }); } else { Ext.Msg.show({ title:'Notice', msg: 'Please select at least one order to transfer ?', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } } }), theThis.btn_Show_AutoTransfer = new Ext.Button({ iconCls: 'icon-move-right', text: 'Setup Auto-Transfer', tooltip : 'Setup Auto-Transfer Kounta\'s orders to Cooking the Books', scale : 'large', handler: function() { theThis.getAutoTransferConfigurationWindow(); } }), // theThis.btn_Auto_Transfer = new Ext.Button({ // iconCls: 'icon-move-right', // text: 'Setup Auto-Transfer', // tooltip : 'Setup Auto-Transfer Kounta\'s orders to Cooking the Books', // scale : 'large', // handler: function () // }), theThis.btn_ShowExportedInvoice = new Ext.Button({ iconCls: 'icon-visible', enableToggle : true, hidden : true, text: 'Show exported invoices', tooltip : 'Show all the invoices included the invoices has been exported to Xero before.', scale : 'large', toggleHandler : function(p_Button, p_State){ Ext.apply(theThis.store_Invoice.baseParams, { start : 0, limit : theThis.getPagingToolbar().pageSize, isShowExported : p_State }); theThis.store_Invoice.load(); if (p_State) p_Button.setText('Hide exported invoices'); else p_Button.setText('Show exported invoices'); } }), '-', theThis.btn_Invoice_StopSearch = new Ext.Button({ xtype : 'button', iconCls : 'icon-stop-search', handler : function(){ theThis.store_Invoice.commitChanges(); //store_Invoice.baseParams = {start : 0, limit : theThis.pageSize}; Ext.apply(theThis.store_Invoice.baseParams, { keyword : "", searchType : -1, start : 0, limit : theThis.pt_Invoice.pageSize }); theThis.store_Invoice.load(); } }), theThis.txt_Invoice_SearchInvoiceValue = new Ext.form.TextField({ emptyText : 'Search value ...', listeners: { specialkey: function(f,e){ if (e.getKey() == e.ENTER) { theThis.btn_Invoice_SearchInvoice.handler.call(theThis.btn_Invoice_SearchInvoice.scope); } } } }), theThis.lbl_Invoice_SearchInvoiceDateFrom = new Ext.form.Label({ xtype : 'label', text : "From :", hidden : true }),' ', theThis.txt_Invoice_SearchInvoiceDateFrom = new Ext.form.DateField({ xtype : 'datefield', format : "j/n/Y", altFormats : 'j/n/y', value : new Date(), hidden : true, width : 200 }),' ', theThis.lbl_Invoice_SearchInvoiceDateTo = new Ext.form.Label({ xtype : 'label', text : "To :", hidden : true }),' ', theThis.txt_Invoice_SearchInvoiceDateTo = new Ext.form.DateField({ xtype : 'datefield', format : "j/n/Y", altFormats : 'j/n/y', value : new Date(), hidden : true, width : 200 }), ' ', cmb_SearchInvoice, theThis.btn_Invoice_SearchInvoice = new Ext.Button({ iconCls : 'icon-search-large', scale : 'large', text : 'Search', handler : function(){ theThis.store_Invoice.commitChanges(); var searchType = cmb_SearchInvoice.getValue(); var searchValue; if (searchType == 1 || searchType == 3) { searchValue = theThis.txt_Invoice_SearchInvoiceValue.getValue(); } else if (searchType == 2) { // Get the From Date var fromDate = theThis.txt_Invoice_SearchInvoiceDateFrom.getValue(); fromDate = Ext.util.JSON.encode(fromDate).replace(/"/g, ''); // Get the To Date var toDate = theThis.txt_Invoice_SearchInvoiceDateTo.getValue(); toDate = Ext.util.JSON.encode(toDate).replace(/"/g, ''); searchValue = fromDate + ";" + toDate; } if (searchType == "") { Ext.Msg.show({ title:'Notice', msg: 'Please choose a search type !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } else { // Send search request theThis.store_Invoice.commitChanges(); // store_Invoice.baseParams = {keyword : searchValue, searchType : searchType, start : 0, limit : theThis.pageSize}; Ext.apply(theThis.store_Invoice.baseParams, { keyword : searchValue, searchType : searchType, start : 0, limit : theThis.pt_Invoice.pageSize }); theThis.store_Invoice.load(); } } }), theThis.btn_Invoice_FilterConfiguration = new Ext.Button({ iconCls : 'icon-search-large', scale : 'large', text : 'Filter Configuration', handler : function(){ theThis.setFilterCondition(); } }) ], cm: stockCM, width: 780, height: 400, autoHeight: false, clicksToEdit: 1, loadMask: true, bbar: theThis.pt_Invoice = new Ext.CTBPagingToolbar({ store: theThis.store_Invoice, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No orders to display" }) , viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); grid_Invoice.on({ rowcontextmenu: function (grid, rowIndex, e) { e.stopEvent(); var row = grid.getView().getRow(rowIndex); Ext.get(row).highlight(); invoiceSm.selectRow(rowIndex); } }); return grid_Invoice; }, // End generateGrid_Databases setFilterCondition: function(){ var theThis = this; Ext.Ajax.request({ method: 'POST', url: '/Kounta/GetIntegrationConfiguration', success: function(result, request) { var jsonData = Ext.decode(result.responseText); var dataObj = jsonData.data; var filterOption = null; if(dataObj != null) { filterOption = { siteId: dataObj.siteId, siteName: dataObj.siteName, categories: dataObj.categories, }; theThis.ctbCountaSelectSitesForConfigurationWindow.setPreloadData(filterOption); } theThis.ctbCountaSelectSitesForConfigurationWindow.showSelectCategoryWindow(function(siteId, siteName, categories){ var integrationConfiguration = { siteId: siteId, siteName: siteName, categories: categories }; Ext.Ajax.request({ method: 'POST', url: '/Kounta/SaveIntegrationConfiguration', params: { integrationConfiguration: Ext.encode(integrationConfiguration) }, success: function(result, request) { //console.log(result.responseText); //dlg_setup.close(); var jsonData = Ext.decode(result.responseText); if(jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info); } else { showErrorNotification('Error', jsonData.message.Info); } }, failure: function(result, request) { //dlg_setup.close(); showErrorNotification('Error', 'Cannot setup the process, please try again. Error: ' + result.responseText); } }); }); }, failure: function(result, request) { //dlg_setup.close(); showErrorNotification('Error', 'Cannot setup the process, please try again. Error: ' + result.responseText); } }); },// END setFilterCondition importOrdersToCTB : function(POSCustomerBusinessDepartmentId, selectedRecords){ var theThis = this; var selectedOrderIds = new Array(); for (var i = 0; i < selectedRecords.length; i++) { selectedOrderIds[i] = selectedRecords[i].data.id; } theThis.loadMask.show(); Ext.Ajax.request({ method: "POST", url: '/Kounta/ImportOrdersToCTB', timeout: 1800000, params: { POSCustomerBusinessDepartmentId : POSCustomerBusinessDepartmentId, selectedOrderIds : Ext.util.JSON.encode(selectedOrderIds) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification('The selected orders have been transferred to Kounta.', NOTIFICATION.ICON_INFORMATION); } else { //showErrorMessageWithEmailNotify(jsonData.message.Info); showErrorNotification('Notice', jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax }, // End generateGrid_Databases getPOSIntegratedBusinessDepartments : function(selectedOrders, callback_Function){ var theThis = this; theThis.loadMask.show(); Ext.Ajax.request({ method: "POST", url: '/Kounta/GetPOSIntegratedBusinessDepartments', timeout: 1800000, params: { }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { if (jsonData.data != null && jsonData.data.length > 0) { if (jsonData.data.length > 1) { // More than 2 for(var i=0; i 0) d.businessDepartmentName += ' - ' + d.outletName; } var dlg_BusinessDepartmentSelector = new Ext.Window({ title : 'Select a business department', closeAction: 'close', iconCls : 'icon-v3-ctb-logo', cls : 'ctbwindow-detail-general', width:390, height: 150, modal : true, callback_AfterSelect : null, defaultPOSCustomerBusinessDepartmentId : jsonData.data[0].POSCustomerBusinessDepartmentId, items : [ new Ext.form.FormPanel ({ region : 'center', frame : true, items : [ new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'POSCustomerBusinessDepartmentId', type: 'number'}, {name: 'businessDepartmentId', type: 'number'}, {name: 'businessDepartmentName', type: 'string'} ] }), fieldLabel: 'Business Department', displayField: 'businessDepartmentName', valueField: 'POSCustomerBusinessDepartmentId', mode : 'local', editable : false, allowBlank : false, emptyText : 'Select a business department ...', typeAhead: true, triggerAction: 'all', lazyRender: true, width : 200, listeners : { afterrender : function(p_This){ var data = new Array(); for (var i = 0; i < jsonData.data.length; i++) { data[i] = [jsonData.data[i].POSCustomerBusinessDepartmentId, jsonData.data[i].businessDepartmentId, jsonData.data[i].businessDepartmentName]; } p_This.getStore().loadData(data); p_This.setValue(dlg_BusinessDepartmentSelector.defaultPOSCustomerBusinessDepartmentId); dlg_BusinessDepartmentSelector.cmb_BusinessDepartments = p_This; } } }) ] }) ], buttons : [ new Ext.Button({ text: 'Select', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ if (!dlg_BusinessDepartmentSelector.cmb_BusinessDepartments.isValid() || dlg_BusinessDepartmentSelector.cmb_BusinessDepartments.getValue() == '') { showErrorNotification('Notice', 'Please select a valid department'); } else { var POSCustomerBusinessDepartmentId = dlg_BusinessDepartmentSelector.cmb_BusinessDepartments.getValue(); //need to check whether it works var businessDepartmentName = dlg_BusinessDepartmentSelector.cmb_BusinessDepartments.getRawValue();//.getText(); if (callback_Function != null) { callback_Function(selectedOrders, POSCustomerBusinessDepartmentId, businessDepartmentName); } dlg_BusinessDepartmentSelector.hide(); } } }), new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ dlg_BusinessDepartmentSelector.hide(); } }) ] }); dlg_BusinessDepartmentSelector.show(); } else if (jsonData.data.length == 1) { var POSCustomerBusinessDepartmentId = jsonData.data[0].POSCustomerBusinessDepartmentId; var businessDepartmentName = jsonData.data[0].businessDepartmentName; if (callback_Function != null) { callback_Function(selectedOrders, POSCustomerBusinessDepartmentId, businessDepartmentName); } } } else { showErrorNotification('Error', 'Cannot find deparment information. Please setup a department first.'); } } else { showErrorNotification('Notice', jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); showErrorNotification('Error', result.responseText); } }); // End ajax }, getAutoTransferConfigurationWindow: function() { var theThis = this; var tpl = new Ext.XTemplate( '

Current settings for auto-transfer sales data from Kounta

', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '
#Business DepartmentSite from KountaSelected Categories
{[xindex]}{posDepartmentName}{siteName}', '', '{id}: {name}
', '
', '
Delete
' ); var store = new Ext.data.JsonStore({ autoLoad : false, baseParams : {start : 0, limit : theThis.pageSize}, proxy: new Ext.data.HttpProxy({ url: '/Kounta/GetAutoTransferConfiguration', dataType: 'json', method: 'POST' }), root: 'data', fields: [ { name: 'connectionId', type: 'number' }, { name: 'posDepartmentId', type: 'number' }, { name: 'posDepartmentName', type: 'string' }, { name: 'optionsJson', type: 'object' } ], idProperty : 'connectionId', listeners: { load: function(store, records, options) { var connections = []; for(var i=0; i'; html += '
to department: '; html += ''+ businessDepartmentName + ' ?'; html += '

After this process has been configured, your sales orders will be transfered from Kounta into Cooking the Books automatically on daily basis.

'; var dlg_setup = new Ext.Window({ title: 'Confirmation', iconCls : 'icon-v3-ctb-logo', cls : 'ctbwindow-detail-general', width: 400, height: 250, modal: true, frame: true, html: html, buttons: [ { text: 'OK', handler: function() { Ext.Ajax.request({ method: 'POST', url: '/Kounta/SetupAutoTransfer', params: { POSCustomerBusinessDepartmentId: POSCustomerBusinessDepartmentId, kountaSiteId: siteId, kountaSiteName: siteName, categories: Ext.encode(categories) }, success: function(result, request) { //console.log(result.responseText); dlg_setup.close(); var jsonData = Ext.decode(result.responseText); if(jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info); } else { showErrorNotification('Error', jsonData.message.Info); } }, failure: function(result, request) { dlg_setup.close(); showErrorNotification('Error', 'Cannot setup the process, please try again. Error: ' + result.responseText); } }); } }, { text: 'Cancel', handler: function() { dlg_setup.close(); } } ] }); dlg_setup.show(); }); //end select business department }); //end select Kounta site } }); Ext.reg('CTBXeroTransferInvoice', Ext.CTBXeroTransferInvoice); Ext.CTBBoard_FoodCostLiveCalendar = Ext.extend(Ext.Window, { title: 'Food cost - Live Calendar', layout: 'border', closeAction: 'hide', iconCls : 'icon-v3-ctb-logo', cls : 'ctbwindow-black-bg', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, width:800, height:500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, listeners : { scope : this, 'beforehide' : function(theThis){ }, 'beforeshow' : function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); }, 'show' : function(theThis){ var today = new Date(); theThis.loadData(today.getMonth() + 1, today.getFullYear()); } }, initComponent : function(){ var theThis = this; // MAIN GRID theThis.pnl_LiveCalendar = theThis.getPanel_LiveCalendar(); theThis.cmb_Month = theThis.getCombobox_Month(); theThis.cmb_Year = theThis.getCombobox_Year(); theThis.btn_LoadData = new Ext.Button({ iconCls : 'icon-stop-search', //text : 'Load data', tooltip : 'Click to reload data', handler : function(){ theThis.loadData(theThis.cmb_Month.getValue(), theThis.cmb_Year.getValue()); } }); theThis.pnl_Main = new Ext.Panel({ layout : 'border', region : 'center', frame : false, tbar : ['-', theThis.cmb_Month, '-', theThis.cmb_Year, '-', theThis.btn_LoadData], items : [theThis.pnl_LiveCalendar] }); theThis.items = [theThis.pnl_Main]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBBoard_FoodCostLiveCalendar.superclass.initComponent.call(this); }, loadData : function(month, year){ var theThis = this; theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Invoice/GetBoard_FoodCostLiveCalendar', params: { month : month, year : year }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.cmb_Month.setValue(jsonData.data.month); theThis.cmb_Year.setValue(jsonData.data.year); theThis.tpl_LiveCalendar.overwrite(theThis.pnl_LiveCalendar.body, jsonData.data); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); }, getPanel_LiveCalendar : function(){ var theThis = this; var str_TemplateBuilder = ''; str_TemplateBuilder += ''+ '
July 2011
'+ '
'+ ''; // Loop to create calendar for (var rowIndex = 0; rowIndex < 5; rowIndex++){ str_TemplateBuilder += ''; for (var colIndex = 0; colIndex < 7; colIndex++){ str_TemplateBuilder += ''; } str_TemplateBuilder += ''; } str_TemplateBuilder += '
' + '' + '' + '' + '' + '' + '' + '' + '
' + (rowIndex == 0 ? 'Sun 26' : '15')+ '
' + 'Daily Food Cost
33.22%' + '
{extraCellInfo_' + rowIndex + '_' + colIndex + '}' + '
' + '
'+ '
'+ '
'; // Create template container theThis.tpl_LiveCalendar = new Ext.XTemplate( '', //'
{headerInfo}
', '
', '', '', '', '', '', '', '', '', '
#575f4b#c4df9b">', '', '', '', '', '', '', '', '
', '', '{timeInfo}', '
', '', '', 'Daily Food Cost
{dailyFoodCost}%', '{extraCellInfo}', '
', '
', '
', '
', '
' ); var pnl_LiveCalendar = new Ext.Panel({ region : 'center', frame : false, bodyBorder : false, autoScroll : true, tpl : theThis.tpl_LiveCalendar, listeners : { afterrender : function(p_This){ theThis.loadMask = new Ext.LoadMask(p_This.getEl(), {msg:"Please wait..."}); } } }); return pnl_LiveCalendar; }, getCombobox_Month : function(){ var data = [ ['January', 1], ['February', 2], ['March', 3], ['April', 4], ['May', 5], ['June', 6], ['July', 7], ['August', 8], ['September', 9], ['October', 10], ['November', 11], ['December', 12] ]; var cmb = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'monthText'}, {name: 'monthNumber', type: 'int'} ], data : data }), width : 150, displayField: 'monthText', valueField: 'monthNumber', typeAhead: true, editable: false, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Month...' }); return cmb; }, getCombobox_Year : function(){ // Get the current year var today = new Date(); var currentYear = today.getFullYear(); var data = [ [currentYear - 9, currentYear - 9], [currentYear - 8, currentYear - 8], [currentYear - 7, currentYear - 7], [currentYear - 6, currentYear - 6], [currentYear - 5, currentYear - 5], [currentYear - 4, currentYear - 4], [currentYear - 3, currentYear - 3], [currentYear - 2, currentYear - 2], [currentYear - 1, currentYear - 1], [currentYear, currentYear] ]; var cmb = new Ext.form.ComboBox({ store: new Ext.data.ArrayStore({ fields: [ {name: 'yearText'}, {name: 'yearNumber', type: 'int'} ], data : data }), width : 80, displayField: 'yearText', valueField: 'yearNumber', typeAhead: true, editable: false, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Year...' }); return cmb; }, initButtons : function(){ var theThis = this; var buttons = [ /*theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } })*/ ]; return buttons; } }); Ext.reg('CTBBoard_FoodCostLiveCalendar', Ext.CTBBoard_FoodCostLiveCalendar); function changeCardLayoutByTimeInterval(containerId, timeInterval){ setTimeout(function(){ var container = Ext.getCmp(containerId); var currentIndex = container.items.indexOf(container.layout.activeItem); var nextIndex = currentIndex + 1 == container.items.length ? 0 : currentIndex + 1; container.layout.setActiveItem(nextIndex); changeCardLayoutByTimeInterval(containerId, timeInterval); }, timeInterval); } Ext.CTBBoard_InvoiceFoodCost = Ext.extend(Ext.Panel, { layout : 'border', title : 'Live Food Cost: based on Purchases to Sales', loadMask: null, timeInterval : 3000, stopSlide : true, weekIndex : 0, pageSize: CTB.init.itemPerPage || 100, startDayOfTheWeek : DAY_SELECTION.MONDAY, stocktakeDate : null, listeners : { afterrender : function(theThis){ // Init loadMask theThis.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); theThis.changeSlide(); } }, changeSlide : function() { var theThis = this; setTimeout(function(){ if (!theThis.stopSlide) { theThis.moveToNextSlide(); theThis.changeSlide(); } }, theThis.timeInterval); //changeCardLayoutByTimeInterval(theThis.pnl_LiveFoodCost.id, theThis.timeInterval); }, moveToNextSlide : function(){ var theThis = this; var container = theThis.pnl_LiveFoodCost; var currentIndex = container.items.indexOf(container.layout.activeItem); var nextIndex = currentIndex + 1 == container.items.length ? 0 : currentIndex + 1; container.layout.setActiveItem(nextIndex); theThis.setTitle(container.layout.activeItem.titleDescription); }, getDialogSelectDate : function(){ var theThis = this; var buttons = []; var buttons_text = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]; for (var i = 0; i < buttons_text.length; i++){ buttons[i] = new Ext.Button({ text : buttons_text[i], scale : 'large', width : 100, height : 30, dateIndex : i, handler : function(){ theThis.startDayOfTheWeek = this.dateIndex; theThis.cookieProvider.set("startDayOfTheWeek", theThis.startDayOfTheWeek); theThis.loadData(); theThis.dlg_SelectDate.hide(); } }); } var dlg_SelectDate = new Ext.Window({ buttons : buttons, modal : true, closeAction : 'hide', resizable : false, title : 'Select date', width : 770, height : 0 }); return dlg_SelectDate; }, loadData : function(){ var theThis = this; theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Invoice/GetBoard_InvoiceFoodCost', params: { weekIndex : theThis.weekIndex, startDayOfTheWeek : theThis.startDayOfTheWeek, stocktakeDate : theThis.stocktakeDate }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { var weekdays = jsonData.data.weekdays; for (var i = 0; i < weekdays.length; i++){ weekdays[i].foodCostOfTheDate = weekdays[i].kitchenRevenueOfTheDate == 0 ? '0.00' : addFullDigitToNumber(roundNumber(weekdays[i].purchaseOfTheDate / weekdays[i].kitchenRevenueOfTheDate * 100, 2), 2), weekdays[i].purchaseOfTheDate = addFullDigitToNumber(roundNumber(weekdays[i].purchaseOfTheDate, 2), 2); weekdays[i].kitchenRevenueOfTheDate = addFullDigitToNumber(roundNumber(weekdays[i].kitchenRevenueOfTheDate, 2), 2); } var wrapperData = { uniqueId : theThis.id, weekdays : weekdays, stocktakeDate : jsonData.data.stocktakeDate, endDateOfTheWeek : jsonData.data.endDateOfTheWeek, purchaseToday : addFullDigitToNumber(roundNumber(jsonData.data.purchaseToday, 2), 2), purchaseYesterday : addFullDigitToNumber(roundNumber(jsonData.data.purchaseYesterday, 2), 2), purchaseThisWeek : addFullDigitToNumber(roundNumber(jsonData.data.purchaseThisWeek, 2), 2), purchaseThisMonth : addFullDigitToNumber(roundNumber(jsonData.data.purchaseThisMonth, 2), 2), purchaseThisYear : addFullDigitToNumber(roundNumber(jsonData.data.purchaseThisYear, 2), 2), purchaseFromLastStocktake : addFullDigitToNumber(roundNumber(jsonData.data.purchaseFromLastStocktake, 2), 2), purchaseMonthUntilEndOfWeekDate : addFullDigitToNumber(roundNumber(jsonData.data.purchaseMonthUntilEndOfWeekDate, 2), 2), purchaseYearUntilEndOfWeekDate : addFullDigitToNumber(roundNumber(jsonData.data.purchaseYearUntilEndOfWeekDate, 2), 2), kitchenRevenueToday : addFullDigitToNumber(roundNumber(jsonData.data.kitchenRevenueToday, 2), 2), kitchenRevenueYesterday : addFullDigitToNumber(roundNumber(jsonData.data.kitchenRevenueYesterday, 2), 2), kitchenRevenueThisWeek : addFullDigitToNumber(roundNumber(jsonData.data.kitchenRevenueThisWeek, 2), 2), kitchenRevenueThisMonth : addFullDigitToNumber(roundNumber(jsonData.data.kitchenRevenueThisMonth, 2), 2), kitchenRevenueThisYear : addFullDigitToNumber(roundNumber(jsonData.data.kitchenRevenueThisYear, 2), 2), kitchenRevenueFromLastStocktake : addFullDigitToNumber(roundNumber(jsonData.data.kitchenRevenueFromLastStocktake, 2), 2), kitchenRevenueMonthUntilEndOfWeekDate : addFullDigitToNumber(roundNumber(jsonData.data.kitchenRevenueMonthUntilEndOfWeekDate, 2), 2), kitchenRevenueYearUntilEndOfWeekDate : addFullDigitToNumber(roundNumber(jsonData.data.kitchenRevenueYearUntilEndOfWeekDate, 2), 2), foodCostToday : jsonData.data.kitchenRevenueToday == 0 ? '0.00' : addFullDigitToNumber(roundNumber(jsonData.data.purchaseToday / jsonData.data.kitchenRevenueToday * 100, 2), 2), foodCostYesterday : jsonData.data.kitchenRevenueYesterday == 0 ? '0.00' : addFullDigitToNumber(roundNumber(jsonData.data.purchaseYesterday / jsonData.data.kitchenRevenueYesterday * 100, 2), 2), foodCostThisWeek : jsonData.data.kitchenRevenueThisWeek == 0 ? '0.00' : addFullDigitToNumber(roundNumber(jsonData.data.purchaseThisWeek / jsonData.data.kitchenRevenueThisWeek * 100, 2), 2), foodCostThisMonth : jsonData.data.kitchenRevenueThisMonth == 0 ? '0.00' : addFullDigitToNumber(roundNumber(jsonData.data.purchaseThisMonth / jsonData.data.kitchenRevenueThisMonth * 100, 2), 2), foodCostThisYear : jsonData.data.kitchenRevenueThisYear == 0 ? '0.00' : addFullDigitToNumber(roundNumber(jsonData.data.purchaseThisYear / jsonData.data.kitchenRevenueThisYear * 100, 2), 2), foodCostFromLastStocktake : jsonData.data.kitchenRevenueFromLastStocktake == 0 ? '0.00' : addFullDigitToNumber(roundNumber(jsonData.data.purchaseFromLastStocktake / jsonData.data.kitchenRevenueFromLastStocktake * 100, 2), 2), foodCostMonthUntilEndOfWeekDate : jsonData.data.kitchenRevenueMonthUntilEndOfWeekDate == 0 ? '0.00' : addFullDigitToNumber(roundNumber(jsonData.data.purchaseMonthUntilEndOfWeekDate / jsonData.data.kitchenRevenueMonthUntilEndOfWeekDate * 100, 2), 2), foodCostYearUntilEndOfWeekDate : jsonData.data.kitchenRevenueYearUntilEndOfWeekDate == 0 ? '0.00' : addFullDigitToNumber(roundNumber(jsonData.data.purchaseYearUntilEndOfWeekDate / jsonData.data.kitchenRevenueYearUntilEndOfWeekDate * 100, 2), 2) }; theThis.pnl_FoodCostTable.update(wrapperData); if (Ext.get(theThis.id + '_SelectStartDateOfTheWeek') != null){ Ext.get(theThis.id + '_SelectStartDateOfTheWeek').on('click', function(){ theThis.dlg_SelectDate.show(); }); } if (Ext.get(theThis.id + '_SelectStocktakeDate') != null){ Ext.get(theThis.id + '_SelectStocktakeDate').on('click', function(){ if (theThis.dlg_StocktakeDateSelector == null) { theThis.dlg_StocktakeDateSelector = new Ext.CTBStocktakeDateRangeSelectorDialog({ title: 'Please select a stocktake date', isForSelectSingleDate : true }); } theThis.dlg_StocktakeDateSelector.callback_AfterSelect = function(startDate, endDate) { theThis.stocktakeDate = startDate; theThis.loadData(); } theThis.dlg_StocktakeDateSelector.show(); }); } } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); }, initComponent: function(){ var theThis = this; theThis.cookieProvider = new Ext.state.CookieProvider; if (theThis.cookieProvider.get("startDayOfTheWeek") != null){ theThis.startDayOfTheWeek = theThis.cookieProvider.get("startDayOfTheWeek"); } theThis.pnl_LiveFoodCost = theThis.getPanel_LiveFoodCost(); //theThis.pnl_ExtraButtons = theThis.getPanel_ExtraButtons(); theThis.pnl_TopButtons = theThis.getPanel_TopButtons(); theThis.dlg_SelectDate = theThis.getDialogSelectDate(); theThis.dlg_FoodCostLiveCalendar = new Ext.CTBBoard_FoodCostLiveCalendar({ }); theThis.dlg_FoodCostPredictor = new Ext.CTBFoodCostPredictorWindow({ }); theThis.items = [theThis.pnl_LiveFoodCost, theThis.pnl_TopButtons];//, theThis.pnl_ExtraButtons]; // Call super class to initialize componenets Ext.CTBBoard_InvoiceFoodCost.superclass.initComponent.call(this); }, getPanel_LiveFoodCost : function(){ var theThis = this; theThis.pnl_FoodCostTable = theThis.getPanel_FoodCostTable(); theThis.chart_DailyFoodCost = theThis.getChart_DailyFoodCost(0, 'Current Week - Food Cost'); theThis.chart_PreviousWeekFoodCost = theThis.getChart_DailyFoodCost(-1, 'Previous Week - Food Cost'); theThis.chart_2WeeksBeforeFoodCost = theThis.getChart_DailyFoodCost(-2, 'Two weeks before - Food Cost'); theThis.chart_3WeeksBeforeFoodCost = theThis.getChart_DailyFoodCost(-3, 'Three weeks before - Food Cost'); theThis.chart_MonthFoodCost = theThis.getChart_MonthFoodCost(); theThis.chart_YearFoodCost = theThis.getChart_YearFoodCost(); var pnl_LiveFoodCost = new Ext.Panel({ region : 'center', layout : 'card', /*tbar : new Ext.Toolbar({ buttonAlign : 'center', items : [ theThis.btn_PreviousWeek = new Ext.Button({ text : 'Previous Week', scale : 'large', iconCls : 'icon-calendar-previous', handler : function(){ theThis.stopSlide = true; theThis.weekIndex--; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }), theThis.btn_3WeeksBefore = new Ext.Button({ text : '3 Weeks Before', scale : 'large', iconCls : 'icon-calendar', handler : function(){ theThis.stopSlide = true; theThis.weekIndex = -3; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }), theThis.btn_2WeeksBefore = new Ext.Button({ text : '2 Weeks Before', scale : 'large', iconCls : 'icon-calendar', handler : function(){ theThis.stopSlide = true; theThis.weekIndex = -2; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }), theThis.btn_CurrentWeek = new Ext.Button({ text : 'Current Week', scale : 'large', iconCls : 'icon-calendar', handler : function(){ theThis.stopSlide = true; theThis.weekIndex = 0; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }), theThis.btn_NextWeek = new Ext.Button({ text : 'Next Week', scale : 'large', iconCls : 'icon-calendar-next', handler : function(){ theThis.stopSlide = true; theThis.weekIndex++; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }), theThis.btn_Daily = new Ext.Button({ text : 'Daily', scale : 'large', iconCls : 'icon-graph', handler : function(){ theThis.stopSlide = true; theThis.store_DailyFoodCost.baseParams.weekIndex = theThis.weekIndex; theThis.store_DailyFoodCost.baseParams.startDayOfTheWeek = theThis.startDayOfTheWeek; theThis.store_DailyFoodCost.load(); theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.chart_DailyFoodCost); theThis.setTitle(theThis.chart_DailyFoodCost.titleDescription); } }), theThis.btn_Monthly = new Ext.Button({ text : 'Monthly', scale : 'large', iconCls : 'icon-graph', handler : function(){ theThis.stopSlide = true; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.chart_MonthFoodCost); theThis.setTitle(theThis.chart_MonthFoodCost.titleDescription); } }), theThis.btn_Yearly = new Ext.Button({ text : 'Yearly', scale : 'large', iconCls : 'icon-graph', handler : function(){ theThis.stopSlide = true; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.chart_YearFoodCost); theThis.setTitle(theThis.chart_YearFoodCost.titleDescription); } }) ] }),*/ activeItem : 0, items : [ theThis.pnl_FoodCostTable, theThis.chart_3WeeksBeforeFoodCost, theThis.chart_2WeeksBeforeFoodCost, theThis.chart_PreviousWeekFoodCost, theThis.chart_DailyFoodCost, theThis.chart_MonthFoodCost, theThis.chart_YearFoodCost ], listeners : { afterrender : function(p_This){ } } }); return pnl_LiveFoodCost; }, getPanel_TopButtons : function(){ var theThis = this; theThis.tpl_TopButtons = new Ext.XTemplate( '', '
', '', '', '', '', '', '', '', '', '
', 'View', '', '
', '
', '
See live food cost calendar
', '
', '
See food cost predictor
', '
', ' ', '
', '
', '
' ); var pnl_TopButtons = new Ext.Panel({ region : 'north', frame : false, height : 25, tpl : theThis.tpl_TopButtons, activeMenuButton : 'Current week', listeners : { afterrender : function(p_This){ theThis.pnl_TopButtons.update({uniqueId : theThis.id}); // View options button Ext.get(String.format('{0}btn_ViewOptions', theThis.id)).on('click', function(e){ p_This.menu_ViewOptions = new Ext.menu.Menu({ items: [ { iconCls: p_This.activeMenuButton == 'Previous week' ? 'icon-v3-menu-tick' : 'no-icon', text: 'Previous week', handler: function (p_ThisButton) { p_This.activeMenuButton = p_ThisButton.text; theThis.stopSlide = true; theThis.weekIndex--; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }, { iconCls: p_This.activeMenuButton == '3 weeks before' ? 'icon-v3-menu-tick' : 'no-icon', text: '3 weeks before', handler: function (p_ThisButton) { p_This.activeMenuButton = p_ThisButton.text; theThis.stopSlide = true; theThis.weekIndex = -3; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }, { iconCls: p_This.activeMenuButton == '2 weeks before' ? 'icon-v3-menu-tick' : 'no-icon', text: '2 weeks before', handler: function (p_ThisButton) { p_This.activeMenuButton = p_ThisButton.text; theThis.stopSlide = true; theThis.weekIndex = -2; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }, { iconCls: p_This.activeMenuButton == 'Current week' ? 'icon-v3-menu-tick' : 'no-icon', text: 'Current week', handler: function (p_ThisButton) { p_This.activeMenuButton = p_ThisButton.text; theThis.stopSlide = true; theThis.weekIndex = 0; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }, { iconCls: p_This.activeMenuButton == 'Next week' ? 'icon-v3-menu-tick' : 'no-icon', text: 'Next week', handler: function (p_ThisButton) { p_This.activeMenuButton = p_ThisButton.text; theThis.stopSlide = true; theThis.weekIndex++; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.pnl_FoodCostTable); theThis.setTitle(theThis.pnl_FoodCostTable.titleDescription); theThis.loadData(); } }, '-', { iconCls: p_This.activeMenuButton == 'Daily' ? 'icon-v3-menu-tick' : 'no-icon', text: 'Daily', handler: function (p_ThisButton) { p_This.activeMenuButton = p_ThisButton.text; theThis.stopSlide = true; theThis.store_DailyFoodCost.baseParams.weekIndex = theThis.weekIndex; theThis.store_DailyFoodCost.baseParams.startDayOfTheWeek = theThis.startDayOfTheWeek; theThis.store_DailyFoodCost.load(); theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.chart_DailyFoodCost); theThis.setTitle(theThis.chart_DailyFoodCost.titleDescription); } }, { iconCls: p_This.activeMenuButton == 'Monthly' ? 'icon-v3-menu-tick' : 'no-icon', text: 'Monthly', handler: function (p_ThisButton) { p_This.activeMenuButton = p_ThisButton.text; theThis.stopSlide = true; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.chart_MonthFoodCost); theThis.setTitle(theThis.chart_MonthFoodCost.titleDescription); } }, { iconCls: p_This.activeMenuButton == 'Yearly' ? 'icon-v3-menu-tick' : 'no-icon', text: 'Yearly', handler: function (p_ThisButton) { p_This.activeMenuButton = p_ThisButton.text; theThis.stopSlide = true; theThis.pnl_LiveFoodCost.layout.setActiveItem(theThis.chart_YearFoodCost); theThis.setTitle(theThis.chart_YearFoodCost.titleDescription); } } ] }); p_This.menu_ViewOptions.show(e.getTarget()); }); // Live food cost calendar button Ext.get(String.format('{0}btnLiveFoodCostCalendar', theThis.id)).on('click', function(e){ theThis.dlg_FoodCostLiveCalendar.show(); }); // Food cost predictor Ext.get(String.format('{0}btnFoodCostPredictor', theThis.id)).on('click', function(e){ theThis.dlg_FoodCostPredictor.show(); }); } } }); return pnl_TopButtons; }, getPanel_FoodCostTable : function(){ var theThis = this; theThis.tpl_FoodCostTable = new Ext.XTemplate( '', '
', '', /*'', '', '',*/ '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '
', 'Food cost based on Purchase to Sales', '
', '
Click here to change start date of week
', '
', '{theDateName}', '', 'Week to date', '', 'Month to date', '', 'Year to date', '', '
Click here to change last stocktake date

{stocktakeDate}', '
', 'Until {endDateOfTheWeek}', '', 'Until today', '', 'Until {endDateOfTheWeek}', '', 'Until today', '
', 'Food Cost %', '', '{foodCostOfTheDate}%', '', '{foodCostThisWeek}%', '', '{foodCostMonthUntilEndOfWeekDate}%', '', '{foodCostThisMonth}%', '', '{foodCostYearUntilEndOfWeekDate}%', '', '{foodCostThisYear}%', '', '{foodCostFromLastStocktake}%', '
', 'Purchase', '', '
${purchaseOfTheDate}
', '
', '
${purchaseThisWeek}
', '
', '
${purchaseMonthUntilEndOfWeekDate}
', '
', '
${purchaseThisMonth}
', '
', '
${purchaseYearUntilEndOfWeekDate}
', '
', '
${purchaseThisYear}
', '
', '
${purchaseFromLastStocktake}
', '
', 'Sales', '', '
${kitchenRevenueOfTheDate}
', '
', '
${kitchenRevenueThisWeek}
', '
', '
${kitchenRevenueMonthUntilEndOfWeekDate}
', '
', '
${kitchenRevenueThisMonth}
', '
', '
${kitchenRevenueYearUntilEndOfWeekDate}
', '
', '
${kitchenRevenueThisYear}
', '
', '
${kitchenRevenueFromLastStocktake}
', '
', '
', '
' ); var pnl_FoodCostTable = new Ext.Panel({ region : 'center', titleDescription : 'Live Food Cost', frame : false, tpl : theThis.tpl_FoodCostTable, listeners : { afterrender : function(p_This){ } } }); return pnl_FoodCostTable; }, getChart_DailyFoodCost : function(weekIndex, title){ var theThis = this; theThis.store_DailyFoodCost = new Ext.data.JsonStore({ baseParams : {start : 0, limit : theThis.pageSize, weekIndex : theThis.weekIndex, startDayOfTheWeek : theThis.startDayOfTheWeek}, proxy: new Ext.data.HttpProxy({ url: '/Invoice/GetChartData_FoodCostWeek', dataType: 'json', method: 'POST' }), autoLoad : false, fields:['name', 'foodCost'], root: 'data', //idProperty: 'menuAnalysisId', //totalProperty : 'totalCount', listeners : { 'beforeload' : function(){ }, 'load' : function(){ theThis.chartObjectDaily = new Ext.chart.LineChart({ store: theThis.store_DailyFoodCost, xField: 'name', yField: 'foodCost', tipRenderer : function(chart, record){ return addFullDigitToNumber(record.data.foodCost, 2) + ' % in ' + record.data.name; }, listeners: { itemclick: function(o){ var rec = store.getAt(o.index); //Ext.example.msg('Item Selected', 'You chose {0}.', rec.get('name')); } } }); theThis.chart_DailyFoodCost.removeAll(true); theThis.chart_DailyFoodCost.add(theThis.chartObjectDaily); theThis.chart_DailyFoodCost.getLayout().setActiveItem(theThis.chartObjectDaily); }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); // extra extra simple var chartContainer = new Ext.Panel({ titleDescription: title, layout:'card', items: [ /*theThis.chartObjectDaily = new Ext.chart.LineChart({ store: theThis.store_DailyFoodCost, xField: 'name', yField: 'foodCost', tipRenderer : function(chart, record){ return addFullDigitToNumber(record.data.foodCost, 2) + ' % in ' + record.data.name; }, listeners: { itemclick: function(o){ var rec = store.getAt(o.index); //Ext.example.msg('Item Selected', 'You chose {0}.', rec.get('name')); } } })*/ ] }); return chartContainer; }, getChart_MonthFoodCost : function(){ var theThis = this; var store = new Ext.data.JsonStore({ baseParams : {start : 0, limit : theThis.pageSize}, proxy: new Ext.data.HttpProxy({ url: '/Invoice/GetChartData_FoodCostMonth', dataType: 'json', method: 'POST' }), autoLoad : true, fields:['name', 'foodCost'], root: 'data', //idProperty: 'menuAnalysisId', //totalProperty : 'totalCount', listeners : { 'beforeload' : function(){ }, 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); // extra extra simple var chartContainer = new Ext.Panel({ titleDescription: 'Month - Food Cost', layout:'fit', items: { xtype: 'linechart', store: store, xField: 'name', yField: 'foodCost', /*yAxis: new Ext.chart.NumericAxis({ displayName: 'Food Cost', labelRenderer : Ext.util.Format.numberRenderer('0,0') }),*/ tipRenderer : function(chart, record){ return addFullDigitToNumber(record.data.foodCost, 2) + ' % in ' + record.data.name; }, listeners: { itemclick: function(o){ var rec = store.getAt(o.index); //Ext.example.msg('Item Selected', 'You chose {0}.', rec.get('name')); } } } }); return chartContainer; }, getChart_YearFoodCost : function(){ var theThis = this; var store = new Ext.data.JsonStore({ baseParams : {start : 0, limit : theThis.pageSize}, proxy: new Ext.data.HttpProxy({ url: '/Invoice/GetChartData_FoodCostYear', dataType: 'json', method: 'POST' }), autoLoad : true, fields:['name', 'foodCost'], root: 'data', //idProperty: 'menuAnalysisId', //totalProperty : 'totalCount', listeners : { 'beforeload' : function(){ }, 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); // extra extra simple var chartContainer = new Ext.Panel({ titleDescription: 'Year - Food Cost', layout:'fit', items: { xtype: 'linechart', store: store, xField: 'name', yField: 'foodCost', tipRenderer : function(chart, record){ return addFullDigitToNumber(record.data.foodCost, 2) + ' % in ' + record.data.name; }, listeners: { itemclick: function(o){ var rec = store.getAt(o.index); //Ext.example.msg('Item Selected', 'You chose {0}.', rec.get('name')); } } } }); return chartContainer; }, getPanel_ExtraButtons : function(){ var theThis = this; var pnl_ExtraButtons = new Ext.Panel({ region : 'east', layout : 'vbox', frame : true, width : 50, layoutConfigs : { defaultMargins : '5 5 5 5' }, items : [ theThis.btn_ShowCalendar = new Ext.Button({ xtype : 'button', scale : 'large', iconCls : 'icon-calendar', handler : function(){ theThis.dlg_FoodCostLiveCalendar.show(); }, listeners : { afterrender : function(p_This){ var annouceTooltip = new Ext.ToolTip({ target: theThis.btn_ShowCalendar.id, anchor: 'right', html: 'Click me to show your
LIVE FOOD COST Calendar
' }); annouceTooltip.show(); } } }), theThis.btn_StopSlide = new Ext.Button({ xtype : 'button', scale : 'large', hidden : true, iconCls : 'icon-cancel-large', tooltip : 'Stop slide', handler : function(){ theThis.stopSlide = true; } }), theThis.btn_MoveNext = new Ext.Button({ xtype : 'button', scale : 'large', hidden : true, iconCls : 'icon-move-right', tooltip : 'Next slide', handler : function(){ theThis.moveToNextSlide(); } }), new Ext.Panel({ height : 100, width : 30 }) ], listeners : { afterrender : function(p_This){ } } }); return pnl_ExtraButtons; } }); Ext.reg('CTBBoard_InvoiceFoodCost', Ext.CTBBoard_InvoiceFoodCost); Ext.CTBInvoiceDetailGrid = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: CTB.init.itemPerPage || 100, border: false, recordObject : null, selectedInvoiceRecord : null, isForCreditNoteRequest : false, hideInstruction : true, isCalculateParentField : true, setSelectedInvoiceRecord : function(theRecord){ var theThis = this; theThis.selectedInvoiceRecord = theRecord; if (theRecord != null) theThis.selectedInvoiceId = theRecord.data.invoiceId; else theThis.selectedInvoiceId = -1; }, parentWindowContainer : null, listeners : { afterrender : function(theThis){ // Init loadMask theThis.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); }, show : function(theThis){ theThis.modifiedRecords = null; } }, instructionText : 'Physical Invoice', instructionBackgroundColor : '#282828', redrawInstruction : function(){ var theThis = this; theThis.pnl_Instruction.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); }, initComponent: function(){ var theThis = this; theThis.StockBrowserDialog = Ext.getCmp('dlg_StockBrowser'); theThis.grid_InvoiceDetail = theThis.getGrid_InvoiceDetail(); theThis.tpl_Instruction = new Ext.XTemplate( '', '
', '', '', '', '', '
', '{instructionText}', '
', '
', '
' ); theThis.pnl_Instruction = new Ext.Panel({ frame : true, border : false, region : 'north', height : 70, tpl : theThis.tpl_Instruction, hidden : theThis.hideInstruction, listeners : { afterrender : function(p_This){ p_This.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); } } }); theThis.items = [theThis.grid_InvoiceDetail, theThis.pnl_Instruction]; // Call super class to initialize componenets Ext.CTBInvoiceDetailGrid.superclass.initComponent.call(this); }, updateTheSubtotal : function(theRecord){ var theThis = this; theThis.getGrid().updateTheSubtotal(theRecord); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_InvoiceDetail; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_InvoiceDetail; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getStore().baseParams = {invoiceId : theThis.selectedInvoiceRecord.data.invoiceId, start : 0, limit : theThis.getPagingToolbar().pageSize}; theThis.getGrid().getStore().load(); }, getCombobox_UnitOfMeasurement : function(callbackfunction) { var cmbGridUOM = new Ext.form.ComboBox({ store: Global_UnitOfMeasurement_Store, displayField: 'UOMName', valueField: 'UOMId', typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local' }); return cmbGridUOM; }, getGrid_InvoiceDetail: function(){ var theThis = this; // shorthand alias var fm = Ext.form; var cmbGridUOM = theThis.getCombobox_UnitOfMeasurement(); // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.recordObject = Ext.data.Record.create([ { name: 'invoiceDetailId', type: 'number' }, { name: 'invoiceId', type: 'number' }, { name: 'supplierStockCode', type: 'string' }, { name: 'stockDesc', type: 'string' }, { name: 'stockUnit', type: 'number' }, { name: 'stockUnitOfMeasurementId', type: 'number' }, { name: 'stockQty', type: 'number' }, { name: 'stockId', type: 'number' }, { name: 'stockSupplierId', type: 'number' }, { name: 'invoiceDetailCost', type : 'number'}, { name: 'invoiceDetailTax', type: 'number' }, { name: 'invoiceDetailSubtotal', type: 'number' }, { name: 'isGstApplied', type: 'boolean' }, { name: 'discountPercentage', type: 'number' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** var store = new Ext.data.JsonStore({ autoLoad : false, proxy: new Ext.data.HttpProxy({ url: '/Invoice/GetInvoiceDetailByInvoiceId', dataType: 'json', method: 'POST' }), //reader: new Ext.data.JsonReader({ fields: theThis.recordObject, root: 'data', idProperty: 'invoiceDetailId', listeners : { 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } //}) }); // *************************************************************************************************** // Selection model // *************************************************************************************************** var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { } } }); // *************************************************************************************************** // Column model // *************************************************************************************************** // Column Models var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'invoiceDetailId', dataIndex: 'invoiceDetailId', hidden: true, width:5 }, { header: 'invoiceId', dataIndex: 'invoiceId', hidden: true, width:5 }, { header: 'Stock Code', dataIndex: 'supplierStockCode', width: 10, hidden : theThis.isForCreditNoteRequest, filter: {xtype : "textfield", filterName : "supplierStockCode", callbackFunction : function(filterValue){ theThis.insertStockSupplierRecordBySupplierStockCode(filterValue, 0); }} }, { header: 'Description', dataIndex: 'stockDesc', width: 30 }, { header: 'Unit', dataIndex: 'stockUnit', width: 15, hidden : theThis.isForCreditNoteRequest }, { header: 'Measurement', dataIndex: 'stockUnitOfMeasurementId', width: 15, hidden : theThis.isForCreditNoteRequest, renderer: Ext.util.Format.comboRenderer(cmbGridUOM) }, { header: 'Quantity' + CTB_SYMBOL.EDIT, dataIndex: 'stockQty', width: 15, editor: new Ext.grid.GridEditor( new Ext.form.SpinnerField({ xtype: 'spinnerfield', allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 3, onFocus: function (txt, e) { this.getEl().dom.select(); } }), { listeners: { beforestartedit: function(editor) { editor.field.currentRecord = editor.record; }, complete : function(p_This, p_Value, p_StartValue){ // Value has been changed by user if (p_Value != p_StartValue){ //updateTheSubtotal(p_This.record); } } } } ) }, { header: 'Cost/Unit', dataIndex: 'invoiceDetailCost', width: 15, hidden : theThis.isForCreditNoteRequest, editor: new Ext.grid.GridEditor( new Ext.form.SpinnerField({ xtype: 'spinnerfield', allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 3, onFocus: function (txt, e) { this.getEl().dom.select(); } }), { listeners: { beforestartedit: function(editor) { editor.field.currentRecord = editor.record; }, complete : function(p_This, p_Value, p_StartValue){ // Value has been changed by user if (p_Value != p_StartValue){ //updateTheSubtotal(p_This.record); } } } } ), renderer: Ext.util.Format.usMoney }, { header: 'DISC %' + CTB_SYMBOL.EDIT, dataIndex: 'discountPercentage', width: 15, hidden : theThis.isForCreditNoteRequest, editor: new Ext.grid.GridEditor( new Ext.form.NumberField({ allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 2, onFocus: function (txt, e) { this.getEl().dom.select(); } }), { listeners: { beforestartedit: function(editor) { editor.field.currentRecord = editor.record; }, complete : function(p_This, p_Value, p_StartValue){ // Value has been changed by user if (p_Value != p_StartValue){ //updateTheSubtotal(p_This.record); } } } } ), renderer: function(val){ return Ext.util.Format.percentage(val); } }, { header: 'Tax' + CTB_SYMBOL.EDIT, dataIndex: 'invoiceDetailTax', width: 15, hidden : theThis.isForCreditNoteRequest, editor: new Ext.grid.GridEditor( new Ext.form.SpinnerField({ xtype: 'spinnerfield', moneySign : '', allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 3, onFocus: function (txt, e) { this.getEl().dom.select(); } }), { listeners: { beforestartedit: function(editor) { editor.field.currentRecord = editor.record; }, complete : function(p_This, p_Value, p_StartValue){ // Value has been changed by user if (p_Value != p_StartValue){ // Mark the record as modified p_This.record.isUserModifiedTax = true; } } } } ), renderer: Ext.util.Format.usMoney }, { header: 'Subtotal', dataIndex: 'invoiceDetailSubtotal', width: 15, hidden : theThis.isForCreditNoteRequest, renderer: Ext.util.Format.usMoney }, { header: '', dataIndex: 'invoiceDetailId', width: 5, renderer: function(val, meta, theRecord){ return String.format('
', theThis.id, val); } }, { header: '', dataIndex: 'invoiceDetailId', width: 0, renderer: function(val, meta, theRecord){ return ''; } } ] }); // This function update tax column for all rows function updateTaxForAllRows(){ for (var i = 0; i < store.getCount(); i++){ var theRecord = store.getAt(i); if (theRecord.data.isGstApplied){ if (theRecord.isUserModifiedTax == null || theRecord.isUserModifiedTax == false) theRecord.set('invoiceDetailTax', roundNumber((theRecord.data.invoiceDetailCost * theRecord.data.stockQty * CTB.init.expenseTax.percentage)/100, 2)); } /*else if (theRecord.data.invoiceDetailTax != 0){ theRecord.set('invoiceDetailTax', roundNumber((theRecord.data.invoiceDetailCost * theRecord.data.stockQty * Global_GSTPercentage)/100, 2)); }*/ } } function updateTheTax(theRecord){ if (theRecord.data.isGstApplied){ if (theRecord.isUserModifiedTax == null || theRecord.isUserModifiedTax == false) theRecord.set('invoiceDetailTax', roundNumber((theRecord.data.invoiceDetailCost * theRecord.data.stockQty * CTB.init.expenseTax.percentage)/100, 2)); } } // This function update the subtotal for individual record function updateTheSubtotal(theRecord){ updateTheTax(theRecord); var theSubTotal = theRecord.get('invoiceDetailTax') + theRecord.get('invoiceDetailCost')*theRecord.get('stockQty'); // Minus the individual discount theSubTotal = theSubTotal - (theSubTotal * theRecord.get('discountPercentage') / 100); theSubTotal = roundNumber(theSubTotal, Global_Money_RoundUpTo); theRecord.set('invoiceDetailSubtotal', theSubTotal); if (theThis.parentWindowContainer != null && theThis.isCalculateParentField) { theThis.parentWindowContainer.refreshCalculatingField(); } } // *************************************************************************************************** // Paging toolbar // *************************************************************************************************** theThis.pt_InvoiceDetail = new Ext.CTBPagingToolbar({ store: store, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No stocks to display", hidden : theThis.isForCreditNoteRequest }); // *************************************************************************************************** // Grid // *************************************************************************************************** var grid = new Ext.grid.EditorGridPanel({ region: 'center', margins : '10 10 0 10', store: store, frame: false, sm : sm, plugins: [new Ext.ux.grid.GridHeaderFilters()], updateTheSubtotal : function(theRecord){ updateTheSubtotal(theRecord); }, tbar : [ theThis.btn_Add = new Ext.Button({ iconCls : 'icon-add', scale : 'large', text : 'New', handler : function(){ theThis.StockBrowserDialog.Global_StockBrowser_CallbackFunction = function(selectedRecords){ theThis.addNewRecord(selectedRecords); }; if (theThis.parentWindowContainer != null) theThis.StockBrowserDialog.Global_StockBrowser_AssignedSupplierId = theThis.parentWindowContainer.cmbSupplier.getValue(); //theThis.StockBrowserDialog.items.get('tab_StockBrowser_AllTabs').setActiveTab(1); theThis.StockBrowserDialog.show(); } }), theThis.btn_Delete = new Ext.Button({ iconCls : 'icon-delete', scale : 'large', text : 'Delete', handler : function(){ var selectedItems = theThis.getGrid().getSelectionModel().getSelections(); if (selectedItems.length > 0) { Ext.Msg.show({ title:'Confirm', msg: 'Are you sure you want to delete the item(s) ?', buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.QUESTION, fn : function(btn) { if (btn == "yes") { var deletedItemIds = new Array(); // Actual deleted item var modifiedRecords = store.getModifiedRecords(); var modifiedInfo = new Array(); // Store the modifed record for recovering from deleting // This loop save the changes for (var i = 0; i < modifiedRecords.length; i++){ modifiedInfo[i] = { invoiceDetailId : modifiedRecords[i].data.invoiceDetailId, stockQty : modifiedRecords[i].data.stockQty }; } // This loop insert deleted item to the array for (var i = 0, j = 0; i < selectedItems.length; i++) { var theId = selectedItems[i].get("invoiceDetailId"); if (theId >= 0){ // Only delete existing detail deletedItemIds[j] = theId; j++; } theThis.getGrid().getStore().remove(selectedItems[i]); } store.commitChanges(); // This is the reason we use modifiedInfo, when we commit, every changes disappear // Recovering the changes // If the item not be deleted for (var i = 0; i < modifiedInfo.length; i++){ var invoiceDetailId = modifiedInfo[i].invoiceDetailId; if (store.getById(invoiceDetailId) != null){ var stockQty = modifiedInfo[i].stockQty; store.getById(invoiceDetailId).set('stockQty', 0); // Make changing mark appearing store.getById(invoiceDetailId).set('stockQty', stockQty); // Recovering the real value } } // Refresh the total if (theThis.parentWindowContainer != null && theThis.isCalculateParentField) theThis.parentWindowContainer.refreshCalculatingField(); // Calling delete if (theThis.selectedInvoiceId != -1 && deletedItemIds.length > 0){ // Only send request when the invoice exist theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Invoice/DeleteStockFromInvoice', params: { invoiceId : theThis.selectedInvoiceId, invoiceDetailIds : Ext.util.JSON.encode(deletedItemIds) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); //grid_Invoice.getStore().load(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } else if (theThis.parentWindowContainer.selectedProformaInvoiceId != -1 && deletedItemIds.length > 0) { // Delete from proforma invoice theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/ProformaInvoice/DeleteStockFromProformaInvoice', params: { proformaInvoiceId : theThis.parentWindowContainer.selectedProformaInvoiceId, proformaInvoiceDetailIds : Ext.util.JSON.encode(deletedItemIds) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); //grid_Invoice.getStore().load(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } // End if } } }); } else { Ext.Msg.show({ title:'Notice', msg: 'Please select item(s) to delete!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); }// End if }// End Handler }), // End delete button theThis.btn_QuickKey = new Ext.Button({ iconCls : 'icon-activate', scale : 'large', text : 'Quick key', handler : function(){ if (theThis.dlg_QuickKey == null) { theThis.dlg_QuickKey = new Ext.CTBStockQuickKey({ callback_QuickAdd : function(stockCode, quantity){ theThis.insertStockSupplierRecordBySupplierStockCode(stockCode, quantity); } }); } // End if theThis.dlg_QuickKey.show(); } // End handler }) ], listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); if (theThis.parentWindowContainer != null && theThis.isCalculateParentField) { theThis.parentWindowContainer.pnl_InvoiceDetail_NumberPad.callback_Assign = function(value){ theThis.getGrid().stopEditing(); var selectedRecords = theThis.getGrid().getSelectionModel().getSelections(); if (selectedRecords.length > 0){ for (var i = 0; i < selectedRecords.length; i++){ selectedRecords[i].set('stockQty', value); updateTheSubtotal(selectedRecords[i]); } } }; } //theThis.getGrid().startEditing(p_rowIndex, 7); // Only stop editing if user's using iPad // We don't want them to see the default keyboard in iPad if (Global_IsiPad) theThis.getGrid().stopEditing(); }, // p_EditedObject INCLUDES : // grid - This grid // record - The record being edited // field - The field name being edited // value - The value being set // originalValue - The original value for the field, before the edit. // row - The grid row index // column - The grid column index afteredit : function( p_EditedObject ) { updateTheSubtotal(p_EditedObject.record); setUpWarningWhenClosePage(); }, beforeedit : function (p_Event) { if (theThis.parentWindowContainer != null && theThis.isCalculateParentField) { theThis.parentWindowContainer.pnl_InvoiceDetail_NumberPad.callback_Next = function(theNumberPad){ try{ if (theNumberPad.isHavingChanges == true){ theNumberPad.operatorClick('='); } theThis.getGrid().getSelectionModel().selectRow(p_Event.row + 1); theThis.getGrid().startEditing(p_Event.row + 1, 7); theThis.getGrid().stopEditing(); }catch(e){ var activePage = 1; var totalCount = theThis.getGrid().getStore().getTotalCount(); if ((activePage+1) <= Math.ceil(totalCount / theThis.pt_InvoiceDetail.pageSize)) { theThis.pt_InvoiceDetail.moveNext(); } else { showErrorNotification('Notice', 'End of invoice details.'); } } }; } } }, cm: cm, width: 780, height: 400, autoHeight: false, clicksToEdit: 1, loadMask: true, bbar : theThis.pt_InvoiceDetail, viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return grid; }, insertStockSupplierRecordBySupplierStockCode : function(supplierStockCode, quantity){ var theThis = this; theThis.promptedStockQuantity = quantity; if (theThis.storeTemporaryStockSupplier == null){ theThis.recordTypeTemporaryStockSupplier = Ext.data.Record.create([ { name: 'stockSupplierId', type: 'number' }, { name: 'supplierStockCode', type: 'string' }, { name: 'supplierCost', type: 'number' }, { name: 'supplierId', type: 'number' }, { name: 'supplierName', type: 'string' }, { name: 'stockId', type: 'number' }, { name: 'stockCode', type: 'string' }, { name: 'stockDesc', type: 'string' }, { name: 'stockUnit', type: 'number' }, { name: 'unitOfMeasurementId', type: 'number' }, { name: 'isGstApplied', type: 'boolean' } ]); theThis.storeTemporaryStockSupplier = new Ext.data.JsonStore({ baseParams : {keyword : supplierStockCode, searchType : 7, supplierId : -1}, // Search type = 1 is for supplier stock code autoLoad : false, proxy: new Ext.data.HttpProxy({ url: '/Stock/GetStockBySupplier', dataType: 'json', method: 'POST' }), fields: theThis.recordTypeTemporaryStockSupplier, root: 'data', idProperty: 'stockSupplierId', listeners : { beforeload : function(){ theThis.loadMask.show(); }, load : function(){ // theThis.storeTemporaryStockSupplier.getRange(0, theThis.storeTemporaryStockSupplier.getCount()); if (theThis.storeTemporaryStockSupplier.getCount() > 0) theThis.addNewRecord(theThis.storeTemporaryStockSupplier.getRange(0, theThis.storeTemporaryStockSupplier.getCount() - 1), theThis.promptedStockQuantity); theThis.loadMask.hide(); }, loadexception : function(){ showStoreLoadingErrorMessage(store); theThis.loadMask.hide(); } } }); } theThis.storeTemporaryStockSupplier.baseParams.keyword = supplierStockCode; theThis.storeTemporaryStockSupplier.baseParams.supplierId = theThis.parentWindowContainer.cmbSupplier.getValue(); theThis.storeTemporaryStockSupplier.reload(); }, addNewRecord : function(selectedRecords, quantity){ var theThis = this; var insertedDetail = new Array(); if (quantity == null) quantity = 0; for(var i = 0; i 0) { Ext.Msg.show({ title:'Save?', msg: "You have made some changes. Do you want to save ?", buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.QUESTION, fn : function(btn){ if (btn == "yes"){ theThis.btn_InvoiceDetail_Save.handler.call(theThis.btn_InvoiceDetail_Save.scope); } else { // Disable the warning when close the page disableWarningWhenClosePage(); store.commitChanges(); theThis.hide(); } } }); return false; } }, hide : function(theThis){ theThis.selectedExistingStockId = -1; theThis.assignedSupplierId = -1; //theThis.selectedProformaInvoiceId = -1; //theThis.creditNoteProformaInvoiceId = -1; }, beforeshow : function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); if (theThis.selectedInvoiceId != -1){ // Fill the detail // Get the selected invoice record var selectedInvoiceRecord = theThis.selectedInvoiceRecord; var invoiceId = selectedInvoiceRecord.data.invoiceId; var invoiceDate = selectedInvoiceRecord.data.invoiceDate; var invoiceNo = selectedInvoiceRecord.data.invoiceNo; theThis.lastInvoiceNo = invoiceNo; // Save the last invoice number to the dialog var supplierList = selectedInvoiceRecord.data.supplierList; var totalTax = selectedInvoiceRecord.data.totalTax; var discount = selectedInvoiceRecord.data.discount; var freightIncludeGST = selectedInvoiceRecord.data.freightIncludeGST; var isReturned = selectedInvoiceRecord.data.isReturned; var supplierId = selectedInvoiceRecord.data.supplierId; var totalAmount = isReturned? -selectedInvoiceRecord.data.totalAmount : selectedInvoiceRecord.data.totalAmount; totalAmount = roundNumber(totalAmount, 2); // Fill the detail theThis.cmbSupplier.doQuery("", true); /*if (supplierId != -1) { cmbSupplier.setValue(supplierId); } else cmbSupplier.setValue(cmbSupplier.getStore().getAt(0).get('supId'));*/ theThis.txt_TopDetail_Date.setValue(invoiceDate); theThis.txt_TopDetail_InvoiceNo.setValue(invoiceNo); theThis.cmb_TopDetail_InvoiceType.setValue(isReturned); theThis.txt_BottomDetail_TotalTax.setValue(totalTax); theThis.txt_BottomDetail_Discount.setValue(discount); theThis.txt_BottomDetail_FreightIncludeGST.setValue(freightIncludeGST); theThis.txt_TopDetail_Total.setValue(totalAmount); theThis.txt_BottomDetail_Total.setValue(totalAmount); if (isReturned) { theThis.txt_TopDetail_Total.setPrefixSign('-'); theThis.txt_BottomDetail_Total.setPrefixSign('-'); } else { theThis.txt_TopDetail_Total.setPrefixSign(''); theThis.txt_BottomDetail_Total.setPrefixSign(''); } // Enable or Disable the Add Payment Button if (selectedInvoiceRecord.data.status == "UNPAID" || selectedInvoiceRecord.data.status == "PAID"){ theThis.btn_Invoice_AddPaymentConfirmation.setVisible(true); } else { theThis.btn_Invoice_AddPaymentConfirmation.setVisible(false); } } // Clear everything else { // Only reset the combobox if user didn't select any supplier before theThis.cmbSupplier.doQuery("", true); theThis.txt_TopDetail_InvoiceNo.setValue(''); theThis.lastInvoiceNo = null; theThis.cmb_TopDetail_InvoiceType.setValue(0); theThis.txt_BottomDetail_TotalTax.setValue(0); theThis.txt_BottomDetail_Discount.setValue(0); theThis.txt_BottomDetail_FreightIncludeGST.setValue(0); theThis.txt_TopDetail_Total.setValue(0); theThis.txt_BottomDetail_Total.setValue(0); theThis.txt_TopDetail_Total.setPrefixSign(''); theThis.txt_BottomDetail_Total.setPrefixSign(''); theThis.cmb_TopDetail_InvoiceType.setValue(false); } }, show : function(theThis){ var store = theThis.grid_InvoiceDetail.getGrid().getStore(); if (theThis.selectedInvoiceId != -1){ // Load the data store.commitChanges(); store.baseParams = {invoiceId : theThis.selectedInvoiceId}; store.load(); theThis.btn_RequestCreditNote.setVisible(true); } else { store.baseParams = {invoiceId : -1}; store.removeAll(); store.commitChanges(); if (theThis.callback_AfterShow != null){ theThis.callback_AfterShow(); } theThis.btn_RequestCreditNote.setVisible(false); } if (theThis.instructionText != null) theThis.grid_InvoiceDetail.redrawInstruction(); // Credit note if (theThis.grid_CreditNoteDetail != null) { var creditNoteStore = theThis.grid_CreditNoteDetail.getGrid().getStore(); if (theThis.selectedInvoiceId != -1){ if (theThis.creditNoteProformaInvoiceId == -1) { // Load the data creditNoteStore.commitChanges(); creditNoteStore.baseParams = {invoiceId : theThis.selectedInvoiceId}; creditNoteStore.load(); theThis.btn_InvoiceDetail_CreditNoteRequest.setVisible(true); theThis.btn_TurnCreditNoteIntoReturnInvoice.setVisible(false); } else { creditNoteStore.commitChanges(); creditNoteStore.removeAll(); theThis.getCreditNoteDetailFromProformaInvoice(theThis.creditNoteProformaInvoiceId); theThis.btn_InvoiceDetail_CreditNoteRequest.setVisible(true); theThis.btn_TurnCreditNoteIntoReturnInvoice.setVisible(true); } } else { creditNoteStore.baseParams = { invoiceId : -1 }; creditNoteStore.removeAll(); creditNoteStore.commitChanges(); } theThis.btn_RequestCreditNote.setVisible(false); } } }, initComponent : function(){ var theThis = this; if (document.URL.indexOf('web.cookingthebooks.com.au') != -1) { theThis.isHideDevelopmentButtons = true; } else theThis.isHideDevelopmentButtons = false; // MAIN GRID theThis.dlg_AddPaymentDetail = theThis.getDialog_AddPaymentDetail(); theThis.dlg_StockExistingOrder = theThis.getStockExistingOrderDialog(); theThis.grid_InvoiceDetail = new Ext.CTBInvoiceDetailGrid({ region : 'center', parentWindowContainer : theThis, hideInstruction : theThis.instructionText == null ? !theThis.isForCreditNoteRequest : false, // If the whole window for credit note request, don't hide instruction instructionText : theThis.instructionText }); theThis.pnl_TopDetail = theThis.getPanel_TopDetail(); theThis.pnl_BottomDetail = theThis.getPanel_BottomDetail(); theThis.pnl_InvoiceDetailCenterWrapper = new Ext.Panel({ layout : 'border', region : 'center', items : [ theThis.grid_InvoiceDetail, theThis.pnl_BottomDetail ] }); theThis.pnl_InvoiceDetail_NumberPad = new Ext.CTBNumberPad({ region : 'east', collapsible : true, collapsed : false, isShowWarningSelectRow : false, width : 477, hidden : theThis.isForCreditNoteRequest }); // Credit note layout if (theThis.isForCreditNoteRequest) { theThis.grid_CreditNoteDetail = new Ext.CTBInvoiceDetailGrid({ region : 'east', width : 400, parentWindowContainer : theThis, isForCreditNoteRequest : theThis.isForCreditNoteRequest, isCalculateParentField : false, instructionText : 'Enter what you actually receive', instructionBackgroundColor : '#00bce2', hideInstruction : false }); theThis.items = [ theThis.grid_InvoiceDetail, theThis.pnl_TopDetail, //theThis.pnl_BottomDetail, theThis.grid_CreditNoteDetail ]; } // Normal invoice input layout else { theThis.items = [ theThis.pnl_InvoiceDetailCenterWrapper, //theThis.grid_InvoiceDetail, theThis.pnl_TopDetail, //theThis.pnl_BottomDetail, theThis.pnl_InvoiceDetail_NumberPad ]; } // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBInvoiceDetailWindow.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; if (theThis.grid_InvoiceDetail.rendered) theThis.grid_InvoiceDetail.clearSelections(); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_InvoiceDetail_CreditNoteRequest = new Ext.Button({ text : 'Send request', hidden : !theThis.isForCreditNoteRequest, tooltip : 'Send the credit note request to supplier', iconCls : 'icon-send-large', scale : 'large', handler : function(){ theThis.saveCreditNoteRequest(function(){ theThis.sendCreditNoteRequest(); }); } // End send request handler button }), theThis.btn_TurnCreditNoteIntoReturnInvoice = new Ext.Button({ text : 'Turn credit note to return invoice', hidden : !theThis.isForCreditNoteRequest, tooltip : 'Turn the credit note to return invoice', iconCls : 'icon-send-large', scale : 'large', handler : function(){ if (theThis.dlg_InvoiceDetail == null) { theThis.dlg_InvoiceDetail = new Ext.CTBInvoiceDetailWindow({ isIgnoreWarningMarkingStockOrderAsInvoice : true, HideShowExistingStockOrdersButton : true, instructionText : 'Please make the change to make it match with the paper credit note.', //saveInvoiceURL : '/ProformaInvoice/SaveProformaInvoiceFromRealInvoiceData', isUsingProformaInvoiceId : false }); } theThis.dlg_InvoiceDetail.setSelectedInvoiceRecord(null); theThis.dlg_InvoiceDetail.assignedSupplierId = theThis.selectedInvoiceRecord.data.supplierId; theThis.dlg_InvoiceDetail.callback_AfterCancel = function(){ /*if (!theThis.selectedProformaInvoiceRecord.data.isFromNormalOrder) theThis.pnl_Container.goToStep(1); else { theThis.pnl_Container.finishAndExit(); }*/ } theThis.dlg_InvoiceDetail.callback_AfterShow = function(){ if (theThis.creditNoteProformaInvoiceId != -1) { // Check if this is used to turn proforma invoice to stored invoice or not theThis.dlg_InvoiceDetail.selectedProformaInvoiceId = theThis.creditNoteProformaInvoiceId; theThis.dlg_InvoiceDetail.getInvoiceDetailFromProformaInvoice(null, true); // No call back function } } theThis.dlg_InvoiceDetail.callback_AfterSave = function(returnNewProformInvoice){ theThis.markCreditNoteAsProcessed(theThis.creditNoteProformaInvoiceId); theThis.dlg_InvoiceDetail.hide(); } theThis.dlg_InvoiceDetail.show(); } // End send request handler button }), theThis.btn_InvoiceDetail_Save = new Ext.Button({ cls : 'ctb-btn-red', text : 'Save', hidden : theThis.isForCreditNoteRequest, iconCls : 'icon-save-large', scale : 'large', handler : function(){ // Wrap data and send saving request theThis.grid_InvoiceDetail.getGrid().stopEditing(); if (!theThis.validateBeforeSave()) { return; } // First checking existence of the invoice number // Only check invoice number if it's in adding mode var invoiceNo = theThis.txt_TopDetail_InvoiceNo.getValue(); if (theThis.lastInvoiceNo == null || theThis.lastInvoiceNo != invoiceNo) // Adding mode or Changeing invoice number in editing moed { Ext.Ajax.request({ method: "POST", url: '/Invoice/SearchInvoicesByInvoiceNumberAndSupplier', params: { invoiceNumber : invoiceNo, supplierId : theThis.cmbSupplier.getValue() }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { if (jsonData.totalCount > 0){ showToolTip(theThis.txt_TopDetail_InvoiceNo.getId(), 'This invoice number has been used before. Please make sure you are not doubling up invoice data.', false, null, null); } else { theThis.saveData(); } } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { //loadMask.hide(); } }); // End ajax } else { theThis.saveData(); } } // End save handler button }), /*theThis.btn_ShowExistingStockOrders = new Ext.Button({ text : 'Show electronic orders', tooltip : 'Show electronic orders from the selected Supplier. You can choose from the list to populate the invoice automatically.', iconCls: 'icon-daily-order', scale: 'large', hidden : theThis.HideShowExistingStockOrdersButton, handler : function(){ theThis.grid_StockExistingOrder.getStore().baseParams = {keyword : theThis.cmbSupplier.getValue(), searchType : 2, start : 0, limit : theThis.pageSize, isRequestFromExistingOrder : true}; theThis.grid_StockExistingOrder.getStore().load(); } }),*/ theThis.btn_RequestCreditNote = new Ext.Button({ text : 'Request credit note', tooltip : 'Request credit note', iconCls: 'icon-daily-order', scale: 'large', hidden : true, handler : function(){ if (theThis.selectedInvoiceRecord != null && theThis.selectedInvoiceRecord.data.creditNoteProformaInvoiceId != null) { if (theThis.dlg_CreditNoteDetail == null) { theThis.dlg_CreditNoteDetail = new Ext.CTBInvoiceDetailWindow({ title : 'Credit note', isIgnoreWarningMarkingStockOrderAsInvoice : true, instructionText : 'This is the invoice', isForCreditNoteRequest : true, isUsingProformaInvoiceId : false }); } theThis.dlg_CreditNoteDetail.setSelectedInvoiceRecord(theThis.selectedInvoiceRecord); theThis.dlg_CreditNoteDetail.assignedSupplierId = theThis.selectedInvoiceRecord.data.supplierId; // Assign the credit note theThis.dlg_CreditNoteDetail.creditNoteProformaInvoiceId = theThis.selectedInvoiceRecord.data.creditNoteProformaInvoiceId; theThis.dlg_CreditNoteDetail.callback_AfterShow = function(){ } theThis.dlg_CreditNoteDetail.show(); } } }), theThis.btn_Invoice_AddPaymentConfirmation = new Ext.Button({ text : 'Add Payment', hidden : true, tooltip : 'Add Payment Detail for this invoice', iconCls: 'icon-money', scale: 'large', handler : function(){ var selectedInvoiceRecord = theThis.selectedInvoiceRecord; //grid_Invoice.getStore().getById(theThis.selectedInvoiceId); theThis.dlg_AddPaymentDetail.setSelectedInvoiceRecord(selectedInvoiceRecord); theThis.dlg_AddPaymentDetail.show(); } }), theThis.btn_More = new Ext.Button({ iconCls : 'icon-v3-dropdown-more', text : 'More', iconAlign : 'right', handler: function (button, e) { if (theThis.menu_MoreOptions == null) { theThis.menu_MoreOptions = new Ext.menu.Menu({ items: [ theThis.btn_ShowExistingStockOrders = new Ext.menu.Item({ text : 'Show electronic orders', tooltip : 'Show electronic orders from the selected Supplier. You can choose from the list to populate the invoice automatically.', iconCls: 'icon-daily-order', scale: 'large', hidden : theThis.HideShowExistingStockOrdersButton, handler : function(){ theThis.grid_StockExistingOrder.getStore().baseParams = {keyword : theThis.cmbSupplier.getValue(), searchType : 2, start : 0, limit : theThis.pageSize, isRequestFromExistingOrder : true}; theThis.grid_StockExistingOrder.getStore().load(); } }), theThis.btn_DownloadInvoiceXML = new Ext.menu.Item({ text : 'Download XML', //hidden : false, hidden : theThis.isHideDevelopmentButtons, tooltip : 'Download the invoice in XML format.', scale : 'large', iconCls : 'icon-xml-document', handler : function(){ var selectedInvoiceRecord = theThis.selectedInvoiceRecord; //grid_Invoice.getStore().getById(theThis.selectedInvoiceId); if (selectedInvoiceRecord.data.invoiceId > 0) { window.location = String.format('/Invoice/DownloadPROACTISInvoiceXML?invoiceId={0}', selectedInvoiceRecord.data.invoiceId); } } }), theThis.btn_SendInvoiceXMLToFTPServer = new Ext.menu.Item({ text : 'Send XML to FTP', hidden : theThis.isHideDevelopmentButtons, tooltip : 'Send Invoice XML to FTP Server.', scale : 'large', iconCls : 'icon-xml-document', handler : function(){ var selectedInvoiceRecord = theThis.selectedInvoiceRecord; //grid_Invoice.getStore().getById(theThis.selectedInvoiceId); if (selectedInvoiceRecord.data.invoiceId > 0) { theThis.loadMask.show(); // Calling delete Ext.Ajax.request({ method: 'POST', url: '/Invoice/SendPROACTISInvoiceXMLToFTP', timeout : 1800000, params: { invoiceId : selectedInvoiceRecord.data.invoiceId }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } } }), theThis.btn_SendOrderXMLToFTPServer = new Ext.menu.Item({ text : 'Send order XML to FTP', hidden : theThis.isHideDevelopmentButtons, tooltip : 'Send related order XML to FTP Server.', scale : 'large', iconCls : 'icon-xml-document', handler : function(){ var selectedInvoiceRecord = theThis.selectedInvoiceRecord; //grid_Invoice.getStore().getById(theThis.selectedInvoiceId); if (selectedInvoiceRecord.data.invoiceId > 0) { theThis.loadMask.show(); // Calling delete Ext.Ajax.request({ method: 'POST', url: '/Invoice/SendPROACTISRelatedOrderXMLToFTP', timeout : 1800000, params: { invoiceId : selectedInvoiceRecord.data.invoiceId }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } } }) ] // menu items }); // End menu declaration } // End "if" checking menu existence // Show the menu theThis.menu_MoreOptions.show(e.getTarget()); } // End "More" button handler }), theThis.btn_Cancel = new Ext.Button({ text : 'Cancel', iconCls: 'icon-cancel-large', scale: 'large', handler : function(){ theThis.hide(); if (theThis.callback_AfterCancel != null) { theThis.callback_AfterCancel(); } } }) ]; return buttons; }, saveData : function(){ var theThis = this; var invoiceDate = theThis.txt_TopDetail_Date.getValue(); var invoiceNo = theThis.txt_TopDetail_InvoiceNo.getValue(); var invoiceType = theThis.cmb_TopDetail_InvoiceType.getValue(); var discount = theThis.txt_BottomDetail_Discount.getValue(); var freightIncludeGST = theThis.txt_BottomDetail_FreightIncludeGST.getValue(); var invoiceDetail = new Array(); var modifiedRecords = theThis.grid_InvoiceDetail.getGrid().getStore().getModifiedRecords(); for (var i = 0;i < modifiedRecords.length; i++) { var theRecord = modifiedRecords[i]; var modifiedDetail = { invoiceDetailId : theRecord.get('invoiceDetailId'), stockQty : theRecord.get('stockQty'), invoiceDetailCost : theRecord.get('invoiceDetailCost'), invoiceDetailTax : theRecord.get('invoiceDetailTax'), stockSupplierId : theRecord.get('stockSupplierId'), stockId : theRecord.get('stockId'), discountPercentage : theRecord.get('discountPercentage') } invoiceDetail[i] = modifiedDetail; } var invoiceObject = { invoiceId : theThis.isUsingProformaInvoiceId == true ? theThis.selectedProformaInvoiceId : theThis.selectedInvoiceId, invoiceDate : invoiceDate, invoiceNo : invoiceNo, isReturned : invoiceType, discount : isNaN(discount) ? 0 : discount, freightIncludeGST : isNaN(freightIncludeGST) ? 0 : freightIncludeGST, invoiceDetail : invoiceDetail, supplierId : theThis.cmbSupplier.getValue(), businessDepartmentId : theThis.cmbBusinessDepartment.getValue() } var invoiceJsonData = Ext.util.JSON.encode(invoiceObject); theThis.loadMask.show(); // Sending ajax request Ext.Ajax.request({ method: "POST", url: theThis.saveInvoiceURL, params: { invoiceData : invoiceJsonData }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); /* Reload Invoice Detail */ theThis.grid_InvoiceDetail.getGrid().getStore().commitChanges(); theThis.hide(); theThis.selectedInvoiceId = jsonData.data.newId; if (theThis.selectedExistingStockOrderId != -1 && theThis.selectedProformaInvoiceId == -1){ // Not going to do this if the proforma invoice has been set for this dialog //if (!theThis.isIgnoreWarningMarkingStockOrderAsInvoice) { //showConfirmMessage('Do you want to hide the existing order ?', function(){ theThis.markStockOrderAsInvoice(theThis.selectedExistingStockOrderId, theThis.selectedInvoiceId, theThis.callback_AfterSave); theThis.selectedExistingStockOrderId = -1; //}); //} //else { //theThis.markStockOrderAsInvoice(theThis.selectedExistingStockOrderId, theThis.selectedInvoiceId, theThis.callback_AfterSave); //theThis.selectedExistingStockOrderId = -1; //} } else { //if (theThis.selectedProformaInvoiceId != -1){ //theThis.markProformaInvoiceAsTransfered(theThis.callback_AfterSave); //} //else { /* Reload Invoice */ if (theThis.callback_AfterSave != null){ theThis.callback_AfterSave(jsonData.data); //grid_Invoice.getStore().reload(); ********** //theThis.callback_AfterSave = null; } //} } if (jsonData.data != null && jsonData.data.newId != null) { // Silently calling for checking over limit when changing stock price // This function is in global.js checkingOverLimitWhenChangingStockPrice(theThis.selectedInvoiceId); } // Disable the warning when close the page disableWarningWhenClosePage(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { showErrorMessage("Server is unavailable. Please try again in a few seconds."); theThis.loadMask.hide(); } }); // End ajax }, saveCreditNoteRequest : function(callback_Function){ var theThis = this; theThis.grid_CreditNoteDetail.getGrid().stopEditing(); var creditNoteProformaInvoiceId = theThis.creditNoteProformaInvoiceId; var invoiceDate = theThis.txt_TopDetail_Date.getValue(); var invoiceNo = theThis.txt_TopDetail_InvoiceNo.getValue(); var invoiceId = theThis.selectedInvoiceRecord.data.invoiceId; var supplierId = theThis.selectedInvoiceRecord.data.supplierId; var creditNoteDetails = new Array(); for (var i = 0; i < theThis.grid_CreditNoteDetail.getGrid().getStore().getCount(); i++) { var theRecord = theThis.grid_CreditNoteDetail.getGrid().getStore().getAt(i); creditNoteDetails[i] = { stockId : theRecord.data.stockId, receivedQty : theRecord.data.stockQty } } var creditNoteWrapper = { creditNoteProformaInvoiceId : creditNoteProformaInvoiceId, invoiceId : invoiceId, invoiceNo : invoiceNo, invoiceDate : invoiceDate, supplierId : supplierId, creditNoteDetails : creditNoteDetails } theThis.grid_CreditNoteDetail.loadMask.show(); // Calling delete Ext.Ajax.request({ method: 'POST', url: '/ProformaInvoice/SaveCreditNoteRequest', params: { creditNoteData : Ext.util.JSON.encode(creditNoteWrapper) }, success : function(result, request) { theThis.grid_CreditNoteDetail.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.creditNoteProformaInvoiceId = jsonData.data.creditNoteProformaInvoiceId; theThis.selectedInvoiceRecord.data.creditNoteProformaInvoiceId = theThis.creditNoteProformaInvoiceId; theThis.grid_CreditNoteDetail.getGrid().getStore().commitChanges(); if (callback_Function != null) callback_Function(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.grid_CreditNoteDetail.loadMask.hide(); } }); // End ajax }, markCreditNoteAsProcessed : function(creditNoteProformaInvoiceId){ var theThis = this; theThis.loadMask.show(); // Calling delete Ext.Ajax.request({ method: 'POST', url: '/ProformaInvoice/UpdateProformaInvoiceStatus', params: { proformaInvoiceId : creditNoteProformaInvoiceId, status : PROFORMA_INVOICE_STATUS.CREDIT_NOTE_TURNED_TO_RETURN_INVOICE }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { //showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax }, sendCreditNoteRequest : function(callback_Function){ var theThis = this; if (theThis.creditNoteProformaInvoiceId == -1){ showErrorNotification('Notice', 'Please save the credit note first'); } else { Global_ContactBrowser_CallbackFunction = function(selectedRecords) { var recipients = ""; for(var i = 0;iDiscount / Adjustment', xtype : 'moneyfield', listeners : { 'spin' : function(p_field, p_down, p_alternative){ var totalValue = roundNumber(theThis.grid_InvoiceDetail.getGrid().getStore().sum('invoiceDetailSubtotal'), 2); theThis.txt_BottomDetail_Total.setValue(totalValue - this.getValue()); } }, onBlur : function(p_field){ if (isNaN(this.getValue())) { this.setValue(0); } var totalValue = roundNumber(theThis.grid_InvoiceDetail.getGrid().getStore().sum('invoiceDetailSubtotal'), 2); theThis.txt_BottomDetail_Total.setValue(totalValue - this.getValue()); }, precision: true, decimalPrecision: 2, width : 200 }), theThis.txt_BottomDetail_FreightIncludeGST = new Ext.form.MoneyField({ fieldLabel: 'Freight (Include GST)', xtype : 'moneyfield', minValue : 0, listeners : { 'spin' : function(p_field, p_down, p_alternative){ theThis.refreshCalculatingField(); } }, onBlur : function(p_field){ if (isNaN(this.getValue())) { this.setValue(0); } theThis.refreshCalculatingField(); }, precision: true, decimalPrecision: 2, width : 200 }), theThis.txt_BottomDetail_Total = new Ext.form.MoneyField({ fieldLabel: 'Total [Actual]', xtype : 'moneyfield', disabledSpinner : true, readOnly : true, precision: true, decimalPrecision: 2, width : 200 })] }); var pnl_BottomDetail = new Ext.Panel({ region : 'south', layout : 'border', height : 120, items : [{xtype : 'panel', region : 'center'},frm_RightForm], frame: true, loadMask: true, viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return pnl_BottomDetail; }, getCombobox_Supplier : function(){ var theThis = this; var store = new Ext.data.JsonStore({ baseParams : {isFromImportDatabase : false}, proxy: new Ext.data.HttpProxy({ url: '/Supplier/GetAllSuppliers', dataType: 'json', method: 'POST' }), fields: [ { name: 'supId' , type: 'number' }, { name: 'supName' , type: 'string' }, { name: 'supFolderId' , type: 'number' }, { name: 'abnNo' , type: 'string' }, { name: 'accNo' , type: 'string' }, { name: 'paymentTerm' , type: 'string' }, { name: 'website' , type: 'string' }, { name: 'defaultStockCategoryId', type: 'number' } ], autoLoad : false, root: 'data', idProperty : 'supId', listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(store); }, load : function(){ if ((theThis.cmbSupplier.lastQuery == null || theThis.cmbSupplier.lastQuery == "")){ if (theThis.selectedInvoiceId != -1){ var selectedInvoiceRecord = theThis.selectedInvoiceRecord; var supplierId = selectedInvoiceRecord.data.supplierId; if (supplierId != -1){ theThis.cmbSupplier.setValue(supplierId); } else theThis.cmbSupplier.setValue(store.getAt(0).get('supId')); } else if (theThis.assignedSupplierId != -1 && store.getCount() > 0){ theThis.cmbSupplier.setValue(theThis.assignedSupplierId); } else if (theThis.selectedInvoiceId == -1 && store.getCount() > 0){ theThis.cmbSupplier.setValue(store.getAt(0).get('supId')); } } theThis.cmbBusinessDepartment.getStore().load(); } } }); var cmbSupplier = new Ext.form.ComboBox({ store: store, displayField: 'supName', valueField: 'supId', typeAhead: true, triggerAction: 'all', minChars: 1, lazyRender: true, editable: true, forceSelection: true, emptyText: 'Select a Supplier...', //valueNotFoundText: 'Select a Supplier...', fieldLabel : 'Supplier', width: 200, //style: { fontSize: '11px' }, mode : 'remote', listeners : { beforequery: function(qe){ delete qe.combo.lastQuery; // Reload every click }, beforeselect : function( p_combo, p_record, p_index ){ var oldValue = theThis.cmbSupplier.getValue(); if (theThis.grid_InvoiceDetail.getGrid().getStore().getCount() > 0){ Ext.Msg.show({ title:'Confirm', msg: 'Are you sure you want to change supplier ?
All detail will be cleared !', buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.QUESTION, fn : function(btn) { if (btn == "yes") { // Only run ajax request if the invoice exist if (theThis.selectedInvoiceId != -1){ theThis.loadMask.show(); // Calling delete Ext.Ajax.request({ method: 'POST', url: '/Invoice/DeleteAllInvoiceDetailByInvoiceId', params: { invoiceId : theThis.selectedInvoiceId }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); //grid_Invoice.getStore().load(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } // End if else { theThis.grid_InvoiceDetail.getGrid().getStore().removeAll(); } } // End if else { theThis.cmbSupplier.doQuery("", true); return false; } // End else } }); // End show message } // End if } } }); return cmbSupplier; }, getCombobox_BusinessDepartment : function(){ var theThis = this; var store = new Ext.data.JsonStore({ baseParams : {supplierId : -1}, proxy: new Ext.data.HttpProxy({ url: '/BusinessDepartment/GetBusinessDepartmentsBySupplierId', dataType: 'json', method: 'POST' }), fields: [ { name: 'businessDepartmentId' , type: 'number' }, { name: 'businessDepartmentName' , type: 'string' } ], autoLoad : false, root: 'data', idProperty : 'businessDepartmentId', listeners : { 'loadexception' : function(){ showStoreLoadingErrorMessage(store); }, beforeload : function(){ theThis.cmbBusinessDepartment.getStore().baseParams = {supplierId : theThis.cmbSupplier.getValue()}; //theThis.cmbBusinessDepartment.getStore().load(); }, load : function(){ if ((theThis.cmbBusinessDepartment.lastQuery == null || theThis.cmbBusinessDepartment.lastQuery == "")){ if (theThis.selectedInvoiceId != -1){ var selectedInvoiceRecord = theThis.selectedInvoiceRecord; var businessDepartmentId = selectedInvoiceRecord.data.businessDepartmentId; if (businessDepartmentId != -1){ theThis.cmbBusinessDepartment.setValue(businessDepartmentId); } else theThis.cmbBusinessDepartment.setValue(store.getAt(0).get('businessDepartmentId')); } /*else if (theThis.assignedSupplierId != -1 && store.getCount() > 0){ theThis.cmbBusinessDepartment.setValue(theThis.assignedSupplierId); }*/ else if (theThis.selectedInvoiceId == -1 && store.getCount() > 0){ theThis.cmbBusinessDepartment.setValue(store.getAt(0).get('businessDepartmentId')); } } } } }); var cmbBusinessDepartment = new Ext.form.ComboBox({ store: store, displayField: 'businessDepartmentName', valueField: 'businessDepartmentId', typeAhead: true, triggerAction: 'all', minChars: 1, lazyRender: true, editable: true, forceSelection: true, emptyText: 'Select a business department...', fieldLabel : 'Business department', width: 200, //style: { fontSize: '11px' }, mode : 'remote', listeners : { beforequery: function(qe){ delete qe.combo.lastQuery; // Reload every click }, beforeselect : function( p_combo, p_record, p_index ){ } } }); return cmbBusinessDepartment; }, // This function validate all the field in the invoice detail before it's being saved validateBeforeSave : function() { var theThis = this; var validateFields = new Array(); validateFields[0] = { ID : theThis.txt_TopDetail_InvoiceNo.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.EMPTY }; validateFields[1] = { ID : theThis.txt_TopDetail_Date.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.DATE }; validateFields[2] = { ID : theThis.txt_TopDetail_Total.id, CUSTOM_FUNCTION : function(){ var userTotal = theThis.txt_TopDetail_Total.getValue(); var actualTotal = theThis.txt_BottomDetail_Total.getValue(); if (userTotal != actualTotal){ return false; } return true; }, CUSTOM_MESSAGE : 'The total from invoice doesn\'t match with the actual total
Please check the detail to make sure your input is right!', VALIDATION_TYPE : VALIDATION_CONSTANTS.CUSTOM }; validateFields[3] = { ID : theThis.txt_BottomDetail_Discount.id, CUSTOM_FUNCTION : function(){ var discountValue = theThis.txt_BottomDetail_Discount.getValue(); if (discountValue < 0) { return true; } return true; }, CUSTOM_MESSAGE : 'Discount is negative by default. You don\'t need to specify negative sign for the discount value!', VALIDATION_TYPE : VALIDATION_CONSTANTS.CUSTOM }; validateFields[4] = { ID : theThis.cmbSupplier.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.EMPTY }; // Call global validate field group return validateFieldGroup(validateFields); }, markStockOrderAsInvoice : function(stockOrderId, invoiceId, callback_Function){ var theThis = this; theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/StockOrder/MarkStockOrderAsInvoice', params: { stockOrderId : stockOrderId, invoiceId : invoiceId }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); if (callback_Function != null) callback_Function(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } theThis.loadMask.hide(); }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax }, getDialog_AddPaymentDetail : function(){ var theThis = this; var frm_Input = new Ext.form.FormPanel({ url: '', frame : true, region : 'center', labelWidth : 150, defaults: { width: 225, msgTarget: 'side' }, listeners : { afterrender : function(p_this){ }, beforeaction : function(p_This, p_Action){ }, actioncomplete : function(p_This, p_Action){ }, actionfailed : function(p_This, p_Action){ } }, items : [ theThis.txt_Invoice_Payment_PaymentDate = new Ext.form.DateField({ xtype : 'datefield', format : "j/n/Y", altFormats : 'j/n/y', name : 'paymentDate', value : new Date(), fieldLabel : 'Payment date', allowBlank : false }), theThis.txt_Invoice_Payment_BankReferenceID = new Ext.form.TextField({ xtype : 'textfield', name : 'paidAmount', value : '', allowBlank: false, fieldLabel : 'Bank Reference Number', onFocus: function (txt, e) { this.getEl().dom.select(); } }), theThis.txt_Invoice_Payment_PaidAmount = new Ext.form.NumberField({ xtype : 'numberfield', name : 'paidAmount', value : 0, allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 2, fieldLabel : 'Paid Amount($)', onFocus: function (txt, e) { this.getEl().dom.select(); } }), theThis.txt_Invoice_Payment_SurchargeAmount = new Ext.form.NumberField({ xtype : 'numberfield', name : 'surchargeAmount', value : 0, allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 2, fieldLabel : 'Surcharge Amount($)', onFocus: function (txt, e) { this.getEl().dom.select(); } }) ] }); var dlg_AddPaymentDetail = new Ext.Window({ closeAction : 'hide', width : 425, height : 200, frame : true, modal : true, title : 'Add Payment Detail', layout : 'border', selectedInvoiceRecord : null, setSelectedInvoiceRecord : function(invoiceRecord){ dlg_AddPaymentDetail.selectedInvoiceRecord = invoiceRecord; // Editing the title theThis.setTitle(String.format('Add Payment Detail for Invoice No : {0}', dlg_AddPaymentDetail.selectedInvoiceRecord.data.invoiceNo)); theThis.txt_Invoice_Payment_PaymentDate.setValue(new Date()); theThis.txt_Invoice_Payment_BankReferenceID.setValue(''); theThis.txt_Invoice_Payment_PaidAmount.setValue(dlg_AddPaymentDetail.selectedInvoiceRecord.data.totalAmount); theThis.txt_Invoice_Payment_SurchargeAmount.setValue(0); }, items : [ frm_Input ], buttons : [ { xtype : 'button', iconCls : 'icon-money', scale : 'large', text : 'Submit', handler : function(){ if (!theThis.txt_Invoice_Payment_PaymentDate.isValid()) return; if (!theThis.txt_Invoice_Payment_BankReferenceID.isValid()) return; if (!theThis.txt_Invoice_Payment_PaidAmount.isValid()) return; if (!theThis.txt_Invoice_Payment_SurchargeAmount.isValid()) return; theThis.loadMask.show(); // Calling ajax request to save payment detail Ext.Ajax.request({ method: 'POST', url: '/Invoice/AddPaymentDetail', timeout: 1800000, params: { invoiceId : theThis.dlg_AddPaymentDetail.selectedInvoiceRecord.data.invoiceId, paymentDate : theThis.txt_Invoice_Payment_PaymentDate.getValue(), bankReferenceID : theThis.txt_Invoice_Payment_BankReferenceID.getValue(), paidAmount : theThis.txt_Invoice_Payment_PaidAmount.getValue(), surchargeAmount : theThis.txt_Invoice_Payment_SurchargeAmount.getValue() }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); theThis.dlg_AddPaymentDetail.hide(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } },{ xtype : 'button', iconCls : 'icon-cancel-large', scale : 'large', text : 'Cancel', handler : function(){ theThis.dlg_AddPaymentDetail.hide(); } } ] }); return dlg_AddPaymentDetail; }, // This function return a dialog that allow user choose a order as a invoice // By a specific supplier getStockExistingOrderDialog : function(){ var theThis = this; // *************************************************************************************************** // Data Fields // *************************************************************************************************** var record = Ext.data.Record.create([ { name: 'stockOrderId' , type: 'number' }, { name: 'stockOrderDate' , type: 'date'}, { name: 'stockOrderNo' , type: 'string'}, { name: 'supplierName' , type: 'string' }, { name: 'supplierId' , type: 'number' }, { name: 'stockOrderTotal' , type: 'number' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** var store = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy({ url: '/StockOrder/SearchStockOrders', dataType: 'json', method: 'POST' }), autoLoad : false, fields: record, root: 'data', idProperty: 'stockOrderId', totalProperty: 'totalCount', listeners : { load : function(){ if (store.getCount() > 0){ // If there's some stock order that need invoice from a specific supplier // Show the dialog to let user choose that order as a invoice theThis.dlg_StockExistingOrder.show(); } else { showSuccessNotification('You don\'t have any stock orders from this supplier.', NOTIFICATION.ICON_INFORMATION); theThis.dlg_StockExistingOrder.hide(); } }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } }); // **************************************************************************************************** // Selection Models // **************************************************************************************************** var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment }, beforerowselect: function(o, rowIndex, keepExisting, record) { } } }); // **************************************************************************************************** // Column Models // **************************************************************************************************** var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'stockOrderId', dataIndex: 'stockOrderId', hidden: true }, { header: 'Date', dataIndex: 'stockOrderDate', width: 40, renderer : function(val){ return Ext.util.Format.date(val, 'd/m/Y'); } }, { header: 'Supplier(s)', dataIndex: 'stockOrderId', width: 50, renderer : function(val){ var supplierId = store.getById(val).get('supplierId'); var supplierName = store.getById(val).get('supplierName'); if (supplierId != -1){ return ''+supplierName+''; } else { if (supplierName != ""){ var suppliers = supplierName.split(";"); var result = '
    '; for (var i = 0;i'; } result += '
'; return result; } else { return '[None]'; } } } }, { header: 'Total', dataIndex: 'stockOrderTotal', width: 10, renderer : Ext.util.Format.usMoney } ] }); /****************************/ /* Grid */ /****************************/ var grid = new Ext.grid.EditorGridPanel({ store: store, title: 'Stock orders', region : 'center', frame: true, listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { var selectedStockOrderId = p_this.getStore().getAt(p_rowIndex).get("stockOrderId"); theThis.selectedExistingStockOrderId = selectedStockOrderId; // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, rowdblclick : function( p_this, p_rowIndex, p_eventObject) { theThis.btn_Invoice_StockExistingOrder.handler.call(theThis.btn_Invoice_StockExistingOrder.scope); } }, tbar : [ theThis.btn_StockExistingOrder_Delele = new Ext.Button({ tooltip : 'Mark the selected order so they will not appear in the list as suggestions anymore.', iconCls: 'icon-delete', text: 'Delete', scale : 'large', handler : function(){ var selectedRecords = grid.getSelectionModel().getSelections(); if (selectedRecords.length > 0){ showConfirmMessage('Are you sure you want to hide these stock orders from suggestion window ? ', function(){ var listOfIds = new Array(); for (var i = 0; i < selectedRecords.length; i++){ listOfIds[i] = selectedRecords[i].data.stockOrderId; } var wrapperObject = {listOfNumbers : listOfIds} grid.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/StockOrder/HideSuggestionStockOrdersInInvoice', params: { listOfStockOrderIds : Ext.util.JSON.encode(wrapperObject) }, success : function(result, request) { grid.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); grid.getStore().reload(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { grid.loadMask.hide(); } }); // End ajax }); } else { showErrorNotification('Notice', 'Please choose item to delele !'); } } }) ], cm: cm, sm: sm, autoHeight: false, clicksToEdit: 1, loadMask: true, bbar: new Ext.PagingToolbar({ store: store, pageSize: theThis.pageSize, displayInfo: true, displayMsg: 'Displaying results {0} - {1} of {2}', emptyMsg: "No orders to display" }), viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); theThis.grid_StockExistingOrder = grid; var dialog = new Ext.Window({ title: 'Stock - Existing Order', layout: 'border', closeAction: 'hide', iconCls : 'icon-stock', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, //maximized : true, width:800, height:500, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, buttons: [ theThis.btn_Invoice_StockExistingOrder = new Ext.Button({ text: 'Select', iconCls : 'icon-ok-large', scale : 'large', handler : function(){ var selectedRecords = grid.getSelectionModel().getSelections(); if (selectedRecords.length == 0){ showErrorNotification('Notice', 'Please choose an order from the list to fill the invoice !'); } else if (selectedRecords.length != 1){ showErrorNotification('Notice', 'Please select only one order from the list !'); } else { theThis.getInvoiceDetailFromExistingOrder(function(){ dialog.hide(); }); } /*if (Global_SelectedExistingStockOrderId != -1){ } else { Ext.Msg.show({ title:'Notice', msg: 'Please choose an order from the list to fill the invoice !', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); } */ } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ dialog.hide(); } })], items : [grid], listeners : { 'beforeshow' : function(p_This){ // Fit this window to the client browser screen with 60% fitWindowSize(p_This, 60); }, 'beforehide' : function(){ } } }); return dialog; }, getInvoiceDetailFromExistingOrder : function(callback_Function){ var theThis = this; theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Invoice/GetInvoiceDetailFromExistingOrder', params: { stockOrderId : theThis.selectedExistingStockOrderId }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification('Existing order populated', NOTIFICATION.ICON_INFORMATION); for(var i = 0; i < jsonData.data.length; i++) { var newInvoiceDetailId = -getRandomNumber(); // Negative for new entry var invoiceDetailTax = jsonData.data[i].isGstApplied == false ? 0 : roundNumber((jsonData.data[i].supplierCost * jsonData.data[i].stockQty * CTB.init.expenseTax.percentage)/100, 2); var store = theThis.grid_InvoiceDetail.getGrid().getStore(); var aNewDetail = new store.recordType({ invoiceDetailId : newInvoiceDetailId, // Negative for new entry invoiceId : theThis.selectedInvoiceId, supplierStockCode : jsonData.data[i].supplierStockCode, stockDesc : jsonData.data[i].stockDesc, stockUnit : jsonData.data[i].stockUnit, stockUnitOfMeasurementId : jsonData.data[i].stockUnitOfMeasurementId, stockQty : 0, // Change later, look at below code stockId : jsonData.data[i].stockId, stockSupplierId : jsonData.data[i].stockSupplierId, invoiceDetailCost : jsonData.data[i].supplierCost, invoiceDetailTax : invoiceDetailTax, isGstApplied : jsonData.data[i].isGstApplied, invoiceDetailSubtotal : roundNumber(jsonData.data[i].stockQty * jsonData.data[i].supplierCost + invoiceDetailTax, 2), // Quantity = 1, then subtotal = cost discountPercentage : jsonData.data[i].discountPercentage }, newInvoiceDetailId); theThis.grid_InvoiceDetail.getGrid().getStore().insert(theThis.grid_InvoiceDetail.getGrid().getStore().getCount(), aNewDetail); theThis.grid_InvoiceDetail.getGrid().getStore().getById(newInvoiceDetailId).set('stockQty', jsonData.data[i].stockQty); theThis.grid_InvoiceDetail.updateTheSubtotal(theThis.grid_InvoiceDetail.getGrid().getStore().getById(newInvoiceDetailId)); if (theThis.grid_CreditNoteDetail != null && theThis.isForCreditNoteRequest){ theThis.grid_CreditNoteDetail.getGrid().getStore().insert(theThis.grid_CreditNoteDetail.getGrid().getStore().getCount(), aNewDetail); theThis.grid_CreditNoteDetail.getGrid().getStore().getById(newInvoiceDetailId).set('stockQty', jsonData.data[i].stockQty); theThis.grid_CreditNoteDetail.updateTheSubtotal(theThis.grid_CreditNoteDetail.getGrid().getStore().getById(newInvoiceDetailId)); } } } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } //Global_SelectedExistingStockOrderId = -1; theThis.loadMask.hide(); if (callback_Function != null) callback_Function(); //dialog.hide(); }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax }, getInvoiceDetailFromProformaInvoice : function(callback_Function, isFromCreditNoteProformaInvoice){ var theThis = this; if (isFromCreditNoteProformaInvoice == null) isFromCreditNoteProformaInvoice = false; theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: isFromCreditNoteProformaInvoice == false ? '/Invoice/GetInvoiceDetailFromProformaInvoice' : '/Invoice/GetInvoiceDetailFromCreditNoteProformaInvoice', params: { proformaInvoiceId : theThis.selectedProformaInvoiceId }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification('Purchase Order Populated', NOTIFICATION.ICON_INFORMATION); var isSetTheTotalDiscount = false; var isSetTheTotalFreight = false; var isSetTheInvoiceNumber = false; var isSetTheInvoiceDate = false; var isSetTheInvoiceType = false; for(var i = 0; i < jsonData.data.length; i++) { var newInvoiceDetailId = -getRandomNumber(); // Negative for new entry var invoiceDetailId = theThis.isUsingProformaInvoiceId == false ? newInvoiceDetailId : jsonData.data[i].proformaInvoiceDetailId; //var invoiceDetailTax = jsonData.data[i].isGstApplied == false ? 0 : roundNumber((jsonData.data[i].supplierCost * jsonData.data[i].stockQty * Global_GSTPercentage)/100, 2); var store = theThis.grid_InvoiceDetail.getGrid().getStore(); var aNewDetail = new store.recordType({ invoiceDetailId : invoiceDetailId, // Negative for new entry invoiceId : theThis.isUsingProformaInvoiceId == false ? theThis.selectedInvoiceId : jsonData.data[i].proformaInvoiceId, supplierStockCode : jsonData.data[i].supplierStockCode, stockDesc : jsonData.data[i].stockDesc, stockUnit : jsonData.data[i].stockUnit, stockUnitOfMeasurementId : jsonData.data[i].stockUnitOfMeasurementId, stockQty : 0, // Change later, look at below code stockId : jsonData.data[i].stockId, stockSupplierId : jsonData.data[i].stockSupplierId, invoiceDetailCost : jsonData.data[i].supplierCost, invoiceDetailTax : jsonData.data[i].invoiceDetailTax, isGstApplied : jsonData.data[i].isGstApplied, invoiceDetailSubtotal : roundNumber(jsonData.data[i].stockQty * jsonData.data[i].supplierCost + jsonData.data[i].invoiceDetailTax, 2), // Quantity = 1, then subtotal = cost discountPercentage : jsonData.data[i].discountPercentage }, invoiceDetailId); theThis.grid_InvoiceDetail.getGrid().getStore().insert(theThis.grid_InvoiceDetail.getGrid().getStore().getCount(), aNewDetail); theThis.grid_InvoiceDetail.getGrid().getStore().getById(invoiceDetailId).set('stockQty', jsonData.data[i].stockQty); var theRecord = theThis.grid_InvoiceDetail.getGrid().getStore().getById(invoiceDetailId); if (jsonData.data[i].invoiceDetailTax != 0) theRecord.isModified = true; // Set the total discount (rounding, adjustment, etc, ...) if (jsonData.data[i].totalDiscount != null && !isSetTheTotalDiscount){ isSetTheTotalDiscount = true; theThis.txt_BottomDetail_Discount.setValue(jsonData.data[i].totalDiscount); } // Set the total freight if (jsonData.data[i].totalFreight != null && !isSetTheTotalFreight){ isSetTheTotalFreight = true; theThis.txt_BottomDetail_FreightIncludeGST.setValue(jsonData.data[i].totalFreight); } // Set the invoice number if (jsonData.data[i].invoiceNo != null && !isSetTheInvoiceNumber){ isSetTheInvoiceNumber = true; theThis.txt_TopDetail_InvoiceNo.setValue(jsonData.data[i].invoiceNo); } // Set the invoice date if (jsonData.data[i].invoiceDate != null && !isSetTheInvoiceDate){ isSetTheInvoiceDate = true; theThis.txt_TopDetail_Date.setValue(new Date(jsonData.data[i].invoiceDate)); } // Set the invoice type if (jsonData.data[i].isReturned != null && !isSetTheInvoiceType){ isSetTheInvoiceType = true; theThis.cmb_TopDetail_InvoiceType.setValue(jsonData.data[i].isReturned); } // Update the line subtotal theThis.grid_InvoiceDetail.updateTheSubtotal(theRecord); if (theThis.grid_CreditNoteDetail != null && theThis.isForCreditNoteRequest){ theThis.grid_CreditNoteDetail.getGrid().getStore().insert(theThis.grid_CreditNoteDetail.getGrid().getStore().getCount(), aNewDetail); theThis.grid_CreditNoteDetail.getGrid().getStore().getById(invoiceDetailId).set('stockQty', jsonData.data[i].stockQty); theThis.grid_CreditNoteDetail.updateTheSubtotal(theThis.grid_CreditNoteDetail.getGrid().getStore().getById(invoiceDetailId)); } } } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } //Global_SelectedExistingStockOrderId = -1; theThis.loadMask.hide(); if (callback_Function != null) callback_Function(); //dialog.hide(); }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax }, getCreditNoteDetailFromProformaInvoice : function(proformaInvoiceId, callback_Function){ var theThis = this; theThis.grid_CreditNoteDetail.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Invoice/GetInvoiceDetailFromProformaInvoice', params: { proformaInvoiceId : proformaInvoiceId }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { //showSuccessNotification('Credit note populated', NOTIFICATION.ICON_INFORMATION); for(var i = 0; i < jsonData.data.length; i++) { var newInvoiceDetailId = -getRandomNumber(); // Negative for new entry var invoiceDetailId = theThis.isUsingProformaInvoiceId == false ? newInvoiceDetailId : jsonData.data[i].proformaInvoiceDetailId; //var invoiceDetailTax = jsonData.data[i].isGstApplied == false ? 0 : roundNumber((jsonData.data[i].supplierCost * jsonData.data[i].stockQty * Global_GSTPercentage)/100, 2); var store = theThis.grid_CreditNoteDetail.getGrid().getStore(); var aNewDetail = new store.recordType({ invoiceDetailId : invoiceDetailId, // Negative for new entry invoiceId : theThis.isUsingProformaInvoiceId == false ? theThis.selectedInvoiceId : jsonData.data[i].proformaInvoiceId, supplierStockCode : jsonData.data[i].supplierStockCode, stockDesc : jsonData.data[i].stockDesc, stockUnit : jsonData.data[i].stockUnit, stockUnitOfMeasurementId : jsonData.data[i].stockUnitOfMeasurementId, stockQty : jsonData.data[i].stockQty, // Change later, look at below code stockId : jsonData.data[i].stockId, stockSupplierId : jsonData.data[i].stockSupplierId, invoiceDetailCost : jsonData.data[i].supplierCost, invoiceDetailTax : jsonData.data[i].invoiceDetailTax, isGstApplied : jsonData.data[i].isGstApplied, invoiceDetailSubtotal : roundNumber(jsonData.data[i].stockQty * jsonData.data[i].supplierCost + jsonData.data[i].invoiceDetailTax, 2), // Quantity = 1, then subtotal = cost discountPercentage : jsonData.data[i].discountPercentage }, invoiceDetailId); if (theThis.grid_CreditNoteDetail != null && theThis.isForCreditNoteRequest){ theThis.grid_CreditNoteDetail.getGrid().getStore().insert(theThis.grid_CreditNoteDetail.getGrid().getStore().getCount(), aNewDetail); theThis.grid_CreditNoteDetail.getGrid().getStore().getById(invoiceDetailId).set('stockQty', jsonData.data[i].stockQty); theThis.grid_CreditNoteDetail.updateTheSubtotal(theThis.grid_CreditNoteDetail.getGrid().getStore().getById(invoiceDetailId)); } } } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } theThis.grid_CreditNoteDetail.loadMask.hide(); if (callback_Function != null) callback_Function(); }, failure : function(result, request) { theThis.grid_CreditNoteDetail.loadMask.hide(); } }); // End ajax }, markProformaInvoiceAsTransfered : function(callback_Function){ var theThis = this; theThis.loadMask.msg = 'Transfering proforma invoice...'; theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/ProformaInvoice/MarkProformaInvoiceAsTransfered', params: { proformaInvoiceId : theThis.selectedProformaInvoiceId, invoiceId : theThis.selectedInvoiceId }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } //Global_SelectedExistingStockOrderId = -1; theThis.loadMask.hide(); theThis.loadMask.msg = 'Loading...'; if (callback_Function != null) callback_Function(); }, failure : function(result, request) { theThis.loadMask.hide(); theThis.loadMask.msg = 'Loading...'; } }); // End ajax } }); Ext.reg('CTBInvoiceDetailWindow', Ext.CTBInvoiceDetailWindow); Ext.CTBTrialDetailPanel = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: 100, recordObject : null, selectedInvoiceRecord : null, isForCreditNoteRequest : false, hideInstruction : true, isCalculateParentField : true, setSelectedInvoiceRecord : function(theRecord){ var theThis = this; theThis.selectedInvoiceRecord = theRecord; if (theRecord != null) theThis.selectedInvoiceId = theRecord.data.invoiceId; else theThis.selectedInvoiceId = -1; }, parentWindowContainer : null, listeners : { afterrender : function(theThis){ // Init loadMask theThis.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); }, show : function(theThis){ theThis.modifiedRecords = null; } }, instructionText : 'Physical Invoice', instructionBackgroundColor : '#66c010', initComponent: function(){ var theThis = this; theThis.StockBrowserDialog = Ext.getCmp('dlg_StockBrowser'); theThis.grid_InvoiceDetail = theThis.getGrid_ReceivingOrder(); theThis.pnl_Instruction = new Ext.Panel({ frame : true, region : 'north', height : 70, hidden : theThis.hideInstruction, html : '
'+ ''+ ''+ ''+ ''+ '
'+ ''+theThis.instructionText+''+ '
'+ '
' }); theThis.items = [theThis.grid_InvoiceDetail, theThis.pnl_Instruction]; // Call super class to initialize componenets Ext.CTBTrialDetailPanel.superclass.initComponent.call(this); }, updateTheSubtotal : function(theRecord){ var theThis = this; theThis.getGrid().updateTheSubtotal(theRecord); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_InvoiceDetail; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_InvoiceDetail; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getStore().baseParams = {invoiceId : theThis.selectedInvoiceRecord.data.invoiceId, start : 0, limit : theThis.getPagingToolbar().pageSize}; theThis.getGrid().getStore().load(); }, getCombobox_UnitOfMeasurement : function(callbackfunction) { var cmbGridUOM = new Ext.form.ComboBox({ store: Global_UnitOfMeasurement_Store, displayField: 'UOMName', valueField: 'UOMId', typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local' }); return cmbGridUOM; }, getGrid_ReceivingOrder: function(){ var theThis = this; // shorthand alias var fm = Ext.form; var cmbGridUOM = theThis.getCombobox_UnitOfMeasurement(); // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.recordObject = Ext.data.Record.create([ { name: 'invoiceDetailId', type: 'number' }, { name: 'invoiceId', type: 'number' }, { name: 'supplierStockCode', type: 'string' }, { name: 'stockDesc', type: 'string' }, { name: 'stockUnit', type: 'number' }, { name: 'stockUnitOfMeasurementId', type: 'number' }, { name: 'stockQty', type: 'number' }, { name: 'stockId', type: 'number' }, { name: 'stockSupplierId', type: 'number' }, { name: 'invoiceDetailCost', type : 'number'}, { name: 'invoiceDetailTax', type: 'number' }, { name: 'invoiceDetailSubtotal', type: 'number' }, { name: 'isGstApplied', type: 'boolean' }, { name: 'discountPercentage', type: 'number' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** var store = new Ext.data.JsonStore({ autoLoad : false, proxy: new Ext.data.HttpProxy({ url: '/Invoice/GetInvoiceDetailByInvoiceId', dataType: 'json', method: 'POST' }), //reader: new Ext.data.JsonReader({ fields: theThis.recordObject, root: 'data', idProperty: 'invoiceDetailId', listeners : { 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(store); } } //}) }); // *************************************************************************************************** // Selection model // *************************************************************************************************** var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { } } }); // *************************************************************************************************** // Column model // *************************************************************************************************** // Column Models var cm = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ sm, { header: 'invoiceDetailId', dataIndex: 'invoiceDetailId', hidden: true }, { header: 'invoiceId', dataIndex: 'invoiceId', hidden: true }, { header: 'Stock Code', dataIndex: 'supplierStockCode', width: 10, hidden : theThis.isForCreditNoteRequest }, { header: 'Description', dataIndex: 'stockDesc', width: 30 }, { header: 'Unit', dataIndex: 'stockUnit', width: 15, hidden : theThis.isForCreditNoteRequest }, { header: 'Measurement', dataIndex: 'stockUnitOfMeasurementId', width: 15, hidden : theThis.isForCreditNoteRequest, renderer: Ext.util.Format.comboRenderer(cmbGridUOM) }, { header: 'Quantity' + CTB_SYMBOL.EDIT, dataIndex: 'stockQty', width: 15, editor: new Ext.grid.GridEditor( new Ext.form.SpinnerField({ xtype: 'spinnerfield', allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 3, onFocus: function (txt, e) { this.getEl().dom.select(); } }), { listeners: { beforestartedit: function(editor) { editor.field.currentRecord = editor.record; }, complete : function(p_This, p_Value, p_StartValue){ // Value has been changed by user if (p_Value != p_StartValue){ //updateTheSubtotal(p_This.record); } } } } ) }, { header: 'Cost/Unit', dataIndex: 'invoiceDetailCost', width: 15, hidden : theThis.isForCreditNoteRequest, editor: new Ext.grid.GridEditor( new Ext.form.SpinnerField({ xtype: 'spinnerfield', allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 3, onFocus: function (txt, e) { this.getEl().dom.select(); } }), { listeners: { beforestartedit: function(editor) { editor.field.currentRecord = editor.record; }, complete : function(p_This, p_Value, p_StartValue){ // Value has been changed by user if (p_Value != p_StartValue){ //updateTheSubtotal(p_This.record); } } } } ), renderer: Ext.util.Format.usMoney }, { header: 'DISC %' + CTB_SYMBOL.EDIT, dataIndex: 'discountPercentage', width: 15, hidden : theThis.isForCreditNoteRequest, editor: new Ext.grid.GridEditor( new Ext.form.NumberField({ allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 2, onFocus: function (txt, e) { this.getEl().dom.select(); } }), { listeners: { beforestartedit: function(editor) { editor.field.currentRecord = editor.record; }, complete : function(p_This, p_Value, p_StartValue){ // Value has been changed by user if (p_Value != p_StartValue){ //updateTheSubtotal(p_This.record); } } } } ), renderer: function(val){ return Ext.util.Format.percentage(val); } }, { header: 'Tax' + CTB_SYMBOL.EDIT, dataIndex: 'invoiceDetailTax', width: 15, hidden : theThis.isForCreditNoteRequest, editor: new Ext.grid.GridEditor( new Ext.form.SpinnerField({ xtype: 'spinnerfield', moneySign : '', allowBlank: false, allowNegative: false, minValue : 0, allowDecimals : true, decimalPrecision: 3, onFocus: function (txt, e) { this.getEl().dom.select(); } }), { listeners: { beforestartedit: function(editor) { editor.field.currentRecord = editor.record; }, complete : function(p_This, p_Value, p_StartValue){ // Value has been changed by user if (p_Value != p_StartValue){ // Mark the record as modified p_This.record.isMofified = true; } } } } ), renderer: Ext.util.Format.usMoney }, { header: 'Subtotal', dataIndex: 'invoiceDetailSubtotal', width: 15, hidden : theThis.isForCreditNoteRequest, renderer: Ext.util.Format.usMoney } ] }); // This function update tax column for all rows function updateTaxForAllRows(){ for (var i = 0; i < store.getCount(); i++){ var theRecord = store.getAt(i); if (theRecord.data.isGstApplied){ if (theRecord.isMofified == null || theRecord.isMofified == false) theRecord.set('invoiceDetailTax', roundNumber((theRecord.data.invoiceDetailCost * theRecord.data.stockQty * Global_GSTPercentage)/100, 2)); } /*else if (theRecord.data.invoiceDetailTax != 0){ theRecord.set('invoiceDetailTax', roundNumber((theRecord.data.invoiceDetailCost * theRecord.data.stockQty * Global_GSTPercentage)/100, 2)); }*/ } } function updateTheTax(theRecord){ if (theRecord.data.isGstApplied){ if (theRecord.isMofified == null || theRecord.isMofified == false) theRecord.set('invoiceDetailTax', roundNumber((theRecord.data.invoiceDetailCost * theRecord.data.stockQty * Global_GSTPercentage)/100, 2)); } } // This function update the subtotal for individual record function updateTheSubtotal(theRecord){ updateTheTax(theRecord); var theSubTotal = theRecord.get('invoiceDetailTax') + theRecord.get('invoiceDetailCost')*theRecord.get('stockQty'); // Minus the individual discount theSubTotal = theSubTotal - (theSubTotal * theRecord.get('discountPercentage') / 100); theSubTotal = roundNumber(theSubTotal, Global_Money_RoundUpTo); theRecord.set('invoiceDetailSubtotal', theSubTotal); if (theThis.parentWindowContainer != null && theThis.isCalculateParentField) { theThis.parentWindowContainer.refreshCalculatingField(); } } // *************************************************************************************************** // Paging toolbar // *************************************************************************************************** theThis.pt_InvoiceDetail = new Ext.CTBPagingToolbar({ store: store, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No stocks to display", hidden : theThis.isForCreditNoteRequest }); // *************************************************************************************************** // Grid // *************************************************************************************************** var grid = new Ext.grid.EditorGridPanel({ updateTheSubtotal : function(theRecord){ updateTheSubtotal(theRecord); }, tbar : [ theThis.btn_Add = new Ext.Button({ iconCls : 'icon-add', scale : 'large', text : 'Add', handler : function(){ theThis.StockBrowserDialog.Global_StockBrowser_CallbackFunction = function(selectedRecords) { var insertedDetail = new Array(); for(var i = 0; i 0) { Ext.Msg.show({ title:'Confirm', msg: 'Are you sure you want to delete the item(s) ?', buttons: Ext.Msg.YESNO, icon: Ext.MessageBox.QUESTION, fn : function(btn) { if (btn == "yes") { var deletedItemIds = new Array(); // Actual deleted item var modifiedRecords = store.getModifiedRecords(); var modifiedInfo = new Array(); // Store the modifed record for recovering from deleting // This loop save the changes for (var i = 0; i < modifiedRecords.length; i++){ modifiedInfo[i] = { invoiceDetailId : modifiedRecords[i].data.invoiceDetailId, stockQty : modifiedRecords[i].data.stockQty } } // This loop insert deleted item to the array for (var i = 0, j = 0; i < selectedItems.length; i++) { var theId = selectedItems[i].get("invoiceDetailId"); if (theId >= 0){ // Only delete existing detail deletedItemIds[j] = theId; j++; } theThis.getGrid().getStore().remove(selectedItems[i]); } store.commitChanges(); // This is the reason we use modifiedInfo, when we commit, every changes disappear // Recovering the changes // If the item not be deleted for (var i = 0; i < modifiedInfo.length; i++){ var invoiceDetailId = modifiedInfo[i].invoiceDetailId; if (store.getById(invoiceDetailId) != null){ var stockQty = modifiedInfo[i].stockQty; store.getById(invoiceDetailId).set('stockQty', 0); // Make changing mark appearing store.getById(invoiceDetailId).set('stockQty', stockQty); // Recovering the real value } } // Refresh the total if (theThis.parentWindowContainer != null && theThis.isCalculateParentField) theThis.parentWindowContainer.refreshCalculatingField(); // Calling delete if (theThis.selectedInvoiceId != -1 && deletedItemIds.length > 0){ // Only send request when the invoice exist theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Invoice/DeleteStockFromInvoice', params: { invoiceId : theThis.selectedInvoiceId, invoiceDetailIds : Ext.util.JSON.encode(deletedItemIds) }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { showSuccessNotification(jsonData.message.Info, NOTIFICATION.ICON_INFORMATION); //grid_Invoice.getStore().load(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } // End if } } }); } else { Ext.Msg.show({ title:'Notice', msg: 'Please select item(s) to delete!', buttons: Ext.Msg.OK, icon: Ext.MessageBox.WARNING }); }// End if }// End Handler }) // End delete button ], region: 'center', store: store, frame: true, sm : sm, listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); if (theThis.parentWindowContainer != null && theThis.isCalculateParentField) { theThis.parentWindowContainer.pnl_InvoiceDetail_NumberPad.callback_Assign = function(value){ theThis.getGrid().stopEditing(); var selectedRecords = theThis.getGrid().getSelectionModel().getSelections(); if (selectedRecords.length > 0){ for (var i = 0; i < selectedRecords.length; i++){ selectedRecords[i].set('stockQty', value); updateTheSubtotal(selectedRecords[i]); } } } } //theThis.getGrid().startEditing(p_rowIndex, 7); // Only stop editing if user's using iPad // We don't want them to see the default keyboard in iPad if (Global_IsiPad) theThis.getGrid().stopEditing(); }, // p_EditedObject INCLUDES : // grid - This grid // record - The record being edited // field - The field name being edited // value - The value being set // originalValue - The original value for the field, before the edit. // row - The grid row index // column - The grid column index afteredit : function( p_EditedObject ) { updateTheSubtotal(p_EditedObject.record); }, beforeedit : function (p_Event) { if (theThis.parentWindowContainer != null && theThis.isCalculateParentField) { theThis.parentWindowContainer.pnl_InvoiceDetail_NumberPad.callback_Next = function(theNumberPad){ try{ if (theNumberPad.isHavingChanges == true){ theNumberPad.operatorClick('='); } theThis.getGrid().getSelectionModel().selectRow(p_Event.row + 1); theThis.getGrid().startEditing(p_Event.row + 1, 7); theThis.getGrid().stopEditing(); }catch(e){ var activePage = 1; var totalCount = theThis.getGrid().getStore().getTotalCount(); if ((activePage+1) <= Math.ceil(totalCount / theThis.pt_InvoiceDetail.pageSize)) { theThis.pt_InvoiceDetail.moveNext(); } else { showErrorNotification('Notice', 'End of invoice details.'); } } } } } }, cm: cm, width: 780, height: 400, autoHeight: false, clicksToEdit: 1, loadMask: true, bbar : theThis.pt_InvoiceDetail, viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return grid; } }); Ext.reg('CTBTrialDetailPanel', Ext.CTBTrialDetailPanel); Ext.CTBTrialWindow = Ext.extend(Ext.Window, { title: 'TRIAL PROGRAM A FEW QUICK QUESTIONS', layout: 'border', closeAction: 'hide', expandOnShow : true, closable: true, resizable: true, modal: true, plain: true, minimizable : true, maximizable : true, monitorResize : true, width:720, height:350, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, listeners : { scope : this, afterrender : function(theThis){ theThis.loadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."}); }, beforehide : function(theThis){ }, hide : function(theThis){ }, beforeshow : function(theThis){ }, show : function(theThis){ } }, initComponent : function(){ var theThis = this; theThis.pnl_TopDetail = theThis.getPanel_TopDetail(); theThis.items = [ theThis.pnl_TopDetail ]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBTrialWindow.superclass.initComponent.call(this); }, initButtons : function(){ var theThis = this; var buttons = [ theThis.btn_TRYNOW = new Ext.Button({ text : 'TRY NOW', scale : 'large', handler : function(){ if (theThis.validateBeforeSave()){ var title = theThis.cmbTitle.getValue(); var name = theThis.txt_Name.getValue(); theThis.loadMask.show(); // Calling delete Ext.Ajax.request({ method: 'POST', url: '/Invoice/DeleteInvoices', params: { title : title, name : name }, success : function(result, request) { theThis.loadMask.hide(); }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax } } // End send request handler button }), theThis.btn_CANCEL = new Ext.Button({ text : 'CANCEL', scale : 'large', handler : function(){ theThis.hide(); } // End save handler button }) ]; return buttons; }, validateBeforeSave : function() { var theThis = this; var validateFields = new Array(); validateFields[0] = { ID : theThis.txt_Name.id, VALIDATION_TYPE : VALIDATION_CONSTANTS.EMPTY }; // Call global validate field group return validateFieldGroup(validateFields); }, getPanel_TopDetail : function(){ var theThis = this; theThis.cmbTitle = theThis.getCombobox_Title(); var frm_LeftForm = new Ext.form.FormPanel({ baseCls: 'x-plain', labelWidth: 100, defaultType: 'textfield', items: [ theThis.cmbTitle, /*theThis.txt_TopDetail_Date = new Ext.form.DateField({ fieldLabel: 'Date', xtype : 'datefield', name: 'datefield', value : new Date(), format : "j/n/Y", altFormats : 'j/n/y', width : 200 }),*/ theThis.txt_Name = new Ext.form.TextField({ fieldLabel: 'NAME', name: 'name', width : 200 }), theThis.rg_RegistrationType = new Ext.form.RadioGroup({ fieldLabel: 'TYPE', vertical: false, //hideLabel : true, itemCls: 'x-check-group-alt', columns: 2, listeners : { change : function(p_this, p_radio){ } }, items: [ {boxLabel: 'Business', name: 'rg_RegistrationType', inputValue: 'business', checked:true}, {boxLabel: 'Student', name: 'rg_RegistrationType', inputValue: 'student'} ] }), theThis.txt_Company = new Ext.form.TextField({ fieldLabel: 'COMPANY*', name: 'name', width : 200 }), theThis.txt_Address = new Ext.form.TextArea({ fieldLabel: 'ADDRESS*', name: 'address', width : 200 }), theThis.txt_Telephone = new Ext.form.TextField({ fieldLabel: 'TELEPHONE*', name: 'telephone', width : 200 }), theThis.txt_Email = new Ext.form.TextField({ fieldLabel: 'EMAIL*', name: 'email', width : 200 }) ] }); theThis.cmbHeardFrom = theThis.getCombobox_HeardFrom(); var frm_RightForm = new Ext.form.FormPanel({ baseCls: 'x-plain', labelWidth: 150, //columnWidth : .50, defaultType: 'textfield', items: [ theThis.lbl_WhereDidYouHearAboutUs = new Ext.form.Label({ text : 'WHERE DID YOU HEAR ABOUT US?' }), theThis.cmbHeardFrom, theThis.lbl_WhereDidYouHearAboutUs = new Ext.form.Label({ text : 'CAN WE CONTACT YOU ?' }), theThis.rg_Contact = new Ext.form.RadioGroup({ fieldLabel: 'Can we contact you ?', vertical: false, hideLabel : true, itemCls: 'x-check-group-alt', columns: 2, listeners : { change : function(p_this, p_radio){ } }, items: [ {boxLabel: 'Yes', name: 'rg_Contact', inputValue: 'Yes', checked:true}, {boxLabel: 'No', name: 'rg_Contact', inputValue: 'No'}, ] }) ] }); var pnl_TopDetail = new Ext.Panel({ region: 'center', layout : 'hbox', layoutConfig: { defaultMargins : '5 5 5 5' }, height : 105, items : [ frm_LeftForm, new Ext.Panel({ width : 50 }), frm_RightForm], frame: true, loadMask: true, viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return pnl_TopDetail; }, getCombobox_Title : function(){ var data = [ ['Mr', 'Mr'], ['Mrs', 'Mrs' ] ]; var cmbTitle = new Ext.form.ComboBox({ fieldLabel: 'TITLE', width : 100, store: new Ext.data.ArrayStore({ fields: [ {name: 'name' , type : 'string'}, {name: 'value', type: 'boolean'} ], data : data }), displayField: 'name', valueField: 'value', editable: false, typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Choose title ...', listeners : { select : function( p_combo, p_record, p_index){ } } }); return cmbTitle; }, getCombobox_HeardFrom : function(){ var data = [ ['MAGAZINE ADVERTISING', 'MAGAZINE ADVERTISING'] ]; var cmbHeardFrom = new Ext.form.ComboBox({ fieldLabel: 'Title', hideLabel : true, width : 300, store: new Ext.data.ArrayStore({ fields: [ {name: 'name' , type : 'string'}, {name: 'value', type: 'boolean'} ], data : data }), displayField: 'name', valueField: 'value', editable: false, typeAhead: true, triggerAction: 'all', lazyRender: true, mode: 'local', emptyText: 'Heard from ...', listeners : { select : function( p_combo, p_record, p_index){ } } }); return cmbHeardFrom; } }); Ext.reg('CTBTrialWindow', Ext.CTBTrialWindow); var Enable_Stock_Invoice = true; Ext.onReady(function () { var loadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."}); var fm = Ext.form; // Get the Business department tab var pnl_Invoice = Ext.getCmp('pnl_Invoice'); if(!pnl_Invoice) return; var grid_Invoice = new Ext.CTBXeroTransferInvoice({ region : 'center', margins : '10 15 10 15', border : false }); var pnl_InvoiceLayout = new Ext.Panel({ layout: 'border', bodyCssClass : 'x-panel-whitebgcolor', border : false, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, items : [grid_Invoice] }); pnl_Invoice.add(pnl_InvoiceLayout); pnl_Invoice.doLayout(); }); // End Ext.Ready Ext.CTBXeroSupplierTransferingLogGrid = Ext.extend(Ext.Panel, { layout : 'border', loadMask: null, pageSize: CTB.init.itemPerPage || 100, recordObject : null, instructionText : 'Transfering suppliers in progress, please wait ...', instructionBackgroundColor : '#fd4242', callback_ContinueButtonClick : null, dlg_Parent : null, isCancelled : false, MYOBHistoryTransactionRecord : null, totalProcessedRecord : 0, listeners : { afterrender : function(theThis){ // Init loadMask theThis.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); }, show : function(theThis){ theThis.totalProcessedRecord = 0; } }, initComponent: function(){ var theThis = this; theThis.tpl_Instruction = new Ext.XTemplate( '', '
', '', '', '', '', '
', '{instructionText}', '
', '
', '
' ); theThis.pnl_Instruction = new Ext.Panel({ frame : true, region : 'north', height : 70, tpl : theThis.tpl_Instruction, listeners : { afterrender : function(p_This){ p_This.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); } } }); theThis.grid_SupplierTransferingLogs = theThis.getGrid_SupplierTransferingLogs(); theThis.items = [theThis.grid_SupplierTransferingLogs, theThis.pnl_Instruction]; // Call super class to initialize componenets Ext.CTBXeroSupplierTransferingLogGrid.superclass.initComponent.call(this); }, clearSelections : function(){ var theThis = this; theThis.getGrid().getSelectionModel().clearSelections(); }, getGrid: function(){ var theThis = this; return theThis.grid_SupplierTransferingLogs; }, getPagingToolbar: function(){ var theThis = this; return theThis.pt_SupplierTransferingLog; }, getSelectedRecords: function(){ var theThis = this; return theThis.getGrid().getSelectionModel().getSelections(); }, loadData: function(){ var theThis = this; theThis.isCancelled = false; theThis.getGrid().getStore().removeAll(); theThis.instructionText = "Transfering suppliers in progress, please wait ..."; theThis.pnl_Instruction.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); theThis.btn_Continue.setVisible(false); theThis.getXeroHistoryTransaction(function(){ theThis.transferAllSuppliersFromCTBToXero(); }); /*theThis.getGrid().getStore().commitChanges(); theThis.getGrid().getStore().baseParams = {start : 0, limit : theThis.pageSize}; theThis.getGrid().getStore().load();*/ }, getGrid_SupplierTransferingLogs: function(){ var theThis = this; // shorthand alias var fm = Ext.form; // *************************************************************************************************** // Data Fields // *************************************************************************************************** theThis.supplierTransferingLogRecord = Ext.data.Record.create([ { name: 'supplierTransferingLogID' , type: 'string' }, { name: 'xeroSupplierId' , type: 'string' }, { name: 'supplierId' , type: 'number' }, { name: 'supplierName' , type: 'string' }, { name: 'abnNo' , type: 'string' }, { name: 'paymentTerm' , type: 'string' }, { name: 'accountNo' , type: 'string' }, { name: 'isActive' , type: 'boolean' }, { name: 'website' , type: 'string' }, { name: 'address' , type: 'object' }, { name: 'contact' , type: 'object' }, { name: 'xeroProcessingStatus' , type: 'string' }, { name: 'xeroTransferingMessage' , type: 'string' } ]); // *************************************************************************************************** // Stores // *************************************************************************************************** theThis.store_SupplierTransferingLog = new Ext.data.JsonStore({ proxy: new Ext.data.HttpProxy({ url: '/Xero/SearchSupplierTransferingLogs', dataType: 'json', method: 'POST' }), fields: theThis.supplierTransferingLogRecord, root: 'data', idProperty: 'supplierTransferingLogID', totalProperty : 'totalCount', autoLoad : false, listeners : { 'load' : function(){ }, 'loadexception' : function(){ showStoreLoadingErrorMessage(theThis.store_SupplierTransferingLog, function(){ theThis.dlg_Parent.connectToXero(function(){ theThis.store_SupplierTransferingLog.load(); }); }); } } //}) }); // *************************************************************************************************** // Grid // *************************************************************************************************** //------------------------------------------------------------------- // Selection model //------------------------------------------------------------------- var sm = new Ext.grid.CheckboxSelectionModel({ listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { // Do nothing at the moment } } }); var supplierTransferingLogSm = new Ext.grid.CheckboxSelectionModel({ singleSelect : true, listeners: { // On selection change, set enabled state of the removeButton // which was placed into the GridPanel using the ref config selectionchange: function(sm) { } } }); // Column Models var stockCM = new Ext.grid.ColumnModel({ // specify any defaults for each column defaults: { sortable: true // columns are not sortable by default }, columns: [ supplierTransferingLogSm, { header: 'supplierTransferingLogID', dataIndex: 'supplierTransferingLogID', hidden: true }, { header: 'supplierId', dataIndex: 'supplierId', hidden: true }, { header: 'Supplier Name', dataIndex: 'supplierName', width: 45 }, { header: 'Message', dataIndex: 'xeroTransferingMessage', width: 50, renderer: function(val, meta, theRecord) { if (theRecord.data.xeroProcessingStatus == XERO_PROCESSING_STATUS.PROCESSING) return 'Processing...'; else return val; } }, { header: 'Status', dataIndex: 'xeroProcessingStatus', width: 5, renderer: function(val) { if (val == XERO_PROCESSING_STATUS.PROCESSING) return '
Processing...
'; else if (val == XERO_PROCESSING_STATUS.SUCCEED) return '
Tranfer successfully.
'; else if (val == XERO_PROCESSING_STATUS.FAILED) return '
Failed to transfer!
'; } } ] }); /********************************************************************************************/ // SupplierTransferingLog grid var grid_SupplierTransferingLog = new Ext.grid.EditorGridPanel({ store : theThis.store_SupplierTransferingLog, frame : true, region : 'center', sm : supplierTransferingLogSm, buttons : [ theThis.btn_Continue = new Ext.Button({ text: 'Finish', iconCls : 'icon-ok-large', scale : 'large', hidden : true, handler : function(){ if (theThis.callback_ContinueButtonClick != null) theThis.callback_ContinueButtonClick(); } }), theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.isCancelled = true; if (theThis.dlg_Parent != null) theThis.dlg_Parent.hide(); } }) ], listeners : { rowclick : function ( p_this, p_rowIndex, p_eventObject ) { // Hightlight the selected row var selectedRow = p_this.getView().getRow(p_rowIndex); Ext.get(selectedRow).highlight(); }, rowdblclick : function ( p_this, p_rowIndex, p_eventObject ) { }, afterrender : function(){ /*theThis.store_SupplierTransferingLog.baseParams = {keyword: "", start: 0, limit: theThis.pageSize}, theThis.store_SupplierTransferingLog.load();*/ } }, cm: stockCM, width: 780, height: 400, autoHeight: false, clicksToEdit: 1, loadMask: true, /*bbar: theThis.pt_SupplierTransferingLog = new Ext.CTBPagingToolbar({ store: theThis.store_SupplierTransferingLog, pageSize: theThis.pageSize, displayInfo: true, emptyMsg: "No logs to display" }),*/ viewConfig: { enableRowBody: true, forceFit: true // IMPORTANT (USE THIS ATTRIBUTE TO USE PERCENTAGE IN COLUMN MODEL) } }); return grid_SupplierTransferingLog; }, // End generateGrid_Databases transferAllSuppliersFromCTBToXero : function(){ var theThis = this; theThis.totalProcessedRecord = 0; theThis.transferSuppliersInBatch(); //theThis.startProcessingIndex = 0; //theThis.loopTransferSupplier(); }, getXeroHistoryTransaction : function(callback_Function){ var theThis = this; theThis.loadMask.show(); Ext.Ajax.request({ method: 'POST', url: '/Kounta/GetNewMYOBHistoryTransaction', params: { }, success : function(result, request) { theThis.loadMask.hide(); var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.MYOBHistoryTransactionRecord = jsonData.data; if (callback_Function != null) callback_Function(); } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { theThis.loadMask.hide(); } }); // End ajax }, loopTransferSupplier : function(){ var theThis = this; if (theThis.isCancelled) return false; var selectedSupplierRecords = theThis.dlg_Parent.selectedSupplierRecords; if (theThis.startProcessingIndex < selectedSupplierRecords.length) { var theNewRecord = theThis.addNewRecord(selectedSupplierRecords[theThis.startProcessingIndex]); theThis.startProcessingIndex++; function transferSupplierNow(){ Ext.Ajax.request({ method: 'POST', url: '/Xero/TransferSupplierFromCTBtoXero', params: { supplierId : theNewRecord.data.supplierId, MYOBHistoryId : theThis.MYOBHistoryTransactionRecord.MYOBHistoryId }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { theThis.updateSupplierTransferingStatus(theNewRecord.data.supplierTransferingLogID, XERO_PROCESSING_STATUS.SUCCEED, jsonData.message.Info); theThis.loopTransferSupplier(); } else { if (jsonData.message.Info == XERO_MESSAGE.ACCESS_TOKEN_EXPIRED || jsonData.message.Info == XERO_MESSAGE.INVALID_ACCESS_TOKEN) { // Reconnect theThis.dlg_Parent.connectToXero(transferSupplierNow); } else { theThis.updateSupplierTransferingStatus(theNewRecord.data.supplierTransferingLogID, XERO_PROCESSING_STATUS.FAILED, jsonData.message.Info); theThis.loopTransferSupplier(); // showErrorMessageWithEmailNotify(jsonData.message.Info); } } }, failure : function(result, request) { theThis.updateSupplierTransferingStatus(theNewRecord.data.supplierTransferingLogID, XERO_PROCESSING_STATUS.FAILED, "Server unavailable!"); } }); // End ajax } transferSupplierNow(); return true; } else { theThis.instructionText = "Transfering progress completed"; theThis.pnl_Instruction.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); theThis.btn_Continue.setVisible(true); return false; } }, transferSuppliersInBatch : function(){ var theThis = this; if (theThis.isCancelled) return false; var selectedSupplierRecords = theThis.dlg_Parent.selectedSupplierRecords; var MYOBSupplierSupplierLinks = new Array(); var supplierIds = new Array(); var lastTotalProcessedRecords = theThis.totalProcessedRecord; var countBatch = 0; for (var i = lastTotalProcessedRecords; i < selectedSupplierRecords.length; i++){ var theNewRecord = theThis.addNewRecord(selectedSupplierRecords[i]); supplierIds[i] = theNewRecord.data.supplierId; theThis.totalProcessedRecord++; // Increase processed record countBatch++; if (countBatch == 10) // 10 item in each batch break; // No need to continue, wait for next batch } if (countBatch == 0) { // End the batch, no more item to process theThis.instructionText = "Transfering progress completed"; theThis.instructionBackgroundColor = "#01DF01"; theThis.pnl_Instruction.update({instructionBackgroundColor : theThis.instructionBackgroundColor, instructionText : theThis.instructionText}); theThis.btn_Continue.setVisible(true); return false; } else if (theThis.totalProcessedRecord <= selectedSupplierRecords.length) { function transferSupplierNow(){ Ext.Ajax.request({ method: 'POST', url: '/Kounta/TransferSupplierBatchFromCTBtoMYOB', timeout: 1800000, params: { CTBSupplierIds : Ext.util.JSON.encode(supplierIds), MYOBHistoryId : theThis.MYOBHistoryTransactionRecord.MYOBHistoryId }, success : function(result, request) { var jsonData = Ext.util.JSON.decode(result.responseText); if (jsonData.message.IsSuccess) { if (jsonData.data.length > 0) { for (var i = 0; i < jsonData.data.length; i++) { var returnBatchMessage = jsonData.data[i]; if (returnBatchMessage.isSuccess) theThis.updateSupplierTransferingStatusBySupplierId(returnBatchMessage.supplierId, XERO_PROCESSING_STATUS.SUCCEED, returnBatchMessage.message); else theThis.updateSupplierTransferingStatusBySupplierId(returnBatchMessage.supplierId, XERO_PROCESSING_STATUS.FAILED, returnBatchMessage.message); } } theThis.transferSuppliersInBatch(); // Continue another batch (if have) } else { showErrorMessageWithEmailNotify(jsonData.message.Info); } }, failure : function(result, request) { showErrorNotification('Notice', 'Server unavailable!'); //theThis.updateSupplierTransferingStatus(theNewRecord.data.invoiceTransferingLogID, XERO_PROCESSING_STATUS.FAILED, "Server unavailable!"); } }); // End ajax } transferSupplierNow(); return true; } }, updateSupplierTransferingStatus : function(supplierTransferingLogID, theStatus, xeroTransferingMessage) { var theThis = this; theThis.getGrid().getStore().getById(supplierTransferingLogID).set('xeroProcessingStatus', theStatus); theThis.getGrid().getStore().getById(supplierTransferingLogID).set('xeroTransferingMessage', xeroTransferingMessage); }, updateSupplierTransferingStatusBySupplierId : function(supplierId, theStatus, xeroTransferingMessage) { var theThis = this; for (var i = 0; i < theThis.getGrid().getStore().getCount(); i++) { var theRecord = theThis.getGrid().getStore().getAt(i); if (theRecord.data.supplierId == supplierId) { theRecord.set('xeroProcessingStatus', theStatus); theRecord.set('xeroTransferingMessage', xeroTransferingMessage); break; } } }, addNewRecord : function(supplierRecord, quantity){ var theThis = this; var theStore = theThis.getGrid().getStore(); var newId = theStore.getCount(); var aNewRecord = new theThis.supplierTransferingLogRecord({ supplierTransferingLogID : newId, xeroSupplierId : '', supplierId : supplierRecord.data.supplierId, supplierName : supplierRecord.data.supplierName, abnNo : supplierRecord.data.abnNo, paymentTerm : supplierRecord.data.paymentTerm, accountNo : supplierRecord.data.accountNo, isActive : supplierRecord.data.isActive, website : supplierRecord.data.website, address : supplierRecord.data.address, contact : supplierRecord.data.contact, xeroProcessingStatus : XERO_PROCESSING_STATUS.PROCESSING }, newId); theStore.insert(theThis.getGrid().getStore().getCount(), aNewRecord); return aNewRecord; } }); Ext.reg('CTBXeroSupplierTransferingLogGrid', Ext.CTBXeroSupplierTransferingLogGrid); Ext.CTBXeroTransferSupplierWindow = Ext.extend(Ext.Window, { title: 'Export suppliers to Xero', layout: 'card', closeAction: 'hide', iconCls: 'icon-stock', expandOnShow: true, closable: true, resizable: true, modal: true, plain: true, minimizable: true, maximizable: true, monitorResize: true, width: 800, height: 500, activeItem : 0, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, pageSize: CTB.init.itemPerPage || 100, accountCode : '', selectedSupplierRecords : null, callback_AfterHide : null, setSelectedSupplierRecords : function(selectedSupplierRecords){ var theThis = this; theThis.selectedSupplierRecords = selectedSupplierRecords; }, listeners: { scope : this, 'beforehide': function(theThis){ }, 'beforeshow': function(theThis){ // Fit this window to the client browser screen with 90% fitWindowSize(theThis, 90); }, 'show': function(theThis){ theThis.layout.setActiveItem(theThis.pnl_XeroSupplierTransferingLogGrid); theThis.pnl_XeroSupplierTransferingLogGrid.loadData(); }, 'hide': function(theThis){ if (theThis.callback_AfterHide != null) { theThis.callback_AfterHide(); } } }, initComponent : function(){ var theThis = this; theThis.pnl_XeroSupplierTransferingLogGrid = new Ext.CTBXeroSupplierTransferingLogGrid({ dlg_Parent : theThis, callback_ContinueButtonClick : function(theStore) { // Reload the supplier grid theThis.hide(); } }); theThis.items = [ theThis.pnl_XeroSupplierTransferingLogGrid ]; // BUTTONS var myButtons = theThis.initButtons(); this.buttons = myButtons; this.initTools(); Ext.CTBXeroTransferSupplierWindow.superclass.initComponent.call(this); }, initButtons : function(){ var theThis = this; var buttons = [ /*theThis.btn_Cancel = new Ext.Button({ text: 'Cancel', iconCls : 'icon-cancel-large', scale : 'large', handler : function(){ theThis.hide(); } })*/ ]; return buttons; }, connectToXero : function(callbackFunction, customMessage){ var theThis = this; if (customMessage == null) customMessage = "Your access to Xero has been expired. Please reconnect."; if (theThis.dlg_ConnectToXero == null) { theThis.dlg_ConnectToXero = new Ext.CTBXeroConnectWindow({ callback_ContinueButtonClick : function() { // Continue the process if only there is a valid connection established theThis.dlg_ConnectToXero.hide(); if (callbackFunction != null) callbackFunction(); } }); } theThis.dlg_ConnectToXero.customMessage = customMessage; theThis.dlg_ConnectToXero.show(); } }); Ext.reg('CTBXeroTransferSupplierWindow', Ext.CTBXeroTransferSupplierWindow); var Enable_Xero_Supplier = true; Ext.onReady(function () { var loadMask = new Ext.LoadMask(Ext.getBody(), {msg:"Please wait..."}); var fm = Ext.form; // Get the Business department tab var pnl_Supplier = Ext.getCmp('pnl_Supplier'); var grid_Supplier = new Ext.CTBSupplierBrowserGrid({ region : 'center', title : 'Suppliers', margins : '10 15 10 15', border : false, readOnly : true, isFromImportDatabase : false, hideXeroTransferSuppliers : false, hideXeroShowExportedSuppliers : false, listeners : { afterrender : function(theThis){ theThis.loadData(); } } }); var pnl_SupplierLayout = new Ext.Panel({ layout: 'border', bodyCssClass : 'x-panel-whitebgcolor', border : false, defaults: { split: true, animFloat: false, autoHide: false, useSplitTips: true }, items : [grid_Supplier] }); pnl_Supplier.add(pnl_SupplierLayout); pnl_Supplier.doLayout(); }); // End Ext.Ready /* * show a window for the user to conduct exporting * Created: 09 April 2015 by Andy C */ Ext.CTBRecipeMenuTransferPanel = Ext.extend(Ext.Panel, { //title: 'Select Recipe Menu to Export', width: 500, height: 300, layout: 'border', initComponent: function() { this.recipeMenuGrid = this.getRecipeMenuPanel(); this.items = this.recipeMenuGrid; this.ctbCountaSelectSitesWindow = new Ext.CTBKountaSelectSiteWindow(); //this.bbar = this.getButtons(); Ext.CTBRecipeMenuTransferPanel.superclass.initComponent.call(this); }, listeners: { afterrender: function() { this.loadMask = new Ext.LoadMask(this.getEl(), {msg:"Please wait..."}); this.recipeMenuGrid.loadData(); } }, getRecipeMenuPanel: function() { var theThis = this; var recipeRecord = new Ext.data.Record.create([ { name: 'recipeId', type: 'number' }, { name: 'recipeName', type: 'string' }, { name: 'menuSellingPrice', type: 'number' }, { name: 'recipeMenuId', type: 'number' }, { name: 'recipeMenuName', type: 'string' }, { name: 'menuHeading', type: 'string' }, { name: 'recipeMediaId', type: 'number' }, { name: 'isRecipeActive', type: 'boolean' }, //below two fields are used to show the result { name: 'result', type: 'boolean'}, { name: 'message', type: 'string' } ]); var store = new Ext.data.GroupingStore({ proxy: new Ext.data.HttpProxy({ url: '/RecipeMenu/GetRecipeMenuDetailsFromCTB', dataType: 'json', method: 'POST' }), reader: new Ext.data.JsonReader({ fields: recipeRecord, root: 'data', idProperty: 'recipeId', totalProperty : 'totalCount' }), autoLoad : false, groupField : 'recipeMenuId', listeners : { 'load' : function(store, records, options){ if(theThis.loadMask) theThis.loadMask.hide(); //console.log('data loaded.'); //for(var i=0; iDELETED'; else return ''; } }, { header: 'Price', width: 30, dataIndex: 'menuSellingPrice' }, { header: 'Menu Heading', width: 30, dataIndex: 'menuHeading' }, { header: 'Recipe Menu', dataIndex: 'recipeMenuId', width: 30, renderer: function(value, metaData, record) { return record ? record.data.recipeMenuName : value; } }, { header: 'Export Status', width: 30, dataIndex: 'result', renderer: function(value) { if(value) return 'Exported'; else return null; } }, { header: 'Export Message', width: 200, dataIndex: 'message'} ] }); var btnExport = new Ext.Button({ text: 'Export to Kounta', handler: function(btn) { if(!theThis.recipeMenuGrid) return; var resetStatus = true; var selected = theThis.recipeMenuGrid.getSelectedItems(resetStatus); //console.log('selected:' + selected); if(!selected.length) { showErrorNotification('Error','You have not selected any recipes to export.'); return; } else { //show a window to let the user select a site //this function is performed when signing in Kounta //theThis.showSelectSiteWindow(function(siteId) { theThis.ctbCountaSelectSitesWindow.showSelectSiteWindow(function(siteId, siteName) { var selectedrecipes = theThis.recipeMenuGrid.getSelectedItems(false); var data = Ext.encode(selectedrecipes); theThis.loadMask.show(); Ext.Ajax.request({ url: '/RecipeMenu/ExportRecipeMenuToKounta', method: 'POST', timeout: 1000 * 60 * 30, //30 minutes params: {data: data, siteId: siteId}, //params: {data: data}, success: function(response, request) { theThis.loadMask.hide(); //theThis.recipeMenuGrid.clearSelections(); //console.log(response.responseText); var jsonData = Ext.decode(response.responseText); if(jsonData.message.IsSuccess) { showSuccessNotification(jsonData.totalCount + ' recipe(s) have been exported to Kounta.'); if(jsonData.data.length > 0) { var store = theThis.recipeMenuGrid.getStore(); var data = jsonData.data; for(var i=0; i 1 ? "Items" : "Item"]})' }), viewConfig: { forceFit: true}, loadData: function() { if(theThis.loadMask) theThis.loadMask.show(); store.load(); } }); grid.getSelectedItems = function(resetStatus) { var result = []; var selected = this.getSelectionModel().getSelections(); if(selected.length > 0) { for(var i=0; i