commonModule.directive('animationEnd', function () {
    return {
        restrict: 'A',
        scope: {
            animationEnd: '&'
        },
        link: function(scope, element) {
            var events = 'animationend webkitAnimationEnd';

            element.on(events, function (event) {
                if (_.isFunction(scope.animationEnd)) {
                    scope.animationEnd({
                        '$event': event
                    });
                }
            });
        }
    };
});
angular.module('mc.resizer', []).directive('resizer', ['$document', function ($document) {

    return function ($scope, $element, $attrs) {

        $element.on('mousedown', function (event) {
            event.preventDefault();

            $document.on('mousemove', mousemove);
            $document.on('mouseup', mouseup);
        });

        function mousemove(event) {

            if ($attrs.resizer == 'vertical') {
                // Handle vertical resizer
                var x = event.pageX;

                if ($attrs.resizerMax && x > $attrs.resizerMax) {
                    x = parseInt($attrs.resizerMax);
                }

                $element.css({
                    left: x + 'px'
                });

                $($attrs.resizerLeft).css({
                    width: x + 'px'
                });
                $($attrs.resizerRight).css({
                    left: (x + parseInt($attrs.resizerWidth)) + 'px'
                });

            } else {
                // Handle horizontal resizer
                var y = window.innerHeight - event.pageY;

                //������ʱʹ��Ĭ��ֵ,Ĭ��ֵΪ resizer �ָ�������ؼ��Ĺ�ͬ���ؼ��ĸ߶ȼ�ȥ resizer �ĸ߶�
                var bottomMax = $($attrs.resizerTop).parent().height() - parseInt($attrs.resizerHeight);
                var customBottomMAx = parseInt($attrs.bottomMax);
                bottomMax = (isNaN(customBottomMAx) || customBottomMAx > bottomMax) ? bottomMax : customBottomMAx;

                if (y > bottomMax) {
                    y = bottomMax;
                }
                
                var bottomMin = $attrs.bottomMin ? parseInt($attrs.bottomMin) : 0;
                if (y < bottomMin) {
                    y = bottomMin;
                }

                if ($attrs.icon && $attrs.iconDiff) {
                    var diff = parseInt($attrs.iconDiff);
                    $('#' + $attrs.icon).css({
                        bottom: (y - diff) + 'px'
                    });
                }

                $element.css({
                    bottom: y + 'px'
                });

                $($attrs.resizerTop).css({
                    bottom: (y + parseInt($attrs.resizerHeight)) + 'px'
                });

                $($attrs.resizerBottom).css({
                    height: y + 'px'
                });
            }
        }

        function mouseup() {
            $document.unbind('mousemove', mousemove);
            $document.unbind('mouseup', mouseup);
        }
    };
}]);
/*
 * @description:
 * scroll specified element to top when item clicked
 * 
 * @usage:
 * <div ris-back-to-top="#elementid">
 * 
 */
commonModule.directive("risBackToTop", function () {
    'use strict';
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            element.on("click", function () {
                $(attr.risBackToTop).animate({ scrollTop: 0 }, "slow");
            });
        }
    };
});
commonModule.directive('risDatepickerPopup', function () {
    return {
        restrict: 'EAC',
        require: 'ngModel',
        link: function (scope, element, attr, controller) {
            //remove the default formatter from the input directive to prevent conflict
            controller.$formatters.shift();
        }
    }
})
/*
focus on element when event is triggered.

usage:
<textarea id="newNoteTextArea" csd-focus-on="eventName"></textarea>
*/

commonModule.directive('risFocusOn', ['$timeout', function ($timeout) {
    'use strict';

    return function (scope, elem, attr) {
        scope.$on(attr.risFocusOn, function () {
            $timeout(function () {
                elem[0].focus();
            }, 500);
        });
    };
}]);
/*
 * @description:
 * only can input number [0-9] string and backspace, 
 * but Allow: backspace, delete, tab, escape, enter, Ctrl+A, home, end, left, right
 * 
 * @usage:
 * <div ris-input-number-string>
 * 
 */

commonModule.directive("risInputNumberString", function () {
    'use strict';
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on("keydown", function (e) {
                // Allow: backspace, delete, tab, escape, enter and .
                if (_.contains([46, 8, 9, 27, 13, 110], e.keyCode) ||
                    // Allow: Ctrl+A
                    e.ctrlKey === true && _.contains([65, 67, 86, 88], e.keyCode) ||
                    // Allow: home, end, left, right
                    (e.keyCode >= 35 && e.keyCode <= 39)) {
                    // let it happen, don't do anything
                    return;
                }
                // Ensure that it is a number and stop the keypress
                if ((e.shiftKey || (e.keyCode < 48 || e.keyCode > 57)) && (e.keyCode < 96 || e.keyCode > 105)) {
                    e.preventDefault();
                }
            });
            element.on("paste", function (e) {
                var text = (e.originalEvent || e).clipboardData.getData('text/plain');
                if (text && !text.match(new RegExp("^\\d*$"))) {
                    e.preventDefault();
                }
            });
            element.on("change", function () {
                if (attrs.risInputNumberString === 'LargerThanZero' && this.value === '0') {
                    this.value = '';
                }
            });
            element.on("dragenter", function () {
                return false;
            });
            element.on("dragover", function () {
                return false;
            });
            element.on("dragleave", function () {
                return false;
            });
            element.on("drop", function (e) {
                e.preventDefault();
                return false;
            });
        }
    };
});
/*
* @description:

* @usage:
* <tr ris-repeat-done="items_done" ng-repeat="item in items">
*/
commonModule.directive('risRepeatDone', ['$timeout', function ($timeout) {
    return {
        restriction: 'A',
        link: function ($scope, element, attr) {
            if ($scope.$last) {
                $timeout(function () {
                    $scope.$emit(attr.risRepeatDone || "repeat_done", element);
                });
            }
        }
    }
}]);
/*
 * @description:
 * expand detail panel for a table row
 * 
 * @usage:
 *  <table data-template-url="app/insurance/views/patient-claims-detail-view.html" 
 *     [data-ris-table-expand="single"] [data-onload="loadClaimDetail"] [data-apply-on="PatientClaim:RepeatDone"]>
 * 
 */

commonModule.directive('risTableExpand', ['$http', '$templateCache', '$compile', '$timeout',
    function ($http, $templateCache, $compile, $timeout) {
        'use strict';

        return {
            restrict: 'A',
            link: function (scope, element, attr) {

                var scrollIntoView = function (id) {
                    if ($('#' + id).prev().length > 0) {
                        $('#' + id).prev()[0].scrollIntoView();
                    }
                }

                var apply = function () {
                    // gernarate uniq id for each tr element except header
                    // and remove before attach click handler
                    element.find("tbody > tr").uniqueId().off('click', expand).on('click', expand);
                }

                var expand = function () {
                    var self = this;
                    var $this = $(this);
                    var id = $this.attr('id');

                    // handle with just open one row.
                    if (attr.risTableExpand === "single") {
                        // close other opend row
                        element.find('.csd-expanded-row').not('.' + $this.attr('id')).hide();
                        element.find('.csd-selected-row').not('#' + $this.attr('id')).removeClass('csd-selected-row');
                    }

                    // find expand detail
                    var detail = element.find('.' + id);
                    // if can't find then init the detail panel
                    if (!detail.length) {
                        // find click row scope by element
                        var rowScope = angular.element(self).scope();
                        // attach hide fn
                        rowScope.hide = function () { $this.trigger('click'); }
                        // execute pre data load fn if existing
                        attr.onload && scope[attr.onload](rowScope);
                        // load and cache template
                        $http.get(attr.templateUrl, { cache: true }).success(function (template) {
                            // complie template with row scope
                            var rowDetail = $compile(template)(rowScope);
                            // insert after row
                            $this.addClass('csd-selected-row').after(rowDetail.addClass('csd-expanded-row ' + id));
                            scrollIntoView(id);
                        });
                    } else {
                        // already existing, normaly toggle open and close
                        detail.toggle('fast');
                        $this.toggleClass('csd-selected-row');

                        if (detail.is(":visible")) {
                            scrollIntoView(id);
                        }
                    }

                    scope.$emit('table-row-expanded');
                }

                // apply fn by event or default [table renderd]
                if (attr.applyOn) {
                    scope.$on(attr.applyOn, apply);
                } else {
                    $timeout(apply, 500);
                }
            }
        };
    }]);
/*
 angular-tablesort v1.0.4
 (c) 2013 Mattias Holmlund, http://mattiash.github.io/angular-tablesort
 License: MIT
*/

commonModule.directive('risTableSortWrapper', ['$log', '$parse', function ($log, $parse) {
    'use strict';
    return {
        scope: true,
        controller: ['$scope', function ($scope) {
            $scope.sortExpression = [];
            $scope.headings = [];

            var parse_sortexpr = function (expr) {
                return [$parse(expr), null, false];
            };

            this.setSortField = function (sortexpr, element) {
                var i;
                var expr = parse_sortexpr(sortexpr);
                if ($scope.sortExpression.length === 1
                    && $scope.sortExpression[0][0] === expr[0]) {
                    if ($scope.sortExpression[0][2]) {
                        element.removeClass("tablesort-desc");
                        element.addClass("tablesort-asc");
                        $scope.sortExpression[0][2] = false;
                    }
                    else {
                        element.removeClass("tablesort-asc");
                        element.addClass("tablesort-desc");
                        $scope.sortExpression[0][2] = true;
                    }
                }
                else {
                    for (i = 0; i < $scope.headings.length; i = i + 1) {
                        $scope.headings[i]
                            .removeClass("tablesort-desc")
                            .removeClass("tablesort-asc");
                    }
                    element.addClass("tablesort-asc");
                    $scope.sortExpression = [expr];
                }
            };

            this.addSortField = function (sortexpr, element) {
                var i;
                var toggle_order = false;
                var expr = parse_sortexpr(sortexpr);
                for (i = 0; i < $scope.sortExpression.length; i = i + 1) {
                    if ($scope.sortExpression[i][0] === expr[0]) {
                        if ($scope.sortExpression[i][2]) {
                            element.removeClass("tablesort-desc");
                            element.addClass("tablesort-asc");
                            $scope.sortExpression[i][2] = false;
                        }
                        else {
                            element.removeClass("tablesort-asc");
                            element.addClass("tablesort-desc");
                            $scope.sortExpression[i][2] = true;
                        }
                        toggle_order = true;
                    }
                }
                if (!toggle_order) {
                    element.addClass("tablesort-asc");
                    $scope.sortExpression.push(expr);
                }
            };

            this.registerHeading = function (headingelement) {
                $scope.headings.push(headingelement);
            };

            $scope.sortFun = function (a, b) {
                var i, aval, bval, descending, filterFun;
                for (i = 0; i < $scope.sortExpression.length; i = i + 1) {
                    aval = $scope.sortExpression[i][0](a);
                    bval = $scope.sortExpression[i][0](b);
                    filterFun = b[$scope.sortExpression[i][1]];
                    if (filterFun) {
                        aval = filterFun(aval);
                        bval = filterFun(bval);
                    }
                    if (_.isUndefined(aval) || _.isNull(aval)) {
                        aval = "";
                    }
                    if (_.isUndefined(bval) || _.isNull(bval)) {
                        bval = "";
                    }
                    descending = $scope.sortExpression[i][2];
                    if (aval > bval) {
                        return descending ? -1 : 1;
                    }
                    else if (aval < bval) {
                        return descending ? 1 : -1;
                    }
                }
                return 0;
            };
        }]
    };
}]);

commonModule.directive('risTableSortCriteria', function () {
    return {
        require: "^risTableSortWrapper",
        link: function (scope, element, attrs, tsWrapperCtrl) {
            var clickingCallback = function (event) {
                scope.$apply(function () {
                    if (event.shiftKey) {
                        tsWrapperCtrl.addSortField(attrs.risTableSortCriteria, element);
                    }
                    else {
                        tsWrapperCtrl.setSortField(attrs.risTableSortCriteria, element);
                    }
                });
            };
            element.bind('click', clickingCallback);
            element.addClass('tablesort-sortable');
            if ("risTableSortDefault" in attrs && attrs.risTableSortDefault !== "0") {
                tsWrapperCtrl.addSortField(attrs.risTableSortCriteria, element);
                if (attrs.risTableSortDefault === "descending") {
                    tsWrapperCtrl.addSortField(attrs.risTableSortCriteria, element);
                }
            }
            tsWrapperCtrl.registerHeading(element);
        }
    };
});

commonModule.directive("risTableSortRepeat", ['$compile', function ($compile) {
    return {
        terminal: true,
        require: "^risTableSortWrapper",
        priority: 1000000,
        link: function (scope, element, attr) {
            var repeatExpr = element.attr("ng-repeat") || attr.ngRepeat;
            repeatExpr = repeatExpr.replace(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(\s+track\s+by\s+[\s\S]+?)?\s*$/,
                "$1 in $2 | tablesortOrderBy:sortFun$3");
            element.removeAttr("ris-table-sort-repeat");
            element.attr("ng-repeat", repeatExpr);
            $compile(element)(scope);
        }
    };
}]);

commonModule.filter('tablesortOrderBy', function () {
    return function (array, sortfun) {
        if (!array)
            return;
        var arrayCopy = [];
        for (var i = 0; i < array.length; i++) {
            arrayCopy.push(array[i]);
        }
        return arrayCopy.sort(sortfun);
    };
});

commonModule.filter('parseInt', function () {
    return function (input) {
        return parseInt(input);
    };
});

commonModule.filter('parseFloat', function () {
    return function (input) {
        return parseFloat(input);
    };
});
/*
sticky table header
*
usage:
*  <div data-ris-table-sticky-header style="max-height: 170px; overflow-x: hidden; overflow-y: auto; margin-bottom: 10px;">
*           <table id="transactions" class="csd-table csd-col8-right" style="display: table;">
*                <thead>
*                    <tr>
*/
commonModule.directive("risTableStickyHeader", ['$log', '$timeout', function ($log, $timeout) {
    'use strict';

    return function (scope, element, attrs) {
        // auto scroll
        if (attrs.scrollOn) {
            scope.$on(attrs.scrollOn, function (event, args) {
                // 35 for sticky header height
                element.scrollTop(element.scrollTop() - 35 + element.find('#' + args.target).closest('tr').position().top);
            });
        }

        $timeout(function () {
            element.find('table').floatThead({
                scrollContainer: function () {
                    return element;
                }
            });
        }, 1000);
    }
}]);
commonModule.filter('risTextHighlight', function() {
    // create highlight bit map, highlighted character will be marked value as 'true'
    // for example, {0: false, 1: true, 2: true}
    var buildHighlightMap = function(text, searchString) {
        var searchTermArray = searchString.trim().split(/\s+/gi);

        var highlightMap = {};
        for (var i = 0; i < text.length; i++) {
            // set all as 'false' by default
            highlightMap[i] = false;
        }

        var lowerCaseText = text.toLowerCase();
        searchTermArray.forEach(function(term) {
            var startIndex = -1;
            do {
                startIndex = lowerCaseText.indexOf(term.toLowerCase(), startIndex + 1);
                if (startIndex !== -1) {
                    for (var k = startIndex; k < startIndex + term.length; k++) {
                        highlightMap[k] = true;
                    }
                } else {
                    break;
                }
            } while ((startIndex + term.length) <= text.length);
        });

        return highlightMap;
    };

    // split the text to be slices by hightlighted text. 
    // for example, text = 'James', searchString = 'ame'. textSliceArray will be [{'J', false}, {'ame', true}, {'s', false}]  
    var splitTextByHighlightedText = function(text, highlightMap) {
        // append a flag for the ending
        highlightMap[text.length] = !highlightMap[text.length - 1];
        var textSliceArray = [];
        var highlightFlag = highlightMap[0];
        var textSiice = [];
        for (var j = 0; j <= text.length; j++) {
            if (highlightFlag !== highlightMap[j]) {
                textSliceArray.push({
                    value: textSiice.join(''),
                    highlight: highlightFlag
                });
                textSiice = [];
                highlightFlag = highlightMap[j];
            }
            if (j < text.length) {
                textSiice.push(text[j]);
            }
        };
        return textSliceArray;
    };

    var buildHighlightHTML = function(text, highlightMap) {
        var textSliceArray = splitTextByHighlightedText(text, highlightMap);
        var highlightedHTML = '';
        _.each(textSliceArray, function(textSlice) {
            highlightedHTML += textSlice.highlight ? ('<span class="search-text-highlight">' + _.escape(textSlice.value) + '</span>') : _.escape(textSlice.value);
        });
        return highlightedHTML;
    };

    var buildSSNHighlightHTML = function(text) {
        // for SSN display ***-**-**** and show text as tooltip
        return '<span class="search-text-highlight" title="' + text + '">***-**-****</span>';
    };

    return function(text, searchString, isSSN) {
        /// <summary>
        /// Filter to highlight text. This filter will return html, so it will work with 'ng-bind-html'.
        /// This filter also depends on css class '.search-text-highlight' for the highlight style.
        /// @example,
        /// <span ng-bind-html="item.value | risTextHighlight : highlightTexts"></span>
        /// <span ng-bind-html="item.value | risTextHighlight : highlightTexts : item.name==='SSN'"></span>
        /// </summary>
        /// <param name="text">text to be highlighted</param>
        /// <param name="searchString">search string which can contain multiple terms with a space ' '.</param>
        /// <param name="isSSN">indicate if the text is SSN</param>
        /// <returns type="">formatted html for highlighting</returns>
        if ((text || angular.isNumber(text)) && (searchString || angular.isNumber(searchString))) {

            text = text.toString();
            searchString = searchString.toString();

            if (isSSN) {
                return buildSSNHighlightHTML(text);
            }

            // normal case to highlight matched characters
            var highlightMap = buildHighlightMap(text, searchString);
            var hasMatchedText = _.contains(highlightMap, true);

            if (hasMatchedText) {
                return buildHighlightHTML(text, highlightMap);
            } else {
                return _.escape(text);
            }
        } else {
                return _.escape(text);
        }
    };
});
// Directive for truncating the text and show whole text as tooltip if it is truncated.
// Notice that this directive is working with the '.text-truncate' style class.
// .text-truncate {
//   /*max-width: 200px;*/
//   white-space: nowrap;
//   overflow: hidden;
//   text-overflow: ellipsis;
//   display:inline-block;
// }
// @example,
// - truncate the tab.tabName if its width is greater than 150px. The max-width will be specifed by the value of this directive. 
//   NOTE: specify the max-width in this directive is NOT recommended and may be removed! Please specify it in the css file.
//   <span ris-text-truncate="150px">{{tab.tabName}}</span>
// - the value of max-width is optional, if you already have width or max-width set on the element.
//   <span ris-text-truncate>{{tab.tabName}}</span>
// - in case you do not want to show default tooltip, specify the attribute 'disable-truncate-tooltip ="false"'
//   <span ris-text-truncate="150px" disable-truncate-tooltip="true">{{tab.tabName}}</span>
// - 'truncate-tooltip' can be specified for tooltip content in case the text and tooltip is different or other specical cases.
//   <span ris-text-truncate="150px" truncate-tooltip="tooltip content">{{tab.tabName}}</span>
commonModule.directive('risTextTruncate', ['$log',
function ($log) {
    'use strict';

    $log.debug('risTextTruncate.ctor()...');

    // Runs during compile
    return {
        scope: true, // {} = isolate, true = child, false/undefined = no change // conflict with translate -> multiple directives asking for isolated scope
        restrict: 'A', // E = Element, A = Attribute, C = Class, M = Comment
        link: function ($scope, iElm) {
            var maxWidthWithUnit = iElm.attr('ris-text-truncate');
            if (maxWidthWithUnit) {
                iElm.css('max-width', maxWidthWithUnit);
                // ris-text-truncate: max-width should be set by CSS file on the HTML element, not by the value of "ris-text-truncate"!
            }

            // set 'text-truncate' class to current element
            iElm.addClass('text-truncate');

            // show whole text as tooltip if text is truncated.
            var disableTruncateTooltip = iElm.attr('disable-truncate-tooltip');
            if (!disableTruncateTooltip) {
                iElm.on('mouseover', function () {
                    var jqThis = $(this);
                    jqThis.css({ 'overflow': 'visible' });
                    if (this.scrollWidth > this.offsetWidth) {
                        var tooltipText = iElm.attr('truncate-tooltip');
                        if (!angular.isString(tooltipText) && !angular.isNumber(tooltipText)) {
                            tooltipText = jqThis.text();
                        }

                        if (jqThis.attr('data-original-title') !== tooltipText) {
                            jqThis.attr('data-original-title', tooltipText);
                            jqThis.tooltip({
                                placement: 'bottom',
                                container: 'body'
                            });
                            jqThis.tooltip('show');
                        }
                    } else {
                        jqThis.attr('data-original-title', '');
                        jqThis.tooltip('hide');
                    }
                    jqThis.css({ 'overflow': 'hidden' });
                });
            }
        }
    };
}
]);
// Account select tree view, select multiple accounts with checkboxes
commonModule.directive('accountMultiSelector', ['$log', '$translate',
    function ($log, $translate) {
        'use strict';
        $log.debug('accountMultiSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/account-multi-selector/account-multi-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                accountDataSource: '=*',
                isShow: '=',
                selectedAccountCodes: '=',
                title: '=',
                isSingleMode: '=?',
                selectorOptions: '=?',
                selectorApi: '=?' // In: onSelectorClose, onSelectorConfirm; Out: getGridInstance
            },
            link: function (scope, element) {
                scope.columnDefs = [{
                    caption: $translate.instant('SubjectCode'),
                    dataField: 'code',
                    isIdentity: true
                }, {
                    caption: $translate.instant('SubjectName'),
                    dataField: 'name'
                }, {
                    caption: $translate.instant('SubjectDirection'),
                    dataField: 'directionName'
                }, {
                    caption: $translate.instant('SubjectType'),
                    dataField: 'AcctPropName'
                }, {
                    visible: false,
                    dataField: 'parentCode',
                    isParentKey: true
                }];

                scope.parentCheckable = true;
            }
        };
    }
]);
commonModule.
controller('accountSelectorController', ['$scope',
    function ($scope) {
        $scope.selectedAccount = null;
        $scope.getSelectedAccountDisplayText = function () {
            if ($scope.selectedAccountCode != null) {
                return $scope.selectedAccountCode + '-' + $scope.selectedAccountName;
            }
            else {
                return '';
            }
        };
        $scope.selectAccount = function (account) {
            $scope.selectedAccountCode = account.code;
            $scope.selectedAccountName = account.name;
        };
    }
]);
// appDocumentTreeView
// Document tree view
commonModule.directive('accountSelector', ['$log',
    function ($log) {
        'use strict';
        $log.debug('accountSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/account-selector/account-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: { selectedAccountCode: '=',
                     stdAccountsCategories: '=',
                     selectedAccountName:'='},
            controller: 'accountSelectorController',
            link: function (scope, element) {
                element.find('.selector-input').on('focus', function () {
                    element.find('.account-tree-container').show();
                });
                $(document).on('click', function () {
                    element.find('.account-tree-container').hide();
                }).on('click', '.account-tree-wrapper', function (e) {
                    e.stopPropagation();
                });
            }
        };
    }
]);
commonModule.controller('accountVoucherGridFilterController', ['$scope', '$log', '$translate', '$timeout', 'apiInterceptor', 'Upload'
    , 'dataImportService', 'SweetAlert', '$q', 'uiGridConstants', 'projectService', 'uiGridGroupingConstants', 'enums'
    , 'vatImportService', 'i18nService', 'browserService', '$interval', 'region', 'vatSessionService', 'vatReductionService',
    function ($scope, $log, $translate, $timeout, apiInterceptor, Upload
        , dataImportService, SweetAlert, $q, uiGridConstants, projectService, uiGridGroupingConstants,enums
        , vatImportService, i18nService, browserService, $interval, region, vatSessionService, vatReductionService) {
        'use strict';
        $log.debug("accountVoucherGridFilterController  start.....");
        $log.debug($scope.enterpriseCode);
        $log.debug($scope.periodId);
        $log.debug($scope.selectedVouchers);
        
        function initGridView(periodId, accountCode) {
            var remapBatchId = !_.isUndefined($scope.reMapItem) ? $scope.reMapItem.remapBatchId : null;
            vatReductionService.getVouchersByConditions(periodId, accountCode, $scope.processTypeId, remapBatchId)
                .success(function (or) {
                    if (or.result) {
                        $scope.gridData = [];
                        $scope.gridData = or.data;
                        $log.debug($scope.gridData);                  
                        initGirdConfig();

                    }
                });
        }


        function initGirdConfig() {
            initGridFilter();         
            $("#gridOptions").dxDataGrid({
                dataSource: {
                    store: {
                        data: $scope.gridData,
                        type: "array",
                        key: 'voucherID'
                    }
                },
                allowColumnResizing: true,
                showRowLines: true,
                showColumnLines: true,
                rowAlternationEnabled: true, //单双行颜色
                showBorders: true,
                noDataText: $translate.instant('AccountVoucher_DataGrid_NoDataText'),
                scrolling: {
                    mode: "standard" //standard 设置为infinite或者virtual: paging配置将不可用
                },
                filterRow: {
                    visible: true,
                    applyFilter: "auto",
                    showOperationChooser:false //filterRow是否出现放大镜的筛选条件
                },
                searchPanel: {
                    visible: true,
                    width: 240,
                    placeholder: $translate.instant('Search'),
                },
                pager:{
                    allowedPageSizes: "auto",
                    visible: "auto"
                },
                paging:{
                    enabled: true,
                    pageIndex: 0,
                    pageSize: constant.page.pageSize
                },
                selection : {
                    mode: 'multiple',
                    allowSelectAll: false,  
                    selectAllMode: 'allPages',
                    showCheckBoxesMode: 'always',
                    deferred: true
                },
                selectionFilter: $scope.filterCondition, //使用filter来把$scope.selectedVouchers中的凭证勾选上            
                columns: [
                    {
                        alignment: "left",
                        dataField: "period",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColPeriod'),   
                        columnAutoWidth: true
                        //sortOrder: 'asc',
                        //sortIndex: 0
                    },
                    {
                        alignment: "center",
                        dataField: "date",
                        dataType: "date",
                        format: "yyyy-MM-dd",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColDate'),
                        columnAutoWidth: true
                        //sortOrder: 'asc',
                        //sortIndex: 1
                    },
                    {
                        dataField: "group",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColGroup'),
                        //sortIndex: 2,
                        //sortOrder: 'asc',
                        columnAutoWidth: true
                    },
                    {
                        dataField: "vid",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColVID'),
                        //sortIndex: 3,
                        //sortOrder: 'asc',
                        columnAutoWidth: true
                    },
                    {
                        dataField: "customerCode",
                        caption: $translate.instant('AccountVoucher_DataGrid_CustomerCode'),
                        columnAutoWidth: true
                    },
                    {
                        dataField: "summary",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColSummary'),
                        columnAutoWidth: true
                    },
                    {
                        dataField: "acctCodeAndNameShow",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColAcctCodeAndNameShow'),
                        columnAutoWidth: true
                    },
                    {
                        dataField: "stdCodeAndNameShow",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColStdCodeAndNameShow'),
                        columnAutoWidth: true
                    },
                    {
                        dataField: "debit",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColDebit'),
                        alignment: "right",
                        columnAutoWidth: true
                    },
                    {
                        dataField: "credit",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColCredit'),
                        alignment: "right",
                        columnAutoWidth: true
                    },
                    {
                        dataField: "vid",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColVID'),
                        alignment: "right",
                        columnAutoWidth: true,
                        visible: false
                    },
                    {
                        dataField: "voucherID",
                        caption: $translate.instant('AccountVoucher_DataGrid_VoucherID'),
                        alignment: "right",
                        columnAutoWidth: true,
                        visible: false
                    },
                    {
                        dataField: "itemID",
                        caption: $translate.instant('AccountVoucher_DataGrid_ItemID'),
                        alignment: "right",
                        columnAutoWidth: true,
                        visible: false
                    },
                    {
                        dataField: "mappingUser",
                        caption: $translate.instant('AccountVoucher_DataGrid_MappingUser'),
                        alignment: "right",
                        columnAutoWidth: true,
                        visible: false
                    },
                ],
                onSelectionChanged: function (selectedItems) {                            
                    $scope.gridInstance.getSelectedRowsData().done(function (rowData) {
                        $scope.selectedVouchers = rowData;
                    });                 
                },
                onContentReady: function () {                   
                    //setVoucherSelected();                  
                    $scope.gridInstance.getSelectedRowsData().done(function (rowData) {
                        $scope.selectedVouchers = rowData;
                    });
                },
                onCellPrepared: function (e) {
                                    
                    //新增状态时,已经做过凭证重分类的分录不能选择 
                    if ($scope.processTypeId === enums.processType.Add) {
                        if (e.rowType === "data" && e.column.command === 'select') {
                            var stdCode = e.row.data.stdCode;
                            var remapId = e.row.data.remapId;
                            if (!_.isNull(stdCode) && !_.isNull(remapId)) {
                                var instance = e.cellElement.find('.dx-select-checkbox').dxCheckBox("instance");
                                instance.option("disabled", true);
                                e.cellElement.off();
                            }                                                                                 
                        }
                    }     
                    
                    //编辑状态时:1) 没有重对应过的分录 2)当前重对应记录对应的分录可以 check/uncheck; 
                    //对应到'其他'重对应记录的分录'不可以' check/uncheck (其实这些分录都不会显示出来)
                    if ($scope.processTypeId === enums.processType.Edit) {
                        if (e.rowType === "data" && e.column.command === 'select') {
                            var stdCode = e.row.data.stdCode;
                            var remapId = e.row.data.remapId;
                            if (!_.isNull(stdCode) && !_.isNull(remapId) && !_.isNull($scope.reMapItem) && !_.isUndefined($scope.reMapItem)) {
                                var chkRepId = _.find($scope.reMapItem.remapIdes, function (num) { return num === remapId; });
                                if (_.isUndefined(chkRepId)) {
                                    var instance = e.cellElement.find('.dx-select-checkbox').dxCheckBox("instance");
                                    instance.option("disabled", true);
                                    e.cellElement.off();
                                }                                                        
                            }
                        }
                    }

                    
                }
            });         
        }


        //凭证重对应编辑时, 勾选已重对应的凭证
        function setVoucherSelected () {        
            if (!_.isNull($scope.selectedVouchers) && !_.isNull($scope.gridData)
                && $scope.selectedVouchers.length > 0 && $scope.gridData.length > 0) {
                var voucherIndexArray = [];
                var gridInstance = $('#gridOptions').dxDataGrid('instance');
                var pageIndex = gridInstance.pageIndex();
                var dataSource = gridInstance.option("dataSource");
                var pageData = _.chain(dataSource).rest(pageIndex * constant.page.pageSize).first(constant.page.pageSize).value()
                $scope.selectedVouchers.forEach(function (item, index) {
                    pageData.forEach(function (vdItem, vdIndex) {
                        if (_.isEqual(item.voucherID, vdItem.voucherID)) {                
                            voucherIndexArray.push(vdIndex);
                        }
                    });
                });         
                             
                $log.debug(pageData);           
                gridInstance.selectRowsByIndexes(voucherIndexArray);              
            }
        };


        //result example:
        //  [
        //    ["voucherID", "=", "DEAC1059-5088-469B-B0C8-3A5612E1DF63"], "or",
        //    ["voucherID", "=", "48F38499-762E-44D9-83A5-4FBFF8FA5A1A"], "or",
        //    ["voucherID", "=", "E6886487-927C-4CF5-A3E4-7F94A856184F"]
        //  ]
        function initGridFilter() {    
            $scope.filterCondition = [];
            $scope.selectedVoucherIds = _.map($scope.selectedVouchers, function (item) { return item.voucherID});
            $scope.selectedVoucherIds.forEach(function (item, index) {
                var tempFilter = ["voucherID", "=", item];
                if (index > 0) {
                    $scope.filterCondition.push("or");
                }
                $scope.filterCondition.push(tempFilter);             
            });

            $log.debug("initGridFilter");
            $log.debug($scope.filterCondition);
        }

        //开始
        (function initialize() {
            $scope.gridData = [];
            initGirdConfig();
            $scope.initGridView = initGridView;
            $scope.gridInstance = $('#gridOptions').dxDataGrid('instance');
            
        })();
    }
]);
commonModule.directive('accountVoucherGridFilter', ['$log',
    function ($log) {
        'use strict';
        $log.debug('vatParentCodeModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/account-voucher-grid-filter/account-voucher-grid-filter.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'accountVoucherGridFilterController',
            scope:
            {   
                isSearching: "=?",    
                periodId: '=?',
                enterpriseCode: '=?',
                selectedVouchers: "=?",
                processTypeId: "=?",
                reMapItem: "=?"
            },
            link: function ($scope, element) {       
                $scope.$watch("isSearching", function (newValue, oldValue) {
                        if (!_.isUndefined(newValue) && !_.isUndefined(oldValue)) {
                            if (!_.isEqual(newValue, oldValue) && newValue) {
                                $log.debug("start account-voucher-grid-filter.js watching: isSearching");             
                                $scope.initGridView($scope.periodId, $scope.enterpriseCode);                     
                            }
                        }                                      
                });                

            }
        };
    }
]);
commonModule.
controller('ackPaginationController', ['SweetAlert', '$scope', '$log', '$translate', '$location', '$timeout', '$interval', '$uibModal', '$document', 'InvoiceManageService',
    function (SweetAlert, $scope, $log, $translate, $location, $timeout, $interval, $uibModal, $document, InvoiceManageService) {

        //分页的设置
        $scope.pagingOptions = {
            pageIndex: $scope.pageOptions.pageIndex || 1,  //当前页码
            totalItems: $scope.pageOptions.totalItems || 0,  //总数据
            totalPages: $scope.pageOptions.totalPages || 0,//总页数
            maxSize: $scope.pageOptions.maxSize || 10, //分页数字的限制。
            pageSize: $scope.pageOptions.pageSize || constant.page.pageSizeArrary[1],  //每页多少条数据 
            pageSizeString: constant.page.pageSizeArrary[1].toString(),
            firstPage: '<<', //$translate.instant('PagingFirstPage'),
            previousPage: '<', //$translate.instant('PagingPreviousPage'),
            nextPage:'>',// $translate.instant('PagingNextPage'),
            lastPage: '>>', //$translate.instant('PagingLastPage'),
        };

        //赋值
        $scope.pageOptions = $scope.pagingOptions;
        $scope.hideSelector = $scope.hidePageSizeSelector ? true : false;

        var refreshDataTable = function () {
       
            if (_.isFunction($scope.refreshTable)) {
                $scope.refreshTable();
            }
        };

        //分页里面的处理
        $scope.pagingService = {
            //分页下拉组装
            populatePagingSelection: function () {
                var pagingSelection = [];
                var pageArray = constant.page.pageSizeArrary;
                for (var i = 0 ; i < pageArray.length; i++) {
                    var selection = { id: pageArray[i], value: pageArray[i] };
                    pagingSelection.push(selection);
                }
                $scope.pageOptions.pagingSelection = pagingSelection;
            },

            //分页的时候改变数字
            pageIndexChanging: function () {
                if ($scope.pageOptions.pageIndex > $scope.pageOptions.totalPages) {
                    $scope.pagingOptions.pageIndex = $scope.pageOptions.totalPages;
                }
                if ($scope.pageOptions.pageIndex <= 0) {
                    $scope.pageOptions.pageIndex = 1;
                }

                $log.log('Page changed to: ' + $scope.pageOptions.pageIndex);
                refreshDataTable();
            },

            //每页显示的数据下拉改变
            pageSizeSelectionChanged: function () {
                $scope.pageOptions.pageSize = parseInt($scope.pageOptions.pageSizeString);
                refreshDataTable();
            },
        };



        (function initialize() {
            $log.debug('ackPaginationController.ctor()...');

            $scope.pagingService.populatePagingSelection();
        
        })();
    }
]);

commonModule.directive('ackPagination', ['$log',
    function ($log) {
        'use strict'; 
        $log.debug('ackPagination.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/ack-pagination/ack-pagination.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'ackPaginationController',
            scope:
            {
                //pageIndex: '=?',
                //pageSize: '=?',
                //totalItems: '=?',
                //totalPages: '=?',
                pageOptions: '=?',
                refreshTable: '&',
                hidePageSizeSelector: '=?',
            }
        };
    }
]);
commonModule.
controller('addEnterpriseAccountModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', '$filter', 'SweetAlert', 'enterpriseAccountService', 'apiInterceptor', 'Upload',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, $filter, SweetAlert, enterpriseAccountService, apiInterceptor, Upload) {

        var modalSelector = '#addEnterpriceAccountSetPop';
        var uploadUrl = apiInterceptor.webApiHostUrl + '/enterpriseAccountManage/Upload';
        var resumable = true;

        var showWarning = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.warning(errMsg);
        };

        var showSuccessMsg = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.success(errMsg);
        };

        var showModal = function () {
            $(modalSelector).modal("show");
        };
        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {

                if (newValue == constant.Operation.Add) {
                    $scope.isAdd = true;
                    showModal();
                } else if (newValue == constant.Operation.Edit) {

                }
            }
        });

        $(".addEnterpriceAccountSetPop").on("hidden.bs.modal", function () {
            $scope.operateType = null;
        });

        $scope.closeModal = function () {
            $scope.operateType = null;
        };

        var hasDataUpdated = function () {
            $scope.operateType = null;
            $scope.isUpdate = true;
        };

        $scope.saveEnterpriseAccountSet = function () {

            resetErrorStatusSet();
            if (!($('#addEnterpriceAccountSetForm').valid())) {
                return false;
            }

            if ($scope.isAdd && !$scope.file) {
                SweetAlert.warning($translate.instant(resources.setfileRequired));
                return false;
            }

            enterpriseAccountSetOrgValidate();
            hasDataUpdated();
        };


        var importData = function () {
            if (!$scope.file || !$scope.file.name) {

                SweetAlert.info($translate.instant('SelectCustomerFileRequired'));
                return;
            }

            var tempFileName = PWC.newGuid() + '.dat';
            var token = $('input[name="__RequestVerificationToken"]').val();

            // if (!getEnterpriseAccountSetOrgListUI()) {
            //     return;
            // }

            // var orgList = $scope.editModel.saveOrgList;
            // var json = JSON.stringify(orgList);

            var enterpriseAccountSetID = $scope.isAdd ? '' : $scope.enterpriseAccountSetSelect().id;

            // updateProgressToZero();
            Upload.upload({
                url: uploadUrl,
                data: {
                    cancel: false,
                    filename: $scope.file.name,
                    tempFileName: tempFileName,
                    Remark: $scope.remark,
                    name: $scope.editModel.name,
                    // selectedOrgList: json,
                    enterpriseAccountSetID: enterpriseAccountSetID,
                    isImportAppend: $scope.isImportAppend,
                },
                file: $scope.file,
                resumeChunkSize: resumable ? $scope.chunkSize : null,
                headers: {
                    'Access-Control-Allow-Origin': '*',
                    Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken,
                    __RequestVerificationToken: token,
                    withCredentials: true
                },
                __RequestVerificationToken: token,
                withCredentials: true
            }).then(function (resp) {
                var ret = resp.data;
                if (ret.result) {

                    $scope.errList = [];
                    $scope.ImportErrorTag = false;
                    // 全部导入成功
                    $('#addEnterpriceAccountSetPop').modal('hide');
                    $('#importEnterpriceAccountSetPop').modal('hide');
                    if ($scope.isAdd) {
                        SweetAlert.success($translate.instant('AddSuccess'));
                    } else {
                        SweetAlert.success($translate.instant('ImportSuccess'));
                    }

                } else {

                    if (ret.resultMsg && ret.resultMsg.length > 0) {
                        SweetAlert.warning($translate.instant(ret.resultMsg));
                        //SweetAlert.swal($translate.instant(ret.resultMsg));
                        $scope.errList = [];
                        $scope.ImportErrorTag = false;
                    } else {
                        // 提示没有导入成功的数据
                        var codeNameList = [];

                        var errorInfo = $translate.instant('ImportErrorTips').format(ret.data.length);
                        $scope.errList = ret.data;
                        $scope.ImportErrorTag = true;

                        SweetAlert.swal({
                            title: $translate.instant('EnterpriceAccountManage'),
                            text: errorInfo,
                            type: "info",
                            showCancelButton: false,
                            closeOnConfirm: false,
                            closeOnCancel: true,
                            html: true
                        });

                    }
                }

            }, function (resp) {
                console.log('Error status: ' + resp.status);
            }, function (evt) {
                var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                $log.debug('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
            });
        };
        var setErrorStyle = function (error, element) {
            if (element.hasClass('has-error')) {
                element.parent().addClass('has-error');
                error.insertAfter(element);
                error.addClass('label');
            }
        };

        var saveEditEnterpriseAccountSet = function () {
            resetErrorStatusSet();
            if (!($('#addEnterpriceAccountSetForm').valid())) {
                return;
            }

            if ($scope.isAdd) {
                $scope.isImportAppend = false;
                importData();
            } else {

                // 有文件的修改
                if ($scope.file) {

                    SweetAlert.swal({
                        title: $translate.instant('ComfirmImportData'),
                        text: $translate.instant('EnterpriseAccountSetOverLayImportTips'),
                        type: "warning",
                        showCancelButton: true,
                        confirmButtonColor: "#DD6B55",
                        confirmButtonText: $translate.instant('Confirm'),
                        cancelButtonText: $translate.instant('Cancel'),
                        closeOnConfirm: false,
                        closeOnCancel: true
                    },
                        function (isConfirm) {
                            if (isConfirm) {
                                // 选中
                                importData();
                            }
                        });

                } else {
                    // 没有文件修改
                    var model = {
                        id: $scope.enterpriseAccountSetSelect().id,
                        name: $scope.editModel.name,
                        // enterpriseAccountSetOrgList: []
                    };

                    // if (!getEnterpriseAccountSetOrgListUI()) {
                    //     return;
                    // }

                    // model.enterpriseAccountSetOrgList = $scope.editModel.saveOrgList;

                    enterpriseAccountService.updateEnterpriseAccountSet(model).success(function (data) {
                        if (data && data.result) {
                            $('#addEnterpriceAccountSetPop').modal('hide');
                            loadEnterpriseAccountSetList();
                            SweetAlert.success($translate.instant('SaveSuccess'));
                        } else {
                            swal($translate.instant('SaveFail'), $translate.instant(data.resultMsg), 'warning');
                        }
                    });
                }
            }
        };

        var getEnterpriseAccountSetOrgListUI = function () {

            var enterpriseAccountSetOrgList = [];
            var isError = false;
            if ($scope.editModel.enterpriseAccountSetOrgList && $scope.editModel.enterpriseAccountSetOrgList.length > 0) {
                for (var i = 0; i <= $scope.editModel.enterpriseAccountSetOrgList.length - 1; i++) {
                    var row = $scope.editModel.enterpriseAccountSetOrgList[i];
                    var item = {
                        OrganizationID: row.organizationID,
                        EffectiveDateStr: row.effectiveDateStr,
                        ExpiredDateStr: row.expiredDateStr
                    };

                    if (!row.organizationID) {
                        SweetAlert.warning(resources.organizationRequired);

                        return false;
                    }

                    if (!row.effectiveDateStr) {
                        SweetAlert.warning(resources.effectiveDateRequired);
                        return false;
                    }

                    if (!row.expiredDateStr) {
                        SweetAlert.warning(resources.expiredDateRequired);
                        return false;
                    }

                    if (!validateDate(row.effectiveDateStr, row.expiredDateStr)) {
                        SweetAlert.warning($translate.instant('EffectiveDateAreaProblem'));
                        return false;
                    }

                    enterpriseAccountSetOrgList.push(item);
                };
            }

            $scope.editModel.saveOrgList = enterpriseAccountSetOrgList;
            return true;
        };

        var validateDate = function (from, to) {
            var fromDate = new Date(from + '-01');
            var toDate = new Date(to + '-01');
            toDate.setMonth(toDate.getMonth() + 1);
            toDate.setDate(toDate.getDate() - 1);

            if (fromDate <= toDate) {
                return true;
            } else {
                return false;
            }
        };

        // 验证机构唯一性
        var enterpriseAccountSetOrgValidate = function () {
            var model = {
                id: $scope.editModel.id,
                enterpriseAccountSetOrgList: []
            };

            if (!getEnterpriseAccountSetOrgListUI()) {
                return;
            }

            model.enterpriseAccountSetOrgList = $scope.editModel.saveOrgList;

            enterpriseAccountService.enterpriseAccountSetOrgValidate(model).success(function (data) {
                if (data && data.result) {
                    // 验证成功
                    saveEditEnterpriseAccountSet();
                } else {
                    if (data.data && data.data.length > 0) {
                        var orgNameList = [];
                        var i = 1;
                        data.data.forEach(function (row) {
                            orgNameList.push(i + '.' + $translate.instant('OrganizationName') + ':' + row.organizationName);
                            i++;
                        });

                        orgNameList = getLimitLogs(orgNameList);

                        var str = orgNameList.join('<br/>');

                        str = "<div class='text-left'>" + str + '</div>';

                        SweetAlert.swal({
                            title: $translate.instant(data.resultMsg),
                            text: str,
                            type: "warning",
                            showCancelButton: false,
                            confirmButtonColor: "#DD6B55",
                            confirmButtonText: $translate.instant('Confirm'),
                            cancelButtonText: $translate.instant('Cancel'),
                            closeOnConfirm: false,
                            closeOnCancel: false,
                            html: true
                        }
                             );

                    }
                }

            });
        };

        var resetErrorStatusSet = function () {
            var currentForm = $('#addEnterpriceAccountSetForm');
            $('#addEnterpriceAccountSetForm .has-error > label').remove();
            currentForm.find('.has-error').removeClass('has-error');
            validatorset.resetForm();
        };

        var resources = {
            codeRequired: $translate.instant('EnterpriceAccountCodeRequired'),
            nameRequired: $translate.instant('EnterpriceAccountNameRequired'),
            selectDirectionRequired: $translate.instant('StandardAccountRequired'),
            selectAcctPropRequired: $translate.instant('StandardAccountAccountTypesRequired'),
            setnameRequired: $translate.instant('EnterpriceAccountSetNameRequired'),
            setfileRequired: $translate.instant('EnterpriceAccountSetFileRequired'),
            enterpriseAccountSetNameRepeat: $translate.instant('EnterpriseAccountSetNameRepeat'),
            organizationRequired: $translate.instant('SelectOrganizationRequired'),
            effectiveDateRequired: $translate.instant('EffectiveDateRequired'),
            expiredDateRequired: $translate.instant('ExpiredDateRequired')
        };



        var validatorset = $("#addEnterpriceAccountSetForm").validate({
            errorClass: "has-error",
            rules: {
                name: {
                    required: true,
                    remote: {
                        type: "get",
                        url: apiInterceptor.webApiHostUrl + "/enterpriseAccountManage/enterpriseAccountSetNameValidate",
                        data: {
                            id: function () {
                                return $("#enterpriseAccountSetID").val();
                            },
                            name: function () {
                                return $("#enterpriseAccountSetName").val();
                            }
                        },
                        dataType: "json",
                        dataFilter: function (data, type) {

                            var ret = JSON.parse(data);
                            if (ret && ret.result)
                                return true;
                            else
                                return false;
                        }
                    }
                },
                fileName: {
                    // 把这条注释条, ng-required生效
                    // required: true
                },
                organization: {
                    // required: true
                },
                effectiveDate: {
                    // required: true
                },
                expiredDate: {
                    // required: true
                }

            },
            messages: {
                name: {
                    required: resources.setnameRequired,
                    remote: resources.enterpriseAccountSetNameRepeat
                },
                fileName: {
                    required: resources.setfileRequired
                },
                organization: {
                    required: resources.organizationRequired
                },
                effectiveDate: {
                    required: resources.effectiveDateRequired
                },
                expiredDate: {
                    required: resources.expiredDateRequired
                }

            },
            errorPlacement: function (error, element) {
                setErrorStyle(error, element);
            }
        });


        (function initialize() {
            $log.debug('addEnterpriseAccountModalController.ctor()...');
            // showModal();
        })();

    }
]);

commonModule.directive('addEnterpriseAccountModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('addExistUserModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/add-enterprise-account-modal/add-enterprise-account-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'addEnterpriseAccountModalController',
            scope:
            {
                operateType: '=',
                isUpdate: '=?'
            },
            link: function (scope, element) {


            }
        };
    }
]);
commonModule.
controller('addExistDimensionModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', '$filter', 'SweetAlert', 'roleService', 'userService', 'permissionService', 'dimensionService',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, $filter, SweetAlert, roleService, userService, permissionService, dimensionService) {

        $scope.searchValue = "";

        var modalSelector = '#addDimensionModal';

        var showWarning = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.warning(errMsg);
        };

        var showSuccessMsg = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.success(errMsg);
        };

        var showModal = function () {

            $scope.originalList = angular.copy($scope.selectedDimensionList);
            getDimensionList();
            $(modalSelector).modal("show");
        };

        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {

                if (newValue == constant.Operation.Add) {
                    showModal();
                } else if (newValue == constant.Operation.Edit) {

                }
            }
        });

        $(".addRoleModal").on("hidden.bs.modal", function () {
            $scope.operateType = null;
        });

        $scope.closeModal = function () {
            $scope.operateType = null;
        };

        $scope.Save = function () {
            //返回用户ID列表
            //console.log(JSON.stringify($scope.selectedRoleList));
            $scope.operateType = null;
            $scope.isUpdate = true;
            $(modalSelector).modal("hide");
        };


        var setSelectItems = function (data) {

            if ($scope.selectedDimensionList && $scope.selectedDimensionList.length > 0) {
                for (var i = 0; i < data.length; i++) {

                    if ($scope.selectedDimensionList.indexOf(data[i].id) > -1) {
                        data[i].selected = true;
                        data[i].expanded = true;
                    }

                    if (data[i].items && data[i].items.length > 0) {
                        setSelectItems(data[i].items);
                    }
                }
            }

            return data;
        };

        //获取维度列表
        var getDimensionList = function () {

            dimensionService.getDevDimensionTreeList().success(function (data) {
                if (data) {
                    var data = setSelectItems(data);
                    $scope.dimensionTreeViewData = data;
                }
            });
        };

        //var loadDimensionValueByID = function (dimensionID) {
        //    dimensionService.getDimensionValueList(dimensionID).success(function (data) {
        //        if (data) {
        //            //$scope.dimensionValueTreeViewData = data;
        //        }
        //    });
        //};

        $scope.searchOptions = {
            bindingOptions: {
                value: "searchValue"
            },
            placeholder: $translate.instant('Search'),
            width: 518,
            mode: "search",
            valueChangeEvent: "keyup"
        };

        //加载维度值配置
        //var loadDimensionValueTree = function () {
        //    $scope.dimensionValueTreeViewOptions = {
        //        bindingOptions: {
        //            dataSource: 'dimensionValueTreeViewData',
        //            searchValue: 'searchValue'
        //        },

        //        selection: {
        //            mode: "multiple"
        //        },

        //        loadPanel: {
        //            enabled: true
        //        },
        //        scrolling: {
        //            mode: "virtual"
        //        },
        //        keyExpr: "id",
        //        parentIdExpr: "parentID",
        //        showRowLines: true,
        //        showColumnLines: true,
        //        expandAllEnabled: true,
        //        rowAlternationEnabled: true,
        //        expandedRowKeys: [1],
        //        showBorders: true,
        //        noDataText: $translate.instant('NoDataText'),
        //        selectAllText: $translate.instant('SelectAll'),
        //        displayExpr: 'name',  //显示的属性名称,默认为text
        //        itemsExpr: 'subRoles',  //子层的数组名称,默认为items
        //        //scrollDirection:'vertical',  //Accepted Values: 'vertical' | 'horizontal' | 'both'
        //        selectNodesRecursive: true,  //级联选择
        //        showCheckBoxesMode: 'normal', //Accepted Values: 'none' | 'normal' | 'selectAll'
        //        onItemSelectionChanged: function (obj, element, model, node) {
        //            populateSelectedRole(obj.itemData);
        //        },
        //        onInitialized: function (e) {
        //            //$scope.widgetInstance = e.component;
        //        },
        //        //点击行,选中
        //        onItemClick: function (e) {
        //            //loadDimensionValueByID(e.itemData.id);
        //        },
        //        onContentReady: function (object, container) {
        //            object.element.find('.dx-checkbox-checked').addClass('dx-state-disabled');
        //        }
        //    };
        //};

        //加载维度配置
        var loadDimensionTree = function () {
            $scope.dimensionTreeViewOptions = {
                bindingOptions: {
                    dataSource: 'dimensionTreeViewData',
                    searchValue: 'searchValue'
                },

                selection: {
                    mode: "multiple"
                },

                loadPanel: {
                    enabled: true
                },
                scrolling: {
                    mode: "virtual"
                },
                keyExpr: "id",
                //parentIdExpr: "parentID",
                showRowLines: true,
                showColumnLines: true,
                expandAllEnabled: true,
                rowAlternationEnabled: true,
                expandedRowKeys: [1],
                showBorders: true,
                noDataText: $translate.instant('NoDataText'),
                selectAllText: $translate.instant('SelectAll'),
                //displayExpr: 'name',  //显示的属性名称,默认为text
                //itemsExpr: 'subRoles',  //子层的数组名称,默认为items
                //scrollDirection:'vertical',  //Accepted Values: 'vertical' | 'horizontal' | 'both'
                selectNodesRecursive: true,  //级联选择
                showCheckBoxesMode: 'normal', //Accepted Values: 'none' | 'normal' | 'selectAll'
                onItemSelectionChanged: function (obj, element, model, node) {
                    populateSelectedDimensionValueList(obj.itemData);
                },
                onInitialized: function (e) {
                    $scope.widgetInstance = e.component;
                },
                //点击行,选中
                onItemClick: function (e) {

                    //loadDimensionValueByID(e.itemData.id);
                },
                onItemRendered: function (e) {

                    var originalList = $scope.originalList;

                    if (e && e.itemData && originalList && originalList.length > 0) {

                        if (originalList.indexOf(e.itemData.id) > -1) {
                            e.itemElement.closest('li.dx-treeview-node').find('.dx-checkbox-checked').addClass("dx-state-disabled");
                        }

                        if (e.itemData.items && e.itemData.items.length>0) {
                            var subRoles = e.itemData.items;
                            var subRoleId = _.pluck(subRoles, 'id');
                            var hasCheckedAll = true;
                            for (var i = 0; i < originalList.length; i++) {
                                var hasFind = _.find(subRoleId, function (item) {
                                    return item.id == originalList[i].id;
                                });
                                if (!hasFind) {
                                    hasCheckedAll = false;
                                    break;
                                }
                            }
                            if (hasCheckedAll) {
                                e.itemElement.closest('li.dx-treeview-node').find('.dx-checkbox-checked').addClass("dx-state-disabled");
                            }
                        }
                    }
                }
                //onContentReady: function (object, container) {
                //    object.element.find('.dx-checkbox-checked').addClass('dx-state-disabled');
                //}
            };
        };

        //构造选中的维度值list
        var populateSelectedDimensionValueList = function (itemData) {

            var itemIndex = -1;

            if (itemData.selected) {
                if (itemData.parentId != null && itemData.parentId !== undefined) {
                    if ($scope.selectedDimensionList.indexOf(itemData.id) < 0) {
                        $scope.selectedDimensionList.push({
                            'parentID': itemData.parentId,
                            'id': itemData.id
                        });
                    } 
                } else {
                    itemData.items.forEach(function (x) {
                        if ($scope.selectedDimensionList.indexOf(x.id) < 0) {
                            $scope.selectedDimensionList.push({
                                'parentID': itemData.id, //当前选中节点的ID,也就是父级ID
                                'id': x.id   //叶子节点ID
                            });
                        }
                    });
                }
            } else if (!itemData.selected) {

                if (itemData.parentId != null && itemData.parentId !== undefined) {
                    $.each($scope.selectedDimensionList, function (index, item) {
                        if (item.id === itemData.id) {
                            $scope.selectedDimensionList.splice(index, 1);
                            return false;
                        }
                    });
                } else {
                    var parentID = itemData.id;
                    var cloneSelectedDimensionList = angular.copy($scope.selectedDimensionList);
                    var removeIndexList = [];

                    $.each(cloneSelectedDimensionList, function (index, item) {
                        itemData.items.forEach(function (x) {
                            if (item.id === x.id && item.parentID === parentID) {
                                removeIndexList.push(index);
                            }
                        });
                    });

                    //从后往前删除
                    for (var i = removeIndexList.length - 1; i >= 0; i--) {
                        $scope.selectedDimensionList.splice(removeIndexList[i], 1);
                    }

                    $scope.selectedDimensionList.forEach(function (item) {
                        $scope.widgetInstance.selectItem(item);
                    });
                }
            }
            console.log($scope.selectedDimensionList);
        };

        (function initialize() {
            $log.debug('addExistDimensionModalController.ctor()...');

            //loadDimensionValueTree();
            loadDimensionTree();
            // showModal();
        })();

    }
]);

commonModule.directive('addExistDimensionModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('addExistDimensionModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/add-exist-dimension-modal/add-exist-dimension-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'addExistDimensionModalController',
            scope:
            {
                operateType: '=',
                isUpdate: '=?',
                selectedDimensionList: '=?'
            },
            link: function (scope, element) {


            }
        };
    }
]);
commonModule.
controller('addExistOrganizationModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', '$filter', 'SweetAlert', 'orgService', 'userService',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, $filter, SweetAlert, orgService, userService) {
        $scope.gridInstance = null;
        var modalSelector = '#addOrgModal';

        var showWarning = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.warning(errMsg);
        };

        var showSuccessMsg = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.success(errMsg);
        };

        var showModal = function () {
            
            $scope.originalList = angular.copy($scope.selectedKeyItems);
            $scope.selectedOrgList = [];
            getOrgList();
            $(modalSelector).modal("show");
        };
        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {

                if (newValue == constant.Operation.Add) {
                    showModal();
                } else if (newValue == constant.Operation.Edit) {

                }
            }
        });

        $(".addOrgModal").on("hidden.bs.modal", function () {
            $scope.operateType = null;
            $scope.DataGridSource=[];
        });

        $scope.closeModal = function () {
            $scope.operateType = null;
            $scope.DataGridSource=[];
        };

        $scope.Save = function ()
        {
            //返回机构列表
            //console.log(JSON.stringify($scope.selectedOrgList));
            $scope.operateType = null;
            $scope.isUpdate = true;
            $scope.DataGridSource=[];
            $(modalSelector).modal("hide");
        };

        var setSelectItems=function(selectedKeyItems)
        {
            //设置选中
            $timeout(function () {
                $scope.gridInstance.clearSelection();
                if (selectedKeyItems && selectedKeyItems.length > 0) {
                    $scope.gridInstance.selectRows(selectedKeyItems, true);
                }
            }, 100); 
        };

        var getOrgList = function () {
            orgService.getOrgListLevel().success(function (data) {
                if (data) {
                    $scope.DataGridSource = data;

                    setSelectItems($scope.selectedKeyItems);
                }
            });
        };

        var loadDatagrid = function () {
            $scope.orgDataGridOptions = {
                bindingOptions: {
                    dataSource: 'DataGridSource'
                }, 
                columns: [
                        {
                            dataField: "name",
                            caption: $translate.instant('OrganizationName'),
                            width:200
                        },
                        {
                            dataField: "businessUnitName",
                            caption: $translate.instant('BusinessUnit')
                        },
                        {
                            dataField: "areaName",
                            caption: $translate.instant('AreaTitleName'),
                            width:100
                        },
                        {
                            dataField: "industryName",
                            caption: $translate.instant('PIndustry')
                        }
                ],

                loadPanel: {
                    enabled: true
                },
                scrolling: {
                    mode: "virtual"
                },
                keyExpr: "id",
                parentIdExpr: "parentID",
                selection: {
                    mode: "multiple",
                    showCheckBoxesMode: "always",
                    allowSelectAll: false
                },
                allowColumnResizing: true,
                columnAutoWidth: true,
                showRowLines: true,
                showColumnLines: true,
                autoExpandAll: true,
             
                rowAlternationEnabled: true,  //单双行颜色
                noDataText: $translate.instant('NoDataText'),
                showBorders: true,
                //sorting: {
                //    mode: "none"
                //},
                searchPanel: {
                    placeholder: $translate.instant('Search'),
                    width:518,
                    visible: true
                },
                onInitialized: function (e) {
                    $scope.gridInstance = e.component;
                },
                onSelectionChanged: function (e) {
                    //整个集合 List
                    var rowList = e.selectedRowsData;
                    $scope.selectedOrgList = rowList; 
                    //只有orgID List
                    var keyList = e.selectedRowKeys;
                    $scope.selectedKeyItems = keyList;

                },
                onRowPrepared: function (e) {
                    if (e && e.data) {
                        if ($scope.originalList.indexOf(e.data.id) > -1)
                        {
                            e.rowElement.addClass("dx-state-disabled");
                        }
                    }
                },
                onContentReady: function (e, container)
                {
                    //e.element.find('.dx-selection .dx-checkbox-checked').addClass('dx-state-disabled');
                    //e.element.find('.dx-selection').addClass('dx-state-disabled');
                    //e.element.find('.dx-selection .dx-checkbox-checked').addClass('dx-state-disabled');

                    //var $checkBox = $('.dx-header-row .dx-checkbox').first();
                    //$checkBox.on('dxclick', function (e) {
                    //    var isChecked = $checkBox.dxCheckBox('instance').option('value');
                    //    if (!isChecked)
                    //    {    //追加原始角色选中
                    //        if ($scope.originalList && $scope.originalList.length > 0)
                    //        {
                    //            setSelectItems($scope.originalList);
                    //        }
                    //    }
                    //});
                }
            };

        };

        (function initialize() {
            $log.debug('addExistOrganizationModalController.ctor()...');
        
            loadDatagrid();
           // showModal();
        })();
    }
]);

commonModule.directive('addExistOrganizationModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('addExistUserModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/add-exist-organization-modal/add-exist-organization-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'addExistOrganizationModalController',
            scope:
            {
                operateType: '=',
                isUpdate: '=?',
                selectedOrgList: '=?',
                selectedKeyItems: '=?'
            } ,
            link: function (scope, element) {
            }
        };
    }
]);
commonModule.
controller('addExistRoleModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', '$filter', 'SweetAlert', 'roleService', 'userService', 'permissionService',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, $filter, SweetAlert, roleService, userService, permissionService) {

        $scope.searchValue = "";

        var modalSelector = '#addRoleModal';
        $scope.allowUncheck = false;

        var showWarning = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.warning(errMsg);
        };

        var showSuccessMsg = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.success(errMsg);
        };

        var showModal = function () {
            // $scope.selectedRoleList = [];
            // $scope.selectedRoleList = ['1a22c719-9751-4a7c-a3b5-6bf333567970', '468AAF7D-268B-4ADF-A331-FF762C950EC6'];

            $scope.originalRoleList = angular.copy($scope.selectedRoleList);

            getDataList();
            initPermissionByRoleIDList($scope.selectedRoleList);
            $(modalSelector).modal("show");
        };
        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {
                reset();
                if (newValue == constant.Operation.Add) {
                    showModal();
                } else if (newValue == constant.Operation.Edit) {

                }
            }
        });

        var reset = function () {
            $scope.searchValue = '';
        };

        $(".addRoleModal").on("hidden.bs.modal", function () {
            $scope.operateType = null;
        });

        $scope.closeModal = function () {
            $scope.operateType = null;
        };

        $scope.Save = function () {
            //返回用户ID列表
            //console.log(JSON.stringify($scope.selectedRoleList));
            $scope.operateType = null;
            $scope.isUpdate = true;
            $(modalSelector).modal("hide");
        };


        var setSelectItems = function (roleData) {

            if ($scope.selectedRoleList && $scope.selectedRoleList.length > 0) {
                for (var i = 0; i < roleData.length; i++) {

                    if ($scope.selectedRoleList.indexOf(roleData[i].id) > -1) {
                        roleData[i].selected = true;
                        roleData[i].expanded = true;
                    }

                    if (roleData[i].subRoles && roleData[i].subRoles.length > 0) {
                        setSelectItems(roleData[i].subRoles);
                    }
                }
            }

            return roleData;
        };

        var getDataList = function () {

            roleService.getRoleListByServiceGroup().success(function (roleData) {
                if (roleData) {
                    var data = setSelectItems(roleData);
                    $scope.roleTreeViewData = data;
                }
            });
        };

        var initPermissionByRoleIDList = function (roleIDList)
        {
            permissionService.getDevTreePermissionsByRoleIDList(roleIDList, constant.serviceType.VAT).success(function (data) {
                if (data) {
                    $scope.permissionTreeViewData = data;
                }
            });

        };

        var loadPermissionByRoleID = function (roleID) {
            permissionService.getDevTreePermissionsByRoleID(roleID, constant.serviceType.VAT).success(function (data) {
                if (data) {
                    $scope.permissionTreeViewData = data.permissionDevTreeList;
                }
            });
        };

        $scope.searchOptions = {
            bindingOptions: {
                value: "searchValue"
            },
            placeholder: $translate.instant('Search'),
            width: 518,
            mode: "search",
            valueChangeEvent: "keyup"
        };

        var loadPermissionTree = function () {
            $scope.permissionTreeViewOptions = {
                bindingOptions: {
                    dataSource: 'permissionTreeViewData',
                    searchValue: 'searchValue'
                },
                dataStructure: "plain",
                selection: {
                    mode: "single"
                },
                loadPanel: {
                    enabled: true
                },
                scrolling: {
                    mode: "virtual"
                },
                keyExpr: "id",
                // parentIdExpr: "pLevel",

                showRowLines: true,
                showColumnLines: true,
                rowAlternationEnabled: true,
                showBorders: true,
                noDataText: $translate.instant('NoDataText'),
                selectAllText: $translate.instant('SelectAll')
            };
        };

        var loadRoleTree = function () {
            $scope.roleTreeViewOptions = {
                bindingOptions: {
                    dataSource: 'roleTreeViewData',
                    searchValue: 'searchValue'
                },
                selection: {
                    mode: "multiple"
                },

                loadPanel: {
                    enabled: true
                },
                scrolling: {
                    mode: "virtual"
                },
                keyExpr: "id",
                parentIdExpr: "parentID",
                showRowLines: true,
                showColumnLines: true,
                expandAllEnabled: true,
                rowAlternationEnabled: true,
                expandedRowKeys: [1],
                showBorders: true,
                noDataText: $translate.instant('NoDataText'),
                selectAllText: $translate.instant('SelectAll'),
                displayExpr: 'name',  //显示的属性名称,默认为text
                itemsExpr: 'subRoles',  //子层的数组名称,默认为items
                //scrollDirection:'vertical',  //Accepted Values: 'vertical' | 'horizontal' | 'both'
                selectNodesRecursive: true,  //级联选择
                showCheckBoxesMode: 'normal', //Accepted Values: 'none' | 'normal' | 'selectAll'
                onItemSelectionChanged: function (obj, element, model, node) {

                    populateSelectedRole(obj.itemData);
                },
                onInitialized: function (e) {
                    $scope.widgetInstance = e.component;
                },
                //点击行,选中
                onItemClick: function (e) {

                    loadPermissionByRoleID(e.itemData.id);
                },
                onItemRendered: function (e) {

                    if ($scope.allowUncheck) { return;}

                    var originalRoleList = $scope.originalRoleList;

                    if (e && e.itemData && originalRoleList && originalRoleList.length>0) {
                    
                        if (originalRoleList.indexOf(e.itemData.id) > -1) {
                            e.itemElement.closest('li.dx-treeview-node').find('.dx-checkbox-checked').addClass("dx-state-disabled");
                        }
                        if (e.itemData.isRoleCategory && e.itemData.subRoles.length > 0)
                        {
                            var subRoles = e.itemData.subRoles;
                            var subRoleId = _.pluck(subRoles, 'id');
                            var hasCheckedAll = true;
                            for (var i = 0; i < originalRoleList.length; i++) {
                                var hasFind = _.find(subRoleId, function (item) {
                                    return item.id == originalRoleList[i].id;
                                });
                                if (!hasFind) {
                                    hasCheckedAll = false;
                                    break;
                                }
                            }
                            if (hasCheckedAll)
                            {
                                e.itemElement.closest('li.dx-treeview-node').find('.dx-checkbox-checked').addClass("dx-state-disabled");
                            }
                        } 
                    }
                }
            };

        };
        //构造选中的角色list
        var populateSelectedRole = function (itemData) {

            var itemIndex = -1;

            $.each($scope.selectedRoleList, function (index, item) {
                if (item.id === itemData.id) {
                    itemIndex = index;
                    return false;
                }
            });

            if (itemData.selected && itemIndex === -1) {
                if (itemData.isRoleCategory) {
                    //选择父级角色分类
                    itemData.subRoles.forEach(function (item) {
                        if ($scope.selectedRoleList.indexOf(item.id) < 0) {
                            $scope.selectedRoleList.push(item.id);
                        }
                    });
                } else {
                    //选择叶子节点角色
                    $scope.selectedRoleList.push(itemData.id);
                }

            } else if (!itemData.selected) {
                //$scope.selectedRoleList.splice(itemIndex, 1);
                //$scope.selectedRoleList.forEach(function (item) {
                //    $scope.widgetInstance.selectItem(item);
                //});
                if (!itemData.isRoleCategory) {
                    //叶子节点取消选中情况
                    $.each($scope.selectedRoleList, function (index, item) {
                        if (item === itemData.id) {
                            $scope.selectedRoleList.splice(index, 1);
                            return false;
                        }
                    });
                } else {

                    var cloneSelectedRoleList = angular.copy($scope.selectedRoleList);
                    var removeIndexList = [];

                    $.each(cloneSelectedRoleList, function (index, item) {
                        itemData.subRoles.forEach(function (x) {
                            if (item === x.id) {
                                removeIndexList.push(index);
                            }
                        });
                    });

                    //从后往前删除
                    for (var i = removeIndexList.length - 1; i >= 0; i--) {
                        $scope.selectedRoleList.splice(removeIndexList[i], 1);
                    }

                    $scope.selectedRoleList.forEach(function (item) {
                        $scope.widgetInstance.selectItem(item);
                    });

                    if (!$scope.allowUncheck) {
                        $scope.originalRoleList.forEach(function (item) {
                            $scope.widgetInstance.selectItem(item);
                        });
                    }

                }
            }

            $scope.selectedItemList = [];
            $scope.roleTreeViewData.forEach(function (item) {
                var subRoles = _.filter(item.subRoles, function (item) {
                    return $scope.selectedRoleList.indexOf(item.id) > -1;
                });

                subRoles.forEach(function (row) {
                    $scope.selectedItemList.push(row);
                });
            });


        };

        (function initialize() {
            $log.debug('addExistUserModalController.ctor()...');

            loadRoleTree();
            loadPermissionTree();
        
            //  showModal();
        }) ();

}
]);

commonModule.directive('addExistRoleModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('addExistUserModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/add-exist-role-modal/add-exist-role-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'addExistRoleModalController',
            scope:
            {
                operateType: '=',
                isUpdate: '=?',
                selectedRoleList: '=?',   //only id 
                selectedItemList: '=?',     //include id, name,etc,
                allowUncheck: '=?',
            },
            link: function (scope, element) {


            }
        };
    }
]);
commonModule.
controller('addExistUserModalController', ['$scope', '$log', '$translate', 'uiGridConstants', 'ackUibModal', '$timeout', '$interval', '$filter', 'SweetAlert', 'dimensionService', 'userService',
    function ($scope, $log, $translate, uiGridConstants, ackUibModal, $timeout, $interval, $filter, SweetAlert, dimensionService, userService) {

        $scope.gridInstance = null;
        var modalSelector = '#addUserModal';
        $scope.allowUncheck = false;

        //弹框服务
        $scope.modalService = {
            userModal: {
                open: function () {
                    $scope.userModalInstance = ackUibModal($scope, 'addExistUserModal.html', 'add-exist-user-modal-wrap', '.add-exist-user-modal-wrap', 'static',
                        function () {
                        $scope.operateType = null;
                    });
                    $scope.userModalInstance.open();
                },
                close: function () {
                    $scope.isUpdate = true;
                    $scope.userModalInstance.close();
                },
                cancel: function () {
                    $scope.userModalInstance.cancel();
                },
            }
        }

        var showModal = function () {
            //$scope.selectedKeyItems = ['90154bc8-be4a-46f2-ac08-84c1cdf8b381', 'f525f1f1-749b-4dc8-9d86-72d9014156a3', 'b5050352-e095-4d5a-bd74-dced354d063e', '8be3ce87-1193-4b35-8fda-2d5a191ce341']
            $scope.selectedUserList = [];
            $scope.originalList = angular.copy($scope.selectedKeyItems);
            getUserList();
            $scope.modalService.userModal.open();
        };

        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {
              
                if (newValue == constant.Operation.Add) {
                    showModal();
                } else if (newValue == constant.Operation.Edit) {

                }
            }
        });

        $scope.closeModal = function () {
            $scope.modalService.userModal.cancel();
        };

        $scope.Save = function ()
        {
            //返回用户ID列表
            //console.log(JSON.stringify($scope.selectedUserList));
            
            //$scope.operateType = null;
            //$scope.isUpdate = true;
           // $(modalSelector).modal("hide");
            $scope.modalService.userModal.close();
        };

        //将角色列表换成逗号分隔
        var formatRoleList = function (roleInfoList) {
            var newList = "";
            roleInfoList.forEach(function (row) {
                if (row) {
                    newList += row.name + constant.comma;
                }
            });
            if (newList.length > 0) {
                newList = newList.substr(0, newList.length - 1);
            }

            return newList;
        }

        var setUserCheckStatus = function (selectedKeyItems)
        {
            if (selectedKeyItems && selectedKeyItems.length > 0) {
                var selectItems = [];

                selectedKeyItems.forEach(function (key) {
                    var temp = _.find($scope.userDataGridSource, function (item) {
                        return item.userID === key;
                    });
                    if (temp && temp != null) {
                        selectItems.push(temp);
                    }
                });

                $timeout(function () {
                    $scope.gridInstance.clearSelection();
                    var key = $scope.gridInstance.keyOf(selectItems);
                    $scope.gridInstance.selectRows(key, true);
                }, 100);
            }
            else {
                $timeout(function () {
                    $scope.gridInstance.clearSelection();
                }, 100);
            }
        };
        var getUserList = function () {

            userService.getAllUserRoleList(constant.serviceType.VAT).success(function (data) {
                if (data) {
                     
                    data.forEach(function (row) {
                        var roleNames = _.pluck(row.roleInfoList, 'name');
                        row.roleInfoStr = roleNames.join(constant.comma);
                    });

                    $scope.userDataGridSource = data;

                    //console.log('$scope.selectedKeyItems : ' + $scope.selectedKeyItems);
                    setUserCheckStatus($scope.selectedKeyItems);
                }
            });
        };


        var loadUserDatagrid = function () {
            $scope.userDataGridOptions = {
                bindingOptions: {
                    dataSource: 'userDataGridSource',
                },
                selection: {
                    mode: "multiple",
                     showCheckBoxesMode: 'always'
                },
                allowColumnResizing: true,
                columnAutoWidth: true,
                columns: [
                        {
                            dataField: "userName",
                            caption: $translate.instant('PUserName'),
                            width:100
                        },
                        {
                            dataField: "roleInfoStr",
                            caption: $translate.instant('Role'),
                            width: 250
                        },
                        {
                            dataField: "organizationName",
                            caption: $translate.instant('PCompany'),
                            width: 200
                        }
                ],

                loadPanel: {
                    enabled: true
                },
                scrolling: {
                    mode: "virtual"
                },
                //showCheckBoxesMode: 'always',
                //keyExpr: "userID",
                showRowLines: true,
                showColumnLines: true,
                rowAlternationEnabled: true,
               
                showBorders: true,
                sorting: {
                    mode: "none"
                },
                noDataText: $translate.instant('NoDataText'),
                searchPanel: {
                    placeholder: $translate.instant('Search'),
                    width: 567,
                    visible: true
                },
                onInitialized: function (e) {
                    $scope.gridInstance = e.component;
                },
                onSelectionChanged: function (selectedItems,a,b,c) {

                    //整个集合 List
                    var rowList = selectedItems.selectedRowsData;
                    $scope.selectedUserList = rowList;
                    //只有orgID List
                    var keyList = $.map(rowList, function (value) { return value.userID });
                    $scope.selectedKeyItems = keyList;

                    ////追加原始的
                    //if ($scope.selectedKeyItems.length == 0) {
                    //    setUserCheckStatus($scope.originalList);
                    //}

                },
                onContentReady: function (e, container)
                {
                    if (!$scope.allowUncheck) {
                        var $checkBox = $('.dx-header-row .dx-checkbox').first();
                        $checkBox.on('dxclick', function (e) {
                            var isChecked = $checkBox.dxCheckBox('instance').option('value');
                            if (!isChecked) {    //追加原始角色选中
                                if ($scope.originalList && $scope.originalList.length > 0) {
                                    setUserCheckStatus($scope.originalList);
                                }
                            }
                        });
                    }
                },
                onRowPrepared: function (e) {
                    //只有不允许取消的时候才disabled
                    if (!$scope.allowUncheck) {
                        if (e && e.data) {
                            if ($scope.originalList.indexOf(e.data.userID) > -1) {
                                e.rowElement.addClass("dx-state-disabled");
                            }
                        }
                    }
                }
            };

        };

        (function initialize() {
            $log.debug('addExistUserModalController.ctor()...');
        
            loadUserDatagrid();
            //showModal();
        })();
    }
]);

commonModule.directive('addExistUserModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('addExistUserModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/add-exist-user-modal/add-exist-user-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'addExistUserModalController',
            scope:
            {
                operateType: '=',
                isUpdate: '=?',
                selectedUserList: '=?',
                selectedKeyItems: '=?',
                allowUncheck: '=?',
            },
            link: function (scope, element) {


            }
        };
    }
]);
commonModule.
controller('AreaSelectorController', ['$scope', 'areaService','$translate',
    function ($scope, areaService, $translate) {

        $scope.pleaseSelect =  $translate.instant('PleaseSelect') ;

        $scope.init = function () {
            if ($scope.isShowAll) {
                areaService.tree(1).success(function (data) {
                    if (data && data.length > 0) {
                        $scope.areaList = data;
                    }
                });
            }
            else {
                areaService.tree(0).success(function (data) {
                    if (data && data.length > 0) {
                        $scope.areaList = data;
                    }
                });
            }
          
        };


        $scope.selectedArea = null;
        $scope.getSelectedAreaDisplayText = function () {
            if ($scope.selectedAreaId != null) {
                return $scope.selectedAreaName;
            }
            else {
                return '';
            }
        };

        $scope.selectArea = function (area) {
           
            $scope.selectedAreaName = area.name;
            $scope.selectedAreaId = area.id;
            $scope.componentSelectedArea = area;
            $('.dropdown').removeClass('open');
           // $scope.onChange();
        };


        $scope.$watch('selectedAreaId', function (newValue, oldValue) {
            if (newValue !== oldValue) {
               // $scope.onChange();
            }

            // 强制重新取数据
            if ($scope.componentSelectedArea && $scope.componentSelectedArea.forceRefresh) {
                $scope.init();
            }
        });

        $scope.init();
    }
]);
commonModule.directive('areaSelector', ['$log',
    function ($log) {
        'use strict';
        $log.debug('areaSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/area-selector/area-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                selectedAreaCode: '=',
                selectedAreaName: '=',
                selectedAreaId: '=',
                componentSelectedArea: '=',
                isShowAll: '=',
                loadData: '&',
                onChange: '&onChange'
            },
            controller: 'AreaSelectorController',
            link: function (scope, element) {
                $(document).on('click', '.custom-tree-wrapper', function (e) {
                     e.stopPropagation();
                });
            }
        };
    }
]);
frameworkModule.directive('atmsBusyIndicator', ['$log', function ($log) {
    'use strict';

    $log.debug('atms-busy-indicator constructor...');

    return {
        restrict: "E",
        templateUrl: '/app/common/controls/atms-busy-indicator/atms-busy-indicator.html' + '?_=' + Math.random(),
        replace: true,
        link: function (scope, element) {
            // hide the element initially
            element.hide();
        }
    };
}]);
commonModule.controller('cellDetailPanelController', ['$log', '$scope', '$translate',
function ($log, $scope, $translate) {
    var hidePanel = function () {
        $('#cellDetailPanel').hide('normal');

    };
    var lastHeight = -1;
    var togglePanel = function () {
        $('#cellDetailConent').toggle('normal');
        $scope.isExpand = !$scope.isExpand;
        if ($scope.isExpand) {
            if (lastHeight === -1) lastHeight = '650px';
            $('#cellDetailPanel').css({ 'min-height': '650px', 'height': lastHeight });
        } else {
            lastHeight = $('#cellDetailPanel').css('height');
            $('#cellDetailPanel').css({ 'min-height': '0px', 'height': '0px' });
        }

    };
    var initGrid = function () {
        $scope.gridOptions = {
            bindingOptions: {
                dataSource: 'detail.dataSources',
                columns: 'columnsOptions',
                height:'height'

            },
            showColumnLines: false,
            showBorders: true,
            showColumnHeaders: true,
            showRowLines: false,          
            width: '100%',
            noDataText: '',
            paging: {
                enabled: false
            },

            summary: {
                totalItems: [
                    //{
                    //    column: 'id',
                    //    customizeText: function (data) {
                    //        return $translate.instant('Subtotal');
                    //    }
                    //},
                {
                    column: "amount",
                    customizeText: function (data) {
                        var message = $translate.instant('Subtotal') + ' ';
                        if ($scope.detail.cellValue != null && $scope.detail.cellValue!=undefined) {
                            message  += Number($scope.detail.cellValue).formatAmount();
                        }
                        return message;
                    }
                }
                ]
            }
        };
    };
    $scope.$watch('sourceType', function (newData, oldData) {
        if (newData !== oldData) {
            if ($scope.sourceType === -1) {
                $scope.columnsOptions = [
                  { dataField: 'id', caption: $translate.instant('SequenceNo'), width: '20%', alignment: 'left' },
                  { dataField: 'rowName', caption: $translate.instant('Project'), width: '40%' },
                  { dataField: 'columnName', caption: $translate.instant('TaxReportColumn'), width: '40%' },
                   { dataField: 'cellPosition', caption: $translate.instant('CellColumn'), width: '40%' },
                  { dataField: 'amount', caption: $translate.instant('Amount'), width: '42%', format: { type: 'fixedPoint', precision: 2 } }
                ];

            } else {
                $scope.columnsOptions = [
                   { dataField: 'id', caption: $translate.instant('SequenceNo'), width: '18%', alignment: 'left' },
                   { dataField: 'name', caption: $translate.instant('CITProject'), width: '50%' },
                   { dataField: 'amount', caption: $translate.instant('Amount'), width: '42%', format: { type: 'fixedPoint', precision: 2 } }
                ];

            }
        }

    });
    (function () {

        $scope.hidePanel = hidePanel;
        $scope.isExpand = true;
        $scope.togglePanel = togglePanel;
        initGrid();
       
    })();
}]);
commonModule.directive('cellDetailPanel', ['$log','$timeout',
function ($log, $timeout) {
    $log.debug('cellDetailPanel directive start...');
    return {
        restrict: 'E',
        templateUrl: '/app/common/controls/atms-cell-detail-panel/cell-detail-panel.html' + '?_=' + Math.random(),
        scope: {
            detail: '=',
            sourceType:'='
        },
        controller: 'cellDetailPanelController',
        link: function ($scope, $element, $attr) {
           
            $element.draggable({                
                cancel: '#data-source'
             });
            
            //计算datagrid的高度
            $scope.setInvoiceGridHeight = function () {
                var pageHeight = $('#cellDetailConent').height();              
                var topTitleHeight = $('#cell-position').outerHeight();
                var pageSearchHeight = $('#key-data').outerHeight();
                var pageFastSearchHeight = $('#cell-formula').outerHeight();              
                var subHeight = pageHeight - topTitleHeight - pageSearchHeight - pageFastSearchHeight-100;
                $('#data-source').css({ height: subHeight });
                var dataSourceTitleHeight = $('#datasource-title').outerHeight();
                $scope.height = subHeight - dataSourceTitleHeight - 20;

                try {
                    $('#bspl-dataSourceGrid').dxDataGrid('instance').repaint();
                }
                catch (e) {
                    console.log(e);
                }
            };

            //注册广播
            $scope.$on('refreshCellPanel', function (isShow) {
                if (isShow) {
                    //设置表格高度
                    //$timeout(function () {
                        $scope.setInvoiceGridHeight();
                    //}, 500);
                }
            });
            
           
            $("#cellDetailPanel").resizable({
                stop: function (event, ui) {
                    $scope.setInvoiceGridHeight();
                }
            });
        }
    }
}]);
commonModule.directive('atmsPermission', ['$compile', '$document', '$parse', 'userService', 'loginContext', 'vatSessionService', '$state',
    function ($compile, $document, $parse, userService, loginContext, vatSessionService, $state) {

        return {
            restrict: "A",
            link: function (scope, element, attr) {

                var permissionCode = attr['permissionCode'];
                var controlType = attr['permissionControlType'];

                console.log('controlType', controlType);

                var orgID = vatSessionService && vatSessionService.project ? vatSessionService.project.organizationID : null;

                var setUI = function (isshow) {
                    if (isshow) {
                        return;
                    }

                    if (!isshow) {
                        element[0].disabled = true;
                        element.addClass('no-permission');
                    }

                    if (controlType && controlType.toLowerCase() === 'ngif') {
                        element.css('display', 'none');
                    }
                    else if (controlType && (controlType.toLowerCase() === 'ngshow' || controlType.toLowerCase() === 'nghide')) {
                        element.css('visibility', 'hidden');
                    } else if (controlType && controlType.toLowerCase() === 'prohibit') {

                        $state.go('noPermissionPage');
                    }
                };

                userService.getUserPermissionNew(loginContext.userName, function (data) {

                    var isshow = false;
                    if (orgID) {
                        isshow = window.PWC.isHaveOrganizationPermission(orgID, permissionCode, data);
                    } else {
                        isshow = window.PWC.isHavePermission(permissionCode, data);
                    }

                    setUI(isshow);
                });
            }
        };
    }]);
// Popover control inherit from bootstrap popover.

// Simplest eg. 
//<button title="Test Title" data-content="Here is an example popover" data-placement="right" atms-popover>PopTest</button>

// data-placement attribute.
// It is used to specify the placement of popover.
// Available values: 'bottom' 'top' 'left' 'right' 'topLeft' 'topRight' 'rightTop' 'rightBottom' 'bottomLeft' 'bottomRight' 'leftTop' 'leftBottom'

// Use 'auto' option in data-placement.
// This will allow popover to locate itself automatically which consider the boundary of its parent.
// It will go through an ordered placement list. If there is not enough space for current placement, then it will go to next.
// The placements specified in data-placement attribute will be add to the top of the ordered list.
// eg. <button title="Test Title" data-content="Here is an example popover" data-placement="auto right left top bottom" atms-popover>PopTest</button>

// popover-auto-hide attribute.
// It is used to specify whether hide the popover when mouse click out.
// Set it to 'true' to hide the popover otherwise 'false'.
// Default is 'false'.
// eg. <button popover-auto-hide="true" title="Test Title" data-content="Here is an example popover" atms-popover>PopTest</button>

// data-templateurl attribute.
// It is used to specify url of html template. This template will be load each time the popover openned.
// It will be compiled and link to the scope of this directive.
// eg. <button data-templateurl="/app/atms-popover-test.html" atms-popover>PopTest</button>
// 'onPopoverShown' will be triggered when popover is shown. for example, on-popover-shown="onPopupShown" 
// 'onPopoverHidden' will be triggered when popover is hidden. for exmaple, on-popover-hidden="onPopupHidden"

commonModule.directive('atmsPopover', ['$compile', '$document', '$parse', function ($compile, $document, $parse) {
    return {
        restrict: "A",
        link: function (scope, element, attr) {
            var popoverOptions = {
                compliler: $compile,
                scope: scope,
                // Disable fade animation for now. Because if you click the button to toggle popover multiple times, sometimes the 
                // popover is not removed from DOM and is invisible. This will block you to click the content behind it.
                animation: false
            };

            if (attr['useOptimizedPlacementAlgorithm']) {
                popoverOptions.useOptimizedPlacementAlgorithm = attr['useOptimizedPlacementAlgorithm'];
            }

            if (attr['popoverContainer']) {
                popoverOptions.container = attr['popoverContainer'];
            }

            if (attr['popoverTrigger']) {
                popoverOptions.trigger = attr['popoverTrigger'];
            }

            element.popover(popoverOptions);

            var popContent;
            var onClick = function (event) {
                if (!popContent)
                    return;
                var iswithinElement = popContent.find(event.target).length > 0 || popContent.context === event.target;
                var isOnCalendar = $(event.target).closest('.datepicker').length > 0;
                var isInTooltip = $(event.target).closest('.tooltip-inner').length > 0;
                //=>Alsace Updatev
                var isInChildPopver = $(event.target).closest('.child-popover').length > 0;
                if (iswithinElement || isOnCalendar || isInTooltip || isInChildPopver) {
                    event.stopPropagation();
                } else {
                    element.popover('hide');
                }
            };

            var onResize = function () {
                element.popover('hide');
            };

            var subscribeGlobalEvent = function () {
                $document.on('mousedown', onClick);
                $(window).on('resize', onResize);
            };

            var unsubscribeGlobalEvent = function () {
                $document.off('mousedown', onClick);
                $(window).off('resize', onResize);
            };

            var isAutoHide = attr['popoverAutoHide'] === 'true';
            var onShowPopover = attr['onShowPopover'];

            if (onShowPopover) {
                element.on('show.bs.popover', function (event) {
                    scope[onShowPopover](event);
                });
            }

            element.on('shown.bs.popover', function (event, popElement) {
                var onPopoverShown = attr['onPopoverShown'];
                if (onPopoverShown) {
                    var onPopoverShownAction = $parse(onPopoverShown);
                    onPopoverShownAction(scope).call();

                }

                if (isAutoHide) {
                    unsubscribeGlobalEvent();
                    subscribeGlobalEvent();
                    popContent = $(popElement);
                }
            });

            element.on('hidden.bs.popover', function (event) {
                var onPopoverHidden = attr['onPopoverHidden'];
                if (onPopoverHidden) {
                    scope[onPopoverHidden](event);
                }
                unsubscribeGlobalEvent();
            });

            scope.$on('atms-popover:event', function (event, action) {
                element.popover(action);
            });
        }
    };
}]);
commonModule.
controller('customAttributeModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', 'areaRegionService', '$filter', 'SweetAlert', 'statisticAttributeService', 'dimensionService','enums',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, areaRegionService, $filter, SweetAlert, statisticAttributeService, dimensionService,enums) {

        var selectedModel = '#addDimensionModal' + $scope.dimensionId;

        var showWarning = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.warning(errMsg);
        };

        var showSuccessMsg = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.success(errMsg);
        };

        var getDimensionList = function () {
            dimensionService.getDimensionList().success(function (data) {
                $scope.customDimensionList = _.where(data, function (item) {
                    return item.isSystemDimension === true;
                });

                $log.debug($scope.customDimensionList);

                //$scope.selectedFirst = $scope.orgFields[6];
                //$scope.selectedSecond = $scope.orgFields[3];
            });
        };

        //自定义显示属性列表
        var getStatisticAttributeList = function () {
            var parentDimensionID = $scope.dimensionId;
             
            //属性列表,多少个自定义属性,多少个dropdown list

            if ($scope.tabType !== 3) {
                statisticAttributeService.getByParentDimensionID(parentDimensionID).success(function (data) {
                    if (data) {
                        
                        $scope.statisticAttrList = data;

                        if (!$scope.statisticAttrList || $scope.statisticAttrList.length === 0) {
                            var statisticAttrTemp = {

                            };

                            $scope.statisticAttrList.push(statisticAttrTemp);
                        }

                        //下拉列表内容
                        getDropdownList('');
                    }
                });
            } else {
                //如果是机构Tab的话
                statisticAttributeService.getOrgSubChildrenStatAttributeList(parentDimensionID).success(function (data) {
                    if (data) {
                        $scope.statisticAttrList = data;

                        $scope.firstRowList = [];
                        var list = JSON.parse(JSON.stringify($scope.statisticAttrList));
                        $scope.firstRowList.push(list[0]);
                        $scope.firstRowList.push(list[1]);

                        $scope.statisticAttrList.splice(0, 2);

                        //下拉列表内容
                        getDropdownList(constant.DimensionType.OrgSubChildren);
                    }
                });
            } 
        };

        var getDropdownList = function (dictionaryCode) {
            //下拉列表内容
            statisticAttributeService.get(dictionaryCode).success(function (data) {
                if (data) {
                    $scope.dimensionList = data;

                    //显示已经设置的自定义属性
                    var list = $scope.statisticAttrList;
                     
                    if (dictionaryCode == constant.DimensionType.OrgSubChildren) {
                        $scope.withoutOrgAttrList = _.filter(data, function (item) {
                            return item.isOrgSelfProperty != true;
                        });
                    }

                    $scope.isBUTabType = false;
                    //事业部,第一行的机构,固定
                    if ($scope.tabType == 1) {
                        //第一行,永远显示机构数,并且不可编辑
                        list[0].attrSelectedID = constant.attributeID.orgSubChildrenID;
                        $scope.isBUTabType = true;
                        for (var i = 1; i < list.length; i++) {
                            list[i].attrSelectedID = list[i].attributeID;
                        }

                    }
                    else if ($scope.tabType === 3) {
                        var firstRowlist = $scope.firstRowList;
                        for (var i = 0; i < firstRowlist.length; i++) {
                            firstRowlist[i].attrSelectedID = firstRowlist[i].attributeID;
                        }
                        for (var i = 0; i < list.length; i++) {
                            list[i].attrSelectedID = list[i].attributeID;
                        }
                    } else if ($scope.tabType == 2) {
                        // 这是区域
                        $scope.firstRowList = [];
                        var notFirstRowList = [];
                        for (var i = 0; i < list.length; i++) {
                            list[i].attrSelectedID = list[i].attributeID;
                            if (i <=1){
                                $scope.firstRowList.push(list[i]);
                            } else{
                                notFirstRowList.push(list[i]);
                            }
                        }

                        $scope.statisticAttrList = notFirstRowList;

                    }
                    else {
                        for (var i = 1; i < list.length; i++) {
                            list[0].attrSelectedID = list[i].attributeID;
                        }
                    }
                }
            });
        };

        var editAttributeModel = function () {
            initData();
            //  $('#addDimensionModal').appendTo("body").modal('show');
            $(selectedModel).modal('show');
        }

        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {

                if (newValue == constant.Operation.Add) {

                } else if (newValue == constant.Operation.Edit) {
                    editAttributeModel();
                }
            }
        });

        $(".addDimensionModal").on("hidden.bs.modal", function () {
            $scope.operateType = null;
        });

        $scope.closeModal = function () {
            $scope.operateType = null;
        };

        //自定义显示属性后,保存
        var saveAttr = function () {
            //fix bug for 10146. 如果没有选择值 请弹出错误提示框!
            var filterResult = _.filter($scope.statisticAttrList, function (row) {
                return !row.attrSelectedID;
            });

            if (filterResult && filterResult.length > 0) {
                showWarning("PleaseSelectAttr");
                return false;
            }

            if ($scope.tabType !== 3 && $scope.tabType !== 2) {
                saveAttrExceptOrgStructure();
            } else {
                saveAttrForOrgStructure();
            }
        };

        

        var saveAttrForOrgStructure = function () {

            var selectedAttr = [];
            var selectedAttrTemp = [];
            var selectedAttrTempFirstRow = [];

            var firstRowList = $scope.firstRowList;
            var list = $scope.statisticAttrList;
            var hasError = false;

            firstRowList.forEach(function (row) {
                if (row.attrSelectedID) {
                    var selectedID = row.attrSelectedID;
                    //维度不能重复选择
                    if (selectedAttrTempFirstRow.indexOf(selectedID) >= 0) {
                        hasError = true;
                        return;
                    }
                    selectedAttrTempFirstRow.push(selectedID);
                    selectedAttr.push({ attributeID: selectedID, dimensionID: $scope.dimensionId });
                }
            });

            list.forEach(function (row) {
                if (row.attrSelectedID) {
                    var selectedID = row.attrSelectedID;
                    //维度不能重复选择
                    if (selectedAttrTemp.indexOf(selectedID) >= 0) {
                        hasError = true;
                        return;
                    }
                    selectedAttrTemp.push(selectedID);
                    selectedAttr.push({ attributeID: selectedID, dimensionID: $scope.dimensionId });
                }
            });
            if (hasError) {
                showWarning("SelectAttrDuplicated");
                return false;
            }
            //至少选择一个维度
            if (selectedAttrTemp.length == 0) {
                showWarning("SelectOneAttr");
                return false;
            }

            statisticAttributeService.updateRange(selectedAttr).success(function (data) {
                if (data) {

                    showSuccessMsg('SaveSuccess');
                    $(selectedModel).modal('hide');

                    $scope.isUpdate = true;
                    $scope.operateType = null;
                    // $scope.refreshAttributeList();
                }
            });

        };

        ///除了机构层级之外的
        var saveAttrExceptOrgStructure = function () {
            var selectedAttr = [];
            var selectedAttrTemp = [];

            var list = $scope.statisticAttrList;
            var hasError = false;
            list.forEach(function (row) {
                if (row.attrSelectedID) {
                    var selectedID = row.attrSelectedID;
                    //维度不能重复选择
                    if (selectedAttrTemp.indexOf(selectedID) >= 0) {
                        hasError = true;
                        return;
                    }
                    selectedAttrTemp.push(selectedID);
                    selectedAttr.push({ attributeID: selectedID, dimensionID: $scope.dimensionId });
                }
            });
            if (hasError) {
                showWarning("SelectAttrDuplicated");
                return false;
            }
            //至少选择一个维度
            if (selectedAttrTemp.length == 0) {
                showWarning("SelectOneAttr");
                return false;
            }
            //$state.params.dimensionID
            statisticAttributeService.updateRange(selectedAttr).success(function (data) {
                if (data) {

                    showSuccessMsg('SaveSuccess');
                    $(selectedModel).modal('hide');

                    $scope.isUpdate = true;
                    $scope.operateType = null;
                    $scope.refreshAttributeList();
                }
            });
        };

        //删除自定义的维度
        var deleteAttr = function (row) {
            for (var i = 0; i < $scope.statisticAttrList.length; i++) {
                if ($scope.statisticAttrList[i].attributeID == row.attributeID) {
                    $scope.statisticAttrList.splice(i, 1);
                    break;
                }
            }

        };

        //添加自定义显示属性
        var AddAttr = function () {
            if ($scope.statisticAttrList.length < $scope.dimensionList.length) {
                var newObject = { dimensionID: '', name: '', IsActive: true };

                $scope.statisticAttrList.push(newObject);
            }
            else {
                showWarning("AddToMaximum");
            }
        };

        var initData = function () {
            getStatisticAttributeList();
            getDimensionList();
        };

        (function initialize() {
            $log.debug('orgCustomAttributeModalController.ctor()...');

            $scope.refreshAttributeList = getStatisticAttributeList;
            $scope.AddAttr = AddAttr;
            $scope.SaveAttr = saveAttr;
            $scope.deleteAttr = deleteAttr;
        })();
    }
]);

commonModule.directive('customAttributeModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('orgCustomAttributeModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/custom-attribute-modal/custom-attribute-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'customAttributeModalController',
            scope:
            {
                operateType: '=',
                attributeId: '=?',
                isUpdate: '=?',
                dimensionId: '=?',

                //维度类型,目的是为了区分弹出框的样式
                //tabType=1 事业部
                //tabType=2 区域
                //tabType=3 机构层次
                //tabType=4 其他自定义
                tabType: '=?',

                // 配置的纬度值列表
                statisticAttrList: '=?',
            }
        };
    }
]);
commonModule.
controller('editBusinessUnitModalController', ['$scope', '$log', 'SweetAlert', '$translate', 'businessUnitService', 'uiGridConstants', 'Upload', 'apiInterceptor', '$interval', '$q',
    function ($scope, $log, SweetAlert, $translate, businessUnitService, uiGridConstants, Upload, apiInterceptor, $interval, $q) {

        var editModalSelector = "#BU-modal";
        $scope.editingObject = { id: "", Name: "", IsActive: true };
        //显示指定消息编码对应的翻译文本信息
        var showError = function (messageCode) {
            var errMsg = $translate.instant(messageCode);
            SweetAlert.warning(errMsg);
        };

        var resetError = function () {
            var elms = $(editModalSelector).find("form:first div[data-for]");
            elms.html("");
            elms.attr("class", "validate-success");

            $scope.editingObject = { ID: "", Name: "", IsActive: true };
        };

        //获取事业部数据
        var getbusinessUnitList = function () {
            var deferred = $q.defer();
            businessUnitService.getBusinessUnitList().success(function (data) {
                $scope.businessUnitList = data;
                deferred.resolve();
            });
            return deferred.promise;
        };


        var editBU = function ()
        {
            getbusinessUnitList().then(function () {
                $scope.isEdit = true;
                if ($scope.selectedBusinessUnitId) {

                    var data = _.find($scope.businessUnitList, function (num) {
                        return num.id === $scope.selectedBusinessUnitId;
                    });
                    if (data) {
                        $scope.editingObject = { id: data.id, Name: data.name, IsActive: data.isActive };
                    }
                }
                $(editModalSelector).modal('show');
            });
        };

        var addBU = function () {
            getbusinessUnitList().then(function () {
                $scope.isEdit = false;
                $scope.editingObject = { id: "", Name: "", IsActive: true };
                $(editModalSelector).modal('show');
            });
        };
        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {
                resetError();
                if (newValue == constant.Operation.Add) {
                    addBU();
            
                } else if (newValue == constant.Operation.Edit) {
                    editBU();
                }
            }
        });

        $(editModalSelector).on("hidden.bs.modal", function () {
            $scope.operateType = null;
        });

        $scope.closeModal = function () {
            $scope.operateType = null;
        };

        //保存当前正在编辑数据行,经过界面初步校验后才会进入本功能
        $scope.save = function () {
            if ($scope.editingObject == null) {
                return;
            }

            if (!($(editModalSelector).find("#edit-form").valid())) {
                return;
            }


            var businessUnitArray = [];
            businessUnitArray.push($scope.editingObject);

            var successedFun = function (rst) {

                $(editModalSelector).modal('hide');

                if ($scope.isEdit) {
                    SweetAlert.success($translate.instant("OrganizationStructureEditSuccess"));
                }
                else {
                    SweetAlert.success($translate.instant("OrganizationStructureAddSuccess"));
                }
                $scope.isUpdate = true;
                $scope.operateType = null;
                $scope.refreshBuList();
            }

            if ($scope.isEdit) {
                businessUnitService.updateBusinessUnit(businessUnitArray).success(successedFun);

            } else {
                businessUnitService.addBusinessUnit(businessUnitArray).success(successedFun);
            }


        };


        var intiValidate = function () {

            $.validator.addMethod("BusinessUnitRepeated", function (value, element, param) {
                if ($scope.businessUnitList && $scope.businessUnitList.length > 0) {
                    var objects = $.grep($scope.businessUnitList, function (n, i) {
                        return $scope.editingObject.id != n.id && $.trim(n.name) == $.trim(value);
                    });

                    return objects.length < 1;
                }

                return true;

            });

            formValidator = $(editModalSelector).find("#edit-form").validate({
                debug: true,

                rules: {
                    Name: {
                        required: true,
                        minlength: 2,
                        maxlength: 50,
                        BusinessUnitRepeated: true
                    },
                    IsActive: {
                        required: "input[name='IsActive']:checked"
                    }
                },
                messages: {
                    Name: {
                        required: $translate.instant('BusinessUnitEmptyNode'),
                        minlength: $translate.instant('BusinessUnitEmptyNode'),
                        maxlength: $translate.instant('BusinessUnitOutOfLengthNode'),
                        BusinessUnitRepeated: $translate.instant('BusinessUnitDuplicateNode')
                    },
                    IsActive: $translate.instant('BusinessUnitStatusUnsureness')
                },
                errorPlacement: function (error, element) {
                    var elm = $(element).parents("form:first");
                    elm = elm.find("div[data-for='" + element.attr("name") + "']");
                    elm.html(error);
                    elm.attr("class", "validate-fail");
                }
            }
            );
        };


        (function initialize() {
            $log.debug('editBusinessUnitModalController.ctor()...');
            $scope.refreshBuList = getbusinessUnitList;
            intiValidate();
        })();
    }
]);

commonModule.directive('editBusinessUnitModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('editRegionModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/edit-business-unit-modal/edit-business-unit-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'editBusinessUnitModalController',
            scope:
            {
                operateType: '=',
                selectedBusinessUnitId: '=?',
                isUpdate: '=?'
            }
        };
    }
]);
commonModule.
controller('editDimensionValueModalController', ['$scope', '$log', 'SweetAlert', '$translate', 'dimensionService', 'uiGridConstants', 'Upload', 'apiInterceptor', '$interval', '$q',
    function ($scope, $log, SweetAlert, $translate, dimensionService, uiGridConstants, Upload, apiInterceptor, $interval, $q) {

        var editModalSelector = "#Dimension-value-modal";
        $scope.editingObject = { id: "", Name: "", IsActive: true };
        //显示指定消息编码对应的翻译文本信息
        var showError = function (messageCode) {
            var errMsg = $translate.instant(messageCode);
            SweetAlert.warning(errMsg);
        };

        var resetError = function () {
            var elms = $(editModalSelector).find("form:first div[data-for]");
            elms.html("");
            elms.attr("class", "validate-success");

            $scope.editingObject = { ID: "", Name: "", IsActive: true };
        };

        //获取维度值数据
        var getDimensionValueList = function () {
            var deferred = $q.defer();
            var dimensionID = $scope.dimensionId;
            dimensionService.getDimensionValueList(dimensionID).success(function (data) {
                if (data) {
                    $scope.DimensionValueList = data;
                    deferred.resolve();
                }
            });
            return deferred.promise;
        };


        var editDimensionValue = function () {

            getDimensionValueList().then(function () {
                $scope.isEdit = true;
                if ($scope.selectedDimensionValueId) {

                    var data = _.find($scope.DimensionValueList, function (num) {
                        return num.id === $scope.selectedDimensionValueId;
                    });
                    if (data) {
                        $scope.editingObject = { id: data.id, Name: data.name, dimensionID: $scope.dimensionId, IsActive: data.isActive };
                        $scope.DimensionName = $scope.dimensionName;
                    }
                }
                $(editModalSelector).modal('show');
            });
        };

        var addDimensionValue = function () {
            getDimensionValueList().then(function () {
                $scope.isEdit = false;
                $scope.editingObject = { id: "", Name: "", IsActive: true, dimensionID: $scope.dimensionId };
                $(editModalSelector).modal('show');
            });
        };
        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {
                resetError();
                if (newValue == constant.Operation.Add) {
                    addDimensionValue();
            
                } else if (newValue == constant.Operation.Edit) {
                    editDimensionValue();
                }
            }
        });

        $(editModalSelector).on("hidden.bs.modal", function () {
            $scope.operateType = null;
        });

        $scope.closeModal = function () {
            $scope.operateType = null;
        };

        //保存当前正在编辑数据行,经过界面初步校验后才会进入本功能
        $scope.save = function () {
            if ($scope.editingObject == null) {
                return;
            }

            if (!($(editModalSelector).find("#edit-form").valid())) {
                return;
            }


            var editModel = $scope.editingObject;

            var successedFun = function (rst) {
                if (!rst.result)
                {
                    showError(rst.resultMsg);
                    return false;
                }
                $(editModalSelector).modal('hide');

                if ($scope.isEdit) {
                    SweetAlert.success($translate.instant("OrganizationStructureEditSuccess"));
                }
                else {
                    SweetAlert.success($translate.instant("OrganizationStructureAddSuccess"));
                }
                $scope.isUpdate = true;
                $scope.operateType = null;
                $scope.refreshDimensionValueList();
            }

            if ($scope.isEdit) {
                dimensionService.updateDimensionValue(editModel).success(successedFun);

            } else {
                dimensionService.addDimensionValue(editModel).success(successedFun);
            }


        };


        var intiValidate = function () {

            $.validator.addMethod("dimensionValueRepeated", function (value, element, param) {
                if ($scope.DimensionValueList && $scope.DimensionValueList.length > 0) {
                    var objects = $.grep($scope.DimensionValueList, function (n, i) {
                        return $scope.editingObject.id != n.id && $.trim(n.name) == $.trim(value);
                    });

                    return objects.length < 1;
                }

                return true;

            });

            formValidator = $(editModalSelector).find("#edit-form").validate({
                debug: true,

                rules: {
                    Name: {
                        required: true,
                        minlength: 2,
                        maxlength: 50,
                        dimensionValueRepeated: true
                    },
                    IsActive: {
                        required: "input[name='IsActive']:checked"
                    }
                },
                messages: {
                    Name: {
                        required: $translate.instant('DimensionValueEmptyNode'),
                        minlength: $translate.instant('DimensionValueEmptyNode'),
                        maxlength: $translate.instant('DimensionValueOutOfLengthNode'),
                        dimensionValueRepeated: $translate.instant('DimensionValueDuplicated')
                    },
                    IsActive: $translate.instant('DimensionValueStatusUnsureness')
                },
                errorPlacement: function (error, element) {
                    var elm = $(element).parents("form:first");
                    elm = elm.find("div[data-for='" + element.attr("name") + "']");
                    elm.html(error);
                    elm.attr("class", "validate-fail");
                }
            }
            );
        };


        (function initialize() {
            $log.debug('editDimensionValueModalController.ctor()...');
            $scope.refreshDimensionValueList = getDimensionValueList;
            intiValidate();
        })();
    }
]);

commonModule.directive('editDimensionValueModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('editRegionModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/edit-dimension-value-modal/edit-dimension-value-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'editDimensionValueModalController',
            scope:
            {
                operateType: '=',
                selectedDimensionValueId: '=?',
                isUpdate: '=?',
                dimensionName: '=?',
                dimensionId: '=?'
            }
        };
    }
]);
commonModule.
controller('editFormulaModalController', ['$scope', '$log', '$translate', '$location', '$timeout', '$interval', '$filter', '$q', 'SweetAlert',
    '$uibModal', 'serviceTypeService', 'formulaService',
    function($scope, $log, $translate, $location, $timeout, $interval, $filter, $q, SweetAlert, $uibModal, serviceTypeService, formulaService) {
        var allCategory = {
            id: "-1",
            name: $translate.instant("All"),
            prefix: "ALL",
            isActive: true
        };

        var thisConstant = {
            serviceTypeSelect: 'serviceTypeSelect',
            formulaDxList: 'formulaDxList',
            formulaNameGet: 'GET'
        };

        var thisData = {
            serviceTypeList: [],
            formulaList: [],
            formulaTreeView: null,
        };

        var thisDataService = {
            newModel: function() {
                var editModel = {};

                return editModel;
            },
            save: function() {
                // if ($scope.selectFormula) {
                //     $log.debug('选中的公式为:' + JSON.stringify($scope.selectFormula));
                // }

                thisModalService.close($scope.selectFormula);
            }
        };


        var thisModalService = {
            modalInstance: null,
            open: function(editModel) {
                $scope.editModel = editModel;
                mainModule.resetSelectedFormula();

                var container;
                if ($scope.containerSelector) {
                    container = angular.element($scope.containerSelector);
                }
                else {
                    container = angular.element('body');
                }

                if (container.length > 1) {
                    container = angular.element(container[0]);
                }

                var modalInstance = $uibModal.open({
                    animation: true,
                    backdrop: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'editFormulaModal.html',
                    appendTo: container,
                    scope: $scope,
                    windowClass: 'edit-formula-modal-wrapper',
                    resolve: {
                        editModel: editModel
                    }
                });

                modalInstance.closed.then(function () {
                    if ($scope.isUpdate) {
                        $scope.onClosed({
                            formula: $scope.selectFormula
                        });
                    }
                });

                modalInstance.result.then(function(data) {
                    $scope.editModel = data;
                    $scope.operateType = null;
                    $scope.isUpdate = true;
                }, function() {
                    $scope.operateType = null;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });

                thisModalService.modalInstance = modalInstance;

                // 加载服务类型
                $timeout(function () {
                    var promise;
                    if (thisData.serviceTypeList && thisData.serviceTypeList.length > 0) {
                    
                        mainModule.renderServiceTypeSelect(thisData.serviceTypeList);
                        promise = $q.when();
                    } else {
                        promise = mainModule.loadServiceType();
                    }

                    promise = promise.then(function () {
                        thisData.formulaList = $scope.formulaList;
                        $scope.formulaTranslatorModel.formulaList = thisData.formulaList;

                        // 确定
                        $scope.save = thisDataService.save;

                        // 取消
                        $scope.cancel = thisModalService.cancel;

                        // 加载公式
                        if (!thisData.formulaList || thisData.formulaList.length === 0) {
                            return mainModule.loadFormulaList();
                        }
                        else {
                            return $q.when();
                        }
                    });

                    promise = promise.then(function () {
                        mainModule.searchFormula();

                        $(".edit-formula-modal-wrapper .modal-content").css('top', '0px');
                        $(".edit-formula-modal-wrapper .modal-content").css('left', '0px');
                        $(".edit-formula-modal-wrapper .modal-content").draggable({
                            cursor: "cursor",
                            scroll: true,
                            cancel: '.btn, input, .form-control, .formula-text, .close, div.label'
                        });

                    });
                }, 10);
            },
            newModel: function() {
                var editModel = thisDataService.newModel();
                thisModalService.open(editModel);
            },
            close: function(result) {
                if (thisModalService.modalInstance) {
                    thisModalService.modalInstance.close(result);
                }
            },
            cancel: function() {
                if (thisModalService.modalInstance) {
                    thisModalService.modalInstance.dismiss('cancel');
                }
            }
        };

        var mainModule = {
            main: function() {

                $scope.formulaTranslatorModel = {
                    formulaList: [],
                    formulaName: '',
                    formulaParams: ''
                };


                mainModule.watchFunction();
            },
            watchFunction: function() {
                $scope.$watch('operateType', function(newValue, oldValue) {
                    if (newValue) {
                        thisModalService.newModel();
                    }
                });
            },
            loadServiceType: function() {
                return serviceTypeService.getServiceTypeList().success(function(data) {

                    // 只拿有效的
                    data = _.filter(data, function(row) {

                        return row.isActive;
                    });

                    if (data) {
                        data.unshift(allCategory);
                    
                        thisData.serviceTypeList = data;
                        mainModule.renderServiceTypeSelect(data);
                    }
                });
            },

            loadFormulaList: function() {
                return formulaService.getAll().success(function(data) {

                    var tempList;
                    if (data && data.data) {
                        tempList = _.map(data.data, function (row) {
                            return {
                                id: row.id,
                                code: row.formulaName,
                                name: row.chineseName,
                                description: row.description,
                                englishName: row.englishName,
                                requiredParamNum: row.requiredParamNum,
                                params: ''
                            };
                        });
                    }
                    else {
                        tempList = [];
                    }

                    thisData.formulaList = tempList;
                    $scope.formulaTranslatorModel.formulaList = tempList;
                });
            },

            renderServiceTypeSelect: function(data) {
                var value = data && data.length > 0 ? data[0].id : null;
                $('#' + thisConstant.serviceTypeSelect).dxSelectBox({
                    dataSource: data,
                    valueExpr: 'id',
                    displayExpr: 'name',
                    value: value,
                    onSelectionChanged: function(args) {
                        $scope.editModel.searchText = '';
                        mainModule.resetSelectedFormula();
                        mainModule.searchFormula();
                    }
                });
            },

            resetServiceType: function () {
                var o = $('#' + thisConstant.serviceTypeSelect).dxSelectBox('option');
                var onSelectionChanged = o.onSelectionChanged;
                $('#' + thisConstant.serviceTypeSelect).dxSelectBox({ onSelectionChanged: null });
                $('#' + thisConstant.serviceTypeSelect).dxSelectBox({ value: allCategory.id });
                $('#' + thisConstant.serviceTypeSelect).dxSelectBox({ onSelectionChanged: onSelectionChanged });
            },

            resetSelectedFormula: function () {
                $scope.formulaTranslatorModel.params = ''
                $scope.formulaTranslatorModel.formulaName = '';
                $scope.selectFormula = null;
            },

            searchFormula: function() {

                var o = $('#' + thisConstant.serviceTypeSelect).dxSelectBox('option');
                var serviceType = o.value;

                var filterList = [];
                if ($scope.editModel.searchText) {
                    // 搜索框有值则只显示匹配输入值的公式
                    var upperText = $scope.editModel.searchText.toUpperCase();

                    filterList = _.filter(thisData.formulaList, function(row) {

                        if (row.code && row.code.toUpperCase().indexOf(upperText) > -1) {
                            return true;
                        }

                        if (row.name && row.name.toUpperCase().indexOf(upperText) > -1) {
                            return true;
                        }

                        return false;
                    });

                    filterList = mainModule.filterServiceType(allCategory.id, filterList);


                } else {
                    // 搜索框无值则显示选择的税种对应的公式
                    filterList = mainModule.filterServiceType(serviceType, thisData.formulaList);
                }

                mainModule.renderFormulaDxTreeView(filterList);
            },

            searchFormulaByName: function () {
                
                mainModule.resetServiceType();
                mainModule.searchFormula();
            },

            filterServiceType: function(serviceType, filterSearchList) {
                if (!filterSearchList || filterSearchList.length === 0) {
                    filterSearchList = thisData.formulaList;
                }

                var filterList = _.filter(filterSearchList, function(row) {
                    if (row.code === thisConstant.formulaNameGet) {
                        // get 函数不展示
                        return false;
                    }

                    if (serviceType === allCategory.id) {
                        // 选择所有类别时
                        return true;
                    }

                    if (!row.serviceType) {

                        // 不知道服务类型的,也返回
                        return true;
                    }

                    if (row.serviceType && row.serviceType === serviceType) {
                        return true;
                    }

                    return false;
                });

                return filterList;
            },

            renderFormulaDxTreeView: function(data) {

                data = angular.copy(data);
                data.forEach(function(row) {
                    row.label = row.code + '(' + row.name + ')';
                });

                var $treeView = $('#' + thisConstant.formulaDxList).dxTreeView({
                    dataSource: data,
                    keyExpr: "id",
                    parentIdExpr: "parentID",
                    displayExpr: "label",
                    selectByClick: true,
                    expandAllEnabled: true,
                    selectNodesRecursive: true,
                    showCheckBoxesMode: "none",
                    selectionMode: 'single',
                    height: '130px',
                    noDataText: '',
                    onItemSelectionChanged: function (args) {
                        $scope.$apply(function () {
                            var itemData = args.itemData;
                            $scope.formulaTranslatorModel.formulaName = itemData.code;
                            // $scope.formulaTranslatorModel.params = itemData.params;
                            $scope.selectFormula = itemData;
                        });
                    }
                });

                thisData.formulaTreeView = $treeView.dxTreeView("instance");
            },
        };

        (function initialize() {
            mainModule.main();

            $scope.searchFormulaByName = mainModule.searchFormulaByName;
        })();
    }
]);
commonModule.directive('editFormulaModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('editUserModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/edit-formula-modal/edit-formula-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'editFormulaModalController',
            scope:
            {
                operateType: '=',
                accountDataSource: '=?',
                selectFormula:'=?',
                formulaList: '=?',
                containerSelector: '@?',
                onClosed: '&'
            }
            //,
            //link: function (scope, element) {
            //    element.find('.selector-input').on('focus', function () {
            //        element.find('.org-tree-container').show();
            //    });
            //    $(document).on('click', function () {
            //        element.find('.org-tree-container').hide();
            //    }).on('click', '.org-tree-wrapper', function (e) {
            //        e.stopPropagation();
            //    });
            //}
        };
    }
]);
commonModule.controller('editInvoiceModalController', ['$log', '$scope', '$translate', '$uibModal', '$document', 'SweetAlert', 'enums',
    '$timeout', '$document', '$compile', 'vatOutputInvoiceManageService', 'userService', 'loginContext', 'cardValidationService', '$state','$q',
    function ($log, $scope, $translate, $uibModal, $document, SweetAlert, enums, $timeout, $document, $compile, vatOutputInvoiceManageService,
        userService, loginContext, cardValidationService, $state,$q) {

        var thisService = {

            // 最大金额
            MaxPrice: 10000000.00,
            debug: false,

            // 从数据库中获取的修改理由
            OutputInvoiceUpdateReasonList: null,

            // 选中BD列表
            selectEntityList_ID: 'selectEntityList_ID',

            // 手动添加发票
            select_ADD_EntityList_ID: 'select_ADD_EntityList_ID',

            isChanged: false,

            // debug 用的 理由 与 OutputInvoiceUpdateReasonList 结构相同
            reasonList: [
                { id: '0062b0da-08a5-44e7-8dfd-5b880e20e8cc', englishName: 'Autopilot Hardware', chineseName: '辅助驾驶金额未加,手动调价' },
                { id: '1062b0da-08a5-44e7-8dfd-5b880e20e8cc', englishName: 'High Amperage Charger Upgrade', chineseName: '高功率车载充电器金额未加,手动调价' },
                { englishName: 'Insurance Subsidy', chineseName: '保险优惠未扣,手动调价' },
                { englishName: 'Trade-in Value Uplift', chineseName: '置换激励未扣,手动调价' },
                { englishName: 'Referral Credit', chineseName: '老车主推荐激励未扣,手动调价' }
            ],

            // 测试编辑数据
            testEditModel: null,
            OwnerOrgModel: {},

            // 主函数
            main: function () {

                $scope.isReadOnly = true;

                // 只能查看,不能修改
                $scope.isQueryOnly = false;
                $scope.editModel = {};

                thisService.getUserOwnerOrganization();
                $scope.updateStatus = thisService.updateStatus;

                thisService.watchCollection();

                thisService.test();

                thisService.bindEvent();
            },

            // 绑定事件
            bindEvent: function () {
                $scope.changeSubtotalforFinalPayment = thisService.changeSubtotalforFinalPayment;
            },

            // 限制输入两位小数
            limitTwoDigital: function (value) {
                //先把非数字的都替换掉,除了数字和.
                value = value.replace(/[^\d.]/g, "");
                //必须保证第一个为数字而不是.
                value = value.replace(/^\./g, "");
                //保证只有出现一个.而没有多个.
                value = value.replace(/\.{2,}/g, ".");
                //保证.只出现一次,而不能出现两次以上
                value = value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
                //保证.只后面只能出现两位有效数字
                value = value.replace(/([0-9]+\.[0-9]{2})[0-9]*/, "$1");

                return value;
            },

            // 购房名称及身份证号码,组织机构代码
            getBuyerInfo: function (data) {

                var str = '';

                if (!data) {
                    return str;
                }

                // if (data.registrationLocalName) {
                //     str = data.registrationLocalName;
                // }

                if (data.driverLicense) {
                    str += data.driverLicense;
                }

                if (data.organizationCode) {
                    str += data.organizationCode;
                }

                return str;

            },

            // 设置价格
            setPrice: function (data) {
                // 不含税价
                if (data.vatRateorLevyRate && data.subtotalforFinalPayment) {

                    // var rateStr = data.vatRateorLevyRate.replace('%', '');
                    // var rate = parseInt(rateStr) / 100;

                    // var notExcludeTaxPrice = data.subtotalforFinalPayment / (1 + rate);

                    // var price = Math.floor(notExcludeTaxPrice * 100) / 100;

                    // // 为了精确度的问题
                    // data.vatTax = (data.subtotalforFinalPayment * 10000 - price * 10000) / 10000;

                    // data.excludeTaxPrice = price;

                    vatOutputInvoiceManageService.computeBDPrice(data).success(function (ret) {
                        data.vatTax = ret.vatTax;
                        data.excludeTaxPrice = ret.excludeTaxPrice
                    });
                }
            },

            // 测试辅助方法
            test: function () {
                if (thisService.debug) {

                    // 测试编辑数据
                    thisService.testEditModel = {
                        registrationLocalName: 'tom li',
                        companyVATIDTaxID: '234826348762384',
                        governmentClassification: '小轿车',
                        brandandModelNumber: '拓速乐纯电动轿车 S60R5',
                        producingPlace: '美国',
                        certificateNumber: '',
                        importCertificateNumber: 'H34234234234',
                        ciqNumber: 'A234234234',
                        motorNumber: 'T937459834',
                        vin: '5Y837438743743',
                        subtotalforFinalPaymentCH: '陆拾伍万',
                        subtotalforFinalPayment: '650000.00',
                        invoiceCode: '',
                        invoiceNumber: '',
                        salesUnitName: '特斯拉汽车销售服务(xx)有限公司',
                        salesUnitPhoneNumber: '020-37253253',
                        salesTaxPayerNumber: '977277237575276354',
                        salesAccount: '23123123123',
                        salesAddress: 'XXX市~~~',
                        salesBankName: '花旗银行',
                        vatRateorLevyRate: '',
                        taxableSubtotal: 650000.00,
                        mainTaxAuthoritiesCode: 'XXX市 9274387293874',
                        excludeTaxPrice: 650000.00,
                        taxPaymentCertificateNumber: '123123213',

                        // 吨位
                        tonnage: null,

                        // 限乘人数
                        capacity: 5,

                        // 生产企业名称
                        manufacturer: 'tesla'
                    };
                }
            },

            // watch 数据
            watchCollection: function () {
                $scope.$watch('operateType', function (newValue, oldValue) {
                    if (newValue) {

                        if (newValue === constant.Operation.Add) {
                            thisService.addInvoiceModalDialog();
                        } else if (newValue === constant.Operation.Edit) {

                            //$scope.isReadOnly = true;
                            thisService.open();
                        } else if (newValue === constant.Operation.Query) {
                            // thisService.showInvoiceDialog();
                            $scope.isQueryOnly = true;
                            thisService.open();
                        }
                    }
                });


                //$scope.$watch('editModel.subtotalforFinalPayment', function (newValue, oldValue) {
                //    if (newValue) {
                //        thisService.changeSubtotalforFinalPayment();
                //    }
                //});
            },

            // 设置勾选
            setCheck: function (data) {

                if (data.historyReasonList && data.historyReasonList.length > 0) {
                    data.historyReasonList = angular.copy(data.historyReasonList);
                    if (data.reasonIDList && data.reasonIDList.length > 0) {
                        var checkedList = _.filter(data.historyReasonList, function (row) {
                            return data.reasonIDList.indexOf(row.id) > -1;
                        });

                        if (checkedList && checkedList.length > 0) {
                            checkedList.forEach(function (row) {
                                row.checked = true;
                            });
                        }
                    }
                }

                return data;
            },

            // 编辑发票修改
            editCheckInvoice: function (model) {
                if (!model.reasonList || model.reasonList.length === 0) {
                    return $translate.instant('ReasonRequire');
                }

                if (!model.subtotalforFinalPayment) {
                    return $translate.instant('SubtotalforFinalPaymentRequire');
                }

                return null;
            },

            // 首次设置价格
            firstSetPrice: function (data) {
                if (data.vatTax === null || data.excludeTaxPrice === null) {
                    data = this.setPrice(data);
                }

                return data;
            },

            addControlsInit: function () {

                var selectedTaxControlId = null;
                if (thisService.OwnerOrgModel && thisService.OwnerOrgModel.taxControlDiskList && thisService.OwnerOrgModel.taxControlDiskList.length === 1) {
                    $scope.editModel.taxControlDisk = thisService.OwnerOrgModel.taxControlDiskList[0];
                    selectedTaxControlId = thisService.OwnerOrgModel.taxControlDiskList[0].id;
                }



                $scope.textBoxOption = {
                    registrationLocalNameOpt: {
                        bindingOptions: {
                            value: 'editModel.registrationLocalName',
                        },
                        maxLength: 100,
                        placeholder: $translate.instant('RegistrationLocalNamePlaceholder')
                    },
                    buyerCodeOpt: {
                        bindingOptions: {
                            value: 'editModel.buyerIDOrCode',
                        },
                        maxLength: 100,
                        placeholder: $translate.instant('BuyerCodePlaceholder')
                    },
                    companyVATIDTaxIDOpt: {
                        bindingOptions: {
                            value: 'editModel.companyVATIDTaxID',
                        },
                        maxLength: 50,
                        placeholder: $translate.instant('CompanyVATIDTaxIDPlaceholder')
                    },
                    governmentClassificationOpt: {
                        dataSource:constant.CarType,
                        bindingOptions: {
                            value: 'editModel.governmentClassification',
                        },
                    },
                    brandandModelNumberOpt: {
                        bindingOptions: {
                            value: 'editModel.brandandModelNumber',
                        },
                        maxLength: 50,
                        placeholder: $translate.instant('BrandandModelNumberPlaceholder')
                    },
                    producingPlaceOpt: {
                        bindingOptions: {
                            value: 'editModel.producingPlace',
                        },
                        maxLength: 20,
                        placeholder: $translate.instant('ProducingPlacePlaceholder')
                    },
                    certificateNumberOpt: {
                        bindingOptions: {
                            value: 'editModel.certificateNumber',
                        },
                        maxLength: 50,
                        placeholder: $translate.instant('CertificateNumberPlaceholder')
                    },
                    importCertificateNumberOpt: {
                        bindingOptions: {
                            value: 'editModel.importCertificateNumber',
                        },
                        maxLength: 50,
                        placeholder: $translate.instant('ImportCertificateNumberPlaceholder')
                    },
                    ciqNumberOpt: {
                        bindingOptions: {
                            value: 'editModel.ciqNumber',
                        },
                        maxLength: 50,
                        placeholder: $translate.instant('CiqNumberPlaceholder')
                    },
                    motorNumberOpt: {
                        bindingOptions: {
                            value: 'editModel.motorNumber',
                        },
                        maxLength: 50,
                        placeholder: $translate.instant('MotorNumberPlaceholder')
                    },
                    vinOpt: {
                        bindingOptions: {
                            value: 'editModel.vin',
                        },
                        maxLength: 50,
                        placeholder: $translate.instant('VinPlaceholder')
                    },
                    subtotalforFinalPaymentCHOpt: {
                        bindingOptions: {
                            value: 'editModel.subtotalforFinalPaymentCH',
                        },
                        readOnly: true
                    },
                    subtotalforFinalPaymentOpt: {
                        bindingOptions: {
                            value: 'editModel.subtotalforFinalPayment',
                        },
                        valueChangeEvent: "keyup",
                        maxLength: 20,
                        placeholder: $translate.instant('SubtotalforFinalPaymentPlaceholder'),
                        onValueChanged: function (e) {
                            $scope.editModel.subtotalforFinalPayment = e.value;
                            thisService.changeSubtotalforFinalPayment();
                        }
                    },
                    salesUnitNameOpt: {
                        bindingOptions: {
                            value: 'editModel.salesUnitName',
                        },
                        readOnly: true
                    },
                    salesUnitPhoneNumberOpt: {
                        bindingOptions: {
                            value: 'editModel.salesUnitPhoneNumber',
                        },
                        readOnly: true
                    },
                    salesTaxPayerNumberOpt: {
                        bindingOptions: {
                            value: 'editModel.salesTaxPayerNumber',
                        },
                        readOnly: true
                    },
                    salesAccountOpt: {
                        bindingOptions: {
                            value: 'editModel.salesAccount',
                        },
                        readOnly: true
                    },
                    salesAddressOpt: {
                        bindingOptions: {
                            value: 'editModel.salesAddress',
                        },
                        readOnly: true
                    },
                    salesBankNameOpt: {
                        bindingOptions: {
                            value: 'editModel.salesBankName',
                        },
                        readOnly: true
                    },
                    vatRateorLevyRateOpt: {
                        bindingOptions: {
                            value: 'editModel.vatRateorLevyRate',
                        },
                        height: 44,
                        readOnly: true
                    },
                    vatTaxOpt: {
                        bindingOptions: {
                            value: 'editModel.vatTax',
                        },
                        height: 44,
                        readOnly: true
                    },
                    excludeTaxPriceOpt: {
                        bindingOptions: {
                            value: 'editModel.excludeTaxPrice',
                        },
                        readOnly: true
                    },
                    tonnageOpt: {
                        bindingOptions: {
                            value: 'editModel.tonnage',
                        },
                        maxLength: 10,
                        placeholder: $translate.instant('TonnagePlaceholder')
                    },
                    capacityOpt: {
                        bindingOptions: {
                            value: 'editModel.capacity',
                        },
                        maxLength: 10,
                        valueChangeEvent: "keyup",
                        // placeholder:$translate.instant('CapacityPlaceholder'),
                        onValueChanged: function (e) {
                            $scope.editModel.capacity = e.value.replace(/[^\d]/g, "");
                        }
                    },
                    selectTaxControlDiskOptions: {
                        bindingOptions: {
                            dataSource: 'editModel.taxControlDiskList',
                            value: 'editModel.taxControlDisk.id',
                        },
                        //dataSource: thisService.OwnerOrgModel.taxControlDiskList,
                        onSelectionChanged: function (args) {
                            $scope.editModel.taxControlDisk = args.selectedItem;
                             
                        },
                        itemTemplate: function (itemData, itemIndex, itemElement) {
                            var span = $('<span title="' + itemData.name + '">').text(itemData.name);
                            itemElement.append(span);
                        },
                        noDataText: $translate.instant('NoDataText'),
                        valueExpr: 'id',
                        displayExpr: 'name'
                    },

                };

                $scope.validateOption = {
                    registrationLocalNameOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('RegistrationLocalNameRequire')
                        }]
                    },
                    buyerCodeOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('BuyerCodePlaceholder')
                        },
                         {
                             type: 'stringLength',
                             min: 18, max: 18,
                             message: $translate.instant('LengthNotEqual') + '&nbsp;18'
                         },
                        {
                            type: "pattern",
                            pattern: '^[a-zA-Z0-9]+$',
                            message: $translate.instant('NotLetterAndNumber')
                        },
                        //{
                        //    type: "custom",
                        //    validationCallback: function (options) {
                        //        //表示目前的值是组织机构代码
                        //        if ($scope.editModel.companyVATIDTaxID) {
                        //            return true;
                        //        }
                        //        //身份证号码
                        //        var data = options.value;
                        //        var r = cardValidationService.CardCheck(data);
                        //        options.rule.message = r.message;
                        //        return r.pass;
                        //    }
                        //}
                        ]
                    },
                    companyVATIDTaxIDOpt: {
                        validationRules: [
                        //    {
                        //    type: "required",
                        //    message: $translate.instant('CompanyVATIDTaxIDRequire')
                        //},
                        //{
                        //    type: 'stringLength',
                        //    min: 18, max: 18,
                        //    message: $translate.instant('LengthNotEqual') + '&nbsp;18'
                        //},
                        //{
                        //    type: "pattern",
                        //    pattern: '^[a-zA-Z0-9]+$',
                        //    message: $translate.instant('NotLetterAndNumber')
                        //},
                        {
                            type: "custom",
                            message: $translate.instant('OrgCompanyIDNotEqual'),
                            validationCallback: function (options) {
                                var data = options.value;
                                if (data !== null && data !== undefined && data !== '') {
                                    if (data !== $scope.editModel.buyerIDOrCode) {
                                        options.rule.message = $translate.instant('OrgCompanyIDNotEqual');
                                        return false;
                                    }

                                }
                                return true;
                            }
                        }]
                    },
                    governmentClassificationOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('GovernmentClassificationRequire')
                        }]
                    },
                    brandandModelNumberOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('BrandandModelNumberRequire')
                        }]
                    },
                    producingPlaceOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('ProducingPlaceRequire')
                        }]
                    },
                    certificateNumberOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('CertificateNumberRequire')
                        }]
                    },
                    importCertificateNumberOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('ImportCertificateNumberRequire')
                        },
                         {
                             type: 'stringLength',
                             min: 12, max: 12,
                             message: $translate.instant('LengthNotEqual') + '&nbsp;12'
                         },
                        {
                            type: "pattern",
                            pattern: '^[a-zA-Z0-9]+$',
                            message: $translate.instant('NotLetterAndNumber')
                        }
                        ]
                    },
                    ciqNumberOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('CiqNumberRequire')
                        },
                         {
                             type: 'stringLength',
                             min: 9, max: 9,
                             message: $translate.instant('LengthNotEqual') + '&nbsp;9'
                         },
                        {
                            type: "pattern",
                            pattern: '^[a-zA-Z0-9]+$',
                            message: $translate.instant('NotLetterAndNumber')
                        }]
                    },
                    motorNumberOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('MotorNumberRequire')
                        }]
                    },
                    vinOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('VinRequire')
                        },
                         {
                             type: 'stringLength',
                             min: 17, max: 17,
                             message: $translate.instant('LengthNotEqual') + '&nbsp;17'
                         },
                        {
                            type: "pattern",
                            pattern: '^[a-zA-Z0-9]+$',
                            message: $translate.instant('NotLetterAndNumber')
                        }]
                    },
                    subtotalforFinalPaymentOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('SubtotalforFinalPaymentRequire')
                        }
                        ]
                    },
                    tonnageOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('TonnageRequire')
                        }]
                    },
                    capacityOpt: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('CapacityRequire')
                        }]
                    },
                    selectTaxControlDiskOptions: {
                        validationRules: [{
                            type: "required",
                            message: $translate.instant('TaxControlDiskRequire')
                        }]
                    }

                };

            },

            parseDbModel: function (model) {
                if (!model.vehicleModel) {
                    //model.vehicleModel = model.governmentClassification;
                }

                if (!model.cabinConfiguration) {
                    var temp = window.PWC.convertChineseSimple(model.capacity);
                    model.cabinConfiguration = temp + "座座椅布局";
                }

                return model;
            },

            // 打开弹出框
            open: function () {
                var editModel = {};


                thisService.isChanged = false;

                if (this.testEditModel) {
                    editModel = thisService.testEditModel;


                }

                $scope.showCancelRemark = false;
                if ($scope.invoiceModel) {
                    thisService.setPrice($scope.invoiceModel);

                    if ($scope.isReadOnly) {

                        if ($scope.invoiceModel.bdStatus === 5) {
                            $scope.showCancelRemark = true;
                        }

                        if ($scope.invoiceModel.bdStatus === 'Cancelled') {
                            $scope.showCancelRemark = true;
                        }
                    }
                    $scope.editModel = $scope.invoiceModel;
                    if (!$scope.editModel.buyerIDOrCode) {
                        $scope.editModel.buyerIDOrCode = thisService.getBuyerInfo($scope.invoiceModel);
                    }

                    if ($scope.editModel.bdIssuedDate) {
                        $scope.editModel.bdIssuedDate = new Date($scope.editModel.bdIssuedDate).formatDateTime('yyyy-MM-dd');
                    }

                } else {
                    $scope.editModel = editModel;
                }

                //editModel.historyReasonList = thisService.reasonList;
                if (thisService.OutputInvoiceUpdateReasonList && thisService.OutputInvoiceUpdateReasonList.length > 0) {
                    $scope.editModel.historyReasonList = _.filter(thisService.OutputInvoiceUpdateReasonList, function (row) {
                        return row.type === constant.OutputInvoiceReasonType.EditInvoiceReason;
                    });

                    $scope.editModel.historyReasonList = angular.copy($scope.editModel.historyReasonList);

                    thisService.firstSetPrice($scope.editModel);
                    // $scope.invoiceModel.checked
                } else {
                    vatOutputInvoiceManageService.getAllOutputInvoiceUpdateReasonList().success(function (data) {

                        thisService.OutputInvoiceUpdateReasonList = data;
                        $scope.editModel.historyReasonList = _.filter(thisService.OutputInvoiceUpdateReasonList, function (row) {
                            return row.type === constant.OutputInvoiceReasonType.EditInvoiceReason;
                        });

                        $scope.editModel.historyReasonList = angular.copy($scope.editModel.historyReasonList);

                        thisService.firstSetPrice($scope.editModel);
                    });
                }

                var modalInstance = $uibModal.open({
                    animation: true,
                    backdrop: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'editInvoiceModal.html',
                    windowClass: 'edit-invoice-modal-wrapper',
                    scope: $scope,
                    size: 'size',
                    resolve: {
                        editModel: $scope.editModel
                    }
                });

                modalInstance.result.then(function (data) {
                    // $scope.templateModel = data;
                    $scope.isUpdate = true;
                    $scope.isReadOnly = true;
                    $scope.isQueryOnly = false;

                    $scope.operateType = null;
                }, function () {
                    $scope.operateType = null;
                    $scope.isReadOnly = true;
                    $scope.isUpdate = false;
                    $scope.isQueryOnly = false;
                    // $scope.onClosed({ param: {} });
                    // 如果修改了,数据,点取消之后,数据应该同步
                    if (thisService.isChanged && $scope.onChanged) {
                        $scope.onChanged({ param: {} });
                    }

                    $log.info('Modal dismissed at: ' + new Date());
                });


                var saveData = function (model) {

                    vatOutputInvoiceManageService.addOutputInvoicePrinted(model, true).success(function (ret) {

                        if (ret.result) {
                            $scope.isUpdate = true;
                            $scope.operateType = null;
                            $scope.isReadOnly = true;
                            // SweetAlert.success($translate.instant('SaveSuccess'));
                            modalInstance.close(model);
                            $scope.onClosed({ param: model });
                        } else {
                            swal($translate.instant('SaveFail'), $translate.instant('SaveFail'), 'warning');
                        }

                    });
                };

                // 打印
                $scope.save = function () {

                    var model = $scope.editModel;

                    // 选中的理由
                    model.reasonList = _.filter(model.historyReasonList, function (row) {
                        return row.checked;
                    });

                    var checkResult = thisService.editCheckInvoice(model);

                    if (checkResult) {
                        swal($translate.instant('SaveFail'), checkResult, 'warning');
                        return;
                    }

                    model = thisService.parseDbModel(model);
                    saveData(model);
                };

                $scope.saveUpdate = function () {

                    var model = $scope.editModel;

                    // 选中的理由
                    model.reasonList = _.filter(model.historyReasonList, function (row) {
                        return row.checked;
                    });

                    var checkResult = thisService.editCheckInvoice(model);

                    if (checkResult) {
                        swal($translate.instant('SaveFail'), checkResult, 'warning');
                        return;
                    }

                    model.id = model.editInvoiceId;

                    model = thisService.parseDbModel(model);

                    vatOutputInvoiceManageService.updateOutputInvoiceEdit(model).success(function (ret) {
                        if (ret.result) {
                            SweetAlert.success($translate.instant('SaveSuccess'));
                            $scope.isReadOnly = true;

                            thisService.isChanged = true;

                            // 保持成功修改后添加历史记录
                            $scope.saveEditInvoiceHistory();

                        } else {
                            swal($translate.instant('SaveFail'), $translate.instant('SaveFail'), 'warning');
                        }
                    });
                };

                // 取消
                $scope.cancel = function () {
                    modalInstance.dismiss('cancel');
                };

                // 设置entity info
                var setEntityInfo = function (data) {
                    $scope.editModel.salesUnitName = data.name;
                    $scope.editModel.salesUnitPhoneNumber = data.phoneNumber;
                    $scope.editModel.salesTaxPayerNumber = data.taxPayerNumber;
                    $scope.editModel.salesAccount = data.bankAccountNumber;
                    $scope.editModel.salesAddress = data.manufactureAddress;
                    $scope.editModel.salesBankName = data.bankAccountName;
                    $scope.editModel.salesOrgID = data.id;
                    $scope.editModel.taxControlDisk = {};
                    if (data.taxControlDiskList && data.taxControlDiskList.length > 0) {
                        data.taxControlDiskList.forEach(function (row) {

                            row.name = row.taxControlDiskSerialNumber + row.taxControlDiskDescribe;
                        });

                        if (data.taxControlDiskList.length === 1) {
                            $scope.editModel.taxControlDisk = data.taxControlDiskList[0];
                        }
                    }

                    $scope.editModel.taxControlDiskList = data.taxControlDiskList;

                };

                if ($scope.editModel.salesUnitName) {
                    var obj = _.find($scope.editModel.sameVehicleroutinglocationList, function (row) {
                        return row.name === $scope.editModel.salesUnitName;
                    });

                    if (obj) {
                        $scope.editModel.salesOrgID = obj.id;
                    }
                }

                if ($scope.editModel.sameVehicleroutinglocationList && $scope.editModel.sameVehicleroutinglocationList.length > 0) {

                    $timeout(function () {

                        $('#' + thisService.selectEntityList_ID).dxSelectBox({
                            dataSource: $scope.editModel.sameVehicleroutinglocationList,
                            valueExpr: 'id',
                            value: $scope.invoiceModel.salesOrgID,
                            displayExpr: 'name',
                            onSelectionChanged: function (args) {
                                setEntityInfo(args.selectedItem);
                            }
                        });

                    }, 50);

                }

            },

            // 手动添加发票弹出框
            addInvoiceModalDialog: function () {
                thisService.addControlsInit();


                var editModel = {
                    registrationLocalName: '',
                    companyVATIDTaxID: '',
                    governmentClassification: '',
                    brandandModelNumber: '',
                    producingPlace: '美国',
                    certificateNumber: '无',
                    importCertificateNumber: '',
                    ciqNumber: '',
                    motorNumber: '',
                    vin: '',
                    subtotalforFinalPaymentCH: '',
                    subtotalforFinalPayment: '',
                    invoiceCode: '',
                    invoiceNumber: '',
                    salesUnitName: '',
                    salesUnitPhoneNumber: '',
                    salesTaxPayerNumber: '',
                    salesAccount: '',
                    salesAddress: '',
                    salesBankName: '',
                    vatRateorLevyRate: '17%',
                    taxableSubtotal: 0.00,
                    mainTaxAuthoritiesCode: '',
                    excludeTaxPrice: 0,
                    taxPaymentCertificateNumber: '',

                    // 吨位
                    tonnage: '无',

                    // 限乘人数
                    capacity: '',

                    // 生产企业名称
                    manufacturer: '拓速乐佛利蒙总装厂'
                };

                //editModel.historyReasonList = thisService.reasonList;

                // thisService.setPrice(editModel);

                $scope.editModel = editModel;
                $scope.editModel.buyerInfo = thisService.getBuyerInfo($scope.editModel);

                if (thisService.OutputInvoiceUpdateReasonList && thisService.OutputInvoiceUpdateReasonList.length > 0) {
                    var reasonListTemp = _.filter(thisService.OutputInvoiceUpdateReasonList, function (row) {
                        return row.type === constant.OutputInvoiceReasonType.ManualInvoiceReason;
                    });

                    $scope.editModel.historyReasonList = angular.copy(reasonListTemp);

                } else {
                    vatOutputInvoiceManageService.getAllOutputInvoiceUpdateReasonList().success(function (data) {

                        thisService.OutputInvoiceUpdateReasonList = data;
                        var reasonListTemp = _.filter(thisService.OutputInvoiceUpdateReasonList, function (row) {
                            return row.type === constant.OutputInvoiceReasonType.ManualInvoiceReason;
                        });

                        $scope.editModel.historyReasonList = angular.copy(reasonListTemp);
                    });
                }

                var modalInstance = $uibModal.open({
                    animation: true,
                    backdrop: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'addInvoiceModal.html',
                    windowClass: 'edit-invoice-modal-wrapper',
                    scope: $scope,
                    size: 'add',
                    resolve: {
                        editModel: editModel
                    }
                });

                modalInstance.result.then(function (data) {
                    // $scope.templateModel = data;
                    $scope.isUpdate = true;
                    $scope.isReadOnly = true;
                    // $scope.onClosed({ model: data });
                    $scope.operateType = null;
                }, function () {
                    $scope.operateType = null;
                    $scope.isReadOnly = true;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });


                var saveData = function (model) {

                    vatOutputInvoiceManageService.addOutputInvoicePrinted(model, true).success(function (ret) {

                        if (ret.result) {
                            $scope.isUpdate = true;
                            $scope.operateType = null;
                            SweetAlert.success($translate.instant('SaveSuccess'));
                            modalInstance.close(model);

                            $state.go('outputInvoiceManage.issuedInvoiceBdView');
                            //$scope.onClosed({ param: model });

                        } else {
                            swal($translate.instant('SaveFail'), $translate.instant('SaveFail'), 'warning');
                        }

                    });
                };


                $scope.checkReasonChanged = function () {

                    $scope.editModel.reasonList = _.filter($scope.editModel.historyReasonList, function (row) {
                        return row.id === $scope.editModel.selectReasonID;
                    });

                    if (!$scope.editModel.reasonList || $scope.editModel.reasonList.length === 0) {
                        $scope.editModel.historyReasonListError = $translate.instant('ManualReasonRequire');
                        return;
                    } else {
                        $scope.editModel.historyReasonListError = null;
                    }

                };

                // 保存
                $scope.save = function (params) {
                    var model = $scope.editModel;
                    // 选中的理由

                    $scope.checkReasonChanged();
                    var dxResult = DevExpress.validationEngine.validateGroup($('#addInvoiceModalForm').dxValidationGroup("instance")).isValid;
                    var specialValid = true;
                    //表示目前的值是组织机构代码
                    if (!$scope.editModel.companyVATIDTaxID) {
                        //身份证号码
                        // var data = options.value;
                        var r = cardValidationService.CardCheck($scope.editModel.buyerIDOrCode);
                        var IDCard = $("#buyer-code").dxTextBox('instance');
                        IDCard.option("isValid", r.pass);
                        IDCard.option("validationError", { message: r.message });
                        specialValid = r.pass;
                    }
                    else {
                        //表示不是身份证,需要验证2个是否相等
                        var company = $("#company-taxID").dxTextBox('instance');
                        if ($scope.editModel.companyVATIDTaxID !== $scope.editModel.buyerIDOrCode) {
                            company.option("isValid", false);
                            company.option("validationError", { message: $translate.instant('OrgCompanyIDNotEqual') });
                            specialValid = false;
                        }
                        else {
                            company.option("isValid", true);
                            company.option("validationError", { message: '' });
                        }
                    }

                    if (!dxResult || $scope.editModel.historyReasonListError !== null || !specialValid) {
                        return;
                    }

                   $scope.invoiceConfirmModel = {
                        type:1,
                        taxControlDiskID:$scope.editModel.taxControlDisk.id,
                   };
                   $scope.invoiceConfirmType = constant.Operation.Open;
                   model = thisService.parseDbModel(model);

                   $scope.invoiceConfirmFunction = function(param){
                      saveData(model);
                   };
                    
                };

                // 取消
                $scope.cancel = function () {
                    modalInstance.dismiss('cancel');
                };

                // 设置entity info
                var setEntityInfo = function (data) {
                    $scope.editModel.salesUnitName = data.name;
                    $scope.editModel.salesUnitPhoneNumber = data.phoneNumber;
                    $scope.editModel.salesTaxPayerNumber = data.taxPayerNumber;
                    $scope.editModel.salesAccount = data.bankAccountNumber;
                    $scope.editModel.salesAddress = data.manufactureAddress;
                    $scope.editModel.salesBankName = data.bankAccountName;
                    $scope.editModel.vehicleroutinglocation = data.vehicleroutinglocation;
                    $scope.editModel.salesOrgID = data.id;
                    $scope.editModel.taxControlDisk = {};

                    if (data.taxControlDiskList && data.taxControlDiskList.length > 0) {
                        data.taxControlDiskList.forEach(function (row) {

                            row.name = row.taxControlDiskSerialNumber + row.taxControlDiskDescribe;
                        });

                        if (data.taxControlDiskList.length === 1) {
                            $scope.editModel.taxControlDisk = data.taxControlDiskList[0];
                        }
                    }

                    $scope.editModel.taxControlDiskList = data.taxControlDiskList;
                };

                $timeout(function () {

                    setEntityInfo(thisService.OwnerOrgModel);
                    $scope.editModel.sameVehicleroutinglocationList = thisService.OwnerOrgModel.sameVehicleroutinglocationList;

                    if ($scope.editModel.sameVehicleroutinglocationList && $scope.editModel.sameVehicleroutinglocationList.length > 0) {
                        $('#' + thisService.select_ADD_EntityList_ID).dxSelectBox({
                            dataSource: $scope.editModel.sameVehicleroutinglocationList,
                            valueExpr: 'id',
                            value: $scope.editModel.salesOrgID,
                            displayExpr: 'name',
                            onSelectionChanged: function (args) {
                                setEntityInfo(args.selectedItem);
                            }
                        });
                    }

                }, 50);
            },

            // 验证输入的发票信息
            checkInputInvoice: function (data) {
                if (!data.registrationLocalName) {

                    data.registrationLocalNameHasError = true;
                    return $translate.instant('RegistrationLocalNameRequire');
                } else {
                    data.registrationLocalNameHasError = false;
                }

                if (!data.companyVATIDTaxID) {
                    data.companyVATIDTaxIDHasError = true;
                    return $translate.instant('CompanyVATIDTaxIDRequire');
                } else {
                    data.companyVATIDTaxIDHasError = false;
                }

                if (!data.governmentClassification) {
                    return $translate.instant('GovernmentClassificationRequire');
                }

                if (!data.brandandModelNumber) {
                    return $translate.instant('BrandandModelNumberRequire');
                }


                if (!data.producingPlace) {
                    return $translate.instant('ProducingPlaceRequire');
                }


                if (!data.certificateNumber) {
                    return $translate.instant('CertificateNumberRequire');
                }

                if (!data.importCertificateNumber) {
                    return $translate.instant('ImportCertificateNumberRequire');
                }

                if (!data.ciqNumber) {
                    return $translate.instant('CiqNumberRequire');
                }


                if (!data.motorNumber) {
                    return $translate.instant('MotorNumberRequire');
                }


                if (!data.vin) {
                    return $translate.instant('VinRequire');
                }

                if (!data.subtotalforFinalPayment) {
                    return $translate.instant('SubtotalforFinalPaymentRequire');
                }


                if (!data.tonnage) {
                    return $translate.instant('TonnageRequire');
                }


                if (!data.capacity) {
                    return $translate.instant('CapacityRequire');
                }

                return null;

            },

            // 查看发票
            showInvoiceDialog: function () {

                var editModel = {};

                if ($scope.invoiceModel) {
                    $scope.editModel = $scope.invoiceModel;
                    thisService.setPrice($scope.invoiceModel);
                    $scope.editModel.buyerInfo = thisService.getBuyerInfo($scope.invoiceModel);

                } else {
                    $scope.editModel = editModel;
                }

                var modalInstance = $uibModal.open({
                    animation: true,
                    backdrop: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'queryInvoiceModal.html',
                    windowClass: 'edit-invoice-modal-wrapper',
                    scope: $scope,
                    size: 'show',
                    resolve: {
                        editModel: editModel
                    }
                });

                modalInstance.result.then(function (data) {
                    // $scope.templateModel = data;
                    $scope.isUpdate = true;
                    $scope.isReadOnly = true;
                    // $scope.onClosed({ model: data });
                    $scope.operateType = null;
                }, function () {
                    $scope.operateType = null;
                    $scope.isReadOnly = true;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });

                // 取消
                $scope.cancel = function () {
                    modalInstance.dismiss('cancel');
                };
            },

            // 进入编辑状态
            updateStatus: function () {

                $scope.isReadOnly = false;
            },

            // 验证输入金额
            // 小写金额 自动转大写
            changeSubtotalforFinalPayment: function () {

                var value = $scope.editModel.subtotalforFinalPayment;

                value = thisService.limitTwoDigital(value);

                if (value != $scope.editModel.subtotalforFinalPayment) {
                    $scope.editModel.subtotalforFinalPayment = value;
                }

                if (value) {

                    var temp = parseFloat(value);
                    if (temp > thisService.MaxPrice) {
                        value = value.substr(0, value.length - 1);
                        $scope.editModel.subtotalforFinalPayment = value;
                    }
                }

                if (value) {
                    $scope.editModel.subtotalforFinalPaymentCH = window.PWC.convertChineseCurrency(value);
                } else {
                    $scope.editModel.subtotalforFinalPaymentCH = '';
                }

                thisService.setPrice($scope.editModel);
            },

            getUserOwnerOrganization: function () {
                userService.getUserOwnerOrganization().success(function (data) {
                    if (data) {
                        if (data.taxControlDiskList && data.taxControlDiskList.length > 0) {
                            data.taxControlDiskList.forEach(function (row) {

                                row.name = row.taxControlDiskSerialNumber + row.taxControlDiskDescribe;
                            });
                        }
                    }

                    thisService.OwnerOrgModel = data;
                });
            }
        };

        var historyService = {
            main: function () {
                //显示手工导入数据历史记录
                $scope.openEditInvoiceHistory = function (event) {
                    $('#history-pop-container').css({ 'top': 120 + 'px', 'left': -90 + 'px' }).show(500);
                };

                //关闭手工导入数据历史记录
                $scope.closeEditInvoiceHistory = function () {
                    var model = $scope.invoiceModel;
                    $('#history-pop-container').hide(500);
                };

                //toggle手工导入数据历史记录
                $scope.toggleEditInvoiceHistory = function () {
                    $('#history-pop-container').css({ 'top': 120 + 'px', 'left': -90 + 'px' }).toggle(500);
                };

                //获取手工导入数据历史记录
                var getEditInvoiceHistory = function () {
                    if ($scope.editModel && $scope.editModel.editInvoiceId) {
                        vatOutputInvoiceManageService.getOutputInvoiceEditHistory($scope.editModel.editInvoiceId).success(function (result) {
                            if (result && result.length > 0) {
                                _.each(result, function (item) {
                                    item.createTime = (new Date(item.createTime)).dateTimeToString('yyyyMMdd hh:mm');
                                    if (item.amount) {
                                        item.amount = item.amount.formatAmount(2);
                                    }
                                });
                                $scope.syncHistoryList = result;
                            } else {
                                $scope.syncHistoryList = [];
                            }
                        });
                    }
                };

                $scope.$watch('editModel.editInvoiceId', function () {
                    getEditInvoiceHistory();
                });

                $scope.$watch('editModel', function () {
                    if ($scope.editModel) {
                        $scope.manufacturerOrg = $scope.editModel.manufacturer;
                        $scope.salesUnitNameOrg = $scope.editModel.salesUnitName;
                    }
                });

                $scope.saveEditInvoiceHistory = function () {
                    //保存手工编辑发票的历史记录
                    var historyModel = {};
                    historyModel.outputInvoiceID = $scope.editModel.editInvoiceId;
                    historyModel.amount = $scope.editModel.subtotalforFinalPayment;
                    historyModel.createBy = loginContext.userName;
                    _.each($scope.editModel.historyReasonList, function (item) {
                        if (item.checked) {

                            if (historyModel.englishReasons) {
                                historyModel.reasonIDs += ',' + item.id;
                                historyModel.englishReasons += '|' + item.englishName;
                                historyModel.chineseReasons += '|' + item.chineseName;
                            } else {
                                historyModel.reasonIDs = item.id;
                                historyModel.englishReasons = item.englishName;
                                historyModel.chineseReasons = item.chineseName;
                            }

                            historyModel.manufacturer = '';
                            historyModel.issuingEntity = '';
                            if ($scope.manufacturerOrg != $scope.editModel.manufacturer) {
                                historyModel.manufacturer = $scope.editModel.manufacturer;
                            }
                            if ($scope.salesUnitNameOrg != $scope.editModel.salesUnitName) {
                                historyModel.issuingEntity = $scope.editModel.salesUnitName;
                            }
                        }
                    });
                    //添加手工修改数据的历史记录
                    vatOutputInvoiceManageService.addOutputInvoiceEditHistory(historyModel).success(function () {
                        $scope.manufacturerOrg = $scope.editModel.manufacturer;
                        $scope.salesUnitNameOrg = $scope.editModel.salesUnitName;
                        getEditInvoiceHistory();
                    });
                };
            }
        };

        (function () {
            thisService.main();
            historyService.main();
        })();

    }
]);
commonModule.directive('editInvoiceModal', ['$log',
function ($log) {
    return {
        restrict: 'E',
        templateUrl: '/app/common/controls/edit-invoice-modal/edit-invoice-modal.html' + '?_=' + Math.random(),
        replace: true,
        scope: {
            operateType: '=',
            invoiceModel:'=?',
            onClosed:'&',
            onChanged:'&'
        },
        controller: 'editInvoiceModalController',
        link: function ($scope, $element, $attr) {

        }
    }
}]);
commonModule.
controller('editOrganizationModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', 'areaRegionService', '$filter', 'SweetAlert', 'regionService', 'orgService', 'enterpriseAccountService', 'organizationStructureService', 'businessUnitService', 'projectService', 'dimensionService',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, areaRegionService, $filter, SweetAlert, regionService, orgService, enterpriseAccountService, organizationStructureService, businessUnitService, projectService, dimensionService) {

        var selectedModel = '.addOrgControlPop'; //'#addOrgControlPop' + $scope.dimensionId;

        $scope.pleaseSelect = $translate.instant('PleaseSelect');

        var defaultSelcectRegion = {
            id: 0,
            name: '',
            shortName: '',
            mergerName: '',
        };

        $scope.showPage = function (pageIndex) {

            // if (pageIndex === 0)
            // {
            //     $('#orgModalFooter').css('padding-left','139px');
            // } else{
            //     $('#orgModalFooter').css('padding-left','35px');
            // }

        };

        // 新建机构
        var newOrg = function () {
            $scope.editOrgModel = {
                TypeLevel: 1,
                code:''

            };

            refreshOrg();

            $scope.isAdd = true;
            $scope.isShowBasic = false;
            $scope.isShowAdvanced = false;
            $scope.isShowRight = false;
            $scope.selfDimensionError = false;

            // 选项清空
            $scope.selectLevelType = null;
            $scope.selectProvince = null;
            $scope.selectRegionID = null;

            $scope.selectRegion = defaultSelcectRegion;
            $scope.selectProjectIndustry = null;
            $scope.selectBusinessUnit = null;
            if ($scope.newOrganization) {

                // 默认事业部
                if ($scope.newOrganization.businessUnitID) {
                    $scope.selectBusinessUnit = _.find($scope.businessUnitList, function (num) {
                        return num.id === $scope.newOrganization.businessUnitID;
                    });
                }

                // 默认区域
                if ($scope.newOrganization.areaID && $scope.newOrganization.areaName) {
                    $scope.editOrgModel.areaID = $scope.newOrganization.areaID;
                    $scope.editOrgModel.areaName = $scope.newOrganization.areaName;
                }
            }


            $scope.orgAccountList = [];
            $scope.serviceList = [];
            $scope.isCheckedServiceList = [];
            $scope.OrgAccountRowIndex = 1;
            $scope.newOrgAccountRow();

            $scope.selfDimensionModel = getAddOrgSetDimension();
            initIsCheckedServiceList();
            // resetErrorStatus();
            $scope.orgControlForm.$setPristine();
            $scope.advancedControlForm.$setPristine();
            // set first active page is basic info
            $('#orgControlTab a:first').tab('show');
            // $('#orgModalFooter').css('padding-left','139px');
            $(selectedModel).modal('show');
        };

        $scope.nameKeyUp = function(){
            var hasSpecialChar = window.PWC.hasSpecialChar($scope.editOrgModel.name);

            if (hasSpecialChar){
                $scope.editOrgModel.nameError = $translate.instant('SpecialChar');
            } else{
                $scope.editOrgModel.nameError = null;
            }
        }

        // 保存机构
        $scope.saveOrg = function () {

            this.orgControlForm.$setSubmitted();

            var hasSpecialChar = window.PWC.hasSpecialChar($scope.editOrgModel.name);
            if (hasSpecialChar) {
                $scope.editOrgModel.nameError = $translate.instant('SpecialChar');
                $scope.isShowBasic = true;
                return false;
            }

            if (this.orgControlForm.$invalid ) {
                $scope.isShowBasic = true;
                return;
            } else {
                $scope.isShowBasic = false;
            }

            if (checkEnterpriseSetOrg() || checkTemplateList()) {
                $scope.isShowAdvanced = true;
                return;
            } else {
                $scope.isShowAdvanced = false;
            }

            //this.advancedControlForm.$setSubmitted();
            //if (this.advancedControlForm.$invalid) {
            //    $scope.isShowAdvanced = true;
            //    return;
            //} else {
            //    $scope.isShowAdvanced = false;
            //}

            //客户代码是固定死的
            $scope.editOrgModel.clientCode = $scope.projectClientName;
            var editModel = $scope.editOrgModel;

            //判断新增或修改
            //$scope.isAdd = editModel.SaveAsNew;

            if ($scope.selectProjectIndustry) {
                editModel.industryID = $scope.selectProjectIndustry.id;
            }

            //层级
            if ($scope.selectLevelType) {
                editModel.structureID = $scope.selectLevelType.id;
                editModel.structureName = $scope.selectLevelType.name;
            }

            // 区域是必填项
            if ($scope.selectProvince && $scope.selectRegionID) {
                editModel.regionID = $scope.selectRegionID;
            }

            var pId = editModel.parentID;
            //上级公司
            if (!pId || pId === constant.organization.parentIdNull) {
                editModel.parentID = constant.organization.parentIdNull;
            }
            //事业部
            if ($scope.selectBusinessUnit) {
                editModel.businessUnitID = $scope.selectBusinessUnit.id;
            }


            //账套
            if ($scope.orgAccountList) {
                $scope.editOrgModel.enterpriseAccountSetOrgList = [];
                $scope.orgAccountList.forEach(function (row) {
                    if (row.enterpriseAccountSetSelectID) {
                        var enterpriseAccountSetOrg = {};
                        enterpriseAccountSetOrg.enterpriseAccountSetID = row.enterpriseAccountSetSelectID;
                        enterpriseAccountSetOrg.effectiveDateStr = row.startDate;
                        enterpriseAccountSetOrg.expiredDateStr = row.endDate;
                        enterpriseAccountSetOrg.organizationID = $scope.editOrgModel.id;
                        enterpriseAccountSetOrg.id = row.id;
                        $scope.editOrgModel.enterpriseAccountSetOrgList.push(enterpriseAccountSetOrg);
                    }
                });
            }
            //服务
            if ($scope.isCheckedServiceList) {
                $scope.editOrgModel.organizationServiceTemplateGroupList = [];
                $scope.isCheckedServiceList.forEach(function (row) {
                    if (row.isChecked) {
                        var organizationServiceTemplateGroup = {};
                        organizationServiceTemplateGroup.organizationID = $scope.editOrgModel.id;
                        organizationServiceTemplateGroup.serviceTypeID = row.id;
                        organizationServiceTemplateGroup.templateGroupID = row.selectedTemplate.id;
                        $scope.editOrgModel.organizationServiceTemplateGroupList.push(organizationServiceTemplateGroup)
                    }
                });
            }

            // 自定义属性
            editModel.dimensionValueOrgList = getSelfDimensionSetValueList();

            if ($scope.selfDimensionError) {
                $scope.isShowBasic = true;
                return;
            }

            if ($scope.isAdd) {
                editModel.isActive = true;
                orgService.addOrg(editModel).success(function (orgId) {
                    if (orgId && !orgId.result) {
                        SweetAlert.warning($translate.instant(orgId.resultMsg));
                        return;
                    };

                    $(selectedModel).modal('hide');

                    SweetAlert.success($translate.instant('SaveSuccess'));

                    refreshOrg();
                    $scope.operateType = null;
                    $scope.isUpdate = true;
                });
            } else {

                if (editModel.parentID && $scope.selectedOrganization.suborgList) {

                    if (editModel.parentID === editModel.id) {
                        SweetAlert.warning('上级机构不能为机构本身');
                        return;
                    };

                    var subOrg = _.find($scope.selectedOrganization.suborgList, function (row) {
                        return row.id === editModel.parentID;
                    });

                    if (subOrg) {
                        SweetAlert.warning('不能将当前机构的下级机构设置为其上级公司');
                        return;
                    }
                };

                editModel.isActive = !editModel.isActive;
                orgService.updateOrg(editModel).success(function (data) {
                    if (data && !data.result) {
                        //SweetAlert.info("Disable", orgId);
                        SweetAlert.warning($translate.instant(data.resultMsg));
                        return;
                    };

                    $(selectedModel).modal('hide');

                    SweetAlert.success($translate.instant('SaveSuccess'));

                    refreshOrg();
                    $scope.operateType = null;
                    $scope.isUpdate = true;
                });
            }
        };

        var checkSelfDimensionSetList = function () {

        };

        // 获取设置的DimensionValue
        var getSelfDimensionSetValueList = function () {
            $scope.selfDimensionError = false;
            var dimensionValueOrgList = [];
            if (!$scope.selfDimensionModel) {
                return dimensionValueOrgList;
            }

            if ($scope.selfDimensionModel.leftList && $scope.selfDimensionModel.leftList.length > 0) {
                $scope.selfDimensionModel.leftList.forEach(function (row) {
                    if (row.selectDimensionValueID) {
                        var dimensionValueOrg = {
                            dimensionValueID: row.selectDimensionValueID,
                            dimensionID: row.id,
                            organizationID: $scope.editOrgModel.id,
                        };

                        dimensionValueOrgList.push(dimensionValueOrg);
                        row.error = '';
                    } else {
                        if (row.isMandatory && row.dimensionValueList && row.dimensionValueList.length > 0) {
                            row.error = $translate.instant('PleaseSelect');

                            $scope.selfDimensionError = true;
                        } else {
                            row.error = '';
                        }
                    }
                });
            }

            if ($scope.selfDimensionModel.rightList && $scope.selfDimensionModel.rightList.length > 0) {
                $scope.selfDimensionModel.rightList.forEach(function (row) {
                    if (row.selectDimensionValueID) {
                        var dimensionValueOrg = {
                            dimensionValueID: row.selectDimensionValueID,
                            dimensionID: row.id,
                            organizationID: $scope.editOrgModel.id,
                        };

                        dimensionValueOrgList.push(dimensionValueOrg);
                        row.error = '';
                    } else {
                        if (row.isMandatory && row.dimensionValueList && row.dimensionValueList.length > 0) {
                            row.error = $translate.instant('PleaseSelect');

                            $scope.selfDimensionError = true;
                        } else {
                            row.error = '';
                        }
                    }
                });
            }

            return dimensionValueOrgList;
        };

        // 加载机构
        var loadOrg = function (orgId) {
            resetRegion();

            //清空组织机构,重新获取,达到刷新效果
            $scope.editOrgModel = {
                TypeLevel: 1
            };

            refreshOrg();
            $scope.isShowBasic = false;
            $scope.orgControlForm.$setPristine();

            if (!orgId) {
                orgId = $scope.selectCompany.id;
            }
            $("#selectedOrgName-error").hide();
            $scope.isAdd = false;
            $scope.orgHasAccountMapping = false;
            enterpriseAccountService.getAccountMappingOrg(orgId).success(function (data) {
                if (data && data.length > 0) {
                    $scope.orgHasAccountMapping = true;
                }

            });

            orgService.getSingleOrg(orgId).success(function (orgData) {

                $scope.selectCompany = orgData;
                // 设置上级公司
                if (orgData.parentName == null || orgData.parentID == null) {
                    var NoOptions = {
                        'id': constant.organization.parentIdNull,
                        'name': $translate.instant('OrgSelectNoOption')
                    };
                    orgData.parentName = NoOptions.name;
                    orgData.parentID = NoOptions.id;
                }

                $scope.selfDimensionError = false;

                // 设置层级
                $scope.selectLevelType = _.find($scope.levelTypeList, function (num) {
                    return num.id === orgData.structureID;
                });
                // 设置行业

                $scope.selectProjectIndustry = _.find($scope.projectIndustryList, function (num) {
                    return num.id === orgData.industryID;
                });

                $scope.editOrgModel = orgData;

                // 设置地区
                loadProvinceList();

                loadCityList(orgData.parentRegionID);

                //设置事业部
                var businessUnitList = $scope.businessUnitList;
                $scope.selectBusinessUnit = _.find(businessUnitList, function (num) {
                    return num.id === orgData.businessUnitID;
                });

                if ($scope.selectBusinessUnit === undefined) {
                    //angular方式控制出现了很多问题,暂时先用这样的解决方案
                    $scope.selectBusinessUnit = $scope.businessUnitList[0]; //直接选第一个,“请选择”
                    // $('#selectBusinessUnit').append('<option disabled selected="selected">' + orgData.businessUnitName + '</option>');
                }

                $scope.orgAccountList = [];
                $scope.serviceList = [];
                $scope.OrgAccountRowIndex = 1;

                $scope.selfDimensionModel = getUpdateOrgSetDimension(orgData.id, orgData.dimensionValueOrgList);
                setEnterpriseOrgRowList(orgData);
                setIsCheckedServiceList(orgData);

            });

            // set first active page is basic info
            $('#orgControlTab a:first').tab('show');
            // $('#orgModalFooter').css('padding-left','139px');
            $(selectedModel).modal('show');
        };

        var populateDDL = function (data) {
            if (data) {
                var findSelect = _.find(data, function (item) {
                    return item.id == -1;
                });
                if (!findSelect) {
                    data.unshift({ id: -1, name: $scope.pleaseSelect });
                }
            }
            return data;
        };


        $scope.removeDisabled = function () {
            var businessUnitList = $scope.businessUnitList;
            $scope.businessUnitList = _.without(businessUnitList, _.findWhere(businessUnitList, {
                id: 'newadd'
            }));
        };

        // 重置机构信息
        var resetRegion = function () {

            var defaultData = null;
            $scope.CityList = defaultData;
            $scope.ProvinceList = defaultData;
            $scope.selectProvince = defaultData;
            $scope.selectRegionID = defaultData;
        };

        // 获取账套
        var loadEnterpriseAccountSetList = function () {
            enterpriseAccountService.getEnterpriseAccountSetList().success(function (data) {
                // 只获取启用状态的账套
                //data = _.filter(data, function (num) { return num.isActive });
                $scope.enterpriseAccountSetList = data;
                if (data && data.length > 0) {
                    $scope.hasEnterpriseAccountSet = true;

                } else {
                    $scope.hasEnterpriseAccountSet = false;
                }
            });
        };

        // 获取行业信息
        var loadProjectIndustryList = function () {
            orgService.getProjectIndustrys().success(function (data) {
                $scope.projectIndustryList = data;
            });
        };

        // 获取机构层级
        var loadOrganizationStructureService = function () {
            organizationStructureService.getOrganizationStructureList().success(function (data) {
                var filterData = _.filter(data, function (num) {
                    return num.isActive;
                });
                $scope.levelTypeList = filterData;
            });
        };

        // 获取事业部
        var loadBusinessUnitList = function () {
            businessUnitService.getBusinessUnitList().success(function (data) {
                var filterData = _.filter(data, function (item) {
                    return item.isActive;
                });
                $scope.businessUnitList = populateDDL(filterData);
            });
        };

        //获取项目客户信息
        var loadprojectClient = function () {
            projectService.getProjectClientList().success(function (data) {
                if (data && data.length > 0) {
                    $scope.projectClientName = data[0].name;
                }
            });
        };

        // 获取省市
        var loadProvinceList = function () {
            areaRegionService.getProvinces().success(function (data) {
                if (data && data.length > 0) {
                    $scope.ProvinceList = data;
                    $scope.selectProvince = _.find($scope.ProvinceList, function (num) {
                        return num.regionID === $scope.editOrgModel.parentRegionID;
                    });

                    if ($scope.selectProvince) {
                        loadCityList($scope.selectProvince.regionID);
                    }

                } else {
                    data = null;
                    $scope.ProvinceList = data;
                    $scope.selectProvince = data;
                }
            });
        };

        // 加载城市信息
        var loadCityList = function (regionID) {

            if (regionID !== undefined && regionID !== null) {
                areaRegionService.getCities(regionID).success(function (data) {
                    if (data && data.length > 0) {
                        $scope.CityList = data;

                        var target = _.find($scope.CityList, function (num) {
                            return num.regionID === $scope.editOrgModel.regionID;
                        });

                        if (target) {
                            $scope.selectRegionID = $scope.editOrgModel.regionID;
                        } else {
                            $scope.selectRegionID = data[0].regionID;
                        }

                    } else {
                        data = null;
                        $scope.CityList = data;
                        $scope.selectRegionID = null;
                    }
                });
            }
        };

        // 基础数据初始化
        var init = function () {
            loadProjectIndustryList();
            loadOrganizationStructureService();
            loadBusinessUnitList();
            loadProvinceList();
            loadEnterpriseAccountSetList();
            getAllDimensionList();
            loadprojectClient();
        };

        // 验证账套
        var checkEnterpriseSetOrg = function () {
            if ($scope.orgAccountList && $scope.orgAccountList.length > 0) {
                $scope.orgAccountList.forEach(function (row) {

                    $scope.checkEnterpriseAccountSetSelect(row);
                    $scope.checkStartDate(row);
                    $scope.checkEndDate(row);
                });
            }

            var errorList = _.filter($scope.orgAccountList, function (num) {

                return num.enterpriseAccountSetSelectError || num.startDateError || num.endDateError;
            });

            if (errorList && errorList.length > 0) {
                return true;
            } else {
                return false;
            }
        };

        $scope.checkEnterpriseAccountSetSelect = function (row) {
            if (!row.enterpriseAccountSetSelectID && !row.startDate && !row.endDate) {
                row.enterpriseAccountSetSelectError = null;
                return;
            }

            if (!row.enterpriseAccountSetSelectID) {
                row.enterpriseAccountSetSelectError = $scope.resources.OrganizationMsgEnterpriseAccountSetRequired;
            } else {
                row.enterpriseAccountSetSelectError = null;
            }
        };

        // 验证开始时间
        $scope.checkStartDate = function (row) {

            if (row.startDate && !window.PWC.checkMonth(row.startDate)) {
                row.startDateError = $scope.resources.DateMonthFormatError;
                return;
            } else {
                row.startDateError = null;
            }

            if (!row.enterpriseAccountSetSelectID && !row.startDate && !row.endDate) {
                row.startDateError = null;
                return;
            }

            // if (!row.startDate) {
            //     row.startDateError = $scope.resources.EffectiveDateRequired;
            // } else {
            //     row.startDateError = null;
            // }

            if (row.startDate && row.endDate) {

                if (!validateDate(row.startDate, row.endDate)) {
                    row.startDateError = $scope.resources.EffectiveDateAreaProblem;
                } else {
                    row.startDateError = null;
                }
            }
        };

        // 验证结束时间
        $scope.checkEndDate = function (row) {


            // if (!row.endDate) {
            //     row.endDateError = $scope.resources.ExpiredDateRequired;
            // } else {
            //     row.endDateError = null;
            // }

            if (row.endDate && !window.PWC.checkMonth(row.endDate)) {
                row.endDateError = $scope.resources.DateMonthFormatError;
                return;
            } else {
                row.endDateError = null;
            }

            if (!row.enterpriseAccountSetSelectID && !row.startDate && !row.endDate) {
                row.endDateError = null;
                return;
            }


            if (row.startDate && row.endDate) {

                if (!validateDate(row.startDate, row.endDate)) {
                    row.startDateError = $scope.resources.EffectiveDateAreaProblem;
                } else {
                    row.startDateError = null;
                }
            }
        };

        // 验证模板列表
        var checkTemplateList = function () {
            var hasError = false;
            if ($scope.isCheckedServiceList && $scope.isCheckedServiceList.length > 0) {
                $scope.isCheckedServiceList.forEach(function (row) {
                    $scope.checkTemplate(row);
                    if (row.selectedTemplateError) {
                        hasError = true;
                    }
                });
            }

            return hasError;
        };

        // 验证模板方法
        $scope.checkTemplate = function (row) {
            if (row.isChecked) {
                if (!row.selectedTemplate) {
                    row.selectedTemplateError = $scope.resources.OrganizationMsgTemplateRequired;
                } else {
                    row.selectedTemplateError = null;
                }
            } else {
                row.selectedTemplateError = null;
            }
        };

        // 添加一行账套设置
        $scope.newOrgAccountRow = function () {
            var index = $scope.OrgAccountRowIndex;
            var enterpriseAccountSetList = copyArray($scope.enterpriseAccountSetList);
            var d = new Date();
            var now = d.formatDateTime('yyyy-MM');

            var row = {
                enterpriseAccountSetList: enterpriseAccountSetList,
                enterpriseAccountSetSelect: null,
                startDate: null,
                endDate: null,
                fromID: 'orgFrom' + index,
                toID: 'orgTo' + index
            };

            $scope.OrgAccountRowIndex++;
            $scope.orgAccountList.push(row);
            $timeout(function () {
                setDatepickerRow(row);
            }, 200);
        };

        // 删除一行账套
        $scope.deleteAccountModule = function (model) {
            if (model) {
                $scope.orgAccountList.splice(jQuery.inArray(model, $scope.orgAccountList), 1);
            };
        };

        // 选择自定义属性校验
        $scope.checkSelfDimension = function (row) {
            if (row.isMandatory && row.dimensionValueList && row.dimensionValueList.length > 0) {
                if (!row.selectDimensionValueID) {
                    row.error = $translate.instant('PleaseSelect');
                    return;
                }
            }

            row.error = '';
        };

        // 修改机构时,设置账套设置的值
        var setEnterpriseOrgRowList = function (enterpriseAccountSetData) {
            $scope.orgAccountList = [];
            if (!enterpriseAccountSetData.enterpriseAccountSetOrgList || enterpriseAccountSetData.enterpriseAccountSetOrgList.length === 0) {
                return;
            }
            var enterpriseAccountSetList = copyArray($scope.enterpriseAccountSetList);

            enterpriseAccountSetData.enterpriseAccountSetOrgList.forEach(function (row) {
                var index = $scope.OrgAccountRowIndex;
                var rowData = {
                    enterpriseAccountSetList: enterpriseAccountSetList,
                    enterpriseAccountSetSelectID: row.enterpriseAccountSetID,
                    startDate: row.effectiveDateStr,
                    endDate: row.expiredDateStr,
                    fromID: 'orgFrom' + index,
                    toID: 'orgTo' + index,
                    id:row.id,
                };

                $scope.OrgAccountRowIndex++;

                $scope.orgAccountList.push(rowData);
                $timeout(function () {
                    setDatepickerRow(rowData);
                }, 100);
            });

        };

        // 设置时间控件
        var setDatepickerRow = function (rowData) {
            $("#" + rowData.fromID).datepicker({
                minViewMode: 1,
                autoclose: true,
                language: "zh-CN",
                format: "yyyy-mm"
            });

            $("#" + rowData.toID).datepicker({
                minViewMode: 1,
                autoclose: true,
                language: "zh-CN",
                format: "yyyy-mm"
            });

            $("#" + rowData.fromID).on('changeDate', function () {

                if ($("#" + rowData.fromID).val === '') {

                } else {
                    $("#" + rowData.toID).datepicker('setStartDate', $("#" + rowData.fromID).val());
                }
            });

            // 默认的错误信息先设置为空
            rowData.startDateError = null;
            rowData.endDateError = null;
        }

        // 数组复制
        var copyArray = function (data) {
            var ret = [];
            data.forEach(function (row) {

                ret.push(row);
            });

            return ret;
        };

        // 初始化选择服务选项
        var initIsCheckedServiceList = function () {
            $scope.isCheckedServiceList = [];
            projectService.getServiceList().success(function (serviceListData) {
                $scope.serviceList = serviceListData;
                serviceListData.forEach(function (rowData) {
                    var row = {
                        id: rowData.id,
                        name: rowData.name,
                        templateGroupList: rowData.templateGroupList,
                        selectedTemplate: null,
                        isChecked: false,
                    }
                    $scope.isCheckedServiceList.push(row);
                });
            });
        };

        // 设置是否选择服务模板
        var setIsCheckedServiceList = function (orgData) {
            $scope.isCheckedServiceList = [];
            projectService.getServiceList().success(function (serviceListData) {
                $scope.serviceList = serviceListData;
                serviceListData.forEach(function (rowData) {

                    var temp = _.find(orgData.organizationServiceTemplateGroupList, function (num) {
                        return num.serviceTypeID == rowData.id
                    });
                    var ischecked = true;
                    var selectTemplateID = -1;
                    if (temp == undefined) {
                        ischecked = false;
                    } else {
                        selectTemplateID = temp.templateGroupID;
                    }
                    var row = {
                        id: rowData.id,
                        name: rowData.name,
                        templateGroupList: rowData.templateGroupList,
                        selectedTemplate: _.find(rowData.templateGroupList, function (num) {
                            return num.id == selectTemplateID
                        }),
                        isChecked: ischecked,
                    }
                    $scope.isCheckedServiceList.push(row);
                });
            });
        };

        // 说明
        $scope.resources = {
            OrganizationName: $translate.instant('OrganizationName'),
            OrganizationMsgNameRequired: $translate.instant('OrganizationMsgNameRequired'),
            OrganizationParent: $translate.instant('OrganizationParent'),
            OrganizationLevelType: $translate.instant('OrganizationLevelType'),
            OrganizationMsgLevelTypeRequired: $translate.instant('OrganizationMsgLevelTypeRequired'),
            OrganizationClientCode: $translate.instant('OrganizationClientCode'),
            OrganizationMsgClientCodeRequired: $translate.instant('OrganizationMsgClientCodeRequired'),
            OrganizationCode: $translate.instant('OrganizationCode'),
            OrganizationMsgCodeRequired: $translate.instant('OrganizationMsgCodeRequired'),
            OrganizationMsgCodeMaxLength: $translate.instant('OrganizationMsgCodeMaxLength'),
            OrganizationMsgCodePattern: $translate.instant('OrganizationMsgCodePattern'),
            OrganizationMsgCodeUnique: $translate.instant('OrganizationMsgCodeUnique'),
            OrganizationTaxPayerNumber: $translate.instant('OrganizationTaxPayerNumber'),
            OrganizationMsgTaxPayerNumberUnique: $translate.instant('OrganizationMsgTaxPayerNumberUnique'),
            OrganizationMsgAreaRequired: $translate.instant('OrganizationMsgAreaRequired'),
            OrganizationMsgProvinceRequired: $translate.instant('OrganizationMsgProvinceRequired'),
            OrganizationMsgCityRequired: $translate.instant('OrganizationMsgCityRequired'),
            OrganizationMsgEnterpriseAccountSetRequired: $translate.instant('OrganizationMsgEnterpriseAccountSetRequired'),
            EffectiveDateRequired: $translate.instant('EffectiveDateRequired'),
            ExpiredDateRequired: $translate.instant('ExpiredDateRequired'),
            EffectiveDateAreaProblem: $translate.instant('EffectiveDateAreaProblem'),
            OrganizationMsgTemplateRequired: $translate.instant('OrganizationMsgTemplateRequired'),
            OrganizationMsgProjectIndustryRequired: $translate.instant('OrganizationMsgProjectIndustryRequired'),
            DateMonthFormatError: $translate.instant('DateMonthFormatError')
        };

        // 客户代码跟着上级机构是一样的
        //$scope.$watch('editOrgModel.parentName', function (newValue, oldValue) {
        //    if (newValue !== oldValue && newValue && newValue.length > 0 && $scope.editOrgModel.componentSelectedOrg && $scope.isAdd) {
        //        if ($scope.editOrgModel.componentSelectedOrg.clientCode) {
        //            $scope.editOrgModel.clientCode = $scope.editOrgModel.componentSelectedOrg.clientCode;
        //        }
        //    }

        //    if ($scope.editOrgModel.componentSelectedOrg && !$scope.isAdd) {
        //        // 修改机构的上级公司,不能为自己及下级节点

        //    }
        //});

        // 行业发生改变时,只有在已经做过科目对应的机构,且行业是非房地产和房地产 切换时,才需要给出需要重新做科目对应的提示
        $scope.ProjectIndustryChanged = function () {

            //添加机构,过滤,  如果没有做过科目对应,过滤
            if ($scope.isAdd || !$scope.orgHasAccountMapping) {
                return;
            }

            var com = $scope.selectCompany;
            var industry = $scope.selectProjectIndustry;
            if (!industry || !com)
                return;

            var orgID = $scope.selectCompany.id;
            //房地产行业ID
            var Estateid = constant.organization.EstateIndustryId;
            ////仅仅在房地产行业和非房地产行业之间切换时给予提示
            if (com.industryID != industry.id) {
                if (com.industryID == Estateid && industry.id != Estateid) {
                    SweetAlert.warning($translate.instant("OrganizationIndustryChanged"));
                }
                else if (com.industryID != Estateid && industry.id == Estateid) {
                    SweetAlert.warning($translate.instant("OrganizationIndustryChanged"));
                }
                ////仅仅在房地产行业和非房地产行业之间切换时给予提示
                //if (com.industryID != Estateid && industry.id != Estateid)
                //    return;

                //SweetAlert.warning($translate.instant("OrganizationIndustryChanged"));
            }
        };


        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {

                if (newValue == constant.Operation.Add) {
                    // add
                    newOrg();
                } else if (newValue == constant.Operation.Edit) {
                    if ($scope.selectedOrganization) {
                        loadOrg($scope.selectedOrganization.id);
                    }
                }
            }
        });

        $scope.$watch('forceUpdate', function (newValue, oldValue) {
            if (newValue) {
                $scope.forceUpdate = false;
                initParams();
                init();
            }
        });

        // 强制刷新机构控件里的机构
        var refreshOrg = function () {
            $scope.editOrgModel.componentSelectedOrg = {};
            $scope.editOrgModel.componentSelectedOrg.forceRefresh = true;
        }

        $(".addOrgControlPop").on("hidden.bs.modal", function () {
            $('.modal-backdrop').remove();
            $(".addOrgControlPop").hide();
            $scope.operateType = null;

        });

        $scope.closeModal = function () {
            $scope.operateType = null;
        };

        // 初始化参数信息
        var initParams = function () {
            $scope.editOrgModel = {};
            $scope.selectCompany = {};
        };

        // 省改变时联动市
        $scope.populateCities = function () {
            var regionID = $scope.selectProvince && $scope.selectProvince.regionID;
            loadCityList(regionID);
        };

        // 验证是否为时间段
        var validateDate = function (from, to) {
            var fromDate = new Date(from + '-01');
            var toDate = new Date(to + '-01');
            toDate.setMonth(toDate.getMonth() + 1);
            toDate.setDate(toDate.getDate() - 1);

            if (fromDate <= toDate) {
                return true;
            } else {
                return false;
            }
        };

        // 获取所有维度值和维度值配置信息
        var getAllDimensionList = function () {
            dimensionService.getAllDimensionList().success(function (data) {
                $scope.dimensionList = data;
            });
        };

        // 获取添加自定义纬度列表
        var getAddOrgSetDimension = function () {

            var dimensionList = _.filter($scope.dimensionList, function (data) {
                return data.dimensionType === constant.dimensionType.SelfDimension;
            });

            if (dimensionList && dimensionList.length > 0) {
                var rightList = [];
                var leftList = [];

                for (var i = 0; i < dimensionList.length; i++) {
                    var row = dimensionList[i];

                    // 初始化的时候不选择值
                    row.selectDimensionValueID = '';
                    if (i % 2 === 1) {
                        leftList.push(row);
                    } else {
                        rightList.push(row);
                    }
                }

                var model = {
                    leftList: leftList,
                    rightList: rightList
                };

                return model;
            }

            return {
                leftList: [],
                rightList: []
            };
        };

        // 获取修改机构的时候,自定义维度列表
        var getUpdateOrgSetDimension = function (orgid, dimensionValueOrgList) {
            var dimensionList = _.filter($scope.dimensionList, function (data) {
                return data.dimensionType === constant.dimensionType.SelfDimension;
            });

            if (dimensionList && dimensionList.length > 0) {
                var rightList = [];
                var leftList = [];

                for (var i = 0; i < dimensionList.length; i++) {
                    var row = dimensionList[i];

                    // 设置默认选中值
                    var selectObj = _.find(dimensionValueOrgList, function (data) {
                        return data.dimensionID === row.id && data.organizationID === orgid;
                    });

                    row.selectDimensionValueID = selectObj ? selectObj.dimensionValueID : '';

                    if (i % 2 === 1) {
                        leftList.push(row);
                    } else {
                        rightList.push(row);
                    }
                }

                var model = {
                    leftList: leftList,
                    rightList: rightList
                };

                return model;
            }

            return {
                leftList: [],
                rightList: []
            };
        };

        (function initialize() {
            $log.debug('editOrganizationModalController.ctor()...');
            $scope.maxdropLength = 20;
            $scope.maxTitleLength = 10;
            initParams();
            init();
        })();
    }
]);

commonModule.directive('editOrganizationModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('editOrganizationModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/edit-organization-modal/edit-organization-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'editOrganizationModalController',
            scope:
            {
                //区分是添加还是编辑
                operateType: '=',

                //如果是编辑的话,传递机构ID
                selectedOrganization: '=?',

                //watch 是否有机构添加或者编辑 
                isUpdate: '=?',


                newOrganization: '=?',

                dimensionId: '=?',

                forceUpdate:'=?'

            }
            //,
            //link: function (scope, element) {
            //    element.find('.selector-input').on('focus', function () {
            //        element.find('.org-tree-container').show();
            //    });
            //    $(document).on('click', function () {
            //        element.find('.org-tree-container').hide();
            //    }).on('click', '.org-tree-wrapper', function (e) {
            //        e.stopPropagation();
            //    });
            //}
        };
    }
]);
commonModule.
controller('editOrganizationStructureModalController', ['$scope', '$log', 'SweetAlert', '$translate', 'organizationStructureService', 'uiGridConstants', 'Upload', 'apiInterceptor', '$interval', '$q',
    function ($scope, $log, SweetAlert, $translate, organizationStructureService, uiGridConstants, Upload, apiInterceptor, $interval, $q) {

        var editModalSelector = "#org-structure-modal";
        $scope.editingObject = { id: "", name: "", IsActive: true };
        //显示指定消息编码对应的翻译文本信息
        var showError = function (messageCode) {
            var errMsg = $translate.instant(messageCode);
            SweetAlert.warning(errMsg);
        };

        var resetError = function () {
            var elms = $(editModalSelector).find("form:first div[data-for]");
            elms.html("");
            elms.attr("class", "validate-success");

            $scope.editingObject = { ID: "", name: "", IsActive: true };
        };

        //获取机构层级数据
        var getOrgStructureList = function () {
            var deferred = $q.defer();
            organizationStructureService.getOrganizationStructureList().success(function (data) {
         
                $scope.organizationStructureList = data;
                deferred.resolve();
            });
            return deferred.promise;
        };

        var editRow = function ()
        {
            getOrgStructureList().then(function () {
                $scope.isEdit = true;
                if ($scope.selectedId) {

                    var data = _.find($scope.organizationStructureList, function (num) {
                        return num.id === $scope.selectedId;
                    });
                    if (data) {
                        $scope.editingObject = { id: data.id, name: data.name, IsActive: data.isActive };
                    }
                }
                $(editModalSelector).modal('show');
            });
        };

        var addRow = function () {
            getOrgStructureList().then(function () {
                $scope.isEdit = false;
                $scope.editingObject = { id: "", name: "", IsActive: true };
                $(editModalSelector).modal('show');
            });
        };
        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {
                resetError();
                if (newValue == constant.Operation.Add) {
                    addRow();
            
                } else if (newValue == constant.Operation.Edit) {
                    editRow();
                }
            }
        });

        $(editModalSelector).on("hidden.bs.modal", function () {
            $scope.operateType = null;
        });
        $scope.closeModal = function () {
            $scope.operateType = null;
        };

        //保存当前正在编辑数据行,经过界面初步校验后才会进入本功能
        $scope.save = function () {
            if ($scope.editingObject == null) {
                showError("OrganizationStructureNoSelected");
                return;
            }

            if ($scope.editingObject && $scope.editingObject.name.trim().length == 0) {
                showError("OrganizationStructureEmptyNode");
                return;
            }

            if (!($(editModalSelector).find("#edit-form").valid())) {
                return;
            }

            var osArray = [];
            osArray.push($scope.editingObject);

            var successedFun = function (rst) {

                if ($scope.isEdit) {
                    SweetAlert.success($translate.instant("OrganizationStructureEditSuccess"));
                }
                else {
                    SweetAlert.success($translate.instant("OrganizationStructureAddSuccess"));
                }
                $scope.isUpdate = true;
                $scope.operateType = null;
                $scope.refreshData();

                $(editModalSelector).modal('hide');
            }

            if ($scope.isEdit) {
                organizationStructureService.updateOrganizationStructure(osArray).success(successedFun);
            } else {
                organizationStructureService.addOrganizationStructure(osArray).success(successedFun);
            }

        };


        var intiValidate = function () {

            $.validator.addMethod("OrgStructureRepeated", function (value, element, param) {
                if ($scope.organizationStructureList && $scope.organizationStructureList.length > 0) {
                    var objects = $.grep($scope.organizationStructureList, function (n, i) {
                        return $scope.editingObject.id != n.id && $.trim(n.name) == $.trim(value);
                    });

                    return objects.length < 1;
                }

                return true;

            });


            formValidator = $(editModalSelector).find("#edit-form").validate({
                debug: true,

                rules: {
                    name: {
                        required: true,
                        minlength: 2,
                        maxlength: 50,
                        OrgStructureRepeated: true
                    },
                    IsActive: {
                        required: "input[name='IsActive']:checked"
                    }
                },
                messages: {
                    name: {
                        required: $translate.instant('OrganizationStructureEmptyNode'),
                        minlength: $translate.instant('OrganizationStructureEmptyNode'),
                        maxlength: $translate.instant('OrganizationStructureOutOfLengthNode'),
                        OrgStructureRepeated: $translate.instant('OrganizationStructureDuplicateNode')
                    },
                    IsActive: $translate.instant('OrganizationStructureStatusUnsureness')
                },
                errorPlacement: function (error, element) {
                    var elm = $(element).parents("form:first");
                    elm = elm.find("div[data-for='" + element.attr("name") + "']");
                    elm.html(error);
                    elm.attr("class", "validate-fail");
                }
            });
        };


        (function initialize() {
            $log.debug('editOrganizationStructureModalController.ctor()...');
            $scope.refreshData = getOrgStructureList;
            intiValidate();
        })();
    }
]);

commonModule.directive('editOrganizationStructureModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('editRegionModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/edit-organization-structure-modal/edit-organization-structure-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'editOrganizationStructureModalController',
            scope:
            {
                operateType: '=',
                selectedId: '=?',
                isUpdate: '=?'
            }
        };
    }
]);
commonModule.controller('editPriceModalController', ['$log', '$scope', '$translate', '$uibModal', '$document', 'SweetAlert', 'enums',
    '$timeout', '$document', '$compile', 'vatOutputInvoiceManageService',
    function($log, $scope, $translate, $uibModal, $document, SweetAlert, enums, $timeout, $document, $compile, vatOutputInvoiceManageService) {

        var thisService = {
            debug: false,

            // 主函数
            main: function() {

                $scope.editModel = {};

                thisService.watchCollection();

                $scope.changeSubtotalforFinalPayment = thisService.changeSubtotalforFinalPayment;
            },

            // 限制输入两位小数
            limitTwoDigital: function(value) {
                //先把非数字的都替换掉,除了数字和.
                value = value.replace(/[^\d.]/g, "");
                //必须保证第一个为数字而不是.
                value = value.replace(/^\./g, "");
                //保证只有出现一个.而没有多个.
                value = value.replace(/\.{2,}/g, ".");
                //保证.只出现一次,而不能出现两次以上
                value = value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
                //保证.只后面只能出现两位有效数字
                value = value.replace(/([0-9]+\.[0-9]{2})[0-9]*/, "$1");

                return value;
            },

            // watch 数据
            watchCollection: function() {
                $scope.$watch('operateType', function(newValue, oldValue) {
                    if (newValue) {

                        if (newValue === constant.Operation.Edit) {

                            //$scope.isReadOnly = true;
                            thisService.open();
                        }
                    }
                });


                //$scope.$watch('editModel.subtotalforFinalPayment', function (newValue, oldValue) {
                //    if (newValue) {
                //        thisService.changeSubtotalforFinalPayment();
                //    }
                //});
            },

            // 打开弹出框
            open: function() {
                var editModel = {};

                if ($scope.operateModel) {
                    $scope.editModel = $scope.operateModel;
                } else {
                    $scope.editModel = editModel;
                }

                $scope.editModel.oldSubtotalforFinalPayment = $scope.editModel.subtotalforFinalPayment;

                var modalInstance = $uibModal.open({
                    animation: true,
                    backdrop: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'editInvoicePriceModal.html',
                    windowClass: 'edit-price-modal-wrapper',
                    scope: $scope,
                    resolve: {
                        editModel: $scope.editModel
                    }
                });

                modalInstance.result.then(function(data) {
                    // $scope.templateModel = data;
                    $scope.isUpdate = true;
                    $scope.isReadOnly = true;
                    // $scope.onClosed({ model: data });
                    $scope.operateType = null;
                }, function() {
                    $scope.operateType = null;
                    $scope.isReadOnly = true;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });


                var saveData = function(model) {

                    if (!model.bdSubtotalforFinalPayment) {
                        swal($translate.instant('SaveFail'), $translate.instant('PleaseInputPrice'), 'warning');
                        return;
                    }

                    vatOutputInvoiceManageService.manualAdjustPrice(model).success(function(ret) {
                        if (ret.result) {
                            modalInstance.close(model);
                            SweetAlert.success($translate.instant('SaveSuccess'));

                            if ($scope.onClosed) {
                                $scope.onClosed({ param: model });
                            }
                        } else {
                            swal($translate.instant('SaveFail'), $translate.instant('SaveFail'), 'warning');
                        }
                    });

                };

                // 保存
                $scope.save = function() {
                    var model = $scope.editModel;

                    saveData(model);
                };

                // 取消
                $scope.cancel = function() {
                    modalInstance.dismiss('cancel');
                };
            },

            // 验证输入金额
            // 小写金额 自动转大写
            changeSubtotalforFinalPayment: function() {
                var value = $scope.editModel.bdSubtotalforFinalPayment;

                value = thisService.limitTwoDigital(value);

                $scope.editModel.bdSubtotalforFinalPayment = value;
            }

        };

        (function() {
            thisService.main();
        })();

    }
]);
commonModule.directive('editPriceModal', ['$log',
function ($log) {
    return {
        restrict: 'E',
        templateUrl: '/app/common/controls/edit-price-modal/edit-price-modal.html' + '?_=' + Math.random(),
        replace: true,
        scope: {
            operateType: '=',
            operateModel: '=?',
            onClosed:'&'
        },
        controller: 'editPriceModalController',
        link: function ($scope, $element, $attr) {

        }
    }
}]);
commonModule.
controller('editRegionModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', 'areaRegionService', '$filter', 'SweetAlert', 'regionService', '$uibModal',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, areaRegionService, $filter, SweetAlert, regionService, $uibModal) {

        var $ctrl = this;

        var loadProvinceAndCity = function () {

            regionService.getProvinceAndCityTreeList().success(function (data) {

                // 只取有效的数据
                //data = _.filter(data, function (num) { return num.isActive });
                //$scope.provinceList = _.filter(data, function (num) { return num.levelType === 1 });
                //$scope.allCityList = _.filter(data, function (num) { return num.levelType === 2 });
                $scope.provinceCityData = data;
            });
        };

        var getProvinceAndCityList = function (branch) {
            var citys = [];
            if (branch.data.isArea) {
                // 如果是自定义区域

                if (branch.items && branch.items.length > 0) {
                    branch.items.forEach(function (row) {
                        if (!row.data.isArea) {
                            var tempList = getProvinceAndCityList(row);

                            citys = _.union(citys, tempList);
                        }
                    });
                }


            } else {
                // 如果是行政区域, 省
                if (branch.items && branch.items.length > 0) {
                    var tempCities = [];
                    branch.items.forEach(function (row) {
                        citys.push({
                            id: row.id,
                            name: row.text,
                            level: 2,
                            status: 2,
                            parentId: row.parentId
                        });
                    });

                } else {
                    // 市
                }
            }

            return citys;
        };

        var getLabelName = function (item) {

            if (item.items.length == 0) {
                selectedCityList.push(item.label);
                return;
            }

            item.items.forEach(function (itm) {
                getLabelName(itm);
            });
        };

        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {

                if (newValue == 'add') {
                    // add

                    $scope.isAdd = true;

                    // if (!$scope.selectedRegion) {
                    //     $scope.selectedRegion = {

                    //         // 父节点默认大中华区
                    //         id: '000000',
                    //         name: '大中华区'
                    //     };
                    // }

                    thisModalService.newModel();
                } else if (newValue == 'edit' && $scope.selectedRegion && $scope.selectedRegion.id) {
                    thisModalService.loadModel();
                }
            }
        });

        var thisDataService = {
            newModel: function () {
                var editModel = {};
                editModel.isActive = true;
                editModel.RegionNames = [];
                editModel.selectedNodeList = [];
                editModel.isAdd = true;
                editModel.areaName = '';

                return editModel;
            },
            save: function () {

                var validateTemp = getValidateService();
                validateTemp.resetErrorStatus();
                if (!($('#addRegionControlForm').valid())) {
                    return;
                }

                var areaId = $scope.editModel ? $scope.editModel.id : null;
                var parentId = $scope.editModel ? $scope.editModel.parentID : null;
                var name = $scope.editModel.areaName;
                var selectedCity = $scope.editModel.selectedNodeList;

                if (!$scope.editModel.id) {
                    // 添加
                    var saveModel = {
                        parentId: areaId,
                        name: name,
                        cityList: selectedCity
                    };

                    areaRegionService.add(saveModel).success(function (data) {
                        if (!data.result) {
                            swal($translate.instant('SaveFail'), $translate.instant(data.resultMsg), 'warning');
                            return;
                        }

                        SweetAlert.success($translate.instant('SaveSuccess'));
                        thisModalService.close($scope.editModel);
                    });
                } else {
                    var saveModel = {
                        id: areaId,
                        parentId: parentId,
                        name: name,
                        cityList: selectedCity,
                        isActive: $scope.editModel.isActive
                    };

                    areaRegionService.update(saveModel).success(function (data) {
                        if (!data.result) {
                            swal($translate.instant('SaveFail'), $translate.instant(data.resultMsg), 'warning');
                            return;
                        }

                        SweetAlert.success($translate.instant('SaveSuccess'));
                        thisModalService.close($scope.editModel);
                    });
                }
            }
        };

        var thisModalService = {
            modalInstance: null,
            open: function (editModel) {
                $scope.editModel = editModel;
                var modalInstance = $uibModal.open({
                    animation: $ctrl.animationsEnabled,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'editRegionModal.html',
                    scope: $scope,
                    resolve: {
                        editModel: editModel
                    }
                });

                modalInstance.result.then(function (data) {
                    $ctrl.editModel = data;
                    $scope.operateType = null;
                    $scope.isUpdate = true;
                }, function () {
                    $scope.operateType = null;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });

                thisModalService.modalInstance = modalInstance;

                // 确定
                $scope.save = thisDataService.save;

                // 取消
                $scope.cancel = thisModalService.cancel;
            },
            newModel: function () {
                var editModel = thisDataService.newModel();
                thisModalService.open(editModel);
            },
            loadModel: function () {
                regionService.getAreRegionTreeByNodeID($scope.selectedRegion.id).success(function (data) {
                    if (data && data.length > 0) {
                        $scope.selectedBranch = data[0];
                        // this action only get active area
                        $scope.selectedBranch.isActive = true;
                        //$scope.selectedRegion = data[0].data;

                        var editModel = data[0];
                        editModel.SelectedCityList = getProvinceAndCityList(editModel);
                        editModel.IsEdit = true;
                        editModel.areaName = $scope.selectedBranch.text;
                        editModel.isAdd = false;
                        thisModalService.open(editModel);
                    }
                });
            },
            close: function (result) {
                if (thisModalService.modalInstance) {
                    thisModalService.modalInstance.close(result);
                }
            },
            cancel: function () {
                if (thisModalService.modalInstance) {
                    thisModalService.modalInstance.dismiss('cancel');
                }
            }
        };

        var getValidateService = function () {

            var resources = {
                provinceRequired: $translate.instant('ProvinceRequired'),
                areaNameRequired: $translate.instant('AreaNameRequired')
            };

            // 数据验证相关方法
            var validator = $("#addRegionControlForm").validate({
                errorClass: "has-error",
                rules: {
                    province: {
                        required: true
                    },
                    areaName: {
                        required: true,
                        maxlength: 50
                    }
                },
                messages: {
                    province: {
                        required: resources.provinceRequired
                    },
                    areaName: {
                        required: resources.areaNameRequired,
                        maxlength: $translate.instant('AreaNameOutOfLengthNode')
                    }
                },
                errorPlacement: function (error, element) {
                    setErrorStyle(error, element);
                }
            });

            // 设置错误样式
            var setErrorStyle = function (error, element) {
                if (element.hasClass('has-error')) {
                    element.parent().addClass('has-error');
                    error.insertAfter(element);
                    error.addClass('label');
                    // error.addClass('label-danger');
                }
            };

            // 重置错误样式
            var resetErrorStatus = function () {
                var currentForm = $('#addRegionControlForm');
                $.each(currentForm.children(), function (index, element) {
                    // $(element).find('.has-error').removeClass('has-error');

                    $(element).find('.has-error label').remove();
                });
                validator.resetForm();
            };


            return {
                validator: validator,
                setErrorStyle: setErrorStyle,
                resetErrorStatus: resetErrorStatus
            };
        };

        (function initialize() {
            $log.debug('editRegionModalController.ctor()...');

            //loadProvinceAndCity();
        })();
    }
]);


commonModule.directive('editRegionModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('editRegionModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/edit-region-modal/edit-region-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'editRegionModalController',
            scope:
            {
                operateType: '=',
                selectedRegion: '=?',
                isUpdate: '=?'
            }
            //,
            //link: function (scope, element) {
            //    element.find('.selector-input').on('focus', function () {
            //        element.find('.org-tree-container').show();
            //    });
            //    $(document).on('click', function () {
            //        element.find('.org-tree-container').hide();
            //    }).on('click', '.org-tree-wrapper', function (e) {
            //        e.stopPropagation();
            //    });
            //}
        };
    }
]);
commonModule.
controller('editTemplateModalController', ['$scope', '$log', '$translate', '$location', '$timeout', '$interval', '$filter',
    'SweetAlert', '$uibModal', 'apiInterceptor', '$q', 'Upload', 'templateGroupService', 'enums',
    function ($scope, $log, $translate, $location, $timeout, $interval, $filter, SweetAlert, $uibModal, apiInterceptor, $q,
        Upload, templateGroupService, enums) {
        var thisConstant = {
            sheetSelectDxID: window.PWC.newGuid(),
            sheetDxTreeID: window.PWC.newGuid(),

            // 查找现有报表模板
            findSheetDxDropID: window.PWC.newGuid(),
            findSheetDxTreeID: window.PWC.newGuid(),
            searchBoxDivId: window.PWC.newGuid(),

            // get sheetName list 
            uploadUrl: apiInterceptor.webApiHostUrl + '/templateGroup/getSheetNameList',
            // resumable:true,
            getSheetNameListError: '获取Sheet下拉列表失败',
            getSheetNameTitle: '解析Excel',
            allSheets: '所有报表',
            pleaseSelectFile: '请选择文件',
            pleaseSelectTemplate: '请选择报表',
            deleteSuccess: '删除成功',

            // 上传报表路径
            importTemplateExcelFile: apiInterceptor.webApiHostUrl + '/templateGroup/importTemplateExcelFile',
            // 是否是第一次画sheet 的dropdown
            isFirstDrawDxDropDown: true,
            underLineSeparator: '_',
            codeReg: /^[a-zA-Z0-9\.]*$/,
            codeError: 'code必须为英文字母或者数字',
        };

        var thisData = {
            // 所有 sheet Name的数组
            sheetNameList: [],
            // 所有sheet name 的列表[{id:1, name:'sheet名称'}]
            sheetNameObjList: [],
            sheetTreeView: null,
            // dropdown的显示文字
            sheetText: thisConstant.allSheets,
            selectSheetNameList: [],

            // 查找现有报表,选择的报表列表
            selectTemplateCodeList: [],

            findSheetTreeView: null
        };

        var thisDataService = {
            newModel: function() {
                var editModel = {};
                editModel.sheetSelectDxID = thisConstant.sheetSelectDxID;
                editModel.templateGroupID = $scope.templateModel.templateGroupID;
                editModel.addExists = true;
                editModel.findSheetDxDropID = thisConstant.findSheetDxDropID;
                editModel.reportType = $scope.templateModel.reportType;

                return editModel;
            },

            // 获取sheet列表
            getSheetList: function() {
                if (!$scope.editModel || !$scope.editModel.file) {
                    return;
                }

                var deferred = $q.defer();
                var tempFileName = PWC.newGuid() + '.dat';
                var token = $('input[name="__RequestVerificationToken"]').val();
                $('#busy-indicator-container').show();

                Upload.upload({
                    url: thisConstant.uploadUrl,
                    data: {

                        filename: $scope.editModel.file.name,
                        tempFileName: tempFileName,
                    },
                    file: $scope.editModel.file,
                    // resumeChunkSize: resumable ? $scope.chunkSize : null,
                    headers: {
                        'Access-Control-Allow-Origin': '*',
                        Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken,
                        __RequestVerificationToken: token,
                        withCredentials: true
                    },
                    __RequestVerificationToken: token,
                    withCredentials: true
                }).then(function(resp) {
                    var ret = resp.data;
                    $('#busy-indicator-container').hide();
                    deferred.resolve();
                    if (ret.result) {
                        // 导入成功
                        thisData.sheetNameList = ret.data;
                        thisData.sheetNameObjList = thisDataService.parseSheetNameObjList(ret.data);
                        // thisDataService.refreshSheetNameDropDownList(thisData.sheetNameObjList);
                        thisDataService.drawSheetNameDropDownList();

                    } else {

                        if (ret.resultMsg && ret.resultMsg.length > 0) {
                            SweetAlert.warning($translate.instant(ret.resultMsg));

                        } else {

                            SweetAlert.swal({
                                title: thisConstant.getSheetNameTitle,
                                text: thisConstant.getSheetNameListError,
                                type: "info",
                                showCancelButton: false,
                                closeOnConfirm: false,
                                closeOnCancel: true,
                                html: true
                            });

                        }
                    }

                }, function(resp) {
                    deferred.resolve();

                    if (resp.statusText === 'HttpRequestValidationException') {
                        SweetAlert.warning($translate.instant('HttpRequestValidationException'));
                    } else {
                        SweetAlert.warning('SaveFail');
                    }

                    console.log('Error status: ' + resp.status);
                }, function(evt) {
                    deferred.resolve();
                    var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                    $log.debug('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
                });

            },
            // 验证Template 的code list 必须为英文字母或者数字
            validateTemplateCodeList: function(data) {
                if (data && data.length > 0) {
                    for (var i = 0; i < data.length; i++) {
                        if (!thisDataService.validateTemplateCode(data[i])) {
                            return data[i] + thisConstant.codeError;
                        }
                    }
                }

                return null;
            },

            // 验证Template 的code 必须为英文字母或者数字
            validateTemplateCode: function(value) {
                // body...
                var arr = value.split(thisConstant.underLineSeparator);
                if (arr && arr.length > 0) {
                    // code必须为英文字母或者数字
                    if (!thisConstant.codeReg.test(arr[0])) {
                        return false;
                    }
                }

                return true;
            },
            // 转换sheet obj List
            parseSheetNameObjList: function(data) {
                var ret = [];
                if (data && data.length > 0) {
                    for (var i = 0; i < data.length; i++) {
                        var row = data[i];
                        var item = {
                            name: row,
                        };

                        item.id = row;

                        ret.push(item);
                    }
                }

                return ret;
            },
            // 绘制sheet drop down list
            drawSheetNameDropDownList: function() {
                thisData.dxTreeViewDiv = '<div class="tree-view-list margin-sheet" id="' + thisConstant.sheetDxTreeID + '">';
                $("#" + thisConstant.sheetSelectDxID).dxDropDownBox({
                    value: [],
                    valueExpr: "id",
                    displayExpr: "name",
                    // text: thisConstant.allSheets,
                    showClearButton: false,
                    noDataText: '',
                    dataSource: thisData.sheetNameObjList,
                    contentTemplate: function(e) {
                        var value = e.component.option("value"),
                            $treeView = $(thisData.dxTreeViewDiv).dxTreeView({
                                dataSource: e.component.option("dataSource"),
                                dataStructure: "plain",
                                keyExpr: "id",
                                parentIdExpr: "parentID",
                                selectionMode: "multiple",
                                displayExpr: "name",
                                selectByClick: true,
                                noDataText: '',
                                expandAllEnabled: true,
                                selectNodesRecursive: true,
                                showCheckBoxesMode: "selectAll",

                                selectAllText: '全部',
                                onSelectionChanged: function(args) {
                                    var value = args.component.getSelectedNodesKeys();
                                    thisData.selectSheetNameList = value;
                                    e.component.option("value", value);
                                }
                            });

                        thisData.sheetTreeView = $treeView.dxTreeView("instance");
                        thisData.sheetText = e.component.option("text");

                        e.component.on("valueChanged", function(args) {

                            // var value = args.value;
                            // syncTreeViewSelection(thisData.sheetTreeView, value);
                        });

                        return $treeView;
                    }
                });
            },

            // 上传报表
            save: function(modalInstance) {
                if (!$scope.editModel || !$scope.editModel.file) {
                    SweetAlert.warning(thisData.pleaseSelectFile);

                    return;
                }

                var deferred = $q.defer();
                var tempFileName = PWC.newGuid() + '.dat';
                var token = $('input[name="__RequestVerificationToken"]').val();


                var json = '';
                if (thisData.selectSheetNameList && thisData.selectSheetNameList.length > 0) {

                    var validateRet = thisDataService.validateTemplateCodeList(thisData.selectSheetNameList);
                    if (validateRet) {
                        SweetAlert.warning(validateRet);
                        return;
                    }

                    json = JSON.stringify(thisData.selectSheetNameList);

                } else {
                    SweetAlert.warning(thisData.pleaseSelectTemplate);
                    return;
                }

                // 转圈圈
                $('#busy-indicator-container').show();

                Upload.upload({
                    url: thisConstant.importTemplateExcelFile,
                    data: {
                        templateGroupID: $scope.editModel.templateGroupID,
                        sheetList: json,
                        filename: $scope.editModel.file.name,
                        tempFileName: tempFileName,
                        reportType: $scope.editModel.reportType
                    },
                    file: $scope.editModel.file,
                    // resumeChunkSize: resumable ? $scope.chunkSize : null,
                    headers: {
                        'Access-Control-Allow-Origin': '*',
                        Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken,
                        __RequestVerificationToken: token,
                        withCredentials: true
                    },
                    __RequestVerificationToken: token,
                    withCredentials: true
                }).then(function(resp) {
                    var ret = resp.data;
                    $('#busy-indicator-container').hide();
                    deferred.resolve();
                    if (ret.result) {
                        // 导入成功
                        // 获取name
                        var array = thisData.selectSheetNameList[0].split(thisConstant.underLineSeparator);

                        var resultModel = {
                            name: array[1]
                        };
                        modalInstance.close(resultModel);

                    } else {

                        if (ret.resultMsg && ret.resultMsg.length > 0) {
                            SweetAlert.warning(ret.data + $translate.instant(ret.resultMsg));

                        } else {

                            SweetAlert.swal({
                                title: thisConstant.getSheetNameTitle,
                                text: thisConstant.getSheetNameListError,
                                type: "info",
                                showCancelButton: false,
                                closeOnConfirm: false,
                                closeOnCancel: true,
                                html: true
                            });

                        }
                    }

                }, function(resp) {
                    deferred.resolve();

                    if (resp.statusText === 'HttpRequestValidationException') {
                        SweetAlert.warning($translate.instant('HttpRequestValidationException'));
                    } else {
                        SweetAlert.warning($translate.instant('SaveFail'));
                    }

                    console.log('Error status: ' + resp.status);
                }, function(evt) {
                    deferred.resolve();
                    var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                    $log.debug('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
                });
            },
            saveFindAdd: function(modalInstance) {
                // body...
                if (!thisData.selectTemplateCodeList || thisData.selectTemplateCodeList.length === 0) {
                    SweetAlert.warning(thisConstant.pleaseSelectTemplate);
                }

                var model = {
                    serviceTypeID: $scope.editModel.serviceTypeID,
                    payTaxType: $scope.editModel.payTaxType,
                    reportType: $scope.editModel.reportType,
                    industryIDs: $scope.editModel.industryIDs,
                    templateGroupID: $scope.editModel.templateGroupID,
                    templateIdList: thisData.selectTemplateCodeList
                };


                var filterTemplate = _.filter(thisData.allTemplateList, function(row) {
                    return model.templateIdList.indexOf(row.id) > -1;
                });

                var codeKey = _.uniq(_.pluck(filterTemplate, 'code'));

                var repeatCode = [];

                codeKey.forEach(function(row) {

                    var filter = _.filter(filterTemplate, function(t) {
                        return row === t.code;
                    });

                    if (filter && filter.length > 1) {
                        repeatCode.push(row);
                    }
                });

                if (repeatCode && repeatCode.length > 0) {
                    SweetAlert.warning(repeatCode.join(',') + '代码重复');
                    return;
                }

                templateGroupService.addExistTemplate(model).success(function(ret) {
                    console.log(ret);
                    if (ret.result) {

                        // 选中的第一个报表
                        var bindModel = _.find(thisData.allTemplateList, function(row) {
                            return row.templateGroupID && thisData.selectTemplateCodeList.indexOf(row.id) > -1;
                        });


                        thisData.resultModel = bindModel;
                        $scope.operateType = null;
                        thisData.isUpdate = true;

                        modalInstance.close(bindModel);
                    } else {
                        if (ret.resultMsg && ret.resultMsg.length > 0) {
                            SweetAlert.warning($translate.instant(ret.resultMsg));

                        } else {
                            SweetAlert.warning($translate.instant('SaveFail'));
                        }
                    }
                });
            },

            // 绘制查找sheet的dropdown 列表
            drawFindSheetDropDownList: function(data) {
                // body...
                thisData.dxTreeViewFindDiv = '<div class="tree-view-list margin-find" id="' + thisConstant.findSheetDxTreeID + '">';
                thisData.searchBoxDiv = '<div class="search-box" id="' + thisConstant.searchBoxDivId + '">';

                // data.forEach(function(row){

                //     row.expanded = true;
                // });

                var getSearchList = function(dataSource, value) {
                    if (!value) {
                        return dataSource;
                    }

                    dataSource.forEach(function (x) {
                        x.expanded = false;
                    });

                    var groupIDs = _.uniq(_.pluck(dataSource, 'parentID'));
                    var group = _.filter(dataSource, function(row) {
                        return groupIDs.indexOf(row.id) >= 0;
                    });

                    var result = _.filter(dataSource, function(row) {

                        if (!row.nameDisplay) {
                            return false;
                        }

                        return row.nameDisplay.toLowerCase().indexOf(value.toLowerCase()) > -1;
                    });

                    if (result && result.length > 0) {
                        var templateGroup = _.uniq(_.pluck(result, 'parentID'));
                        templateGroup.forEach(function(id) {
                            internalSearchParent(result, group, id);
                        });
                    }

                    return result;
                };

                var internalSearchParent = function (result, group, id) {
                    var find = _.find(result, function (t) {
                        return t.id === id;
                    });

                    if (!find) {
                        find = _.find(group, function (t) {
                            return t.id === id;
                        });

                        if (find) {
                            if (find.parentID && !find.expanded) {
                                internalSearchParent(result, group, find.parentID);
                            }

                            find.expanded = true;
                            result.push(find);
                        }
                    }
                    else if (find.parentID && !find.expanded) {
                        internalSearchParent(result, group, find.parentID);
                    }
                    else {
                        find.expanded = true;
                    }
                };

                var searchTextChange = function(value) {
                    var o = $('#' + thisConstant.findSheetDxTreeID).dxTreeView('option');
                    var orgList = getSearchList(thisData.allTemplateList, value);
                    o.dataSource = orgList;
                    o.value = [];
                    $('#' + thisConstant.findSheetDxTreeID).dxTreeView('option', o);
                };
                $("#" + thisConstant.findSheetDxDropID).dxDropDownBox({
                    value: [],
                    valueExpr: "id",
                    displayExpr: "nameDisplay",
                    // text: thisConstant.allSheets,
                    showClearButton: false,
                    noDataText: '',
                    dataSource: thisData.allTemplateList,
                    contentTemplate: function(e) {
                        var value = e.component.option("value"),
                            $treeView = $(thisData.dxTreeViewFindDiv).dxTreeView({
                                dataSource: e.component.option("dataSource"),
                                dataStructure: "plain",
                                keyExpr: "id",
                                parentIdExpr: "parentID",
                                selectionMode: "multiple",
                                displayExpr: "nameDisplay",
                                expandedExpr: 'expanded',
                                selectByClick: true,
                                expandAllEnabled: true,
                                selectNodesRecursive: true,
                                showCheckBoxesMode: "normal",
                                noDataText: '',
                                height: '300px',
                                value: [],
                                itemTemplate: function(itemData, itemIndex, itemElement) {
                                    itemElement.append("<span title='" + itemData.nameDisplay + "'>" + itemData.nameDisplay + "</span>");
                                },
                                onItemSelectionChanged: function(args) {
                                    var value = args.component.getSelectedNodesKeys();
                                    thisData.selectTemplateCodeList = value;
                                    e.component.option("value", value);
                                }
                            });

                        thisData.findSheetTreeView = $treeView.dxTreeView("instance");
                        thisData.sheetText = e.component.option("text");
                        var textBox = $(thisData.searchBoxDiv).dxTextBox({
                            placeholder: "搜索",
                            mode: "search",
                            onValueChanged: function(args) {
                                var value = args.value;
                                searchTextChange(value);
                            },
                            onKeyUp: function(args) {
                                var value = $(args.element).dxTextBox('option').text;
                                searchTextChange(value);
                            }
                        });

                        e.component.on("valueChanged", function(args) {

                            // var value = args.value;
                            // syncTreeViewSelection(thisData.sheetTreeView, value);
                        });

                        var wrapper = $("<div>").append(textBox).append('<br/>').append($treeView);

                        return wrapper;
                    }
                });
            },

            // 删除系统级别的报表
            deleteSystemTemplate: function() {

                // 删除模板服务
                var deleteTemplate = function(model) {
                    templateGroupService.deleteTemplate(model).success(function(ret) {
                        if (ret.result) {
                            $scope.operateType = null;
                            $scope.isUpdate = true;
                            SweetAlert.warning('删除成功');
                            $scope.onClosed({ model: null });
                            $scope.operateType = null;
                        } else {
                            SweetAlert.warning($translate.instant('SaveFail'));
                        }
                    });
                };


                var text = "确定要删除报表" + $scope.templateModel.name + "吗?";

                SweetAlert.swal({
                        title: '确定删除吗?',
                        text: text,
                        type: "warning",
                        showCancelButton: true,
                        confirmButtonColor: "#DD6B55",
                        confirmButtonText: $translate.instant('Confirm'),
                        cancelButtonText: $translate.instant('Cancel'),
                        closeOnConfirm: false,
                        closeOnCancel: true
                    },
                    function(isConfirm) {
                        if (isConfirm) {
                            var model = {
                                id: $scope.templateModel.id,
                                isDeletePermanent: false,
                                path: $scope.templateModel.path
                            };
                            deleteTemplate(model);
                        } else {
                            $scope.operateType = null;
                            $scope.isUpdate = false;
                        }
                    });
            }
        };

        var thisModalService = {
            modalInstance: null,
            open: function(editModel) {
                $scope.editModel = editModel;

                var modalInstance = $uibModal.open({
                    animation: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'editTemplateModal.html',
                    windowClass: 'edit-template-modal-wrapper',
                    scope: $scope,
                    resolve: {
                        editModel: editModel
                    }
                });


                modalInstance.result.then(function(data) {
                    thisData.isUpdate = true;
                    thisData.resultModel = data;
                    $scope.onClosed({ model: data });
                    $scope.operateType = null;
                }, function() {
                    $scope.operateType = null;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });

                $scope.getSheetList = thisDataService.getSheetList;

                // 确定
                $scope.save = function() {

                    if ($scope.editModel.addExists) {
                        thisDataService.saveFindAdd(modalInstance);
                    } else {
                        thisDataService.save(modalInstance);
                    }
                }

                // 取消
                $scope.cancel = function() {
                    modalInstance.dismiss('cancel');
                };

                $timeout(function() {
                    thisData.sheetNameObjList = [];
                    // 下拉框内容
                    thisDataService.drawSheetNameDropDownList();

                }, 10);
            },
            newModel: function() {
                var editModel = thisDataService.newModel();
                thisModalService.open(editModel);
                var serviceTypeID = $scope.templateModel.serviceTypeID;
                
                var payTaxType = (serviceTypeID === enums.serviceType.CIT) ? '' : $scope.templateModel.payTaxType;
                var reportType = (serviceTypeID === enums.serviceType.CIT) ? $scope.templateModel.reportType : '';
                var industryIDs = $scope.templateModel.industryIDs;
                templateGroupService.getTemplateUniqList(serviceTypeID, payTaxType, reportType, industryIDs).success(function (data) {

                    var result = data;
                    if ($scope.templateModel.currentTemplateCodeList && $scope.templateModel.currentTemplateCodeList.length > 0) {

                        result = _.filter(data, function(row) {
                            return $scope.templateModel.currentTemplateCodeList.indexOf(row.code) === -1;
                        });
                    }

                    if (result && result.length > 0) {
                        result.forEach(function(row) {
                            if (row.code) {
                                row.nameDisplay = row.name + thisConstant.underLineSeparator + row.code;
                            } else {
                                row.nameDisplay = row.name;
                            }
                        });
                    }

                    thisData.allTemplateList = result;

                    $timeout(function() {
                        thisDataService.drawFindSheetDropDownList(thisData.allTemplateList);
                    }, 10);
                });

            },
            // 删除报表Comfirm框
            deleteTemplateComfirmModel: function() {
                var editModel = {};
                editModel.title = "删除报表" + $scope.templateModel.code + thisConstant.underLineSeparator + $scope.templateModel.name;
                editModel.deleteConfirmText = '从当前模板删除还是整个系统中删除?';
                editModel.id = $scope.templateModel.id;
                editModel.code = $scope.templateModel.code;
                editModel.name = $scope.templateModel.name;
                editModel.isSystemType = $scope.templateModel.isSystemType;
                editModel.path = $scope.templateModel.path;
                $scope.editModel = editModel;
                var modalInstance = $uibModal.open({
                    animation: true,
                    backdrop: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'deleteTemplateModal.html',
                    windowClass: 'edit-template-modal-wrapper',
                    scope: $scope,
                    resolve: {
                        editModel: editModel
                    }
                });


                modalInstance.result.then(function(data) {
                    $scope.templateModel = data;
                    $scope.isUpdate = true;
                    $scope.onClosed({ model: data });
                    $scope.operateType = null;
                }, function() {
                    $scope.operateType = null;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });

                // 删除模板服务
                var deleteTemplate = function(model) {
                    templateGroupService.deleteTemplate(model).success(function(ret) {
                        if (ret.result) {
                            modalInstance.close(model);
                        } else {
                            SweetAlert.warning($translate.instant('SaveFail'));
                        }

                    });
                };

                // 删除关联
                $scope.deleteRelation = function() {
                    // thisDataService.saveFindAdd(modalInstance)

                    var model = {
                        id: $scope.editModel.id,
                        isDeletePermanent: false,
                        path: $scope.editModel.path
                    };

                    deleteTemplate(model);
                };

                // 永久删除
                $scope.deletePermanent = function() {
                    // 
                    var model = {
                        id: $scope.editModel.id,
                        isDeletePermanent: true,
                        path: $scope.editModel.path
                    };

                    deleteTemplate(model);
                };

                // 取消
                $scope.cancel = function() {
                    modalInstance.dismiss('cancel');
                };
            },
            // 编辑报表名称
            editTemplateNameModal: function() {
                var editModel = {
                    name: $scope.templateModel.name,
                    id: $scope.templateModel.id,
                    code: $scope.templateModel.code,
                    title: '编辑报表' + $scope.templateModel.name
                };

                $scope.editModel = editModel;

                var modalInstance = $uibModal.open({
                    animation: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'editTemplateNameModal.html',
                    windowClass: 'edit-template-name-wrapper',
                    size: 'sm',
                    scope: $scope,
                    resolve: {
                        editModel: editModel
                    }
                });


                modalInstance.result.then(function(data) {
                    $scope.isUpdate = true;
                    $scope.onClosed({ model: data });
                    $scope.operateType = null;
                }, function() {
                    $scope.operateType = null;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });

                // 删除模板服务
                var updateTemplateName = function(model) {
                    templateGroupService.updateTemplateName(model).success(function(ret) {
                        if (ret.result) {
                            // 导入成功
                            modalInstance.close(model);

                        } else {
                            if (ret.resultMsg && ret.resultMsg.length > 0) {
                                SweetAlert.warning(ret.data + $translate.instant(ret.resultMsg));

                            } else {
                                SweetAlert.warning($translate.instant('SaveFail'));
                            }
                        }
                    });
                };

                // 修改报表名称
                $scope.saveUpdateTemplateName = function() {
                    // thisDataService.saveFindAdd(modalInstance)

                    var model = {
                        id: $scope.editModel.id,
                        name: $scope.editModel.name,
                    };

                    updateTemplateName(model);
                };

                // 取消
                $scope.cancel = function() {
                    modalInstance.dismiss('cancel');
                };
            }
        };

        var mainModule = {
            main: function() {

                $scope.editModel = {};
                mainModule.watchFunction();
            },
            watchFunction: function() {
                $scope.$watch('operateType', function(newValue, oldValue) {

                    if (newValue !== oldValue) {
                        thisData.isUpdate = false;
                        thisData.resultModel = null;
                        $scope.isUpdate = false;
                    }

                    if (newValue === constant.Operation.Add) {
                        thisModalService.newModel();
                    } else if (newValue === constant.Operation.Delete) {
                        // 删除

                        if ($scope.templateModel) {
                            if ($scope.templateModel.isSystemType) {
                                // 系统级别直接删除,不用提示
                                thisDataService.deleteSystemTemplate();

                            } else {
                                thisModalService.deleteTemplateComfirmModel();
                            }
                        }
                    } else if (newValue === constant.Operation.Edit) {
                        thisModalService.editTemplateNameModal();
                    }
                });


            }
        };

        (function initialize() {
            mainModule.main();

        })();
    }
]);
commonModule.directive('editTemplateModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('editUserModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/edit-template-modal/edit-template-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'editTemplateModalController',
            scope:
            {
                operateType:'=',
                templateModel:'=?',
                isUpdate:'=?',
                onClosed: '&'
            }
            //,
            //link: function (scope, element) {
            //    element.find('.selector-input').on('focus', function () {
            //        element.find('.org-tree-container').show();
            //    });
            //    $(document).on('click', function () {
            //        element.find('.org-tree-container').hide();
            //    }).on('click', '.org-tree-wrapper', function (e) {
            //        e.stopPropagation();
            //    });
            //}
        };
    }
]);
commonModule.
controller('editTemplategroupModalController', ['$scope', '$log', '$translate', '$location', '$timeout', '$interval', '$filter', 'SweetAlert', '$uibModal', 'apiInterceptor', '$q', 'Upload', 'templateGroupService',
    function($scope, $log, $translate, $location, $timeout, $interval, $filter, SweetAlert, $uibModal, apiInterceptor, $q, Upload, templateGroupService) {
        var thisConstant = {
            sheetSelectDxID: window.PWC.newGuid(),
            sheetDxTreeID: window.PWC.newGuid(),

            // 查找现有报表模板
            findSheetDxDropID: window.PWC.newGuid(),
            findSheetDxTreeID: window.PWC.newGuid(),

            // get sheetName list 
            uploadUrl: apiInterceptor.webApiHostUrl + '/templateGroup/getSheetNameList',
            // resumable:true,
            getSheetNameListError: '获取Sheet下拉列表失败',
            getSheetNameTitle: '解析Excel',
            allSheets: '所有报表',
            pleaseSelectFile: '请选择文件',
            pleaseSelectTemplate: '请选择报表',
            deleteSuccess: '删除成功',

            // 上传报表路径
            importTemplateExcelFile: apiInterceptor.webApiHostUrl + '/templateGroup/importTemplateGroupExcelFile',
            // 是否是第一次画sheet 的dropdown
            isFirstDrawDxDropDown: true,
            underLineSeparator: '_',
            codeReg: /^[a-zA-Z0-9]*$/,
            codeError: 'code必须为英文字母或者数字',
        };


        $scope.resource = {
            nameRequire: '请输入报表名称',
        };

        var thisData = {
            // 所有 sheet Name的数组
            sheetNameList: [],
            // 所有sheet name 的列表[{id:1, name:'sheet名称'}]
            sheetNameObjList: [],
            sheetTreeView: null,
            // dropdown的显示文字
            sheetText: thisConstant.allSheets,
            selectSheetNameList: [],

            // 查找现有报表,选择的报表列表
            selectTemplateCodeList: [],

            findSheetTreeView: null
        };

        var thisDataService = {
            newModel: function() {
                var editModel = {};
                editModel.sheetSelectDxID = thisConstant.sheetSelectDxID;
                editModel.templateGroupID = $scope.objectModel.templateGroupID;
                return editModel;
            },

            // 获取sheet列表
            getSheetList: function() {
                if (!$scope.editModel || !$scope.editModel.file) {
                    return;
                }

                var deferred = $q.defer();
                var tempFileName = PWC.newGuid() + '.dat';
                var token = $('input[name="__RequestVerificationToken"]').val();
                $('#busy-indicator-container').show();

                Upload.upload({
                    url: thisConstant.uploadUrl,
                    data: {

                        filename: $scope.editModel.file.name,
                        tempFileName: tempFileName,
                    },
                    file: $scope.editModel.file,
                    // resumeChunkSize: resumable ? $scope.chunkSize : null,
                    headers: {
                        'Access-Control-Allow-Origin': '*',
                        Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken,
                        __RequestVerificationToken: token,
                        withCredentials: true
                    },
                    __RequestVerificationToken: token,
                    withCredentials: true
                }).then(function(resp) {
                    var ret = resp.data;
                    $('#busy-indicator-container').hide();
                    deferred.resolve();
                    if (ret.result) {
                        // 导入成功
                        thisData.sheetNameList = ret.data;
                        thisData.sheetNameObjList = thisDataService.parseSheetNameObjList(ret.data);
                        // thisDataService.refreshSheetNameDropDownList(thisData.sheetNameObjList);
                        thisDataService.drawSheetNameDropDownList();

                    } else {

                        if (ret.resultMsg && ret.resultMsg.length > 0) {
                            SweetAlert.warning($translate.instant(ret.resultMsg));

                        } else {

                            SweetAlert.swal({
                                title: thisConstant.getSheetNameTitle,
                                text: thisConstant.getSheetNameListError,
                                type: "info",
                                showCancelButton: false,
                                closeOnConfirm: false,
                                closeOnCancel: true,
                                html: true
                            });

                        }
                    }

                }, function(resp) {
                    deferred.resolve();

                    if (resp.statusText === 'HttpRequestValidationException') {
                        SweetAlert.warning($translate.instant('HttpRequestValidationException'));
                    } else {
                        SweetAlert.warning('SaveFail');
                    }

                    console.log('Error status: ' + resp.status);
                }, function(evt) {
                    deferred.resolve();
                    var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                    $log.debug('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
                });

            },
            // 验证Template 的code list 必须为英文字母或者数字
            validateTemplateCodeList: function(data) {
                if (data && data.length > 0) {
                    for (var i = 0; i < data.length; i++) {
                        if (!thisDataService.validateTemplateCode(data[i])) {
                            return data[i] + thisConstant.codeError;
                        }
                    }
                }

                return null;
            },

            // 验证Template 的code 必须为英文字母或者数字
            validateTemplateCode: function(value) {
                // body...
                var arr = value.split(thisConstant.underLineSeparator);
                if (arr && arr.length > 0) {
                    // code必须为英文字母或者数字
                    if (!thisConstant.codeReg.test(arr[0])) {
                        return false;
                    }
                }

                return true;
            },
            // 转换sheet obj List
            parseSheetNameObjList: function(data) {
                var ret = [];
                if (data && data.length > 0) {
                    for (var i = 0; i < data.length; i++) {
                        var row = data[i];
                        var item = {
                            name: row,
                        };

                        item.id = row;

                        ret.push(item);
                    }
                }

                return ret;
            },
            // 绘制sheet drop down list
            drawSheetNameDropDownList: function() {
                thisData.dxTreeViewDiv = '<div class="tree-view-list margin-sheet" id="' + thisConstant.sheetDxTreeID + '">';
                $("#" + thisConstant.sheetSelectDxID).dxDropDownBox({
                    value: [],
                    valueExpr: "id",
                    displayExpr: "name",
                    // text: thisConstant.allSheets,
                    showClearButton: false,
                    dataSource: thisData.sheetNameObjList,
                    contentTemplate: function(e) {
                        var value = e.component.option("value"),
                            $treeView = $(thisData.dxTreeViewDiv).dxTreeView({
                                dataSource: e.component.option("dataSource"),
                                dataStructure: "plain",
                                keyExpr: "id",
                                parentIdExpr: "parentID",
                                selectionMode: "multiple",
                                displayExpr: "name",
                                selectByClick: true,
                                expandAllEnabled: true,
                                selectNodesRecursive: true,
                                showCheckBoxesMode: "selectAll",
                                selectAllText: '全部',
                                onSelectionChanged: function(args) {
                                    var value = args.component.getSelectedNodesKeys();
                                    thisData.selectSheetNameList = value;
                                    e.component.option("value", value);
                                }
                            });

                        thisData.sheetTreeView = $treeView.dxTreeView("instance");
                        thisData.sheetText = e.component.option("text");

                        e.component.on("valueChanged", function(args) {

                            // var value = args.value;
                            // syncTreeViewSelection(thisData.sheetTreeView, value);
                        });

                        return $treeView;
                    }
                });
            },

            // 上传报表
            save: function(modalInstance) {
                // this.editTemplateGroupModalForm.$setSubmitted();
                $scope.validateName();
                if ($scope.editModel.nameError) {
                    return;
                }

                if (!$scope.editModel || !$scope.editModel.file) {
                    SweetAlert.warning(thisConstant.pleaseSelectFile);
                    return;
                }

                var deferred = $q.defer();
                var tempFileName = PWC.newGuid() + '.dat';
                var token = $('input[name="__RequestVerificationToken"]').val();

                var json = '';

                var model = $scope.editModel;
                model.sheetNameList = thisData.selectSheetNameList;
                if (thisData.selectSheetNameList && thisData.selectSheetNameList.length > 0) {

                    var validateRet = thisDataService.validateTemplateCodeList(thisData.selectSheetNameList);
                    if (validateRet) {
                        SweetAlert.warning(validateRet);
                        return;
                    }

                } else {
                    SweetAlert.warning(thisConstant.pleaseSelectTemplate);
                    return;
                }

                json = JSON.stringify(model);

                // 转圈圈
                $('#busy-indicator-container').show();

                Upload.upload({
                    url: thisConstant.importTemplateExcelFile,
                    data: {
                        jsonModel: json,
                        filename: $scope.editModel.file.name,
                        tempFileName: tempFileName
                    },
                    file: $scope.editModel.file,
                    // resumeChunkSize: resumable ? $scope.chunkSize : null,
                    headers: {
                        'Access-Control-Allow-Origin': '*',
                        Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken,
                        __RequestVerificationToken: token,
                        withCredentials: true
                    },
                    __RequestVerificationToken: token,
                    withCredentials: true
                }).then(function(resp) {
                    var ret = resp.data;
                    $('#busy-indicator-container').hide();
                    deferred.resolve();
                    if (ret.result) {
                        // 导入成功
                        modalInstance.close(model);

                    } else {

                        if (ret.resultMsg && ret.resultMsg.length > 0) {
                            SweetAlert.warning(ret.data + $translate.instant(ret.resultMsg));

                        } else {

                            SweetAlert.swal({
                                title: thisConstant.getSheetNameTitle,
                                text: thisConstant.getSheetNameListError,
                                type: "info",
                                showCancelButton: false,
                                closeOnConfirm: false,
                                closeOnCancel: true,
                                html: true
                            });

                        }
                    }

                }, function(resp) {
                    deferred.resolve();

                    if (resp.statusText === 'HttpRequestValidationException') {
                        SweetAlert.warning($translate.instant('HttpRequestValidationException'));
                    } else {
                        SweetAlert.warning($translate.instant('SaveFail'));
                    }

                    console.log('Error status: ' + resp.status);
                }, function(evt) {
                    deferred.resolve();
                    var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
                    $log.debug('progress: ' + progressPercentage + '% ' + evt.config.data.file.name);
                });
            },
            saveFindAdd: function(modalInstance) {
                // body...

                var model = {
                    serviceTypeID: $scope.editModel.serviceTypeID,
                    payTaxType: $scope.editModel.payTaxType,
                    industryIDs: $scope.editModel.industryIDs,
                    templateGroupID: $scope.editModel.templateGroupID,
                    templateCodeList: thisData.selectTemplateCodeList
                };

                templateGroupService.addExistTemplate(model).success(function(ret) {
                    if (ret.result) {
                        modalInstance.close(model);
                    } else {
                        if (ret.resultMsg && ret.resultMsg.length > 0) {
                            SweetAlert.warning($translate.instant(ret.resultMsg));

                        } else {
                            SweetAlert.warning($translate.instant('SaveFail'));
                        }
                    }
                });
            },

            // 绘制查找sheet的dropdown 列表
            drawFindSheetDropDownList: function(data) {
                // body...
                thisData.dxTreeViewDiv = '<div id="' + thisConstant.findSheetDxTreeID + '">';
                $("#" + thisConstant.findSheetDxDropID).dxDropDownBox({
                    value: [],
                    valueExpr: "code",
                    displayExpr: "name",
                    // text: thisConstant.allSheets,
                    showClearButton: false,
                    dataSource: thisData.allTemplateList,
                    contentTemplate: function(e) {
                        var value = e.component.option("value"),
                            $treeView = $(thisData.dxTreeViewDiv).dxTreeView({
                                dataSource: e.component.option("dataSource"),
                                dataStructure: "plain",
                                keyExpr: "code",
                                parentIdExpr: "parentID",
                                selectionMode: "multiple",
                                displayExpr: "name",
                                selectByClick: true,
                                expandAllEnabled: true,
                                selectNodesRecursive: true,
                                showCheckBoxesMode: "normal",
                                onItemSelectionChanged: function(args) {
                                    var value = args.component.getSelectedNodesKeys();
                                    thisData.selectTemplateCodeList = value;
                                    e.component.option("value", value);
                                }
                            });

                        thisData.findSheetTreeView = $treeView.dxTreeView("instance");
                        thisData.sheetText = e.component.option("text");

                        e.component.on("valueChanged", function(args) {

                            // var value = args.value;
                            // syncTreeViewSelection(thisData.sheetTreeView, value);
                        });

                        return $treeView;
                    }
                });
            },

            // 删除系统级别的报表
            deleteTemplateGroup: function() {
                
                // 删除模板服务
                var deleteTemplate = function(model) {
                    templateGroupService.deleteTemplateGroup(model).success(function(ret) {
                        if (ret.result) {
                            $scope.operateType = null;
                            $scope.isUpdate = true;
                            SweetAlert.warning('删除成功');
                            
                            $scope.onClosed({ model: null });

                        } else {
                            SweetAlert.warning($translate.instant(ret.resultMsg));
                            $scope.operateType = null;
                            $scope.isUpdate = false;
                        }
                    });
                };

                var text = "确定要删除" + $scope.objectModel.name + "吗?";

                SweetAlert.swal({
                        title: '确定删除吗?',
                        text: text,
                        type: "warning",
                        showCancelButton: true,
                        confirmButtonColor: "#DD6B55",
                        confirmButtonText: $translate.instant('Confirm'),
                        cancelButtonText: $translate.instant('Cancel'),
                        closeOnConfirm: false,
                        closeOnCancel: true
                    },
                    function(isConfirm) {
                        if (isConfirm) {
                            var model = $scope.objectModel;


                            deleteTemplate(model);
                        } else{
                            $scope.operateType = null;
                            $scope.isUpdate = false;
                        }
                    });
            },
            // 验证TemplateGroupName
            validateName: function() {
                if ($scope.editModel.name) {
                    $scope.editModel.nameError = null;
                } else {
                    $scope.editModel.nameError = $scope.resource.nameRequire;
                }
            }
        };

        var thisModalService = {

            newModel: function() {
                var editModel = $scope.objectModel;

                $scope.editModel = editModel;
                $scope.editModel.name = '';
                $scope.editModel.sheetSelectDxID = thisConstant.sheetSelectDxID;
                $scope.editModel.file = null;
                $scope.editModel.nameError = null;

                var modalInstance = $uibModal.open({
                    animation: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'editTemplateGroupModal.html',
                    windowClass: 'edit-templategroup-modal-wrapper',
                    scope: $scope,
                    resolve: {
                        editModel: editModel
                    }
                });

                modalInstance.result.then(function(data) {
                    $scope.editModel = data;
                    $scope.operateType = null;
                    $scope.isUpdate = true;

                    $scope.onClosed({ model: data });
                }, function() {
                    $scope.operateType = null;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });

                $scope.getSheetList = thisDataService.getSheetList;

                $scope.validateName = thisDataService.validateName;

                // 确定
                $scope.save = function() {
                    thisDataService.save(modalInstance)
                }

                // 取消
                $scope.cancel = function() {
                    modalInstance.dismiss('cancel');
                };
            },

            addGroupFirstModal: function () {
                var editModel = $scope.objectModel;

                $scope.editModel = editModel;
                $scope.editModel.title = '添加模板';
                $scope.editModel.name = '';
                $scope.editModel.groupType = 1;
                $scope.editModel.nameError = null;

                var modalInstance = $uibModal.open({
                    animation: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'editTemplateGroupNameModal.html',
                    windowClass: 'edit-template-groupName',
                    scope: $scope,
                    resolve: {
                        editModel: editModel
                    }
                });

                modalInstance.result.then(function (data) {
                    $scope.editModel = data;
                    $scope.operateType = null;
                    $scope.isUpdate = true;
                    $scope.onClosed({ model: data });
                }, function () {
                    $scope.operateType = null;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });

                $scope.validateName = thisDataService.validateName;

                // 修改报表名称
                $scope.saveUpdateTemplateGroupName = function () {
                    $scope.validateName();
                    if ($scope.editModel.nameError) {
                        return;
                    }

                    templateGroupService.addTemplateGroupWithoutTemplate($scope.editModel).success(function (ret) {
                        if (ret.result) {
                            // 添加成功
                            modalInstance.close($scope.editModel);

                        } else {
                            if (ret.resultMsg && ret.resultMsg.length > 0) {
                                SweetAlert.warning($translate.instant(ret.resultMsg));

                            } else {
                                SweetAlert.warning($translate.instant('SaveFail'));
                            }
                        }
                    });
                };

                // 取消
                $scope.cancel = function () {
                    modalInstance.dismiss('cancel');
                };
            },

            // 编辑报表名称
            editTemplateNameModal: function() {
                var editModel = {
                    name: $scope.objectModel.name,
                    id: $scope.objectModel.id,
                    nameError: null,
                    title: '编辑模板' //'编辑报表' + $scope.objectModel.name
                };

                $scope.editModel = editModel;

                var modalInstance = $uibModal.open({
                    animation: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'editTemplateGroupNameModal.html',
                    windowClass: 'edit-template-groupName',
                    scope: $scope,
                    resolve: {
                        editModel: editModel
                    }
                });

                modalInstance.result.then(function(data) {
                    $scope.editModel = data;
                    $scope.operateType = null;
                    $scope.isUpdate = true;
                    $scope.onClosed({ model: data });
                }, function() {
                    $scope.operateType = null;
                    $scope.isUpdate = false;
                    $log.info('Modal dismissed at: ' + new Date());
                });

                // 修改TemplateGroupName
                var updateTemplateName = function(model) {

                    $scope.validateName();
                    if ($scope.editModel.nameError) {
                        return;
                    }

                    templateGroupService.updateTemplateGroupName(model).success(function(ret) {
                        if (ret.result) {
                            // 导入成功
                            modalInstance.close(model);

                        } else {
                            if (ret.resultMsg && ret.resultMsg.length > 0) {
                                SweetAlert.warning($translate.instant(ret.resultMsg));

                            } else {
                                SweetAlert.warning($translate.instant('SaveFail'));
                            }
                        }
                    });
                };


                $scope.validateName = thisDataService.validateName;

                // 修改报表名称
                $scope.saveUpdateTemplateGroupName = function() {
                    // thisDataService.saveFindAdd(modalInstance)

                    var model = {
                        id: $scope.editModel.id,
                        name: $scope.editModel.name,
                    };

                    updateTemplateName(model);
                };

                // 取消
                $scope.cancel = function() {
                    modalInstance.dismiss('cancel');
                };
            }
        };

        var mainModule = {
            main: function() {

                $scope.editModel = {};
                mainModule.watchFunction();
            },
            watchFunction: function() {
                $scope.$watch('operateType', function(newValue, oldValue) {
                    if (newValue === constant.TemplateGroupOperation.AddDirectly) {
                        thisModalService.newModel();
                    } else if (newValue === constant.TemplateGroupOperation.AddGroupFirst) {
                        thisModalService.addGroupFirstModal();
                    } else if (newValue === constant.TemplateGroupOperation.Delete) {
                        // 删除

                        if ($scope.objectModel) {
                            if (!$scope.objectModel.isSystemType) {
                                // 系统级别直接删除,不用提示
                                thisDataService.deleteTemplateGroup();
                            }
                        }
                    } else if (newValue === constant.TemplateGroupOperation.Edit) {
                        thisModalService.editTemplateNameModal();
                    }
                });
            }
        };

        (function initialize() {
            mainModule.main();

        })();
    }
]);
commonModule.directive('editTemplategroupModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('editTemplategroupModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/edit-templategroup-modal/edit-templategroup-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'editTemplategroupModalController',
            scope:
            {
                operateType: '=',
                objectModel: '=?',
                isUpdate: '=?',
                onClosed: '&'
            }
            //,
            //link: function (scope, element) {
            //    element.find('.selector-input').on('focus', function () {
            //        element.find('.org-tree-container').show();
            //    });
            //    $(document).on('click', function () {
            //        element.find('.org-tree-container').hide();
            //    }).on('click', '.org-tree-wrapper', function (e) {
            //        e.stopPropagation();
            //    });
            //}
        };
    }
]);
commonModule.
controller('editUserModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', 'areaRegionService', '$filter', 'SweetAlert', 'regionService', 'userService', 'enums',
    function($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, areaRegionService, $filter, SweetAlert, regionService, userService, enums) {

        // newUser
        var newUser = function() {
            $scope.isAdd = true;
            $scope.editUserModel = {};
            $scope.editUserModel.isAdmin = false;
            resetErrorStatus();
            $('.edit-user-modal-wrapper .modal').modal('show');
        };

        // loadUser
        var loadUser = function(userId) {
            $scope.isAdd = false;
            resetErrorStatus();
            userService.getSingleUser(userId).success(function(userData) {
                $scope.editUserModel = {};
                $scope.editUserModel.ID = userData.id;
                $scope.editUserModel.UserName = userData.userName;
                $scope.editUserModel.Status = userData.status;
                $scope.editUserModel.OrganizationID = userData.organizationID;
                $scope.editUserModel.Email = userData.email;
                $scope.editUserModel.OrgName = userData.orgName;
                $scope.editUserModel.RoleIDs = userData.roleIDs;
                $scope.editUserModel.RoleNames = userData.roleNames;
                $scope.editUserModel.CreateTime = userData.createTime;
                $scope.editUserModel.Password = userData.password;
                $scope.editUserModel.isAdmin = userData.isAdmin;

            });
            $('.edit-user-modal-wrapper .modal').modal('show');
        };

        // Save role info
        var saveUser = function() {
            var hasError = false;
            if (!($('#userForm').valid())) {
                hasError = true;
            }

            if (!$scope.editUserModel.OrganizationID) {
                $scope.editUserModel.organizationIDError = $translate.instant('SelectOrg');
                $('#dropdownMenu1').addClass('error-button');
                hasError = true;
            }

            // if (!$scope.editUserModel.isAdmin) {
            if (!$scope.editUserModel.RoleIDs || $scope.editUserModel.RoleIDs.length === 0) {
                //$('.selector-input').addClass('error-button');
                $scope.editUserModel.RoleIDsError = $translate.instant('selectOneRoleDesc');
                //hasError = true;
            }
            // }

            if (hasError) {
                return;
            }

            if ($scope.isAdd) {

                userService.addUser($scope.editUserModel).success(function(or) {
                    if (or) {
                        if (or.result === true) {
                            SweetAlert.success($translate.instant('AddUserSuccess'));
                            $scope.editUserModel = {};
                            $scope.isUpdate = true;
                            $('.edit-user-modal-wrapper .modal').modal('hide');
                        } else {
                            SweetAlert.warning($translate.instant(or.resultMsg));
                        }
                    }

                    $scope.operateType = null;
                });
            } else {

                userService.updateUser($scope.editUserModel).success(function(or) {
                    if (or) {
                        if (or.result === true) {
                            SweetAlert.success($translate.instant('UpdateUserSuccess'));
                            $scope.editUserModel = {};
                            $scope.isUpdate = true;
                            $('.edit-user-modal-wrapper .modal').modal('hide');
                        } else {
                            SweetAlert.warning($translate.instant(or.resultMsg));
                        }

                    }

                    $scope.operateType = null;
                });
            }


        };

        // disable user account
        var disableUser = function(user) {
            console.log(JSON.stringify(user));
            SweetAlert.swal({
                    title: $translate.instant('Confirm') + $translate.instant('StopUse') + '?',
                    text: $translate.instant('Confirm') + $translate.instant('StopUse') + user.userName,
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonColor: "#DD6B55",
                    confirmButtonText: $translate.instant('Confirm'),
                    cancelButtonText: $translate.instant('Cancel'),
                    closeOnConfirm: false,
                    closeOnCancel: true
                },
                function(isConfirm) {
                    if (isConfirm) {
                        // 选中
                        userService.enableOrDisableUser(user.id, 0).success(function(or) {
                            if (or) {
                                if (or.result === true) {
                                    $scope.selectedUser.status = enums.userStatus.disabled;
                                    $scope.selectedUser.statusName = $translate.instant('StopUse');
                                    SweetAlert.success($translate.instant('DisableUserSuccess'));
                                    $scope.isUpdate = true;
                                } else {
                                    SweetAlert.warning($translate.instant(or.resultMsg));
                                }
                            }
                        });
                    }

                    $scope.operateType = null;
                });

        };

        //enable user account
        var enableUser = function(userId) {
            userService.enableOrDisableUser(userId, enums.userStatus.active).success(function(or) {
                if (or) {
                    if (or.result === true) {
                        $scope.selectedUser.status = enums.userStatus.active;
                        $scope.selectedUser.statusName = $translate.instant('Enable');
                        SweetAlert.success($translate.instant('EnableUserSuccess'));
                        $scope.isUpdate = true;
                    } else {
                        SweetAlert.warning($translate.instant(or.resultMsg));
                    }
                }

                $scope.operateType = null;
            })
        };

        // operate Type
        $scope.$watch('operateType', function(newValue, oldValue) {
            if (newValue) {

                if (newValue === constant.Operation.Add) {
                    // add

                    newUser();
                } else if (newValue === constant.Operation.Edit && $scope.selectedUser && $scope.selectedUser.id) {

                    loadUser($scope.selectedUser.id);
                } else if (newValue === constant.Operation.Disable) {
                    // 禁用
                    disableUser($scope.selectedUser);
                } else if (newValue === constant.Operation.Enable) {
                    enableUser($scope.selectedUser.id);
                }
            }
        });


        $scope.$watch('editUserModel.OrganizationID', function(newValue, oldValue) {
            if (newValue) {
                $scope.editUserModel.organizationIDError = null;
            }
        });

        $scope.$watch('editUserModel.RoleIDs', function(newValue, oldValue) {
            if (newValue) {
                $scope.editUserModel.RoleIDsError = null;
            }
        });

        // close modal
        $scope.closeModal = function() {
            $scope.operateType = null;
        };

        $(".addUserPop").on("hidden.bs.modal", function() {
            $scope.operateType = null;
        });

        var resources = {
            userNameRequired: $translate.instant('RequireUserName'),
            userEmailRequired: $translate.instant('RequireEmail'),
            userEmailCheck: $translate.instant('RequireCorrectEmail'),
            userOrgRequired: $translate.instant('RequireOrganization')
        };

        var validator = $('#userForm').validate({
            errorClass: "has-error",
            rules: {
                inputUserName: {
                    required: true
                },
                inputUserEmail: {
                    required: true,
                    email: true
                },
                selectedOrgName: {
                    required: true
                }
            },
            messages: {
                inputUserName: {
                    required: resources.userNameRequired
                },
                inputUserEmail: {
                    required: resources.userEmailRequired,
                    email: resources.userEmailCheck
                },
                selectedOrgName: {
                    required: resources.userOrgRequired
                }
            },
            errorPlacement: function(error, element) {
                setErrorStyle(error, element);
            }
        });

        var setErrorStyle = function(error, element) {
            if (element.hasClass('has-error')) {
                element.parent().addClass('has-error');
                error.insertAfter(element);
                error.addClass('label');
            }
            if (element[0].name === 'orgName') {
                element.parent().addClass('col-xs-9');
                element.parent().addClass('padding-left-zero');
            }
        };

        var resetErrorStatus = function() {
            validator.resetForm();
            var currentForm = $('#userForm');
            $(currentForm).find('.has-error').removeClass('has-error');
            $('#dropdownMenu1').removeClass('error-button');
            $('.selector-input').removeClass('error-button');
        };


        (function initialize() {
            $log.debug('editRegionModalController.ctor()...');

            //Save user info
            $scope.saveUser = saveUser;

            //Load user info by userId
            $scope.loadUser = loadUser;

            //Clear user model
            $scope.newUser = newUser;

            //Enable user 
            $scope.enableUser = enableUser;

            //Disable user
            $scope.disableUser = disableUser;
        })();
    }
]);

commonModule.directive('editUserModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('editUserModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/edit-user-modal/edit-user-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'editUserModalController',
            scope:
            {
                operateType: '=',
                selectedUser: '=?',
                isUpdate: '=?',
            }
            //,
            //link: function (scope, element) {
            //    element.find('.selector-input').on('focus', function () {
            //        element.find('.org-tree-container').show();
            //    });
            //    $(document).on('click', function () {
            //        element.find('.org-tree-container').hide();
            //    }).on('click', '.org-tree-wrapper', function (e) {
            //        e.stopPropagation();
            //    });
            //}
        };
    }
]);
commonModule.
controller('exportButtonController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', 'areaRegionService', '$filter', 'SweetAlert', 'regionService', 'userService', 'enums',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, areaRegionService, $filter, SweetAlert, regionService, userService, enums) {
                   
        (function initialize() {
            $log.debug('exportButtonController.ctor()...');
        })();
    }
]);
commonModule.directive('exportButton', ['$log',
    function ($log) {
        'use strict';
        $log.debug('exportButton.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/export-button/export-button.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'exportButtonController',
            scope:
            {
                operateType: '=',
                selectedUser: '=?',
                isUpdate: '=?',
            }          
        };
    }
]);
// Formula parameter selector for formula editor
commonModule.directive('formulaParamSelector', ['$log', '$q', '$timeout', '$translate', '$uibModal', 'enums', 'formulaTranslateUtil',
    'stdAccountService', 'enterpriseAccountService',
    function ($log, $q, $timeout, $translate, $uibModal, enums, formulaTranslateUtil, stdAccountService, enterpriseAccountService) {
        'use strict';
        $log.debug('formulaParamSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/formula-param-selector/formula-param-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                isShow: '=',
                formulaList: '=*',
                formulaName: '=',
                formulaParams: '=',
                accountDataSource: '=?',
                containerSelector: '@?',
                selectorOptions: '=?',
                selectorApi: '=?' // In: onSelectorClose, onSelectorConfirm, getFormulaString
            },
            link: function (scope, element, attr) {
                $log.debug('formulaParamSelector.link()...');
                var options = {
                    animation: true,
                    backdrop: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'formulaParamModal.html',
                    scope: scope,
                    size: 'opened-param-selector',
                    windowClass: 'formula-param-selector-wrapper'
                };

                if (scope.containerSelector) {
                    options.appendTo = angular.element(scope.containerSelector);
                }
                else {
                    options.appendTo = angular.element('body');
                }

                if (options.appendTo.length > 1) {
                    options.appendTo = angular.element(options.appendTo[0]);
                }

                var thisModalService = {
                    modalInstance: null,
                    open: function () {
                        var modalInstance = $uibModal.open(options);

                        modalInstance.closed.then(function () {
                            if (scope.isConfirm) {
                                selectorConfirm();
                            }
                            else {
                                selectorClose();
                            }
                        });

                        modalInstance.result.then(function () {
                            scope.isConfirm = true;
                            scope.isShow = false;
                            $log.info('Modal confirmed at: ' + new Date());
                        }, function () {
                            scope.isConfirm = false;
                            scope.isShow = false;
                            $log.info('Modal dismissed at: ' + new Date());
                        });

                        thisModalService.modalInstance = modalInstance;

                        $timeout(function () {
                            $(".formula-param-selector-wrapper .modal-content").draggable({
                                cursor: "cursor",
                                scroll: true,
                                cancel: '.btn, input, select, label, .form-control, .close, div.label, .formula-translator-wrapper + div'
                            });
                        }, 10);
                    },
                    close: function (result) {
                        if (thisModalService.modalInstance) {
                            thisModalService.modalInstance.close(result);
                        }
                    },
                    cancel: function () {
                        if (thisModalService.modalInstance) {
                            thisModalService.modalInstance.dismiss('cancel');
                        }
                    }
                };

                // 刷新选中的过滤凭证科目代码
                var refreshAccountCode = function () {
                    if (_.isNumber(scope.accountIndex) && !isNaN(scope.accountIndex)) {
                        if (_.isEmpty(scope.selectedAccountCodes)) {
                            scope.curFormula.params[scope.accountIndex].value = '';
                        }
                        else {
                            scope.curFormula.params[scope.accountIndex].value = scope.selectedAccountCodes[0];
                        }
                    }
                };

                // Register api functions in internalApi
                // If selectorApi passed is not undefined, we will use it as internalApi
                scope.internalApi = scope.selectorApi || {};

                scope.close = function () {
                    thisModalService.cancel();
                };

                scope.confirm = function () {
                    thisModalService.close();
                };

                scope.getParamDisplayType = function (p) {
                    if (p) {
                        if (p.paramType === enums.paramType.dropdown) {
                            return 'PleaseSelect';
                        }
                        else if (p.paramType === enums.paramType.accountCode) {
                            return 'SelectAccount';
                        }
                        else if (p.paramDataType === enums.paramType.dropdownNumber) {
                            return 'NumberType';
                        }
                        else if (p.paramDataType === enums.paramDataType.number) {
                            return 'NumberType';
                        }
                        else {
                            return 'StringType';
                        }
                    }
                };

                scope.getOptionText = function (o, displayFormat) {
                    // 格式化字符串中,{0}: option.value, {1}: option.name, {2}: option.shortName
                    var paramStr;
                    if (!_.isEmpty(displayFormat)) {
                        paramStr = displayFormat
                            .replace(/\{0\}/g, o.value)
                            .replace(/\{1\}/g, o.name)
                            .replace(/\{2\}/g, o.shortName);
                    }
                    else {
                        paramStr = o.value;
                    }

                    return paramStr;
                };

                scope.showSelect = function (paramType) {
                    if (paramType === enums.paramType.dropdown) {
                        return true;
                    }
                    else {
                        return false;
                    }
                }

                scope.showAccountSelector = function (paramType) {
                    if (paramType === enums.paramType.accountCode) {
                        return true;
                    }
                    else {
                        return false;
                    }
                };

                scope.showInputSelect = function (paramType) {
                    if (paramType === enums.paramType.dropdownNumber) {
                        return true;
                    }
                    else {
                        return false;
                    }
                };

                scope.openAccountSelect = function (paramIndex) {
                    scope.accountIndex = paramIndex;
                    scope.selectedAccountCodes.length = 0;
                    var initAccount = scope.accountDataSource
                        && _.some(scope.accountDataSource, { code: scope.curFormula.params[paramIndex].value });
                    if (initAccount) {
                        scope.selectedAccountCodes.push(scope.curFormula.params[paramIndex].value);
                    }
                    
                    scope.isAccountSelectorOpen = true;
                };

                scope.inputSelectChanged = function (param) {
                    if (param) {
                        if (param.selectValue === 'Other') {
                            param.value = null;
                            $('#param-select' + param.index).removeClass('special-input-option');
                            $('#param-input' + param.index).removeClass('hide');
                        }
                        else {
                            param.value = param.selectValue;
                            $('#param-input' + param.index).addClass('hide');
                            $('#param-select' + param.index).addClass('special-input-option');
                        }
                    }
                };

                // 设置科目代码选择器
                scope.accountSelectorOptions = {
                    height: 500,
                    top: 140,
                    width: 730
                };
                scope.accountSelectorApi = {
                    onSelectorConfirm: refreshAccountCode
                };
                scope.selectedAccountCodes = [];
                scope.isAccountSelectorOpen = false;

                var selectorClose = function () {
                    if (scope.internalApi && _.isFunction(scope.internalApi.onSelectorClose)) {
                        scope.internalApi.onSelectorClose();
                    }
                };

                var selectorConfirm = function () {
                    if (scope.internalApi && _.isFunction(scope.internalApi.onSelectorConfirm)) {
                        var paramVals = _.map(scope.curFormula.params, function (p) {
                            var rtn = '';
                            if (p && p.value !== undefined && p.value !== null) {
                                if (p.paramDataType === enums.paramDataType.number) {
                                    rtn = p.value.toString();
                                }
                                else {
                                    rtn = '"' + p.value + '"';
                                }
                            }

                            return rtn;
                        });
                        scope.resultParamStr = paramVals.join(',') + ')';
                        scope.internalApi.onSelectorConfirm({
                            'formula': scope.formulaName,
                            'param': scope.resultParamStr
                        });
                    }
                };

                // Adjust the selector options
                var adjustOptions = function () {
                    // Adjust the CSS styles of the selector, currently only support width, height, top and left.
                    scope.selectorOptions = _.extend({}, scope.selectorOptions);
                    var styleStr = ".modal-opened-param-selector > .modal-content > form > .modal-body {";
                    _.chain(scope.selectorOptions).pick('width', 'height', 'top', 'left').pairs().each(function (c) {
                        styleStr = styleStr + c[0] + ':' + c[1] + 'px;';
                    });
                    scope.cssOptions = styleStr + '}';
                };

                var onFormulaChange = function () {
                    if (_.isEmpty(scope.formulaName)) {
                        scope.curFormula = {};
                        paramInfo = null;
                        return;
                    }

                    scope.curFormula = _.findWhere(scope.formulaList, { code: scope.formulaName });
                    scope.resultParamStr = scope.formulaParams;
                    var paramInfo = formulaTranslateUtil.getParamsFromStr(scope.resultParamStr);
                    if (scope.curFormula && paramInfo) {
                        scope.curFormula.params.forEach(function (p) {
                            if (p.paramType === enums.paramType.dropdownNumber) {
                                p.defaultOption = {
                                    name: $translate.instant('Other'),
                                    shortName: $translate.instant('Other'),
                                    value: 'Other'
                                };
                            }

                            if (paramInfo[p.index] && paramInfo[p.index].dataType === p.paramDataType) {
                                p.value = paramInfo[p.index].value;
                                if (!_.isString(p.value)) {
                                    p.value = p.value.toString();
                                }

                                if (p.paramType === enums.paramType.dropdownNumber) {
                                    if (!_.isEmpty(p.options) && _.some(p.options, { value: p.value })) {
                                        p.selectValue = p.value;
                                    }
                                    else {
                                        p.selectValue = 'Other';
                                    }
                                }
                            }
                            else {
                                if (p.paramType === enums.paramType.dropdownNumber) {
                                    p.selectValue = 'Other';
                                }

                                p.value = null;
                            }
                        });
                    }
                };

                var getFormulaString = function () {
                    return scope.formulaName + '(' + scope.formulaParams;
                };

                scope.$watch('isShow', function (newValue, oldValue) {
                    if (newValue) {
                        adjustOptions();

                        if (scope.internalApi) {
                            scope.internalApi.getFormulaString = getFormulaString;
                        }

                        onFormulaChange();
                        thisModalService.open();
                    }
                });

                scope.$watch('formulaName', function (newVal, oldValue) {
                    onFormulaChange();
                });

                scope.$watch('formulaParams', function (newVal, oldValue) {
                    onFormulaChange();
                });

                scope.$watchCollection('formulaList', function (newVal, oldValue) {
                    onFormulaChange();
                });
            }
        };
    }
]);
// Formula translator, show translated formula info
commonModule
    .factory('formulaTranslateUtil', ['$log', '$translate', 'enums',
    function ($log, $translate, enums) {
        'use strict';

        var getParamsFromStr = function (formulaParams) {
            var paramStrs = [];
            if (!_.isEmpty(formulaParams)) {
                formulaParams = formulaParams.trim();
                if (formulaParams.length <= 1 || formulaParams.substring(formulaParams.length - 1) !== ')') {
                    return paramStrs;
                }

                formulaParams = formulaParams.substring(0, formulaParams.length - 1);
                if (formulaParams.indexOf('(') >= 0 || formulaParams.indexOf(')') >= 0) {
                    return paramStrs;
                }

                var params = formulaParams.split(',');
                paramStrs = _.map(params, function (p) {
                    var param = { value: p.trim(), dataType: enums.paramDataType.undefined };
                    if (param.value.length > 0) {
                        var startChar = param.value.substring(0, 1);
                        var endChar = param.value.substring(param.value.length - 1);

                        try {
                            param.value = eval(param.value);
                            param.dataType = typeof (param.value) === 'string' ? enums.paramDataType.string
                                : (typeof (param.value) === 'number' ? enums.paramDataType.number : enums.paramDataType.undefined);
                        }
                        catch (ex) {
                            param.value = undefined;
                            param.dataType = enums.paramDataType.undefined;
                        }
                    }

                    return param;
                });
            }

            return paramStrs;
        };

        var translateFormula = function (formulaList, formulaName, formulaParams, includeOptional) {
            var rtn = '';
            if (!_.isEmpty(formulaList) && !_.isEmpty(formulaName)) {
                var formula = _.findWhere(formulaList, { code: formulaName });
                if (formula) {
                    rtn = formula.name + '(';
                    var paramInfo = getParamsFromStr(formulaParams); // 括号内输入的参数
                    var knownParams = angular.copy(formula.params || []); // 公式已知的参数(数据库中与该公式关联的参数)
                    knownParams.forEach(function (p) {
                        if (paramInfo[p.index] && (p.name === 'ColumnNum' || paramInfo[p.index].dataType === p.paramDataType
                            || p.paramDataType === enums.paramDataType.accountCode && paramInfo[p.index].dataType === enums.paramDataType.string)) {
                            p.value = paramInfo[p.index].value;
                            if (!_.isString(p.value)) {
                                p.value = p.value.toString();
                            }
                        }
                        else {
                            p.value = null;
                        }
                    });

                    var knownParamIndexList = _.pluck(knownParams, 'index');
                    var extraParams = _.filter(paramInfo, function (p) {
                        return knownParamIndexList.indexOf(paramInfo.indexOf(p)) < 0;
                    });

                    _.each(extraParams, function (p) { // 将输入的参数合并入knownParams
                        knownParams.push({
                            index: paramInfo.indexOf(p),
                            value: p.value,
                            paramDataType: p.dataType,
                            paramType: enums.paramType.input
                        });
                    });

                    if (includeOptional == null || includeOptional == undefined) {
                        includeOptional = 'true';
                    }

                    rtn += getParamStrFromParamList(knownParams, formula.requiredParamNum, includeOptional);
                }
            }

            return rtn;
        };

        var getParamStrFromParamList = function (params, requiredParamNum, includeOptional) {
            var rtn = '';
            if (!_.isEmpty(params)) {
                for (var i = 0; i <= params[params.length - 1].index; i++) {
                    var param = _.findWhere(params, { index: i });
                    if (includeOptional === 'true' || i < requiredParamNum
                        || param.value !== undefined && param.value !== null && param.value !== '') {
                        rtn += $translate.instant(getParamDisplayName(param, includeOptional));
                        rtn += ',';
                    }
                }

                rtn = rtn.substring(0, rtn.length - 1);
            }
            rtn = rtn + ')';

            return rtn;
        };

        var getParamDisplayName = function (param, includeOptional) {
            if (!_.isEmpty(param)) {
                var paramStr = '';
                if (param.paramType === enums.paramType.input
                    || param.paramType === enums.paramType.dropdownNumber) {
                    if (param.value === undefined || param.value === null) {
                        if (includeOptional === 'true' && !_.isEmpty(param.name)) {
                            paramStr = param.name;
                        }
                    }
                    else {
                        // 如果输入型参数有options,这些options是特殊情况,按option.name显示;
                        // options里找不到再用displayFormat来格式化
                        var opt;
                        if (_.isEmpty(param.options)) {
                            opt = null;
                        }
                        else {
                            if (param.paramDataType === enums.paramDataType.string) {
                                opt = _.find(param.options, function (p) {
                                    return p.value.toLowerCase() === param.value.toLowerCase();
                                });
                            }
                            else if (param.paramDataType === enums.paramDataType.number) {
                                opt = _.find(param.options, function (p) {
                                    return p.value === param.value.toString();
                                });
                            }
                        }

                        if (param.name === 'ColumnNum') {
                            var val = param.value;
                            if (!isNaN(param.value)) {
                                val = PWC.numToLetter(val - 1);
                            }

                            if (!_.isEmpty(param.displayFormat)) {
                                paramStr = param.displayFormat.replace(/\{0\}/g, val);
                            }
                            else {
                                paramStr = '"' + param + '"';
                            }
                        }
                        else if (!_.isEmpty(opt)) {
                            if (param.paramDataType === enums.paramDataType.string) {
                                paramStr = '"' + opt.name + '"';
                            }
                            else if (param.paramDataType === enums.paramDataType.number) {
                                paramStr = opt.name;
                            }
                        }
                        else if (!_.isEmpty(param.displayFormat)) {
                            var val = param.value;
                            paramStr = param.displayFormat.replace(/\{0\}/g, val);
                        }
                        else {
                            if (param.paramDataType === enums.paramDataType.string) {
                                paramStr = '"' + param.value + '"';
                            }
                            else if (param.paramDataType === enums.paramDataType.number) {
                                var val = param.value;
                                paramStr = val.toString();
                            }
                        }
                    }
                }
                else if (param.paramType === enums.paramType.dropdown
                    || param.paramType === enums.paramType.accountCode) {
                    if (param.value === undefined || param.value === null) {
                        if (includeOptional === 'true' && !_.isEmpty(param.name)) {
                            paramStr = param.name;
                        }
                    }
                    else if (!_.isEmpty(param.options)) {
                        // 如果列表型参数有options,这些options是所有允许的值,将option值格式化后显示;
                        // 格式化字符串中,{0}: option.value, {1}: option.name, {2}: option.shortName
                        var opt;
                        if (param.paramDataType === enums.paramDataType.string) {
                            opt = _.find(param.options, function (p) {
                                return p.value.toLowerCase() === param.value.toLowerCase();
                            });
                        }
                        else if (param.paramDataType === enums.paramDataType.number) {
                            opt = _.find(param.options, function (p) {
                                return p.value === param.value.toString();
                            });
                        }

                        if (!_.isEmpty(opt)) {
                            if (!_.isEmpty(param.displayFormat)) {
                                paramStr = param.displayFormat
                                    .replace(/\{0\}/g, opt.value)
                                    .replace(/\{1\}/g, opt.name)
                                    .replace(/\{2\}/g, opt.shortName);
                            }
                            else {
                                if (param.paramDataType === enums.paramDataType.string) {
                                    paramStr = '"' + opt.value + '"';
                                }
                                else if (param.paramDataType === enums.paramDataType.number) {
                                    paramStr = opt.value;
                                }
                            }
                        }
                        else if (param.paramDataType === enums.paramDataType.string) {
                            paramStr = '"' + param.value + '"';
                        }
                        else if (param.paramDataType === enums.paramDataType.number) {
                            paramStr = param.value.toString();
                        }
                        //else if (!_.isEmpty(param.name)) {
                        //    paramStr = param.name;
                        //}
                    }
                    else if (!_.isEmpty(param.name)) {
                        paramStr = param.name;
                    }
                }

                return paramStr;
            }

            return '';
        };

        return {
            getParamsFromStr: getParamsFromStr,
            getParamDisplayName: getParamDisplayName,
            getParamStrFromParamList: getParamStrFromParamList,
            translateFormula: translateFormula
        };
    }])
    .directive('formulaTranslator', ['$log', '$translate', 'enums', 'formulaTranslateUtil',
    function ($log, $translate, enums, formulaTranslateUtil) {
        'use strict';
        $log.debug('formulaTranslator.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/formula-translator/formula-translator.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                hideMode: '=?', // hide or notVisible
                formulaList: '=*',
                keyValueList: '=*',
                formulaName: '=?', // 公式名,必须传入formulaExp,或是同时传入formulaName & formulaParams
                formulaParams: '=?', // 公式参数
                formulaExp: '=?', // 公式表达式,包含了公式名与参数,支持同时包含多个公式
                accountDataSource: '=',
                includeOptional: '@?', // Default is true. 如果为false,可选参数未输入则不显示;如果为true,可选参数未输入需显示
                translatorFocus: '&',
                translatorBlur: '&'
            },
            link: function (scope, element, attr) {
                var splitExp = function (exp) {
                    var opExp = /[+\-*/]+/g;
                    var leftExp = /\(/g;
                    var rightExp = /\)/g;
                    var strs = [];
                    var rtn = [];
                    if (_.isEmpty(exp)) {
                        return rtn;
                    }

                    // B1 - (1 + BB("VAT001",1,1,0))*0.07 split to ['B1', '-', '(1', '+', 'BB("VAT001",1,1,0)', ')', '*', '0.07']
                    var lastIndex = 0;
                    var result = null;
                    while ((result = opExp.exec(exp)) != null) {
                        var lastExp = exp.substring(lastIndex, opExp.lastIndex - result[0].length);
                        if (!_.isEmpty(lastExp)) {
                            strs.push(lastExp);
                        }

                        strs.push(result[0]);

                        lastIndex = opExp.lastIndex;
                    }

                    strs.push(exp.substring(lastIndex));

                    var inFormula = false;
                    var diff = 0;
                    var startBlockIndex = 0;
                    var toHandleBlocks = [];
                    for (var i = 0; i < strs.length; i++) {
                        strs[i] = strs[i].trim();
                        var leftTime = strs[i].match(leftExp);
                        leftTime = leftTime ? leftTime.length : 0;
                        var rightTime = strs[i].match(rightExp);
                        rightTime = rightTime ? rightTime.length : 0;
                        if (leftTime !== rightTime) {
                            if (diff === 0) {
                                diff = leftTime - rightTime;
                                startBlockIndex = i;
                                if (strs[i][0] !== '(') {
                                    inFormula = true;
                                }
                                else {
                                    inFormula = false;
                                }
                            }
                            else {
                                diff = diff + leftTime - rightTime;
                                if (diff === 0) {
                                    toHandleBlocks.push({
                                        start: startBlockIndex,
                                        end: i,
                                        inFormula: inFormula
                                    });
                                }
                            }
                        }
                    }

                    for (var i = toHandleBlocks.length - 1; i >= 0; i--) {
                        // 如果括号不平衡的块不是formula,需要将括号与内容分离,并需递归处理内容
                        if (toHandleBlocks[i].inFormula) {
                            var newBlock = '';
                            for (var idx = toHandleBlocks[i].start; idx <= toHandleBlocks[i].end; idx++) {
                                newBlock = newBlock + strs[idx];
                            }

                            strs.splice(toHandleBlocks[i].start, toHandleBlocks[i].end - toHandleBlocks[i].start + 1, newBlock);
                        }
                        else {
                            var subBlock = '';
                            var lastBlock = '';

                            for (var j = toHandleBlocks[i].start; j <= toHandleBlocks[i].end; j++) {
                                var tmp = strs[j];
                                if (j === toHandleBlocks[i].start) {
                                    tmp = tmp.substring(1);
                                }
                                else if (j === toHandleBlocks[i].end) {
                                    var lastIndex = tmp.lastIndexOf(')');
                                    tmp = tmp.substring(0, lastIndex);
                                    lastBlock = tmp.substring(lastIndex);
                                }

                                subBlock = subBlock + tmp;
                            }

                            var tmpArr = splitExp(subBlock);
                            strs = _.flatten([strs.slice(0, toHandleBlocks[i].start), '(', tmpArr, ')', lastBlock,
                                strs.slice(toHandleBlocks[i].end + 1)]);
                        }
                    }

                    return strs;
                };

                var getFormulaInfo = function (exp) {
                    var arr = splitExp(exp);
                    return _.map(arr, function (x) {
                        var idx = x.indexOf('(');
                        if (idx > 0) {
                            return {
                                formulaName: x.substring(0, idx),
                                formulaParams: x.substring(idx + 1)
                            };
                        }
                        else {
                            return x;
                        }
                    });
                };

                var translateExp = function (exp) {
                    var formulaInfoList = getFormulaInfo(exp);
                    scope.translatedFormula = _.reduce(formulaInfoList, function (memo, i) {
                        if (!_.isEmpty(i.formulaName)) {
                            return memo + formulaTranslateUtil
                                .translateFormula(scope.formulaList, i.formulaName, i.formulaParams, scope.includeOptional);
                        }
                        else if (i[0] === '@') {
                            var keyValue = _.find(scope.keyValueList, function (x) {
                                return x.code.trim().toLowerCase() === i.toLowerCase();
                            });

                            if (!_.isEmpty(keyValue)) {
                                return keyValue.name;
                            }
                            else {
                                return i;
                            }
                        }
                        else {
                            return memo + i;
                        }
                    }, '');
                };

                scope.translatedFormula = '';

                scope.isHide = function () {
                    return _.isEmpty(scope.translatedFormula) && scope.hideMode === 'hide';
                };

                scope.isNotVisible = function () {
                    return _.isEmpty(scope.translatedFormula) && scope.hideMode !== 'hide';
                };

                scope.$watch('formulaName', function (newVal, oldValue) {
                    scope.translatedFormula = formulaTranslateUtil
                        .translateFormula(scope.formulaList, newVal, scope.formulaParams, scope.includeOptional);
                });

                scope.$watch('formulaParams', function (newVal, oldValue) {
                    scope.translatedFormula = formulaTranslateUtil
                        .translateFormula(scope.formulaList, scope.formulaName, newVal, scope.includeOptional);
                });

                scope.$watch('formulaExp', function (newVal, oldValue) {
                    translateExp(newVal);
                });

                scope.$watchCollection('formulaList', function (newVal, oldValue) {
                    newVal.forEach(function (f) {
                        var params = _.find(f.params, { paramType: enums.paramType.accountCode });
                        if (!_.isEmpty(params) && _.isEmpty(params.options) && !_.isEmpty(scope.accountDataSource)) {
                            params.options = _.map(scope.accountDataSource, function (o) {
                                return {
                                    value: o.code,
                                    name: o.fullName,
                                    shortName: o.name
                                };
                            });
                        }
                    });

                    if (scope.formulaExp) {
                        translateExp(scope.formulaExp);
                    }
                    else {
                        scope.translatedFormula = formulaTranslateUtil
                            .translateFormula(newVal, scope.formulaName, scope.formulaParams, scope.includeOptional);
                    }
                });

                scope.$watchCollection('keyValueList', function (newVal, oldValue) {
                    if (scope.formulaExp) {
                        translateExp(scope.formulaExp);
                    }
                    else {
                        scope.translatedFormula = formulaTranslateUtil
                            .translateFormula(newVal, scope.formulaName, scope.formulaParams, scope.includeOptional);
                    }
                });

                scope.$watchCollection('accountDataSource', function (newVal, oldValue) {
                    if (scope.formulaList) {
                        scope.formulaList.forEach(function (f) {
                            var params = _.find(f.params, { paramType: enums.paramType.accountCode });
                            if (!_.isEmpty(params) && _.isEmpty(params.options) && !_.isEmpty(newVal)) {
                                params.options = _.map(newVal, function (o) {
                                    return {
                                        value: o.code,
                                        name: o.fullName,
                                        shortName: o.name
                                    };
                                });
                            }
                        });
                    }
                    if (scope.formulaExp) {
                        translateExp(scope.formulaExp);
                    }
                    else {
                        scope.translatedFormula = formulaTranslateUtil
                            .translateFormula(newVal, scope.formulaName, scope.formulaParams, scope.includeOptional);
                    }
                });

                element.bind('focus', function (e) {
                    if (_.isFunction(scope.translatorFocus)) {
                        scope.translatorFocus({
                            '$event': e
                        });
                    }
                });

                element.bind('blur', function (e) {
                    if (_.isFunction(scope.translatorBlur)) {
                        scope.translatorBlur({
                            '$event': e
                        });
                    }
                });
            }
        };
    }
    ]);
commonModule.controller('importAuditAdjustController', ['$scope', '$log', '$timeout', '$q', '$translate', 'loginContext'
    , 'apiInterceptor', 'Upload', 'dataImportService', 'SweetAlert', 'vatImportService', 'citSessionService'
    , 'uiGridConstants', 'enums', 'vatCommonService', '$uibModal',
function ($scope, $log, $timeout, $q, $translate, loginContext
    , apiInterceptor, Upload, dataImportService, SweetAlert, vatImportService, citSessionService
    , uiGridConstants, enums, vatCommonService, $uibModal) {
    'use strict';

    var uploadUrl = apiInterceptor.vatWebApiHostUrl + '/FileUpload/NewFile';
    var successCount = 0;
    var resumable = true;
    var projectID = citSessionService.project.id;
    var period = $scope.periodId;
    var projectDbName = citSessionService.project.dbName;
    $scope.chunkSize = 100000;
    var validationErrorType = {
        PeriodParseErrorType: $translate.instant('PeriodParseErrorType'),
        AdjustDateParseErrorType: $translate.instant('AdjustDateParseErrorType'),
        DebitParseErrorType: $translate.instant('DebitParseErrorType'),
        CreditParseErrorType: $translate.instant('CreditParseErrorType'),
        EmptyFieldErrorType: $translate.instant('EmptyFieldErrorType'),
        OverLengthFieldErrorType: $translate.instant('OverLengthFieldErrorType')
    };

    var serverErrorType = {
        EmptyFieldErrorType: 'EmptyField',
        OverLengthFieldErrorType: 'OverLengthField'
    };

    //初始化ack-pagination
    $scope.pagingOptions = {
        pageIndex: 1, //当前页码
        totalItems: 0, //总数据
        totalPages: 10, //总页数
        maxSize: 5, //分页数字的限制。
        pageSize: 5,//constant.page.pageSizeArrary[3], //每页多少条数据,100条
        pageSizeString: constant.page.pageSizeArrary[3].toString(),
        firstPage: $translate.instant('PagingFirstPage'),
        previousPage: $translate.instant('PagingPreviousPage'),
        nextPage: $translate.instant('PagingNextPage'),
        lastPage: $translate.instant('PagingLastPage'),
    };

    //初始化查询参数
    $scope.queryParams = {
        pageInfo: {
            totalCount: 0,
            pageIndex: 0,
            pageSize: 0,
            totalPage: 0,
        },
        periodId: period
    };

    //初始化汇总参数
    $scope.totalData = {
        totalNumber: 0,
        debit: 0,
        credit: 0
    };


    var initColumns = function () {

        $scope.allColumns = [
            $translate.instant('PleaseSelectColumn'),
            $translate.instant('period'),
            $translate.instant('adjustDate'),
            $translate.instant('JournalKMDM'),
            $translate.instant('JournalZY'),
            $translate.instant('JournalJFJE'),
            $translate.instant('JournalDFJE')
        ];

        $scope.necessoryColumns = [
            $translate.instant('JournalKMDM'),
            $translate.instant('JournalJFJE'),
            $translate.instant('JournalDFJE')
        ];
    };

    var initGrid = function () {

        $scope.gridOptions = {
            rowHeight: constant.UIGrid.rowHeight,
            selectionRowHeaderWidth: constant.UIGrid.rowHeight,
            enableFullRowSelection: false,
            enableRowSelection: false,
            enableSorting: false,
            enableFiltering: false,
            enableColumnMenus: false,
            enableRowHeaderSelection: false,
            enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
            columnDefs: [
            {
                field: 'index', name: $translate.instant('ImportErrorPopUpNoCol'), width: '10%', headerCellClass: '', enableFiltering: false,

                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.index}}<span></div>'
            }
            ],
            onRegisterApi: function (gridApi) {
                $scope.gridApiTotal = gridApi;
            }
        };

        $scope.gridOptions.noData = false;
    };

    var setGridCols = function (data) {

        var colCnt = 3;
        var showPeriod = _.filter(data, function (i) {
            return !PWC.isNullOrEmpty(i.monthID);
        }).length > 0;
        if (showPeriod) colCnt++;

        var showDate = _.filter(data, function (i) {
            return i.date != i.createTime;
        }).length > 0;
        if (showDate) colCnt++;

        var showSummary = _.filter(data, function (i) {
            return !PWC.isNullOrEmpty(i.summary);
        }).length > 0;
        if (showSummary) colCnt++;

        var colWidth = PWC.round(90 / colCnt, 0);
        var lastColWidth = 90 - (colCnt - 1) * colWidth;

        $scope.gridOptions.columnDefs = [
        {
            name: $translate.instant('ImportErrorPopUpNoCol'), width: '10%', headerCellClass: '',
            cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.index}}<span></div>'
        }];

        if (showPeriod) {
            $scope.gridOptions.columnDefs.push({
                name: $translate.instant('period'), width: colWidth.toString() + '%', headerCellClass: 'right',
                cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.period}}</span></div>'
            });
        }

        if (showDate) {
            $scope.gridOptions.columnDefs.push({
                name: $translate.instant('adjustDate'), width: colWidth.toString() + '%', headerCellClass: '',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.date | date:"yyyy-MM-dd"}}</span></div>'
            });
        }

        $scope.gridOptions.columnDefs.push({
            name: $translate.instant('JournalKMDM'), width: colWidth.toString() + '%', headerCellClass: '',
            cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.acctCode}}</span></div>'
        });

        if (showSummary) {
            $scope.gridOptions.columnDefs.push({
                name: $translate.instant('JournalZY'), width: colWidth.toString() + '%', headerCellClass: '',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.summary}}</span></div>'
            });
        }

        $scope.gridOptions.columnDefs.push(
         {
             name: $translate.instant('JournalJFJE'), width: colWidth.toString() + '%', headerCellClass: 'right', format: { type: 'fixedPoint', precision: 2 },
             cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.debit}}</span></div>'
         },
         {
             name: $translate.instant('JournalDFJE'), width: lastColWidth.toString() + '%', headerCellClass: 'right', format: { type: 'fixedPoint', precision: 2 },
             cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.credit}}</span></div>'
         });
    };

    $scope.$on(enums.vatEvent.layoutChanged, function () {
        $scope.gridApiTotal.core.handleWindowResize();
    });

    //parentIndex:column index
    //index:selecteditem index
    var mappingColumn = function (parentIndex, index, colName) {
        if (colName) {

            var oldColumn = $scope.selectedColumnMap[parentIndex];
            var newColumn = $scope.allColumns[index];

            if (oldColumn === newColumn) {
                return;
            }
            else {
                $scope.selectedColumnMap[parentIndex] = colName;

                if (colName !== $translate.instant('PleaseSelectColumn')) {
                    $scope.allColumns.splice(index, 1);

                    if (oldColumn && oldColumn !== $translate.instant('PleaseSelectColumn')) {
                        $scope.allColumns.push(oldColumn);
                    }
                }
                else {
                    if (oldColumn) {
                        $scope.allColumns.push(oldColumn);
                    }
                }
            }
        }
        $log.debug($scope.selectedColumnMap);
    };

    var UploadFile = function (file) {
        if (file) {
            if (!file.name.endsWith('.xls') && !file.name.endsWith('.xlsx')) {
                SweetAlert.warning($translate.instant('ImportFileInvalidType'));
                return;
            };
            $scope.initIncomeInvoiceList = [];
            successCount = 0;
            if (!file.$error) {
                var tempFileName = PWC.newGuid() + '.dat';
                Upload.upload({
                    url: uploadUrl,
                    data: {
                        filename: file.name,
                        tempFileName: tempFileName,
                        file: file
                    },
                    resumeChunkSize: resumable ? $scope.chunkSize : null,
                    headers: {
                        'Access-Control-Allow-Origin': '*',
                        Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken
                    },
                    __RequestVerificationToken: $scope.token,
                    withCredentials: true
                }).then(function (resp) {
                    successCount++;
                    $scope.fileName = file.name;
                    if (successCount === 1) {
                        $scope.tempFileName = resp.data;
                        changeSheet(0);
                    }
                });
            }
        }
    }

    var resetMappingRow = function () {
        initColumns();
        $scope.selectedColumnMap = [];
    };

    var changeSheet = function (index) {
        $scope.selectedSheet.sheetIndex = index;
        resetMappingRow();
        if (_.isString($scope.tempFileName)) {
            //$scope.excelSource = { sheetNameList: [], dataList: [] };
            vatImportService.getFileContent($scope.tempFileName, $scope.selectedSheet.sheetIndex, $scope.selectedSheet.topRowNumber).success(function (data) {
                if (data && data.result === false) {
                    SweetAlert.warning(data.resultMsg);
                    return;
                }
                $scope.excelSource = data;
                $scope.firstDataRow = data.dataList[0];
                $scope.startRowList = _.range(data.lastRowIndex);
                $scope.selectedSheet.sheetName = $scope.excelSource.sheetNameList[$scope.selectedSheet.sheetIndex];
                citSessionService.dataChanged = true;
            }).error(function () {
                SweetAlert.error($translate.instant('PleaseContactAdministrator'));
            });
        }
    };

    var validateClientSide = function (dataList) {

        var periodIntCheckMsg = '';
        var periodCnt = 0;
        var dateCheckMsg = '';
        var dateCnt = 0;
        var creditNumberCheckMsg = '';
        var creditCnt = 0;
        var debitNumberCheckMsg = '';
        var debitCnt = 0;

        if (parseInt($scope.StartRowNum) > $scope.excelSource.dataList.length) {
            SweetAlert.warning($translate.instant('StartRowNumberCheckMsg'));
            return;
        }

        for (var i = $scope.StartRowNum - 1; i < $scope.excelSource.dataList.length; i++) {
            var period1 = null;
            if ($.inArray($translate.instant('period'), $scope.selectedColumnMap) >= 0) {
                period1 = $scope.excelSource.dataList[i][$.inArray($translate.instant('period'), $scope.selectedColumnMap)];
            }
            var summary = null;
            if ($.inArray($translate.instant('JournalZY'), $scope.selectedColumnMap) >= 0) {
                summary = $scope.excelSource.dataList[i][$.inArray($translate.instant('JournalZY'), $scope.selectedColumnMap)];
            }
            var adjustDate = null;
            if ($.inArray($translate.instant('adjustDate'), $scope.selectedColumnMap) >= 0) {
                adjustDate = $scope.excelSource.dataList[i][$.inArray($translate.instant('adjustDate'), $scope.selectedColumnMap)];
            }
            var credit = $scope.excelSource.dataList[i][$.inArray($translate.instant('JournalDFJE'), $scope.selectedColumnMap)];
            var debit = $scope.excelSource.dataList[i][$.inArray($translate.instant('JournalJFJE'), $scope.selectedColumnMap)];
            var code = $scope.excelSource.dataList[i][$.inArray($translate.instant('JournalKMDM'), $scope.selectedColumnMap)];

            var curRowInfo = '(' + $translate.instant('RowIndex').formatObj({ rowIndex: i + 1 }) + ')' +
                            $translate.instant('period') + ':' + period1 + ',' +
                            $translate.instant('adjustDate') + ':' + adjustDate + ',' +
                            $translate.instant('JournalKMDM') + ':' + code + ',' +
                            $translate.instant('JournalZY') + ':' + summary + ',' +
                            $translate.instant('JournalJFJE') + ':' + debit + ',' +
                            $translate.instant('JournalDFJE') + ':' + credit + ';<br />';

            $scope.hasOtherPeriod = false;
            if ($.inArray($translate.instant('period'), $scope.selectedColumnMap) >= 0) {
                if (isNaN(parseInt(period1))) {
                    periodIntCheckMsg += curRowInfo;
                    periodCnt++;
                }
                else {
                    if (period1 != period) {
                        //CIT全年时不做此判断
                        if (period !== constant.WholeYearPeriod) {
                            $scope.hasOtherPeriod = true;
                            continue;
                        }                       
                    }
                }
            }

            if ($.inArray($translate.instant('adjustDate'), $scope.selectedColumnMap) >= 0) {
                if (!PWC.checkDate(adjustDate)) {
                    dateCheckMsg += curRowInfo;
                    dateCnt++;
                }
            }

            if (isNaN(parseFloat(credit))) {
                creditNumberCheckMsg += curRowInfo;
                creditCnt++;
            }

            if (isNaN(parseFloat(debit))) {
                debitNumberCheckMsg += curRowInfo;
                debitCnt++;
            }

            if (periodCnt == 0 && creditCnt == 0 && debitCnt == 0 && dateCnt == 0) {
                var item = {
                    'AcctCode': code,
                    'Period': period !== constant.WholeYearPeriod ? period : period1 ,
                    'Debit': debit,
                    'Credit': credit,
                    'Summary': summary,
                    'MonthID': period1,
                    'CreateTime': null,
                    'Date': adjustDate
                };
                if ($.inArray($translate.instant('adjustDate'), $scope.selectedColumnMap) >= 0) {
                    item.CreateTime = new Date();
                };
                dataList.push(item);
            }
        }

        $scope.errorMsgMap = [];

        if (periodCnt > 0) {
            $scope.errorMsgMap.push(
                {
                    'errorType': validationErrorType.PeriodParseErrorType,
                    'errorCount': periodCnt,
                    'errorContent': $translate.instant('PeriodParseErrorMsg').formatObj({ rows: periodIntCheckMsg })
                });
        };

        if (dateCnt > 0) {
            $scope.errorMsgMap.push(
                           {
                               'errorType': validationErrorType.AdjustDateParseErrorType,
                               'errorCount': periodCnt,
                               'errorContent': $translate.instant('AdjustDateParseErrorMsg').formatObj({ rows: dateCheckMsg })
                           });
        }

        if (debitCnt > 0) {
            $scope.errorMsgMap.push(
                {
                    'errorType': validationErrorType.DebitParseErrorType,
                    'errorCount': debitCnt,
                    'errorContent': $translate.instant('DebitParseErrorMsg').formatObj({ rows: debitNumberCheckMsg })
                });
        };

        if (creditCnt > 0) {
            $scope.errorMsgMap.push(
                {
                    'errorType': validationErrorType.CreditParseErrorType,
                    'errorCount': creditCnt,
                    'errorContent': $translate.instant('CreditParseErrorMsg').formatObj({ rows: creditNumberCheckMsg })
                });
        };

        if ($scope.errorMsgMap.length > 0) {
            $('#errorListModal').modal('show');
            return false;
        }
        return true;
    };

    var alerts = function () {
        var deferred = $q.defer();
        $scope.isContinue = true;
        if ($.inArray($translate.instant('period'), $scope.selectedColumnMap) >= 0) {
            if ($scope.hasOtherPeriod) {
                swal({
                    title: "warning!",
                    text: $translate.instant('PeriodDifferenceTip'),
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonColor: "#DD6B55",
                    confirmButtonText: $translate.instant('Yes'),
                    cancelButtonText: $translate.instant('No'),
                    closeOnConfirm: true,
                    closeOnCancel: true
                },
                function (isConfirm) {
                    $scope.isContinue = isConfirm;
                    deferred.resolve();
                });
            }
            else {
                $scope.isContinue = true;
                deferred.resolve();
            }
        }
        else {
            swal({
                title: "warning!",
                text: $translate.instant('NoPeriod'),
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                confirmButtonText: $translate.instant('Yes'),
                cancelButtonText: $translate.instant('No'),
                closeOnConfirm: true,
                closeOnCancel: true
            },
            function (isConfirm) {
                $scope.isContinue = isConfirm;
                deferred.resolve();
            });
        };

        return deferred.promise;
    };

    function doSave2Server(saveType) {
        // saveType 1:override,2:append
        if ($scope.excelSource.sheetNameList.length == 0) {
            SweetAlert.warning($translate.instant('PleaseSelectFileFirst'));
            return;
        }
        var notMappedColumns = '';
        if ($scope.selectedColumnMap.length >= 0) {
            var count1 = 0;
            $scope.necessoryColumns.forEach(function (m) {
                if (m !== $translate.instant('PleaseSelectColumn')) {
                    if ($.inArray(m, $scope.selectedColumnMap) < 0) {
                        notMappedColumns += m + ',';
                        count1++;
                    }
                }
            });
            if (notMappedColumns) {
                SweetAlert.warning($translate.instant('ColumnsMapErrorMsg').formatObj({ columns: notMappedColumns.substring(0, notMappedColumns.length - 1) }));
                return;
            }
        }
        var dataList = [];
        if (!validateClientSide(dataList)) return;
        if (dataList.length == 0) {
            SweetAlert.warning($translate.instant('noCurMonthRecordErrorMsg'));
            return;
        };

        alerts().then(function () {
            if ($scope.isContinue) {
                $scope.errorMsgMap = [];
                if ($scope.errorMsgMap.length > 0) {
                    $('#errorListModal').modal('show');
                    return;
                }
                else {
                    vatImportService.ImportAuditAdjust(dataList, period, saveType).success(function (data) {
                        if (data) {
                            if (data.result) {
                                vatImportService.getImportType(projectID, period).success(function (data1) {
                                    var type = data1;

                                    if (type == enums.vatDataImportStatus.ErpImported) {
                                        dataImportService.manageData(period).success(function (data2) {
                                            vatCommonService.importSetProjectStatus(projectDbName, period, constant.DictionaryDictKey.WFImportAuditAdjust
                                                                                    , enums.FinishStatusEnum.Finished);
                                            vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isAdjustImport, true);
                                            //$log.debug("import auditAdjust save2Server: " + citSessionService.project.importSubStatus.isAdjustImport);
                                            SweetAlert.success($translate.instant('ImportSuccess'));
                                            resetMappingRow();
                                            getVouchers();
                                        }).error(function () {
                                            $log.debug('ErpImported-Error()...');
                                            SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                                        });
                                    }
                                    else if (type == enums.vatDataImportStatus.TbImported) {
                                        vatImportService.refreshTrialBalance(period).success(function (data3) {
                                            if (data3 === true) {
                                                vatCommonService.importSetProjectStatus(projectDbName, period, constant.DictionaryDictKey.WFImportAuditAdjust
                                                                                       , enums.FinishStatusEnum.Finished);
                                                vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isAdjustImport, true);
                                                //$log.debug("import auditAdjust save2Server: " + citSessionService.project.importSubStatus.isAdjustImport);
                                                SweetAlert.success($translate.instant('ImportSuccess'));
                                                resetMappingRow();
                                                getVouchers();
                                            }
                                            else {
                                                $log.debug('TbImported-Server-Error()...');
                                            }
                                        }).error(function () {
                                            $log.debug('TbImported-Error()...');
                                            SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                                        });
                                    }
                                    else {
                                        vatCommonService.importSetProjectStatus(projectDbName, period, constant.DictionaryDictKey.WFImportAuditAdjust
                                                                                 , enums.FinishStatusEnum.Finished);
                                        vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isAdjustImport, true);
                                        //$log.debug("import auditAdjust save2Server: " + citSessionService.project.importSubStatus.isAdjustImport);
                                        SweetAlert.success($translate.instant('ImportSuccess'));
                                        resetMappingRow();
                                        getVouchers();
                                    }
                                    $scope.fileName = '';
                                }).error(function () {
                                    $log.debug('getImportType-Error()...');
                                    SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                                });
                            }
                            else {
                                processValidateMsg(data.data);
                            }
                        }
                    }).error(function () {
                        $log.debug('ImportAuditAdjust-Error()...');
                        SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                    });
                }
            }
        });
    }

    var save2Server = function (saveType) {
        if (citSessionService.project.projectStatusList[period] >= constant.ProjectStatusEnum.Generated) {
            swal({
                title: "warning!",
                text: $translate.instant('IsConfirmToReImport').formatObj({ status: vatCommonService.getProjectStautsEnumDesc(citSessionService.project.projectStatusList[period]) }),
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                confirmButtonText: $translate.instant('Yes'),
                cancelButtonText: $translate.instant('No'),
                closeOnConfirm: true,
                closeOnCancel: true
            },
            function (isConfirm) {
                if (isConfirm) {
                    doSave2Server(saveType);
                }
                else {
                    swal.close();
                }
            });
        }
        else {
            doSave2Server(saveType);
        }
    };

    var buildDataStr = function (p) {
        var empty = '<' + $translate.instant('empty') + '>';
        return '(' + $translate.instant('RowIndex').formatObj({ rowIndex: p.rowIndex }) + ')' +
            $translate.instant('period') + ':' + (PWC.isNullOrEmpty(p.tranCode) ? empty : p.tranCode) + ',' +
            $translate.instant('JournalKMDM') + ':' + (PWC.isNullOrEmpty(p.period) ? empty : p.period) + ',' +
            $translate.instant('JournalZY') + ':' + (PWC.isNullOrEmpty(p.vid) ? empty : p.vid) + ',' +
            $translate.instant('JournalJFJE') + ':' + (PWC.isNullOrEmpty(p.group) ? empty : p.group) + ',' +
            $translate.instant('JournalDFJE') + ':' + (PWC.isNullOrEmpty(p.itemID) ? empty : p.itemID) + ';<br />';
        return '';
    };

    var processValidateMsg = function (errorList) {
        if (errorList && errorList.length > 0) {
            errorList.forEach(function (v) {
                if (v.resultMsg === serverErrorType.EmptyFieldErrorType) {
                    var vString = '';
                    v.data.forEach(function (p) {
                        vString += buildDataStr(p);
                    });
                    $scope.errorMsgMap.push(
                        {
                            'errorType': validationErrorType.EmptyFieldErrorType,
                            'errorCount': v.data.length,
                            'errorContent': $translate.instant('EmptyFieldErrorMsg').formatObj({ rows: vString })
                        });
                }
                else if (v.resultMsg === serverErrorType.OverLengthFieldErrorType) {
                    var vString = '';
                    v.data.forEach(function (p) {
                        vString += buildDataStr(p);
                    });
                    $scope.errorMsgMap.push(
                        {
                            'errorType': validationErrorType.OverLengthFieldErrorType,
                            'errorCount': v.data.length,
                            'errorContent': $translate.instant('OverLengthErrorMsg').formatObj({ rows: vString })
                        });
                }

            });
        };
        if ($scope.errorMsgMap.length > 0) {
            $('#errorListModal').modal('show');
        }
    };
    
    var clear = function () {
        if (period === constant.WholeYearPeriod) {
            showPeriodDrapDown();
        }
        else {
            $scope.selectedPeriod = period;
            deleteAdjustAuditByPeriod();
        }
          
    };
  
    //显示期间选择弹出框
    var showPeriodDrapDown = function () {
        $scope.modalInstance = $uibModal.open({
            animation: false,
            ariaLabelledBy: 'modal-title',
            ariaDescribedBy: 'modal-body',
            templateUrl: 'audit-model-period-dropdown.html',
            scope: $scope,
            windowClass: "audit-model-period-dropdow-popup"
        });

        $scope.closePeriodSelectModal = function () {
            $scope.modalInstance.dismiss('cancel');
        };

        $scope.selectBox = {
            simple: {
                dataSource: $scope.auditPeriods,
                displayExpr: "Period",
                valueExpr: "ID",
                searchEnabled: false,
                placeholder: $translate.instant('PleaseSelectPeriod'),
                noDataText: $translate.instant('NoDataToDispaly'),
                maxLength: 2,
                onSelectionChanged: function (e) {     
                    $scope.selectedPeriod = e.selectedItem.Period;
                }
            }
        };

        vatImportService.getAdjustAuditPeriods().success(function (re) {
            if (re.result) {
                $scope.auditPeriods = [];
                var id = 1;
                $.each(re.data, function (index, item) {
                    var periodDto = {
                        ID: -1,
                        Period: -1
                    };
                    periodDto.ID = id++;
                    periodDto.Period = item;
                    $scope.auditPeriods.push(periodDto);
                });

                $("#auditPeriodSelectBox").dxSelectBox("instance").option("dataSource", $scope.auditPeriods);
            }
        }).error(function () {
            SweetAlert.error($translate.instant('PleaseContactAdministrator'));
        });
    }

    var deleteAdjustAuditByPeriod = function () {
        if (_.isNull($scope.selectedPeriod)) {
            SweetAlert.warning($translate.instant('PleaseSelectPeriod'));
            return;
        }

        var alertMsg = period === constant.WholeYearPeriod
            ? $translate.instant('AdjustAuditClearWarning') : $translate.instant('AdjustAuditClearTips');
      swal({
          title: "warning!",
          text: alertMsg,
          type: "warning",
          showCancelButton: true,
          confirmButtonColor: "#DD6B55",
          confirmButtonText: $translate.instant('Yes'),
          cancelButtonText: $translate.instant('No'),
          closeOnConfirm: true,
          closeOnCancel: true
      }, function (isConfirm) {
          if (isConfirm) {
              var dataList = [];
              var saveType = 1;//overide
              var deleteDto = {
                  serviceTypeId: $scope.serviceTypeId,
                  periodIds: [$scope.selectedPeriod]
              };

              vatImportService.deleteAdjustAudit(deleteDto).success(function (data) {
                  if (data.result) {
                      $scope.selectedPeriod = null;
                      if (period === constant.WholeYearPeriod) {
                          $scope.closePeriodSelectModal();
                      }

                      vatImportService.getImportType(projectID, period).success(function (data1) {
                          var type = data1;
                          if (type === enums.vatDataImportStatus.ErpImported) {
                              dataImportService.manageData(period).success(function (data2) {
                                  vatCommonService.clearDataSetProjectStatus(projectDbName, period, constant.DictionaryDictKey.WFImportAuditAdjust
                                                                            , enums.FinishStatusEnum.NotFinished);
                                  vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isAdjustImport, false);
                                  $log.debug("clear auditAdjust clear: " + citSessionService.project.importSubStatus.isAdjustImport);
                                  SweetAlert.success($translate.instant('ClearSuccess'));                                   
                                  resetMappingRow();
                                  getVouchers();
                              }).error(function () {
                                  $log.debug('ErpImported-Error()...');
                                  SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                              });
                          }
                          else if (type === enums.vatDataImportStatus.TbImported) {
                              vatImportService.refreshTrialBalance(period).success(function (data3) {
                                  if (data3 === true) {
                                      vatCommonService.clearDataSetProjectStatus(projectDbName, period, constant.DictionaryDictKey.WFImportAuditAdjust
                                                                                , enums.FinishStatusEnum.NotFinished);
                                      vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isAdjustImport, false);
                                      //$log.debug("import auditAdjust clear: " + citSessionService.project.importSubStatus.isAdjustImport);
                                      SweetAlert.success($translate.instant('ClearSuccess'));                                       
                                      resetMappingRow();
                                      getVouchers();
                                  }
                                  else {
                                      $log.debug('TbImported-Server-Error()...');
                                  }
                              }).error(function () {
                                  $log.debug('TbImported-Error()...');
                                  SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                              });
                          }
                          else {
                              vatCommonService.clearDataSetProjectStatus(projectDbName, period);
                              vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isAdjustImport, false);
                              //$log.debug("import auditAdjust clear: " + citSessionService.project.importSubStatus.isAdjustImport);
                              SweetAlert.success($translate.instant('ClearSuccess'));
                              resetMappingRow();
                              getVouchers();
                          }

                      }).error(function () {
                          $log.debug('getImportType-Error()...');
                          SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                      });
                  }
              });
          }
      })     
    };

    var getVouchers = function () {
        $scope.queryParams.periodId = period;
        $scope.queryParams.pageInfo = {
            totalCount: $scope.pagingOptions.totalItems,
            pageIndex: $scope.pagingOptions.pageIndex,
            pageSize: $scope.pagingOptions.pageSize,
            totalPage: 0,
        };
        vatImportService.queryAuditAdjust($scope.queryParams).success(function (re) {
            if (re) {
                $scope.excelSource = { sheetNameList: [], dataList: [] };
                initPagingControl(re.pageInfo.totalCount);
                $scope.mapppingList = re.list;
                var seqNo = 1;
                $scope.mapppingList.forEach(function (i) {
                    i.index = seqNo++;
                    i.debit = PWC.round(i.debit, 2);
                    i.credit = PWC.round(i.credit, 2);
                });
                $scope.totalData.totalNumber = re.pageInfo.totalCount;
                $scope.totalData.debit = PWC.round(re.calculateData.debitSum, 2);
                $scope.totalData.credit = PWC.round(re.calculateData.creditSum, 2);
                setGridCols($scope.mapppingList);
                $scope.gridOptions.data = $scope.mapppingList;
                $scope.gridOptions.noData = $scope.mapppingList.length === 0;
                $scope.firstDataRow = null;
                citSessionService.dataChanged = false;
            }
            
        }).error(function () {
            SweetAlert.error($translate.instant('PleaseContactAdministrator'));
        });
    };

    var initPagingControl = function (totalItemsCount) {
        $scope.pagingOptions.totalItems = totalItemsCount;
    }

    $scope.$watch('selectedFileName', function (newValue, oldValue) {
        if (newValue && newValue !== oldValue) {
            UploadFile($scope.selectedFileName);
            resetMappingRow();
        }
    });

    $scope.pagingService = {
        refreshInvoiceDataGrid: function () {
            $log.debug("refreshInvoiceDataGrid");
            getVouchers();
        },
    };

    (function initialize() {
        $scope.StartRowNum = 2;
        $scope.mapppingList = [];
        $scope.mappingRow = null;
        $scope.firstDataRow = null;
        $scope.selectedPeriod = null;
        $scope.selectedColumnMap = [];
        $scope.selectedFileName = '';
        $scope.excelSource = { sheetNameList: [], dataList: [] };
        $scope.selectedSheet = { sheetName: '', sheetIndex: 0, topRowNumber: 0 };
        $scope.deleteAdjustAuditByPeriod = deleteAdjustAuditByPeriod;


        initColumns();
        initGrid();
        getVouchers();
        $scope.refresh = getVouchers;
        $scope.clear = clear;

        $scope.changeSheet = changeSheet;
        $scope.mappingColumn = mappingColumn;
        $scope.save2Server = save2Server;
    })();

   
}
]);

commonModule.directive('importAuditAdjust', ['$log',
    function ($log) {
        'use strict';

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/import/import-audit-adjust/import-audit-adjust.html' + '?_=' + Math.random(),
            scope: {
                serviceTypeId: "=?",
                periodId: "=?"
            },
            controller: 'importAuditAdjustController',
            link: function ($scope, $element, $attr) {
                $scope.token = $('input[name="__RequestVerificationToken"]').val();
            }
        };
    }
]);
commonModule.controller('ImportDataCtrl', ['$scope', '$log', 'Upload', '$timeout', '$http', '$cookies', '$translate', '$interval', 'enums'
    , 'SweetAlert', 'dataImportService', 'vatImportService', 'modelConfigurationService'
    , 'vatSessionService', 'uiGridConstants', 'projectService', 'vatCommonService', 'vatOperationLogService', 'vatWorkflowService',
function ($scope, $log, Upload, $timeout, $http, $cookies, $translate, $interval, enums
    , SweetAlert, dataImportService, vatImportService, modelConfigurationService
    , vatSessionService, uiGridConstants, projectService, vatCommonService, vatOperationLogService, vatWorkflowService) {
    var apiTokenObj = $cookies.getObject('AtmsApiToken');
    var webHost = apiTokenObj.api_host;
    var fileGuid = ''; //保存上传文件后在server端生成的guid 
    var importMethod = ''; //oneClick:一键导入;universal:万能导入
    var importType = -1; //0:覆盖;1:添加
    var projectId = vatSessionService.project.id;
    var period = vatSessionService.month; //period < 0 覆盖导入时会删除所有数据
    var projectDbName = vatSessionService.project.dbName;
    var fileExtension = '';
    var fileNames = [];
    var token = $('input[name="__RequestVerificationToken"]').val();
    var CONST_ACEOLEDB = "Microsoft.ACE.OLEDB.12.0 is not registered"; 
    //上传文件有效后缀名
    var ValidFileExtension = {
        CSV: "csv",
        XLS: "xls",
        XLSX: "xlsx"
    }
    //对应PwC.Tax.Tech.Atms.Globals.Utils:ErpCheckType
    var ErpCheckTypeEnum = {
        Success : 0,
        ComBalanceAcctUnValidate : 1, 
        VoucherAcctValidate : 2, 
        VSingleDebitCreditUnValidate : 3,
        VEmptyCheckUnValidateItemID : 4,
        VEmptyCheckUnValidateGroup : 5,
        VEmptyCheckUnValidateAcctCode : 6,
        VEmptyCheckUnValidateSummary : 7,
        AcctBegBalAcctLevelUnValidate : 8,
        BegBalUnValidate : 9, 
        CompCustEndBalUnValidate : 10,
        CompCustAmountUnValidate : 11,
        CompCustBegBalUnValidate : 12,
        BegEndBalUnValidate : 13,
        DuplicatedVoucher: 14,
        DuplicatedTb: 15
    }
    var TbImportTypeEnum = {
        UnImported : 0,
        TbImported : 1,
        ErpImported : 2
    }

    var validteCategoryEnum = {
        Basic: 1,
        Correctness: 2,
        Duplicate:3
    }

    $scope.period = period;
    $scope.filePath = '';
    $scope.showUniversal = false;
    $scope.startNumber = -1;
    $scope.excelDownloadPath = webHost + '/Resource/ImportData/万能模板.xls';
    $scope.csvDownLoadPath = webHost + '/Resource/ImportData/csv万能模板.zip';
    $scope.duplicateList = [];
    $scope.basicCheckList = [];
    $scope.correctCheckList = [];
    var validteCategory = validteCategoryEnum.Basic;
    //写日志
    var comment = vatSessionService.project.name + " " + vatSessionService.project.year + "年" + vatSessionService.month + "月";
    $scope.moduleid = enums.vatModuleEnum.Import_Erpdata;
    var logDto = {
        ID: '',
        OperationName: '',
        ModuleID: $scope.moduleid,
        OperationObject: $translate.instant('erpData'),
        OperationType: '',
        OperationContent: '',
        OriginalState: '',
        UpdateState: '',
        CreatorID: vatSessionService.logUser.ID,
        Comment: comment,
        IP: '',
        Period: $scope.period,
    };

    //设置正确性、重复数据验证的错误提示图标
    $scope.setValidationErrorStyle = function (chkCorrect,checkDuplicate) {       
        var errorCount = 0;
        var duplicateNum = 0;
        var activeErrorStyle = {
            'background-image': 'url(/app-resources/images/vat/error.png)',
            'background-repeat': 'no-repeat',
            'background-position': 'right 5px center'
        }

        var inactiveErrorStyle = {
            'background-image': 'none'
        }

        if (chkCorrect) {
            for (var i = 1; i < $scope.correctCheckList.length; i++) {
                errorCount = $scope.correctCheckList[i][3]; //[3]: errorCount
                if (errorCount > 0) {
                    break;
                }
            }

            if (errorCount > 0) {
                return activeErrorStyle;
            }
            else {
                return inactiveErrorStyle;
            }
        }
        

        if (checkDuplicate) {
            for (var i = 1; i < $scope.duplicateList.length; i++) {
                duplicateNum = $scope.duplicateList[i][2]; //[2]: duplicateCount;
                if (duplicateNum > 0) {
                    break;
                }
            }

            if (duplicateNum > 0) {
                return activeErrorStyle;
            }
            else {
                return inactiveErrorStyle;
            }
        }
                                    
    };


    //点击一键/万能导入
    $scope.switch = function (index) {
        //一键导入
        if (index === 1) {
            $scope.filePath = $translate.instant('ConfirmSelectErpImportFileTitle');
            importMethod = 'oneClick';
            $scope.showUniversal = false;
            $scope.startNumber = -1;
            $('#btnOneClick').removeClass('disableBtn');
            $('#btnUniversal').addClass('disableBtn');
        }

        //万能导入
        if (index === 2) {
            $scope.filePath = $translate.instant('ConfirmSelectErpImportFileTitle');
            importMethod = 'universal';
            $scope.showUniversal = true;
            $scope.startNumber = 0;
            $('#btnUniversal').removeClass('disableBtn');
            $('#btnOneClick').addClass('disableBtn');
        }
    }


    //上传文件
    $scope.uploadFiles = function (files, errFiles) {
        $scope.f = files;
        $scope.showError = false;
        $scope.errFile = errFiles && errFiles[0];
        if (files && files.length) {
            fileNames = [];
            angular.forEach($scope.f, function (file) {
                fileNames.push(file.name);
            })
            $scope.filePath = fileNames.toString();//$scope.f[0].name;
            if (!checkUploadFiles($scope.f)) {
                return false;
            }

            Upload.upload({
                url: webHost + '/api/v1/financeImportData/importData/financeDataUpload',
                data: {
                    importMethod: importMethod,
                    file: files
                },
                headers: {
                    'Access-Control-Allow-Origin': '*',
                     Authorization: apiTokenObj.token_type + ' ' + apiTokenObj.access_token,
                     from: vatSessionService.project.dbName + '@cn.pwc.com'
                },
                __RequestVerificationToken: token,
                withCredentials: true
            }).then(function (response) {
                var ret = response.data;
                if (ret.result) {
                    fileGuid = ret.data.guid;
                    fileExtension = ret.data.fileExtension;                 
                    //swal({
                    //    title: $translate.instant('SuccessTitle'),
                    //    text: $translate.instant('UploadFileSuccess'),
                    //    type: "success",
                    //    confirmButtonText: $translate.instant('Confirm')
                    //});
                }
                else {
                    if (ret.resultMsg && ret.resultMsg.length > 0) {
                        swal({
                            title:$translate.instant('FailureTitle'),
                            text: $translate.instant('UploadFileFail') + ret.resultMsg,
                            type: "error",
                            confirmButtonText: $translate.instant('Confirm')
                        });
                        //alert(ret.resultMsg);
                    }
                }

                //$timeout(function () {
                //    file.result = response.data;
                //});

            }, function (response) {
                console.log('import error: ' + response.status);
                if (response.status > 0) {
                    //$scope.errorMsg = response.status + ': ' + response.data;
                    $log.debug('erp load file error:');
                    $log.debug(response.status + ': ' + response.data);
                }
                    

            }, function (evt) {
                //file.progress = Math.min(100, parseInt(100.0 *
                //                         evt.loaded / evt.total));
                $scope.progress =
                  Math.min(100, parseInt(100.0 * evt.loaded / evt.total));

            });
        }
        else {
            // $scope.showError = true;
        }

    }


    //导入财务数据
    $scope.importData = function (importTypeParam) {
        if ($scope.filePath == $translate.instant('ConfirmSelectErpImportFileTitle'))
        {
            swal({
                title: $translate.instant('ConfirmSelectErpImportFileTitle'),
                text: $translate.instant('ConfirmSelectErpImportFile'),
                type: "warning",
                confirmButtonText: $translate.instant('Yes')   
            });
            return false;
        }

        if (vatSessionService.project.projectStatusList[period] >= constant.ProjectStatusEnum.Imported) {
            swal({
                title: "warning!",
                text: $translate.instant('IsConfirmToReImport').formatObj({ status: vatCommonService.getProjectStautsEnumDesc(vatSessionService.project.projectStatusList[period]) }),
                type: "warning",
                showCancelButton: true,
                confirmButtonText: $translate.instant('ConfirmYes'),
                cancelButtonText: $translate.instant('ConfirmNo'),
                closeOnConfirm: false,
                closeOnCancel: false
            },
            function (isConfirm) {
                if (isConfirm) {
                    swal.close();
                    startToImportErpData(importTypeParam);
                }
                else {               
                    swal.close();
                }
            });  
        }
        else {
            startToImportErpData(importTypeParam);
        }
            
            
        
    }


    //日志
    $scope.showOperateLogPop = function () {
        $scope.isShowLog = true;
    };


    function startToImportErpData(importTypeParam) {
        var importFileName = "";
        $scope.f.forEach(function (item, index) {
            importFileName += item.name;
        });
        logDto.ID = PWC.newGuid();
        logDto.CreateTime = new Date();
        logDto.UpdateTime = new Date();
        logDto.OperationContent = importFileName;
        if (importTypeParam === 0) { 
            logDto.OperationName = $translate.instant('ConvertErpData');
            logDto.OperationType = enums.vatLogOperationTypeEnum.CoverImport;
        }
        else if (importTypeParam === 1) {
            logDto.OperationName = $translate.instant('AppendErpData');
            logDto.OperationType = enums.vatLogOperationTypeEnum.AddImport;
        }
       
        vatImportService.getImportType(projectId, period).success(function (data) {
            if (data === TbImportTypeEnum.UnImported || data === TbImportTypeEnum.ErpImported) {
                importErpData(importTypeParam);
            }

            if (data === TbImportTypeEnum.TbImported) {
                swal({
                    title: $translate.instant('ConfirmCleartTbTitle'),
                    text: $translate.instant('ConfirmTbDataToDelete'),
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonText: $translate.instant('Yes'),
                    cancelButtonText: $translate.instant('No'),
                    closeOnConfirm: true,
                    closeOnCancel: true
                },
                 function (isConfirm) {
                     //1. 清除TB导入数据
                     if (isConfirm) {
                         $log.debug("confirm to clear TB data");
                         vatImportService.deleteTbData(period)
                           .success(function (data) {
                               $log.debug("deleteTbData(period): ", data);
                               //2. 导入财务数据
                               if (data) {                                 
                                   importErpData(importTypeParam);
                               }
                               else {
                                   swal({
                                       title: $translate.instant('FailureTitle'),
                                       text: $translate.instant('ClearTbError'),
                                       type: "error",
                                       confirmButtonText: $translate.instant('Confirm')
                                   });
                               }
                           });
                     }
                 });
            }
        });
    }

    //校验界面
    $scope.openTab = function (evt, tabId) {
        var i, tabcontent, tablinks;
        //隐藏所有tabContent
        tabcontent = document.getElementsByClassName("tabContent");
        for (i = 0; i < tabcontent.length; i++) {
            tabcontent[i].style.display = "none";
        }

        //删除所有tab button中的active, inactive class
        tablinks = document.getElementsByClassName("tablinks");
        for (i = 0; i < tablinks.length; i++) {
            tablinks[i].className = tablinks[i].className.replace(" active", "");
            tablinks[i].className = tablinks[i].className.replace(" inactive", "");
            tablinks[i].className = tablinks[i].className.replace(" inactive-rightborder", "");   
        }

        //设置选中tab   
        document.getElementById(tabId).style.display = "block";
        evt.currentTarget.className += " active";

        //设置未选中tab
        for (i = 0; i < tablinks.length; i++) {
            if (tablinks[i].id != evt.currentTarget.id) {
                tablinks[i].className += " inactive";

                if ($("#btnCorrectChk").attr("class").indexOf(" active") === -1) {
                    if (_.isEqual(tablinks[i].id, "btnBasicChk")) {
                        tablinks[i].className += " inactive-rightborder";
                    }

                    if (_.isEqual(tablinks[i].id, "btnCorrectChk")) {
                        //基础数据验证和数据正确性验证都不可用时,只要基础数据验证加右边框就可以了
                        if ($("#btnBasicChk").attr("class").indexOf("inactive-rightborder") === -1) {
                            tablinks[i].className += " inactive-rightborder";
                        }
                    }
                }
                
            }            
        }

        //clearAllDataValidationArray();
        if (evt.currentTarget.id === "btnDuplicateData") {
            validteCategory = validteCategoryEnum.Duplicate;
            if ($scope.duplicateList.length === 0) {
                getDuplicateRecords();
            }
            
        }

        if (evt.currentTarget.id === "btnBasicChk") {
            validteCategory = validteCategoryEnum.Basic;
           if ($scope.basicCheckList.length === 0) {
                getBasicValidationRecords();
           }
            
        }

        if (evt.currentTarget.id === "btnCorrectChk") {
            validteCategory = validteCategoryEnum.Correctness;
           if ($scope.correctCheckList.length === 0) {
               getCorrectValidationRecords();
           }
        }
    }


    //双击查看验证详细数据
    $scope.checkDetailDbclick = function (evt) {
        //对应enum: ErpCheckType
        var erpCheckTypeId = -1;
        var errorCount = -1;
        if ($scope.basicCheckList.length > 0 && _.isEqual(validteCategory,validteCategoryEnum.Basic)) {          
            erpCheckTypeId = $scope.basicCheckList[evt.currentTarget.rowIndex][5];
            errorCount = $scope.basicCheckList[evt.currentTarget.rowIndex][3];
        }

        if ($scope.correctCheckList.length > 0 && _.isEqual(validteCategory,validteCategoryEnum.Correctness)) {
            erpCheckTypeId = $scope.correctCheckList[evt.currentTarget.rowIndex][5];
            errorCount = $scope.correctCheckList[evt.currentTarget.rowIndex][3];
        }
        
        if ($scope.duplicateList.length > 0 && _.isEqual(validteCategory,validteCategoryEnum.Duplicate)) {
            erpCheckTypeId = $scope.duplicateList[evt.currentTarget.rowIndex][3];
            errorCount = $scope.duplicateList[evt.currentTarget.rowIndex][2]; 
        }

        if (errorCount > 0) {
            getCheckDetails(erpCheckTypeId);
            if (erpCheckTypeId === ErpCheckTypeEnum.DuplicatedVoucher) {
                $('#duplicatedVouchers').modal('show');
            }
            else if (erpCheckTypeId === ErpCheckTypeEnum.DuplicatedTb) {
                $('#duplicatedTbes').modal('show');
            }
            else {
                $('#detailListModal').modal('show');
            }                  
        }
        else {
            swal({
                title: $translate.instant('WarningTitle'),
                text: $translate.instant('ErpDetailWarning'),
                type: "warning",
                confirmButtonText: $translate.instant('Confirm')
            });
        }     
    }


    //删除选中的Voucher
    $scope.deleteDuplicateVouchers = function () {
        var selectedVouchers = $scope.gridApi.selection.getSelectedGridRows();
        $log.debug("get selected duplicated voucher details");
        $log.debug(selectedVouchers);
     
        if (selectedVouchers.length > 0) {
            var voucherIds = [];
            var voucherAccts = [];
            selectedVouchers.forEach(function(item,index){
                if (!_.isNull(item.entity.voucherID)) {
                    voucherIds.push(item.entity.voucherID);
                    voucherAccts.push(item.entity.acctCode);
                }
            });

            logDto.ID = PWC.newGuid();
            logDto.CreateTime = new Date();
            logDto.UpdateTime = new Date();
            logDto.OperationContent = voucherAccts.join(",");
            logDto.OperationName = $translate.instant('DeleteVoucherDuplicate');
            logDto.OperationType = enums.vatLogOperationTypeEnum.DeleteDuplicate;

            $log.debug("voucherIds ready to be deleted: " + voucherIds);
            //delete 
            dataImportService.deleteVoucherDuplicateItems(voucherIds)
              .success(function (data) {
                  $log.debug("delete duplicated vouchers results: " + data);
                  $('#duplicatedVouchers').modal('hide');
                  if (data) {
                      swal({
                          title: $translate.instant('SuccessTitle'),
                          text: $translate.instant('DeleteSuccess'),
                          type: "success",
                          timer: 1000
                      });

                      logDto.UpdateState = $translate.instant('DeleteSuccess');
                      vatOperationLogService.addOperationLog(logDto);
                      ReCheckAndManageData();
                  }        
                 
              });
        }
        else {
            logDto.UpdateState = $translate.instant('DeleteFailed');
            vatOperationLogService.addOperationLog(logDto);

            swal({
                title: $translate.instant('WarningTitle'),
                text: $translate.instant('DeleteEmptyWarning'),
                type: "warning",
                confirmButtonText: $translate.instant('Confirm')
            });
        }
    }


    //删除选中的CustBalance
    $scope.deleteDuplicateTbes = function () {
        var selectedTbes = $scope.gridApiTb.selection.getSelectedGridRows();
        $log.debug("get selected duplicated custbalance details");
        $log.debug(selectedTbes);
        if (selectedTbes.length > 0) {
            var balanceIds = [];
            var balanceAccts = [];
            selectedTbes.forEach(function (item, index) {
                if (!_.isNull(item.entity.balanceId)) {
                    balanceIds.push(item.entity.balanceId);
                    balanceAccts.push(item.entity.acctCode);
                }
            });

            logDto.ID = PWC.newGuid();
            logDto.CreateTime = new Date();
            logDto.UpdateTime = new Date();
            logDto.OperationContent = balanceAccts.join(",");
            logDto.OperationName = $translate.instant('DeleteCustBalanceDuplicate');
            logDto.OperationType = enums.vatLogOperationTypeEnum.DeleteDuplicate;

            $log.debug("balanceIds ready to be deleted: " + balanceIds);
            //delete 
            dataImportService.deleteCustBalanceItems(balanceIds)
              .success(function (data) {
                  $log.debug("delete duplicated custbalance results: " + data);
                  $('#duplicatedTbes').modal('hide');
                  if (data) {
                      swal({
                          title: $translate.instant('SuccessTitle'),
                          text: $translate.instant('DeleteSuccess'),
                          type: "success",
                          timer: 1000
                      });
                      logDto.UpdateState = $translate.instant('DeleteSuccess');
                      vatOperationLogService.addOperationLog(logDto);
                      ReCheckAndManageData();
                  }
              });
        }
        else {
            logDto.UpdateState = $translate.instant('DeleteFailed');
            vatOperationLogService.addOperationLog(logDto);

            swal({
                title: $translate.instant('WarningTitle'),
                text: $translate.instant('DeleteEmptyWarning'),
                type: "warning",
                confirmButtonText: $translate.instant('Confirm')
            });
        }
    }
    
    
    //检查用户机构权限
    $scope.checkUserOrganizationPermissionList = function () {
        var list = [];
        var userManageTemp = constant.vatPermission.dataImport.erpImport;
        list.push(userManageTemp.importCode);
        $scope.hasImportPermission = false;
        $scope.$root.checkUserOrganizationPermissionList(list).success(function (data) {                     
            $scope.hasImportPermission = data[userManageTemp.importCode];        
        });
    };


    //根据hasImportPermission设置按钮的样式
    $scope.setButtonSetByPermission = function () {
        if (!$scope.hasImportPermission) {
            return { cursor: "not-allowed" };
        }
        else {
            return { cursor: "default" };
        }
    };


    //清理数据校验的数组
    function clearAllDataValidationArray() {
        $log.debug("start to clear all data validation array");
        $scope.duplicateList = [];
        $scope.basicCheckList = [];
        $scope.correctCheckList = [];
    }


    //导入数据
    function importErpData(importTypeParam) {
        $log.debug("start to import data");
        importType = importTypeParam;
        $http({
            method: 'POST',
            url: webHost + '/api/v1/financeImportData/importData/importFinancedata',
            params: {
                importMethod: importMethod,
                importType: importType,
                fileName: fileNames,
                fileGuid: fileGuid,
                fileExtension: fileExtension,
                period: period
            },
            headers: {
                'Access-Control-Allow-Origin': '*',
                Authorization: apiTokenObj.token_type + ' ' + apiTokenObj.access_token,
                from: vatSessionService.project.dbName + '@cn.pwc.com'
            },
            __RequestVerificationToken: token,
            withCredentials: true
        }).then(function successCallback(response) {
            var ret = response.data;
            if (ret.result) {
                swal({
                    title:$translate.instant('SuccessTitle'),
                    text: $translate.instant('ImportErpDataSuccess'),
                    type: "success",
                    timer: 1000           
                });
                $log.debug("import data successfully,start to update project import type");
                logDto.UpdateState = $translate.instant('ImportSuccess');
                vatOperationLogService.addOperationLog(logDto);
                updateProjectImportType();
                clearAllDataValidationArray();                   
                vatCommonService.importSetProjectStatus(projectDbName, period
                                                        , constant.DictionaryDictKey.WFImportErpData
                                                        , enums.FinishStatusEnum.Finished);
                vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isErpImport, true);
                $log.debug("import erp importErpData: " + vatSessionService.project.importSubStatus.isErpImport);
                startManageData(period);               
                $scope.filePath = $translate.instant('ConfirmSelectErpImportFileTitle');; //还原导入文件路径
                $scope.isImportTypeErp = true;
                
            }
            else {
                $scope.filePath = $translate.instant('ConfirmSelectErpImportFileTitle');//还原导入文件路径; //清理导入文件路径
                if (ret.resultMsg && ret.resultMsg.length > 0) {
                    var errorMessages = "";
                    var popUpErrorMsg = "";
                    ret.data.forEach(function (item, index) {
                        errorMessages = errorMessages + "\r\n" + item.errorMsg;
                    });
                    //出错信息中包含CONST_ACEOLEDB的话,弹出特殊提示
                    errorMessages = errorMessages.toLowerCase();
                    if (errorMessages.indexOf(CONST_ACEOLEDB.toLowerCase()) > 0) {
                        popUpErrorMsg = $translate.instant('ACEOLEDBUnInstallError');
                    }
                    else {
                        popUpErrorMsg = $translate.instant('ImportErpDataFail') + ret.resultMsg;
                    }

                    logDto.UpdateState = $translate.instant('FailureTitle');
                    vatOperationLogService.addOperationLog(logDto);

                    swal({
                        title: $translate.instant('FailureTitle'),
                        text: popUpErrorMsg,
                        type: "error",
                        confirmButtonText: $translate.instant('Confirm')
                    });
                }

            }
        }, function errorCallback(response) {
            $log.debug('erp import data error');
            $log.debug(response);
            SweetAlert.error($translate.instant('PleaseContactAdministrator'));
        });
    }


    //上传文件格式验证
    function checkUploadFiles(files) {
        var result = true;
        for (var i = 0; i < files.length; i++) {
            var item = files[i];
            var fileName = item.name;
            var fileExtension = fileName.substr(fileName.lastIndexOf(".") + 1, fileName.length - fileName.lastIndexOf(".")).toLowerCase();
            if (fileExtension !== ValidFileExtension.CSV
              && fileExtension !== ValidFileExtension.XLS
              && fileExtension !== ValidFileExtension.XLSX) {
                swal({
                    title: $translate.instant('WarningTitle'),
                    text:  $translate.instant('ErpUploadFileExtensionCheck'),
                    type:  "warning",
                    confirmButtonText: $translate.instant('Confirm')
                });
                result = false;
            }

            if (fileName.length >= 30) {
                SweetAlert.warning($translate.instant('FileNameTooLong'));
                result = false;
            }
        }
  
        return result;
    }


    //组装重复数据验证数据
    function initDuplicateRecords(or) {
        //添加title
        var data = or.data;
        $scope.duplicateList = [];
        var duplicateTitleDto = [];
        duplicateTitleDto.push($translate.instant('Num'));
        duplicateTitleDto.push($translate.instant('TableName'));
        duplicateTitleDto.push($translate.instant('DuplicateNum'));
        duplicateTitleDto.push($translate.instant('ErpCheckTypeId'));
        $scope.duplicateList.push(duplicateTitleDto);

        data.forEach(function (item, index) {
            var duplicateDto = [];
            if (duplicateTitleDto.indexOf($translate.instant('Num')) !== -1) {
                duplicateDto.push(item.num);
            }

            if (duplicateTitleDto.indexOf($translate.instant('TableName')) !== -1) {
                duplicateDto.push(item.tableName);
            }

            if (duplicateTitleDto.indexOf($translate.instant('DuplicateNum')) !== -1) {
                duplicateDto.push(item.duplicateCount);
            }

            if (duplicateTitleDto.indexOf($translate.instant('ErpCheckTypeId')) !== -1) {
                duplicateDto.push(item.erpCheckTypeId);
            }

            $scope.duplicateList.push(duplicateDto);
        });


        if (or.resultMsg === constant.ValidationMessag.ReValidate) {
            vatWorkflowService.addErpImportExceptionMessage(projectDbName, period, enums.validationType.ErpDuplicate)
                .success(function (or) {
                    if (or.result) {
                        $log.debug("send erp duplicate validation message successfully");
                    }
                });
        }

    }


    //重复数据验证
    function getDuplicateRecords() {
        dataImportService.getDuplicateResults().success(function (or) {
            initDuplicateRecords(or);
          });
    }


    //组装基础校验数据
    function initBasicValicationsRecords(or)
    {
        var data = or.data;
        $scope.basicCheckList = [];
        //添加Title
        var basicChkTilteDto = [];
        basicChkTilteDto.push($translate.instant('Num'));
        basicChkTilteDto.push($translate.instant('ImagePic'));
        basicChkTilteDto.push($translate.instant('DataCheckType'));
        basicChkTilteDto.push($translate.instant('ErrorCount'));
        basicChkTilteDto.push($translate.instant('Tips'));
        basicChkTilteDto.push($translate.instant('ErpCheckTypeId'));
        $scope.basicCheckList.push(basicChkTilteDto);

        data.forEach(function (item, index) {
            var basicChkDto = [];
            if (basicChkTilteDto.indexOf($translate.instant('Num')) !== -1) {
                basicChkDto.push(item.num);
            }


            if (basicChkTilteDto.indexOf($translate.instant('ImagePic')) !== -1) {
                basicChkDto.push(item.imagePic);
            }

            if (basicChkTilteDto.indexOf($translate.instant('DataCheckType')) !== -1) {
                basicChkDto.push(item.dataCheckType);
            }

            if (basicChkTilteDto.indexOf($translate.instant('ErrorCount')) !== -1) {
                basicChkDto.push(item.errorCount);
            }

            if (basicChkTilteDto.indexOf($translate.instant('Tips')) !== -1) {
                basicChkDto.push(item.tips);
            }


            if (basicChkTilteDto.indexOf($translate.instant('ErpCheckTypeId')) !== -1) {
                basicChkDto.push(item.erpCheckTypeId);
            }

            $scope.basicCheckList.push(basicChkDto);
        });

        if (or.resultMsg === constant.ValidationMessag.ReValidate) {
            vatWorkflowService.addErpImportExceptionMessage(projectDbName, period, enums.validationType.ErpBasicCheck)
                .success(function (or) {
                    if (or.result) {
                        $log.debug("send erp basic validation message successfully");
                    }
                });
        }
    }


    //基础数据验证
    function getBasicValidationRecords() {
        dataImportService.getBasicValidationResults()
          .success(function (or) {
              if (or.result) {
                  initBasicValicationsRecords(or);                
              }
              
          });
    }


    //组装数据正确性验证
    function initCorrectValidationRecords(or) {
        //添加Title
        var data = or.data;
        $scope.correctCheckList = [];
        var crtTitleDto = [];
        crtTitleDto.push($translate.instant('Num'));
        crtTitleDto.push($translate.instant('ImagePic'));
        crtTitleDto.push($translate.instant('DataCheckType'));
        crtTitleDto.push($translate.instant('ErrorCount'));
        crtTitleDto.push($translate.instant('Tips'));
        crtTitleDto.push($translate.instant('ErpCheckTypeId'));
        $scope.correctCheckList.push(crtTitleDto);

        data.forEach(function (item, index) {
            var crtValication = [];
            if (crtTitleDto.indexOf($translate.instant('Num')) !== -1) {
                crtValication.push(item.num);
            }

            if (crtTitleDto.indexOf($translate.instant('ImagePic')) !== -1) {
                crtValication.push(item.imagePic);
            }

            if (crtTitleDto.indexOf($translate.instant('DataCheckType')) !== -1) {
                crtValication.push(item.dataCheckType);
            }

            if (crtTitleDto.indexOf($translate.instant('ErrorCount')) !== -1) {
                crtValication.push(item.errorCount);
            }

            if (crtTitleDto.indexOf($translate.instant('Tips')) !== -1) {
                crtValication.push(item.tips);
            }

            if (crtTitleDto.indexOf($translate.instant('ErpCheckTypeId')) !== -1) {
                crtValication.push(item.erpCheckTypeId);
            }
            $scope.correctCheckList.push(crtValication);
        });

        if (or.resultMsg === constant.ValidationMessag.ReValidate) {
            vatWorkflowService.addErpImportExceptionMessage(projectDbName, period, enums.validationType.ErpCorrect)
                .success(function (or) {
                    if (or.result) {
                        $log.debug("send erp correctness validation message successfully");
                    }
                });
        }
    }


    //数据正确性验证
    function getCorrectValidationRecords() {
        dataImportService.getCorrectValidationResults(period).success(function (or) {
              initCorrectValidationRecords(or);
        });
    }


    //运行所有校验并选中基础数据验证
    function getAllValidationResults(isManage) {
        dataImportService.getBasicValidationResults().success(function (or) {
            initBasicValicationsRecords(or);
            dataImportService.getCorrectValidationResults(period).success(function (or) {
                initCorrectValidationRecords(or);
                dataImportService.getDuplicateResults().success(function (or) {
                    initDuplicateRecords(or);
                    triggBasicCheck();
                    $scope.setValidationErrorStyle(true, false);
                    $scope.setValidationErrorStyle(false, true);
                    if (isManage) {
                        SweetAlert.success($translate.instant('ManageDataSuccess'));
                    }                  
                });
            });
        });
    }


    //1.数据整理
    function startManageData(period) {      
        dataImportService.manageData(period).success(function (data) {
            getAllValidationResults(true);
        });
    }


    //根据erpCheckTypeId初始化不同的详细数据
    function getCheckDetails(erpCheckTypeId) {
        $scope.checkDetails = [];
        //试算平和表中的科目不在企业科目列表中
        if (erpCheckTypeId === ErpCheckTypeEnum.ComBalanceAcctUnValidate) {
            dataImportService.getAccountsNotInCompanyBalance()
              .success(function (data) {
                  $scope.checkDetails = initCheckDetailAcct(data);
              });
        }

        //Voucher中的科目不存在于科目表中
        if (erpCheckTypeId === ErpCheckTypeEnum.VoucherAcctValidate) {
            dataImportService.getAccountsNotInVoucherDetails()
              .success(function (data) {
                  $scope.checkDetails = initCheckDetailAcct(data);
              });
        }

        //单个凭证借贷平衡
        if (erpCheckTypeId === ErpCheckTypeEnum.VSingleDebitCreditUnValidate) {
            dataImportService.getSingleVoucherCheck()
              .success(function (data) {
                  $scope.checkDetails = initCheckDetailByVoucher(data);
              });
        }
           
        //Voucher ItemID 为空
        if (erpCheckTypeId === ErpCheckTypeEnum.VEmptyCheckUnValidateItemID) {
            dataImportService.getVoucherEmptyCheck(true, false, false, false, false)
              .success(function (data) {
                  $scope.checkDetails = initCheckDetailByVoucher(data);
              });
        }

        //Voucher Group 为空
        if (erpCheckTypeId === ErpCheckTypeEnum.VEmptyCheckUnValidateGroup) {
            dataImportService.getVoucherEmptyCheck(false, false, true, false, false)
              .success(function (data) {
                  $scope.checkDetails = initCheckDetailByVoucher(data);
              });
        }

        //Voucher AccontCode 为空
        if (erpCheckTypeId === ErpCheckTypeEnum.VEmptyCheckUnValidateAcctCode) {
            dataImportService.getVoucherEmptyCheck(false, false, false, true, false)
              .success(function (data) {
                  $scope.checkDetails = initCheckDetailByVoucher(data);
              });
        }

        //Voucher Summary 为空
        if (erpCheckTypeId === ErpCheckTypeEnum.VEmptyCheckUnValidateSummary) {
            dataImportService.getVoucherEmptyCheck(false,false,false,false,true)
              .success(function (data) {
                  $scope.checkDetails = initCheckDetailByVoucher(data);
            });
        }

        //试算平衡表中期初余额上下级不平衡
        if (erpCheckTypeId === ErpCheckTypeEnum.AcctBegBalAcctLevelUnValidate) {
            dataImportService.getAccountBegBalances(period)
              .success(function (data) {
                  $scope.checkDetails = initCheckDetailAcct(data);
              });
        }

        //试算平衡表中期初余额借贷不平衡
        if (erpCheckTypeId === ErpCheckTypeEnum.BegBalUnValidate) {
            dataImportService.getBegBalancesByPeriod(period)
              .success(function (data) {
                  //title
                  var detailTitleDto = [];
                  detailTitleDto.push($translate.instant('BegDebitBal'));
                  detailTitleDto.push($translate.instant('BegCreditBal'));
                  $scope.checkDetails.push(detailTitleDto);

                  //body
                  var detailDto = [];
                  if (detailTitleDto.indexOf($translate.instant('BegDebitBal')) !== -1) {
                      data.forEach(function (item, index) {
                          if (item.direction == "1") {
                              detailDto.push(item.begBal);
                          }
                      });                    
                  }

                  if (detailTitleDto.indexOf($translate.instant('BegCreditBal')) !== -1) {
                      data.forEach(function (item, index) {
                          if (item.direction == "-1") {
                              detailDto.push(item.begBal);
                          }
                      });
                  }                 
                  $scope.checkDetails.push(detailDto);
              });
        }

        //原始/计算期末余额比较 
        if (erpCheckTypeId === ErpCheckTypeEnum.CompCustEndBalUnValidate) {
            var isExistedEndBal = false;
            dataImportService.getCompCustBalanceDetail(period, period)
              .success(function (data) {
                  dataImportService.isComBalanceEndBalNotZero(period)
                    .success(function (enddata) {
                        isExistedEndBal = enddata;
                        $scope.checkDetails = initCheckDetailCompareEndBal(isExistedEndBal, data);
                    })
              });
        }

        //原始/计算发生额比较
        if (erpCheckTypeId === ErpCheckTypeEnum.CompCustAmountUnValidate) {
            dataImportService.compareCompCustPeriodAmount(period, period)
              .success(function (data) {
                  $scope.checkDetails = initCheckDetailCompareAmount(data);
              });
        }

        //上月期末与导入的本月期初
        if (erpCheckTypeId === ErpCheckTypeEnum.BegEndBalUnValidate) {
            var isExistedEndBal = false;
            dataImportService.compareCustEndCompBeg(period, period)
              .success(function (data) {
                  dataImportService.isComBalanceEndBalNotZero(period)
                    .success(function (endData) {
                        isExistedEndBal = endData;
                        $scope.checkDetails = initCheckDetailEndBalCompare(isExistedEndBal, data);                     
                    });
              });
        }


        //凭证重复
        if (erpCheckTypeId === ErpCheckTypeEnum.DuplicatedVoucher) {
            dataImportService.getDuplicateVouchers()
              .success(function (data) {              
                  $log.debug("set duplicated voucher details data");
                  $scope.gridUiDuplicateVouchers.data = data;
                  $log.debug($scope.gridUiDuplicateVouchers.data);
              });
        }

        //CustBalance重复
        if (erpCheckTypeId === ErpCheckTypeEnum.DuplicatedTb) {
            dataImportService.getCustBalanceDuplicateItems()
              .success(function (data) {
                  $log.debug("set duplicated custbalance details data");
                  $scope.gridUiDuplicateTbes.data = data;
                  $log.debug($scope.gridUiDuplicateTbes.data);
              });
        }
    }


    //初始化Voucher相关的详细信息
    function initCheckDetailByVoucher(data) {
        var detailTitleDto = [];
        var voucherDetails = [];
        //title       
        detailTitleDto.push($translate.instant('AccountCode'));
        detailTitleDto.push($translate.instant('JournalKHDM'));
        detailTitleDto.push($translate.instant('vid'));
        detailTitleDto.push($translate.instant('vGroup'));
        detailTitleDto.push($translate.instant('period'));
        detailTitleDto.push($translate.instant('itemID'));
        detailTitleDto.push($translate.instant('JournalZY'));
        detailTitleDto.push($translate.instant('JournalJFJE'));
        detailTitleDto.push($translate.instant('JournalDFJE'));
        
        voucherDetails.push(detailTitleDto);

        if (_.isNull(data)) {
            return false;
        }

        //body
        data.forEach(function(item,index){
            var detailDto = [];
            if (detailTitleDto.indexOf($translate.instant('AccountCode')) !== -1) {
                detailDto.push(item.acctCode);
            }

            if (detailTitleDto.indexOf($translate.instant('JournalKHDM')) !== -1) {
                detailDto.push(item.customerCode);
            }

            if (detailTitleDto.indexOf($translate.instant('vid')) !== -1) {
                detailDto.push(item.vid);
            }

            if (detailTitleDto.indexOf($translate.instant('vGroup')) !== -1) {
                detailDto.push(item.group);
            }

            if (detailTitleDto.indexOf($translate.instant('period')) !== -1) {
                detailDto.push(item.period);
            }

            if (detailTitleDto.indexOf($translate.instant('itemID')) !== -1) {
                detailDto.push(item.itemID);
            }

            if (detailTitleDto.indexOf($translate.instant('JournalZY')) !== -1) {
                detailDto.push(item.summary);
            }

            if (detailTitleDto.indexOf($translate.instant('JournalJFJE')) !== -1) {
                detailDto.push(item.debit);
            }

            if (detailTitleDto.indexOf($translate.instant('JournalDFJE')) !== -1) {
                detailDto.push(item.credit);
            }
                     
            voucherDetails.push(detailDto);
        });
       
        return voucherDetails;
    }


    //初始话科目相关的详细信息
    function initCheckDetailAcct(data)
    {
        //title
        var detailTitleDto = [];
        var acctDetails = [];
        detailTitleDto.push($translate.instant('AccountCode'));
        acctDetails.push(detailTitleDto);
        if (_.isNull(data)) {
            return false;
        }

        //body
        data.forEach(function (item, index) {
            var detailDto = [];
            if (detailTitleDto.indexOf($translate.instant('AccountCode')) !== -1) {
                detailDto.push(item.acctCode);
            }
            acctDetails.push(detailDto);
        });                 
       
        return acctDetails
    }


    //初始化上月期末与导入的本月期初校验的详细信息
    function initCheckDetailEndBalCompare(isEndBal, data) {
        var detailTitleDto = [];
        var compareDetails = [];

        //title
        detailTitleDto.push($translate.instant('PeriodId'));
        detailTitleDto.push($translate.instant('AccountCode'));
        detailTitleDto.push($translate.instant('AccountName'));
         
        if (isEndBal) {
            detailTitleDto.push($translate.instant('LastPeriodEndBal'));
            detailTitleDto.push($translate.instant('CurrentPeriodEndBal'));
            detailTitleDto.push($translate.instant('BalDiff'));
        }
        else {
            detailTitleDto.push($translate.instant('LastPeriodEndDebitBal'));
            detailTitleDto.push($translate.instant('LastPeriodEndCreditBal'));
            detailTitleDto.push($translate.instant('CurrentPeriodBegDebitBal'));
            detailTitleDto.push($translate.instant('CurrentPeriodBegCreditBal'));
            detailTitleDto.push($translate.instant('DebitBalDiff'));
            detailTitleDto.push($translate.instant('CreditBalDiff'));
        }
        compareDetails.push(detailTitleDto);
        
        if (_.isNull(data)) {
            return false;
        }

        //body
        data.forEach(function (item, index) {
            var detailDto = [];

            if (detailTitleDto.indexOf($translate.instant('PeriodId')) !== -1) {
                detailDto.push(item.periodId);
            }

            if (detailTitleDto.indexOf($translate.instant('AccountCode')) !== -1) {
                detailDto.push(item.accountCode);
            }

            if (detailTitleDto.indexOf($translate.instant('AccountName')) !== -1) {
                detailDto.push(item.accountName);
            }

            if (isEndBal) {
                if (detailTitleDto.indexOf($translate.instant('LastPeriodEndBal')) !== -1) {
                    detailDto.push(item.custEndBal);
                }

                if (detailTitleDto.indexOf($translate.instant('CurrentPeriodEndBal')) !== -1) {
                    detailDto.push(item.comBegBal);
                }

                if (detailTitleDto.indexOf($translate.instant('BalDiff')) !== -1) {
                    detailDto.push(item.begBalDiff);
                }

            }
            else {

                if (detailTitleDto.indexOf($translate.instant('LastPeriodEndDebitBal')) !== -1) {
                    detailDto.push(item.custEndDebitBal);
                }

                if (detailTitleDto.indexOf($translate.instant('LastPeriodEndCreditBal')) !== -1) {
                    detailDto.push(item.custEndCreditBal);
                }

                if (detailTitleDto.indexOf($translate.instant('CurrentPeriodBegDebitBal')) !== -1) {
                    detailDto.push(item.comBegDebitBal);
                }

                if (detailTitleDto.indexOf($translate.instant('CurrentPeriodBegCreditBal')) !== -1) {
                    detailDto.push(item.comBegCreditBal);
                }

                if (detailTitleDto.indexOf($translate.instant('DebitBalDiff')) !== -1) {
                    detailDto.push(item.begDebitDiff);
                }

                if (detailTitleDto.indexOf($translate.instant('CreditBalDiff')) !== -1) {
                    detailDto.push(item.begCreditDiff);
                }
            }
            compareDetails.push(detailDto);
        });
        
        return compareDetails;
    }


    //初始化原始/计算发生额的详细信息
    function initCheckDetailCompareAmount(data) {
        var detailTitleDto = [];
        var amountsDetails = [];

        //title
        detailTitleDto.push($translate.instant('PeriodId'));
        detailTitleDto.push($translate.instant('AccountCode'));
        detailTitleDto.push($translate.instant('AccountName'));
        detailTitleDto.push($translate.instant('ComDebitBal'));
        detailTitleDto.push($translate.instant('ComCreditBal'));
        detailTitleDto.push($translate.instant('CustDebitBal'));
        detailTitleDto.push($translate.instant('CustCreditBal'));
        detailTitleDto.push($translate.instant('DebitBalDiff'));
        detailTitleDto.push($translate.instant('CreditBalDiff'));
        amountsDetails.push(detailTitleDto);

        if (_.isNull(data)) {
            return false;
        }

        //body
        data.forEach(function (item, index) {
            var detailDto = [];

            if (detailTitleDto.indexOf($translate.instant('PeriodId')) !== -1) {
                detailDto.push(item.periodId);
            }

            if (detailTitleDto.indexOf($translate.instant('AccountCode')) !== -1) {
                detailDto.push(item.accountCode);
            }

            if (detailTitleDto.indexOf($translate.instant('AccountName')) !== -1) {
                detailDto.push(item.accountName);
            }

            if (detailTitleDto.indexOf($translate.instant('ComDebitBal')) !== -1) {
                detailDto.push(item.comDebitBal.toFixed(2));
            }

            if (detailTitleDto.indexOf($translate.instant('ComCreditBal')) !== -1) {
                detailDto.push(item.comCreditBal.toFixed(2));
            }

            if (detailTitleDto.indexOf($translate.instant('CustDebitBal')) !== -1) {
                detailDto.push(item.custDebitBal.toFixed(2));
            }

            if (detailTitleDto.indexOf($translate.instant('CustCreditBal')) !== -1) {
                detailDto.push(item.custCreditBal.toFixed(2));
            }

            if (detailTitleDto.indexOf($translate.instant('DebitBalDiff')) !== -1) {
                detailDto.push(item.debitBalDiff.toFixed(2));
            }

            if (detailTitleDto.indexOf($translate.instant('DebitBalDiff')) !== -1) {
                detailDto.push(item.creditBalDiff.toFixed(2));
            }

            amountsDetails.push(detailDto);
        });

        return amountsDetails;
    }


    //初始化原始/计算期末余额的详细信息
    function initCheckDetailCompareEndBal(isEndBal, data) {
        var detailTitleDto = [];
        var compareDetails = [];

        //title
        detailTitleDto.push($translate.instant('PeriodId'));
        detailTitleDto.push($translate.instant('AccountCode'));
        detailTitleDto.push($translate.instant('AccountName'));

        if (isEndBal) {
            detailTitleDto.push($translate.instant('ComEndBal'));
            detailTitleDto.push($translate.instant('CustEndBal'));
            detailTitleDto.push($translate.instant('BalDiff'));
        }
        else {
            detailTitleDto.push($translate.instant('ComDebitBal'));
            detailTitleDto.push($translate.instant('ComCreditBal'));
            detailTitleDto.push($translate.instant('CustDebitBal'));
            detailTitleDto.push($translate.instant('CustCreditBal'));
            detailTitleDto.push($translate.instant('DebitBalDiff'));
            detailTitleDto.push($translate.instant('CreditBalDiff'));
        }
        compareDetails.push(detailTitleDto);

        if (_.isNull(data)) {
            return false;
        }

        //body
        data.forEach(function (item, index) {
            var detailDto = [];

            if (detailTitleDto.indexOf($translate.instant('PeriodId')) !== -1) {
                detailDto.push(item.periodId);
            }

            if (detailTitleDto.indexOf($translate.instant('AccountCode')) !== -1) {
                detailDto.push(item.accountCode);
            }

            if (detailTitleDto.indexOf($translate.instant('AccountName')) !== -1) {
                detailDto.push(item.accountName);
            }

            if (isEndBal) {
                if (detailTitleDto.indexOf($translate.instant('ComEndBal')) !== -1) {
                    detailDto.push(item.comEndBal.toFixed(2));
                }

                if (detailTitleDto.indexOf($translate.instant('CustEndBal')) !== -1) {
                    detailDto.push(item.custEndBal.toFixed(2));
                }

                if (detailTitleDto.indexOf($translate.instant('BalDiff')) !== -1) {
                    detailDto.push(item.endDiff.toFixed(2));
                }

            }
            else {

                if (detailTitleDto.indexOf($translate.instant('ComDebitBal')) !== -1) {
                    detailDto.push(item.comEndDebitBal.toFixed(2));
                }

                if (detailTitleDto.indexOf($translate.instant('ComCreditBal')) !== -1) {
                    detailDto.push(item.comEndCreditBal.toFixed(2));
                }

                if (detailTitleDto.indexOf($translate.instant('CustDebitBal')) !== -1) {
                    detailDto.push(item.custEndDebitBal.toFixed(2));
                }

                if (detailTitleDto.indexOf($translate.instant('CustCreditBal')) !== -1) {
                    detailDto.push(item.custEndCreditBal.toFixed(2));
                }

                if (detailTitleDto.indexOf($translate.instant('DebitBalDiff')) !== -1) {
                    detailDto.push(item.debitBalDiff.toFixed(2));
                }

                if (detailTitleDto.indexOf($translate.instant('CreditBalDiff')) !== -1) {
                    detailDto.push(item.creditBalDiff.toFixed(2));
                }
            }
            compareDetails.push(detailDto);
        });

        return compareDetails;
    } 


    //初始化重复Voucher弹出框
    function initUiGvVoucherDupDetails() {
        $scope.gridUiDuplicateVouchers = {
            //set gridview options
            rowHeight: constant.UIGrid.rowHeight,
            selectionRowHeaderWidth: constant.UIGrid.rowHeight,
            enableSorting: false,
            enableColumnMenus: false,
            enableHorizontalScrollbar: uiGridConstants.scrollbars.enableHorizontalScrollbar,
            enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,
            enableRowSelection: true,
            enableSelectAll: true,
            multiSelect: true,
            enableColumnResizing: true,
            columnDefs: [
                  {
                      name: $translate.instant('period'), width: '10%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.period}}<span></div>'
                  },
                  {
                      name: $translate.instant('vGroup'), width: '15%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.group}}<span></div>'
                  },
                  {
                      name: $translate.instant('vid'), width: '15%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.vid}}<span></div>'
                  },
                  {
                      name: $translate.instant('itemID'), width: '15%', cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.itemID}}</span></div>'
                  },
                  {
                      name: $translate.instant('AccountCode'), width: '15%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.acctCode}}<span></div>'
                  },
                  {
                      name: $translate.instant('JournalZY'), width: '30%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.summary}}<span></div>'
                  },
                  {
                      name: $translate.instant('DebitBal'), width: '15%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.debit}}<span></div>'
                  },
                  {
                      name: $translate.instant('CreditBal'), width: '15%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.credit}}<span></div>'
                  }                 
                  //{
                  //    name: $translate.instant('VoucherID'), width: '20%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.voucherID}}</span></div>'
                  //}
            ],
            onRegisterApi: function (gridApi) {
                $scope.gridApi = gridApi;

                // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                $interval(function () {
                    $scope.gridApi.core.handleWindowResize();
                }, 500, 60 * 60 * 8);

                gridApi.selection.on.rowSelectionChanged($scope, function (row) {
                    var msg = 'row selected ' + row.isSelected;
                    $log.debug(msg);
                });

                gridApi.selection.on.rowSelectionChangedBatch($scope, function (rows) {
                    var msg = 'rows changed ' + rows.length;
                    $log.debug(msg);
                });
            }
        };

        $scope.gridUiDuplicateVouchers.data = [];
    }
    

    //初始化重复Tb弹出框
    function initUiGvTbDupDetails() {
        $scope.gridUiDuplicateTbes = {
            //set gridview options
            rowHeight: constant.UIGrid.rowHeight,
            selectionRowHeaderWidth: constant.UIGrid.rowHeight,
            enableSorting: false,
            enableColumnMenus: false,
            enableHorizontalScrollbar: uiGridConstants.scrollbars.enableHorizontalScrollbar,
            enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,
            enableRowSelection: true,
            enableSelectAll: true,
            multiSelect: true,
            columnDefs: [
                  {
                      name: $translate.instant('period'), width: '10%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.periodId}}<span></div>'
                  },
                  {
                      name: $translate.instant('AccountCode'), width: '15%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.acctCode}}<span></div>'
                  },
                  {
                      name: $translate.instant('JournalKHDM'), width: '15%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.customerCode}}<span></div>'
                  },
                  {
                      name: $translate.instant('BegDebitBal'), width: '20%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.begDebitBal}}<span></div>'
                  },
                  {
                      name: $translate.instant('BegCreditBal'), width: '20%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.begCreditBal}}<span></div>'
                  }, 
                  {
                      name: $translate.instant('BegBal'), width: '20%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.begBal}}<span></div>'
                  }
                               
            ],
            onRegisterApi: function (gridApi) {
                $scope.gridApiTb = gridApi;

                // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                $interval(function () {
                    $scope.gridApiTb.core.handleWindowResize();
                }, 500, 60 * 60 * 8);

                gridApi.selection.on.rowSelectionChanged($scope, function (row) {
                    //var msg = 'row selected ' + row.isSelected;
                    //$log.debug(msg);
                });

                gridApi.selection.on.rowSelectionChangedBatch($scope, function (rows) {
                    //var msg = 'rows changed ' + rows.length;
                    //$log.debug(msg);
                });
            }
        };

        $scope.gridUiDuplicateTbes.data = [];
    }


    //更新TaxAdmin中dbo.PeriodInfo.ImportType
    function updateProjectImportType() {
        var queryImportDto = {
            serviceTypeId: constant.serviceType.VAT,
            periods: [period],
            projectId: projectId,
            importTypeId: enums.TbImportTypeEnum.ErpImported
        }

        vatImportService.updatePeriodStatus(queryImportDto)
          .success(function (data) {
              $log.debug("vatImportService.updatePeriodStatus complete");
          });
    }


    //重新校验和整理数据
    function ReCheckAndManageData() {
        $log.debug("star to recheck and remanage data");         
        dataImportService.reManageData(period).success(function (data) {
            if (data) {
                $log.debug("remanage data successfully");
                getAllValidationResults(true);
            }
        });
    }


    function triggBasicCheck() {
        //默认选中基础校验
        setTimeout(function () {
            $('#btnBasicChk').trigger('click');
        }, 1000);
    }
    

    function getPeriodInfor() {
        vatImportService.getImportType(vatSessionService.project.id, period).success(function (data) {
            $scope.isImportTypeErp = enums.projectImportType.ErpImported === data ? true : false;                          
        });
    }

    //默认显示万能导入   
    $scope.switch(2);
    $scope.checkUserOrganizationPermissionList();
    getPeriodInfor();
    getAllValidationResults(false);
    initUiGvVoucherDupDetails();
    initUiGvTbDupDetails();


}]);
commonModule.directive('importErp', function () {
    return {
        restrict: 'E',
        //transclude: true,
        templateUrl: '/app/common/controls/import/import-erpdata/import-erpdata.html',
        scope: {
            serviceTypeId: "=?",
            periodId: "=?"
        },
        controller: 'ImportDataCtrl'
    }

});

commonModule.controller('importJournalEntryController', ['$scope', '$log', 'loginContext', '$translate', 'apiInterceptor', 'Upload', 'dataImportService'
    , 'SweetAlert', 'vatImportService', '$timeout', '$q', 'enums', 'uiGridConstants', '$interval'
    , 'citSessionService', 'vatOperationLogService', 'projectService', 'vatCommonService', '$uibModal',
 function ($scope, $log, loginContext, $translate, apiInterceptor, Upload, dataImportService, SweetAlert
     , vatImportService, $timeout, $q, enums, uiGridConstants, $interval
     , citSessionService, vatOperationLogService, projectService, vatCommonService, $uibModal) {
     'use strict';

     var uploadUrl = apiInterceptor.vatWebApiHostUrl + '/FileUpload/NewFile';
     var successCount = 0;
     var resumable = true;
     var curPeriod = $scope.periodId;//citSessionService.month; //从页面顶部的选择月份获取月份跟年份
     var curYear = citSessionService.project.year;
     var projectID = citSessionService.project.id;
     var projectDbName = citSessionService.project.dbName;
     var comment = citSessionService.project.name + " " + citSessionService.project.year + $translate.instant('Year')
                 + citSessionService.month + $translate.instant('month');
     var token = $('input[name="__RequestVerificationToken"]').val();


     //导入方式 
     $scope.importEnum = {
         Import: 0,
         CoverImport: 1,
         AddImport: 2
     };
     $scope.chunkSize = 100000;
     $scope.columnNum = 0;
     $scope.selectedPeriod;
     $scope.showImportTable = false; //是否显示导入table
     $scope.showInitTable = false; //是否显示初始数据ui-grid
     $scope.showErrorTable = false; //是否显示错误信息列表       
     $scope.period = citSessionService.month;
     $scope.moduleid = enums.vatModuleEnum.Import_JournalEntry;

     var logDto = {
         ID: '',
         OperationName: '',
         ModuleID: $scope.moduleid,
         OperationObject: $translate.instant('JournalEntryTitle'),
         OperationType: '',
         OperationContent: '',
         OriginalState: '',
         UpdateState: '',
         CreatorID: citSessionService.logUser.ID,
         Comment: comment,
         IP: '',
         Period: $scope.period,
     };

     var validationErrorType = {
         ColumnsMapErrorType: $translate.instant('ColumnsMapErrorType'),
         JournalEntryVIDEmptyErrorType: $translate.instant('JournalEntryVIDEmptyErrorType'),
         JournalEntryGroupEmptyErrorType: $translate.instant('JournalEntryGroupEmptyErrorType'),
         JournalEntryItemIDEmptyErrorType: $translate.instant('JournalEntryItemIDEmptyErrorType'),
         JournalEntryAcctCodeEmptyErrorType: $translate.instant('JournalEntryAcctCodeEmptyErrorType'),
         JournalEntryVoucherDateEmptyErrorType: $translate.instant('JournalEntryVoucherDateEmptyErrorType'),
         JournalEntryDateFormatErrorType: $translate.instant('JournalEntryDateFormatErrorType'),
         JournalEntryAmountErrorType: $translate.instant('JournalEntryAmountErrorType'),
         JournalEntryItemIDFormatErrorType: $translate.instant('JournalEntryItemIDFormatErrorType'),
         JournalEntryPeriodFormatErrorType: $translate.instant('JournalEntryPeriodFormatErrorType'),
         NumOutRangeErrorType: $translate.instant('NumOutRangeErrorType'),
         OutputStringLengthType: $translate.instant('OutputStringLengthType'),
         StartRowError: $translate.instant('StartRowError')
     };


     //初始化ack-pagination
     $scope.pagingOptions = {
         pageIndex: 1, //当前页码
         totalItems: 0, //总数据
         totalPages: 10, //总页数
         maxSize: 5, //分页数字的限制。
         pageSize: constant.page.pageSizeArrary[3], //每页多少条数据,100条
         pageSizeString: constant.page.pageSizeArrary[3].toString(),
         firstPage: $translate.instant('PagingFirstPage'),
         previousPage: $translate.instant('PagingPreviousPage'),
         nextPage: $translate.instant('PagingNextPage'),
         lastPage: $translate.instant('PagingLastPage'),
     };

     //初始化查询参数
     $scope.queryParams = {
         pageInfo: {
             totalCount: 0,
             pageIndex: 0,
             pageSize: 0,
             totalPage: 0,
         },
         periodId: curPeriod
     };

     //初始化汇总参数
     $scope.totalData = {
         totalNumber: 0,
         debit: 0,
         credit: 0
     };


     //初始化列数据
     var initColumns = function () {
         //初始化进项发票汇总表列名(包括请选择列)
         $scope.journalEntryColumns = [
          $translate.instant('PleaseSelectColumn'),
          $translate.instant('JournalPZRQ'),
          $translate.instant('JournalPZLX'),
          $translate.instant('JournalPZH'),
          $translate.instant('JournalFLH'),
          $translate.instant('JournalQJ'),
          $translate.instant('JournalKMDM'),
          $translate.instant('JournalZY'),
          $translate.instant('JournalJFJE'),
          $translate.instant('JournalDFJE'),
          $translate.instant('JournalKHDM')
         ];

         $scope.initJournalEntryColumnsIndex = _.range(1, $scope.journalEntryColumns.length);

         //序时账所有列
         $scope.journalEntryAllColumns = [
          $translate.instant('JournalPZRQ'),
          $translate.instant('JournalPZLX'),
          $translate.instant('JournalPZH'),
          $translate.instant('JournalFLH'),
          $translate.instant('JournalQJ'),
          $translate.instant('JournalKMDM'),
          $translate.instant('JournalZY'),
          $translate.instant('JournalJFJE'),
          $translate.instant('JournalDFJE'),
          $translate.instant('JournalKHDM')
         ];

         //必须进行map的列
         $scope.mustMappingTotalColumns = [
          $translate.instant('JournalPZRQ'),
          $translate.instant('JournalPZLX'),
          $translate.instant('JournalPZH'),
          $translate.instant('JournalFLH'),
          $translate.instant('JournalKMDM'),
          $translate.instant('JournalJFJE'),
          $translate.instant('JournalDFJE')
          //$translate.instant('JournalKHDM')
         ];
     };


     //从数据库中load数据,如果有,则页面导入按钮为覆盖导入或追加导入,否则为导入按钮
     var loadJournalEntryDataFromDB = function () {
         $scope.queryParams.periodId = curPeriod;
         $scope.queryParams.pageInfo = {
             totalCount: $scope.pagingOptions.totalItems,
             pageIndex: $scope.pagingOptions.pageIndex,
             pageSize: $scope.pagingOptions.pageSize,
             totalPage: 0,
         };
         vatImportService.queryJournalEntryData($scope.queryParams).success(function (re) {
             if (re) {
                 $scope.sheetData = {
                     sheetNameList: [],
                     dataList: [],
                     selectedSheetIndex: 0
                 };
                 var data = re.list;
                 var index = 1;
                 var debitSum = 0;
                 var creditSum = 0;
                 initPagingControl(re.pageInfo.totalCount);
                 data.forEach(function (v) {
                     v.index = index++;
                     v.debit = PWC.round(v.debit, 2);
                     v.credit = PWC.round(v.credit, 2);
                 });
                 $scope.initJournalEntryList = data;
                 $scope.gridOptionsJournalEntry.data = data;
                 $scope.totalData.totalNumber = re.pageInfo.totalCount;
                 $scope.totalData.debit = PWC.round(re.calculateData.debitSum, 2);
                 $scope.totalData.credit = PWC.round(re.calculateData.creditSum, 2);
                 $scope.itemIDCount = re.calculateData.itemIDCount;
                 $scope.vidCount = re.calculateData.vidCount;
                 //当数据库中数据>=0时,就显示初始化数据ui-grid,
                 //但是需要当数据库中数据大于0时才不显示导入按钮,而显示覆盖导入和追加导入按钮
                 if (data.length >= 0) {
                     if (data.length > 0) {
                         $scope.isShowImportTotalBtn = false;
                     }
                     $scope.showInitTable = true;
                     $scope.showImportTable = false;
                 }
                 //获取错误列表信息
                 getValidationList().then(function () {
                     if ($scope.errorList.length > 0) {
                         showErrTab();
                         $scope.toggleErrorTab();

                         //当有错误信息时,显示错误信息表
                         $scope.showErrorTable = true;
                     } else {
                         $scope.ImportErrorTab = false;
                         $scope.ImportErrorTag = false;
                         $scope.showErrorTable = false;
                     }
                 });
                 setJeGridColumns(data);                
             }

         });
     };


     //设置序时账Grid的columns
     var setJeGridColumns = function (data){
         if (data && data.length > 0) {
             $scope.gridOptionsJournalEntry.columnDefs = [{
                 name: $translate.instant('ImportErrorPopUpNoCol'),
                 width: 100,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.index}}<span></div>'
             }, {
                 name: $translate.instant('JournalPZRQ'),
                 width: 150,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.date | date:"yyyy-MM-dd"}}<span></div>'
             }];
             //判断期间列是否需要显示
             if (data[0].monthID != null) {
                 $scope.gridOptionsJournalEntry.columnDefs.push({
                     name: $translate.instant('JournalQJ'),
                     width: 100,
                     headerCellClass: 'right',
                     cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.period}}</span></div>'
                 });
             }

             $scope.gridOptionsJournalEntry.columnDefs.push({
                 name: $translate.instant('JournalPZLX'),
                 width: 150,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.group}}">{{row.entity.group}}<span></div>'
             }, {
                 name: $translate.instant('JournalPZH'),
                 width: 200,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.group}}">{{row.entity.vid}}</span></div>'
             }, {
                 name: $translate.instant('JournalKMDM'),
                 width: 150,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span  title="{{row.entity.acctCode}}">{{row.entity.acctCode}}</span></div>'
             });

             //判断是否需要显示摘要列
             if (data[0].summary != null) {
                 $scope.gridOptionsJournalEntry.columnDefs.push({
                     name: $translate.instant('JournalZY'),
                     width: 200,
                     headerCellClass: '',
                     cellTemplate: '<div class="ui-grid-cell-contents"><span  title="{{row.entity.summary}}">{{row.entity.summary}}</span></div>'
                 });
             }

             $scope.gridOptionsJournalEntry.columnDefs.push({
                 name: $translate.instant('JournalJFJE'),
                 width: 150,
                 headerCellClass: 'right',
                 cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.debit}}</span></div>'
             }, {
                 name: $translate.instant('JournalDFJE'),
                 width: 150,
                 headerCellClass: 'right',
                 cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.credit}}</span></div>'
             }, {
                 name: $translate.instant('JournalKHDM'),
                 width: 150,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.customerCode}}</span></div>'
             }, {
                 name: $translate.instant('JournalFLH'),
                 width: 100,
                 headerCellClass: 'right',
                 cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.itemID}}</span></div>'
             });
         } else {
             $scope.gridOptionsJournalEntry.columnDefs = [{
                 name: $translate.instant('ImportErrorPopUpNoCol'),
                 width: 100,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.index}}<span></div>'
             }, {
                 name: $translate.instant('JournalPZRQ'),
                 width: 150,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.date | date:"yyyy-MM-dd"}}<span></div>'
             }, {
                 name: $translate.instant('JournalQJ'),
                 width: 100,
                 headerCellClass: 'right',
                 cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.period}}</span></div>'
             }, {
                 name: $translate.instant('JournalPZLX'),
                 width: 150,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.group}}<span></div>'
             }, {
                 name: $translate.instant('JournalPZH'),
                 width: 200,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.vid}}</span></div>'
             }, {
                 name: $translate.instant('JournalKMDM'),
                 width: 150,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.acctCode}}</span></div>'
             }, {
                 name: $translate.instant('JournalZY'),
                 width: 200,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.summary}}</span></div>'
             }, {
                 name: $translate.instant('JournalJFJE'),
                 width: 150,
                 headerCellClass: 'right',
                 cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.debit}}</span></div>'
             }, {
                 name: $translate.instant('JournalDFJE'),
                 width: 150,
                 headerCellClass: 'right',
                 cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.credit}}</span></div>'
             }, {
                 name: $translate.instant('JournalKHDM'),
                 width: 150,
                 headerCellClass: '',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.customerCode}}</span></div>'
             }, {
                 name: $translate.instant('JournalFLH'),
                 width: 100,
                 headerCellClass: 'right',
                 cellTemplate: '<div class="ui-grid-cell-contents right"><span>{{row.entity.itemID}}</span></div>'
             }];
         }
     }


     //序时账选择列名事件
     //parentIndex:当前列号
     //index:下拉列表中选项的序号
     var mappingColumn = function (parentIndex, index, colName) {
         if (colName) {

             var oldColumn = $scope.selectedColumnMap[parentIndex];
             var newColumn = $scope.journalEntryColumns[index];

             //如果新的选择项与老的选择项一致,则不进行操作
             if (oldColumn === newColumn) {
                 return;
             } else {
                 $scope.selectedColumnMap[parentIndex] = colName;

                 if (colName !== $translate.instant('PleaseSelectColumn')) {
                     //如果当前选择的不是"请选择列名",则将选项从数组中移除
                     $scope.journalEntryColumns.splice(index, 1);

                     if (oldColumn && oldColumn !== $translate.instant('PleaseSelectColumn')) {
                         //将老的选项追加到选项列表中
                         $scope.journalEntryColumns.push(oldColumn);
                     }
                 } else {
                     //如果当前选中的是"请选择列名",则将该列原来的列名追加到选项列表中
                     if (oldColumn) {
                         $scope.journalEntryColumns.push(oldColumn);
                     }
                 }
             }
         }
         //$log.debug($scope.selectedColumnMap);
     };


     //设置上传文件的文件名
     var updateJournalEntryFileName = function (newValue) {
         $scope.fileName = newValue.name;
     };


     //上传文件
     var doUploadJournalEntryFile = function (file) {
         if (file) {
             var arr = file.name.split('.');
             if (arr[arr.length - 1] !== 'xls' && arr[arr.length - 1] !== 'xlsx') {
                 SweetAlert.warning($translate.instant('ImportFileInvalidType'));
                 return;
             }
             $scope.initJournalEntryList = [];
             $scope.gridOptionsJournalEntry.data = [];
             successCount = 0;
             if (!file.$error) {
                 var tempFileName = PWC.newGuid() + '.dat';
                 Upload.upload({
                     url: uploadUrl,
                     data: {
                         filename: file.name,
                         tempFileName: tempFileName,
                         file: file
                     },
                     resumeChunkSize: resumable ? $scope.chunkSize : null,
                     headers: {
                         'Access-Control-Allow-Origin': '*',
                         Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken
                     },
                     __RequestVerificationToken: token,
                     withCredentials: true
                 }).then(uploadJournalEntrySuccess);
             }
         }
     };


     //上传成功后执行函数
     var uploadJournalEntrySuccess = function (resp) {
         console.log(resp);
         successCount++;
         if (successCount === 1) {
             $scope.tempFileName = resp.data;
             //初始化到excel文件的第一个sheet
             changeJournalEntrySheet(0);
         }
     };


     //初始化需要展示的sheet
     var changeJournalEntrySheet = function (selectedSheet) {
         var sheetIndex = _.findIndex($scope.sheetData.sheetNameList, function (num) {
             return num.name === selectedSheet.name;
         })
         $scope.sheetInfo.selectedSheetIndex = sheetIndex === -1 ? 0 : sheetIndex;
         refreshJournalEntryTable();
     };


     //重新load页面上的table
     //做column mapping时只加载constant.pageSize行数据
     var refreshJournalEntryTable = function () {
         //在切换显示页面导入数据时,直接设置初始化数据ui-grid表不可见,错误信息不可见
         //导入数据表格可见
         $scope.showImportTable = true;
         $scope.showErrorTable = false;
         $scope.showInitTable = false;

         if (_.isString($scope.tempFileName)) {
             $scope.sheetData = {
                 sheetNameList: [],
                 dataList: [],
                 selectedSheetIndex: 0
             };
             $scope.columnNum = 0;
             $scope.selectedColumnMap = [];

             vatImportService.getFileContent($scope.tempFileName, $scope.sheetInfo.selectedSheetIndex, constant.pageSize).success(function (data) {
                 //将导入文件的sheet赋值到数组
                 $scope.sheetData = data;
                 //加入index序号
                 var index = 1;
                 data.dataList.forEach(function (v) {
                     v.index = index++;
                 });
                 var sheetNameObjectArray = [];
                 data.sheetNameList.forEach(function (v) {
                     sheetNameObjectArray.push({
                         'name': v
                     });
                 });
                 $scope.sheetData.sheetNameList = sheetNameObjectArray;

                 $scope.columnNum = data.dataList[0] ? data.dataList[0].length : $scope.columnNum;
                 $scope.firstDataRow = data.dataList[0];
                 $scope.startRowList = _.range(data.lastRowIndex);
                 $scope.sheetInfo.selectedSheetName = $scope.sheetData.sheetNameList[$scope.sheetInfo.selectedSheetIndex];
                 initColumns();
                 citSessionService.dataChanged = true; //设置为true表示在切换页面前数据有变更, 需要提示

                 if (data & data.result === false) {
                     SweetAlert.warning(data.resultMsg);
                     return;
                 }
             });
         }
     };


     //对导入数据进行验证(前端)
     var FrontEndValidJournalEntryData = function (journalEntryList) {
         //2:验证关键字段不为空(凭证号,凭证类型,分录号,科目代码)
         //3:验证日期、金额格式、期间格式、分录号格式是否正确
         if (!KeyColumnsEmptyValid(journalEntryList)) {
             return;
         }

         //4:所有验证都通过后,筛选符合期间条件的数据进库
         FilterPeriodData(journalEntryList);

     };


     //1.判断是否有没有map的必须列和起始行输入格式是否正确
     var ColumnsMapCheck = function () {
         var result = true;
         var notMappedColumns = '';
         if ($scope.selectedColumnMap.length >= 0) {
             var count1 = 0;
             $scope.mustMappingTotalColumns.forEach(function (m) {
                 if (m !== $translate.instant('PleaseSelectColumn')) {
                     if ($.inArray(m, $scope.selectedColumnMap) < 0) {
                         notMappedColumns += m + ',';
                         count1++;
                     }
                 }
             });
             if (count1) {
                 result = false;
                 //加入到错误列表中
                 $scope.errorMsgMap.push({
                     'errorType': validationErrorType.ColumnsMapErrorType,
                     'errorCount': count1,
                     'errorContent': $translate.instant('ColumnsMapErrorMsg').formatObj({
                         columns: notMappedColumns.substring(0, notMappedColumns.length - 1)
                     })
                 });
             }
         }
         //2:判断起始行输入框输入内容是否合理
         var startNumberCheckMsg = '';
         var startRowNum = $('#StartRowNum').val();
         if (startRowNum === '') {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.StartRowError,
                 'errorCount': 1,
                 'errorContent': $translate.instant('StartRowNull')
             });
         } else if (parseInt(startRowNum) > $scope.sheetData.dataList.length) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.StartRowError,
                 'errorCount': 1,
                 'errorContent': $translate.instant('StartRowNumberCheckMsg')
             });
         }
         return result;
     };


     //2.验证关键字段不为空(凭证号,凭证类型,分录号,科目代码)
     //3.验证日期、金额格式、期间格式、分录号格式是否正确
     var KeyColumnsEmptyValid = function (journalEntryList) {
         var result = true;
         //#region 定义错误信息

         //凭证号为空
         var VIDEmptyCheckMsg = '';
         var VIDEmptyCheckCount = 0;
         //科目代码为空
         var AcctCodeEmptyCheckMsg = '';
         var AcctCodeEmptyCheckCount = 0;
         //验证凭证日期为空
         var VoucherDateEmptyErrorMsg = '';
         var VoucherDateEmptyErrorCount = 0;

         //验证凭证日期格式错误
         var VourcharDateFormatErrorMsg = '';
         var VourcharDateFormatErrorCount = 0;

         //验证借方金额、贷方金额格式错误
         var AmountFormatErrorMsg = '';
         var AmountFormatErrorCount = 0;

         //验证期间是否是正整数
         var PeriodFormatErrorMsg = '';
         var PeriodFormatErrorCount = 0;

         //验证分录号是否为正整数
         //var ItemIDFormatErrorMsg = '';
         //var ItemIDFormatErrorCount = 0;

         //数据范围超出范围
         var numOutRangeCheckMsg = '';
         var numOutRangeCheckCount = 0;

         //字符长度过长验证
         var stringOverLengthCheckMsg = '';
         var stringOverLengthCheckCount = 0;

         //凭证类型为空
         var groupEmptyCheckMsg = '';
         var groupEmptyCheckCount = 0;

         //分录号为空
         var itemEmptyCheckMeg = '';
         var itemEmptyCheckCount = 0;

         //#endregion

         //#region 验证错误信息
         journalEntryList.forEach(function (m) {
             var tempVID = PWC.isNullOrEmpty(m.VID) ? $translate.instant('NullValue') : m.VID;
             var tempGroup = PWC.isNullOrEmpty(m.Group) ? $translate.instant('NullValue') : m.Group;
             var tempItemID = PWC.isNullOrEmpty(m.ItemID) ? $translate.instant('NullValue') : m.ItemID;

             var curRowInfo = '(' + $translate.instant('RowIndex').formatObj({
                 rowIndex: m.Index
             }) + ')' +
              $translate.instant('JournalPZH') + ':' + tempVID + ',' +
              $translate.instant('JournalPZLX') + ':' + tempGroup + ',' +
              $translate.instant('JournalFLH') + ':' + tempItemID + ';<br />';
             //凭证号为空
             if (PWC.isNullOrEmpty(m.VID)) {
                 VIDEmptyCheckCount++;
                 VIDEmptyCheckMsg += curRowInfo;
             } else {
                 //如果凭证号超过50个字符
                 if (m.VID.length > constant.validateLength.StringLength_50) {
                     stringOverLengthCheckMsg += '(' + $translate.instant('RowIndex').formatObj({
                         rowIndex: m.Index
                     }) + ')' + $translate.instant('JournalPZH') + $translate.instant('OutputStringLengthMsg') + ';<br />';
                     stringOverLengthCheckCount++;
                 }
             }

             if (PWC.isNullOrEmpty(m.Group)) {
                 groupEmptyCheckCount++;
                 groupEmptyCheckMsg += curRowInfo;
             } else {
                 //如果凭证类型超过50个字符
                 if (m.Group.length > constant.validateLength.StringLength_50) {
                     stringOverLengthCheckMsg += '(' + $translate.instant('RowIndex').formatObj({
                         rowIndex: m.Index
                     }) + ')' + $translate.instant('JournalPZLX') + $translate.instant('OutputStringLengthMsg') + ';<br />';
                     stringOverLengthCheckCount++;
                 }
             }
             

             if (PWC.isNullOrEmpty(m.ItemID)) {
                 itemEmptyCheckCount++;
                 itemEmptyCheckMeg += curRowInfo;
             } else {
                 //如果分录号超过50个字符
                 if (m.ItemID.length > constant.validateLength.StringLength_50) {
                     stringOverLengthCheckMsg += '(' + $translate.instant('RowIndex').formatObj({
                         rowIndex: m.Index
                     }) + ')' + $translate.instant('JournalFLH') + $translate.instant('OutputStringLengthMsg') + ';<br />';
                     stringOverLengthCheckCount++;
                 }
             }
             

             //科目代码为空
             if (PWC.isNullOrEmpty(m.AcctCode)) {
                 AcctCodeEmptyCheckCount++;
                 AcctCodeEmptyCheckMsg += curRowInfo;
             } else {
                 //如果科目代码超过50个字符
                 if (m.AcctCode.length > constant.validateLength.StringLength_50) {
                     stringOverLengthCheckMsg += '(' + $translate.instant('RowIndex').formatObj({
                         rowIndex: m.Index
                     }) + ')' + $translate.instant('JournalKMDM') + $translate.instant('OutputStringLengthMsg') + ';<br />';
                     stringOverLengthCheckCount++;
                 }
             }

             //凭证日期为空
             if (PWC.isNullOrEmpty(m.Date)) {
                 VoucherDateEmptyErrorCount++;
                 VoucherDateEmptyErrorMsg += curRowInfo;
             } else {
                 //凭证日期格式错误
                 if (!PWC.checkDate(m.Date)) {
                     VourcharDateFormatErrorMsg += curRowInfo;
                     VourcharDateFormatErrorCount++;
                 }
             }

             //验证金额
             if (isNaN(parseFloat(m.Debit)) || isNaN(parseFloat(m.Credit))) {
                 AmountFormatErrorMsg += curRowInfo;
                 AmountFormatErrorCount++;
             } else {
                 //如果在规定的数值范围外,则提示错误
                 if (parseFloat(m.Debit) < constant.startNum || parseFloat(m.Debit) > constant.endNum) {
                     numOutRangeCheckMsg += '(' + $translate.instant('RowIndex').formatObj({
                         rowIndex: m.Index
                     }) + ')' + $translate.instant('JournalJFJE') + $translate.instant('NumOverLengthMsg') + '<br />';
                     numOutRangeCheckCount++;
                 } else {
                     m.Debit = PWC.round(m.Debit, 2);
                 }
                 //如果在规定的数值范围外,则提示错误
                 if (parseFloat(m.Credit) < constant.startNum || parseFloat(m.Credit) > constant.endNum) {
                     numOutRangeCheckMsg += '(' + $translate.instant('RowIndex').formatObj({
                         rowIndex: m.Index
                     }) + ')' + $translate.instant('JournalDFJE') + $translate.instant('NumOverLengthMsg') + '<br />';
                     numOutRangeCheckCount++;
                 } else {
                     m.Credit = PWC.round(m.Credit, 2);
                 }
             }

             //验证期间为正整数
             if (!PWC.isNullOrEmpty(m.Period)) {
                 if (!PWC.isPositiveInteger(m.Period)) {
                     PeriodFormatErrorMsg += curRowInfo;
                     PeriodFormatErrorCount++;
                 } else {
                     if (m.Period < 1 || m.Period > 12) {
                         numOutRangeCheckCount++;
                         numOutRangeCheckMsg += '(' + $translate.instant('RowIndex').formatObj({
                             rowIndex: m.Index
                         }) + ')' + $translate.instant('JournalQJ') + $translate.instant('PeriodOverLengthMsg') + ';<br />';
                     }
                 }
             }

             //验证客户代码不能超过50个字符
             if (!PWC.isNullOrEmpty(m.CustomerCode) && m.CustomerCode.length > constant.validateLength.StringLength_50) {
                 stringOverLengthCheckMsg += '(' + $translate.instant('RowIndex').formatObj({
                     rowIndex: m.Index
                 }) + ')' + $translate.instant('JournalKHDM') + $translate.instant('OutputStringLengthMsg') + ';<br />';
                 stringOverLengthCheckCount++;
             }

             //摘要不能超过200个字符
             if (!PWC.isNullOrEmpty(m.Summary) && m.Summary.length > constant.validateLength.StringLength_200) {
                 stringOverLengthCheckMsg += '(' + $translate.instant('RowIndex').formatObj({
                     rowIndex: m.Index
                 }) + ')' + $translate.instant('JournalZY') + $translate.instant('OutputStringLengthMsg_200') + ';<br />';
                 stringOverLengthCheckCount++;
             }
         });
         //#endregion 

         //#region 添加错误信息到错误列表

         //push凭证号空信息到错误列表
         if (VIDEmptyCheckCount > 0) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.JournalEntryVIDEmptyErrorType,
                 'errorCount': VIDEmptyCheckCount,
                 'errorContent': VIDEmptyCheckMsg
             });
         }

         if (AcctCodeEmptyCheckCount > 0) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.JournalEntryAcctCodeEmptyErrorType,
                 'errorCount': AcctCodeEmptyCheckCount,
                 'errorContent': AcctCodeEmptyCheckMsg
             });
         }
         if (VoucherDateEmptyErrorCount > 0) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.JournalEntryVoucherDateEmptyErrorType,
                 'errorCount': VoucherDateEmptyErrorCount,
                 'errorContent': VoucherDateEmptyErrorMsg
             });
         }
         if (VourcharDateFormatErrorCount) {
             result = false;
             //凭证日期格式错误
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.JournalEntryDateFormatErrorType,
                 'errorCount': VourcharDateFormatErrorCount,
                 'errorContent': VourcharDateFormatErrorMsg
             });
         }
         //金额格式错误
         if (AmountFormatErrorCount) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.JournalEntryAmountErrorType,
                 'errorCount': AmountFormatErrorCount,
                 'errorContent': AmountFormatErrorMsg
             });
         }
         //验证期间为正整数
         if (PeriodFormatErrorCount) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.JournalEntryPeriodFormatErrorType,
                 'errorCount': PeriodFormatErrorCount,
                 'errorContent': PeriodFormatErrorMsg
             });
         }
         //push字符串过长的错误信息到错误列表
         if (stringOverLengthCheckCount > 0) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.OutputStringLengthType,
                 'errorCount': stringOverLengthCheckCount,
                 'errorContent': stringOverLengthCheckMsg
             });
         }
         //push数值超过范围的错误信息到列表
         if (numOutRangeCheckCount > 0) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.NumOutRangeErrorType,
                 'errorCount': numOutRangeCheckCount,
                 'errorContent': numOutRangeCheckMsg
             });
         }



         if (groupEmptyCheckCount > 0) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.JournalEntryGroupEmptyErrorType,
                 'errorCount': groupEmptyCheckCount,
                 'errorContent': groupEmptyCheckMsg
             });
         }

         if (itemEmptyCheckCount > 0) {
             result = false;
             $scope.errorMsgMap.push({
                 'errorType': validationErrorType.JournalEntryItemIDEmptyErrorType,
                 'errorCount': itemEmptyCheckCount,
                 'errorContent': itemEmptyCheckMeg
             });
         }

         //#endregion
         return result;
     };


     //4:筛选符合期间条件的数据进库
     var FilterPeriodData = function (journalEntryList) {
         //存放筛选后的数据
         $scope.journalEntryListFilter = [];
         if ($.inArray($translate.instant('JournalQJ'), $scope.selectedColumnMap) > -1) {
             $scope.MapPeriodFlag = true; //是否对应了期间列           

             journalEntryList.forEach(function (item) {
                 //截断过长的内容
                 item.Group = item.Group.substring(0, constant.validateLength.StringLength_50);
                 item.VID = item.VID.substring(0, constant.validateLength.StringLength_256);
                 item.AcctCode = item.AcctCode.substring(0, constant.validateLength.StringLength_50);
                 $scope.journalEntryListFilter.push(item);
             });
         } else {
             $scope.MapPeriodFlag = false; //是否对应了期间列
             journalEntryList.forEach(function (item) {
                 //截断过长的内容
                 item.Group = item.Group.substring(0, constant.validateLength.StringLength_50);
                 item.VID = item.VID.substring(0, constant.validateLength.StringLength_256);
                 item.AcctCode = item.AcctCode.substring(0, constant.validateLength.StringLength_50);
                 $scope.journalEntryListFilter.push(item);
             });
             $scope.journalEntryListFilter = journalEntryList;
         }
     };


     //点击导入按钮时,进行导入操作
     var importJournalEntryData = function (importType) {
         //todo:
         if (citSessionService.project.projectStatusList[curPeriod] >= constant.ProjectStatusEnum.Generated) {
             swal({
                 title: "warning!",
                 text: $translate.instant('IsConfirmToReImport').formatObj({
                     status: vatCommonService.getProjectStautsEnumDesc(citSessionService.project.projectStatusList[curPeriod])
                 }),
                 type: "warning",
                 showCancelButton: true,
                 confirmButtonColor: "#DD6B55",
                 confirmButtonText: $translate.instant('Yes'),
                 cancelButtonText: $translate.instant('No'),
                 closeOnConfirm: true,
                 closeOnCancel: true
             },
              function (isConfirm) {
                  if (isConfirm) {
                      doImportJournalEntryData(importType);
                  } else {
                      swal.close();
                  }
              });
         } else {
             doImportJournalEntryData(importType);
         }
     };


     var doImportJournalEntryData = function (importType) {
         if (!$scope.fileName) {
             SweetAlert.warning($translate.instant('PleaseSelectFileFirst'));
             return;
         }

         var importType = importType; //0:第一次导入,1:覆盖导入,2:追加导入

         //设置数据导入时的起始行,默认设置从第一行开始
         var startRowNum = 1;
         if ($('#StartRowNum').val()) {
             startRowNum = $('#StartRowNum').val();
         }

         //验证前,将错误数据清空
         $scope.errorMsgMap = [];

         //1:判断是否有没有map的必须列和起始行输入格式是否正确
         if (!ColumnsMapCheck()) {
             $('#errorListModal').modal('show');
             return;
         }

         //将需要导入的数据组装到list中
         var inputJournalEntryList = [];

         vatImportService.getFileContent($scope.tempFileName, $scope.sheetInfo.selectedSheetIndex, constant.allDataPageSize)
          .success(function (data) {
              var allSheetData = data.dataList;
              for (var i = startRowNum - 1; i < allSheetData.length; i++) {
                  var journalEntryInfo = {
                      'Index': i + 1, //行号
                      'Period': allSheetData[i][$.inArray($translate.instant('JournalQJ'), $scope.selectedColumnMap)], //期间
                      'Date': allSheetData[i][$.inArray($translate.instant('JournalPZRQ'), $scope.selectedColumnMap)], //凭证日期
                      'Group': allSheetData[i][$.inArray($translate.instant('JournalPZLX'), $scope.selectedColumnMap)], //凭证类型
                      'VID': allSheetData[i][$.inArray($translate.instant('JournalPZH'), $scope.selectedColumnMap)], //凭证号
                      'ItemID': allSheetData[i][$.inArray($translate.instant('JournalFLH'), $scope.selectedColumnMap)], //分录号
                      'AcctCode': allSheetData[i][$.inArray($translate.instant('JournalKMDM'), $scope.selectedColumnMap)], //科目代码
                      'Summary': $.inArray($translate.instant('JournalZY'), $scope.selectedColumnMap) > -1 ?
                       allSheetData[i][$.inArray($translate.instant('JournalZY'), $scope.selectedColumnMap)] : null, //摘要
                      'Debit': PWC.isNullOrEmpty(allSheetData[i][$.inArray($translate.instant('JournalJFJE'), $scope.selectedColumnMap)]) ?
                       0 : allSheetData[i][$.inArray($translate.instant('JournalJFJE'), $scope.selectedColumnMap)], //如果金额为空,则设置为0
                      'Credit': PWC.isNullOrEmpty(allSheetData[i][$.inArray($translate.instant('JournalDFJE'), $scope.selectedColumnMap)]) ?
                       0 : allSheetData[i][$.inArray($translate.instant('JournalDFJE'), $scope.selectedColumnMap)], //如果金额为空,则设置为0
                      'CustomerCode': $.inArray($translate.instant('JournalKHDM'), $scope.selectedColumnMap) > -1 ?
                       allSheetData[i][$.inArray($translate.instant('JournalKHDM'), $scope.selectedColumnMap)] : null, //如果用户对应了客户代码,则保存用户对应的客户代码数据,否则保存为null
                      'ImportType': enums.vatImportType.journalEntry, //导入类型
                      'MonthID': $.inArray($translate.instant('JournalQJ'), $scope.selectedColumnMap) > -1 ?
                       allSheetData[i][$.inArray($translate.instant('JournalQJ'), $scope.selectedColumnMap)] : null //如果用户对应了期间字段,则保存用户对应的期间,否则保存为null
                  };
                  inputJournalEntryList.push(journalEntryInfo);
              }


              //前台数据验证
              FrontEndValidJournalEntryData(inputJournalEntryList);

              if ($scope.errorMsgMap.length > 0) {
                  $('#errorListModal').modal('show');
                  return;
              } else {
                  logDto.ID = PWC.newGuid();
                  logDto.CreateTime = new Date();
                  logDto.UpdateTime = new Date();
                  logDto.OperationContent = $scope.fileName;
                  if (importType === $scope.importEnum.Import) {
                      logDto.OperationName = $translate.instant('ImportJournalEntry');
                      logDto.OperationType = enums.vatLogOperationTypeEnum.Import;
                  } else if (importType === $scope.importEnum.CoverImport) {
                      logDto.OperationName = $translate.instant('CoverImportJournalEntry');
                      logDto.OperationType = enums.vatLogOperationTypeEnum.CoverImport;
                  } else if (importType === $scope.importEnum.AddImport) {
                      logDto.OperationName = $translate.instant('AddImportJournalEntry');
                      logDto.OperationType = enums.vatLogOperationTypeEnum.AddImport;
                  }

                  var servicePeriods = [];
                  if ($scope.serviceTypeId === constant.serviceType.CIT) {
                      servicePeriods = _.chain($scope.journalEntryListFilter).map(function (item) { return item.PeriodId }).uniq().value();
                  }
                  else if ($scope.serviceTypeId === constant.serviceType.VAT) {
                      servicePeriods = [curPeriod];
                  }

                  var queryImportDto = {
                      serviceTypeId: $scope.serviceTypeId,
                      periods: servicePeriods,
                      projectId: projectID
                  }


                  vatImportService.getProjectImportType(queryImportDto).success(function (re) {
                      if (re.result) {
                          var periodInforData = re.data;
                          var notImported = _.find(periodInforData, function (item) {
                              return item.importType === enums.projectImportType.UnImported;
                          });
                          var erpImported = _.find(periodInforData, function (item) {
                              return item.importType === enums.projectImportType.ErpImported;
                          });

                          if (!_.isUndefined(notImported) && notImported.length === periodInforData.length) { //没有导入过tb或者erp。则提示需要先导入TB
                              SweetAlert.warning($translate.instant('JournalEntryImportErrorNotImportTBData'));
                          } else if (!_.isUndefined(erpImported)) { //有任一期间导入过erp,则提示不能导入
                              SweetAlert.warning($translate.instant('JournalEntryImportErrorERPDataImportedAlready'));
                          } else {
                              //如果没有选择期间,则系统给出导入所有数据的提示,确认后数据进库,否则,取消导入操作
                              if (!$scope.MapPeriodFlag) {
                                  swal({
                                      title: "warning!",
                                      text: $translate.instant('NoPeriod'),
                                      type: "warning",
                                      showCancelButton: true,
                                      confirmButtonColor: "#DD6B55",
                                      confirmButtonText: $translate.instant('Yes'),
                                      cancelButtonText: $translate.instant('No'),
                                      closeOnConfirm: true,
                                      closeOnCancel: true
                                  },
                                   function (isConfirm) {
                                       if (isConfirm) {
                                           //数据进库
                                           vatImportService.importJournalEntryData($scope.journalEntryListFilter, importType).success(function () {
                                               logDto.UpdateState = $translate.instant('ImportSuccess');
                                               vatOperationLogService.addOperationLog(logDto);
                                               //todo
                                               vatCommonService.setProjectStatus(projectDbName, curPeriod, constant.ProjectStatusEnum.Imported, constant.DictionaryDictKey.WFImportJournalEntry, enums.FinishStatusEnum.Finished);
                                               vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isEntryImport, true);
                                               //$log.debug("import entry importJournalEntryData: " + citSessionService.project.importSubStatus.isEntryImport);
                                               SweetAlert.success($translate.instant('ImportSuccess'));
                                               loadJournalEntryDataFromDB();
                                               $scope.fileName = '';
                                               citSessionService.dataChanged = false; //设置为false表示在切换页面前数据没有变更,不需要提示
                                           }).error(function () {
                                               logDto.UpdateState = $translate.instant('ImportFail');
                                               vatOperationLogService.addOperationLog(logDto);
                                           });
                                       }
                                   });
                              } else {
                                  //数据进库
                                  vatImportService.importJournalEntryData($scope.journalEntryListFilter, importType).success(function () {
                                      logDto.UpdateState = $translate.instant('ImportSuccess');
                                      vatOperationLogService.addOperationLog(logDto);
                                      //todo
                                      vatCommonService.setProjectStatus(projectDbName, curPeriod, constant.ProjectStatusEnum.Imported, constant.DictionaryDictKey.WFImportJournalEntry, enums.FinishStatusEnum.Finished);
                                      vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isEntryImport, true);
                                      //$log.debug("import entry importJournalEntryData: " + citSessionService.project.importSubStatus.isEntryImport);
                                      SweetAlert.success($translate.instant('ImportSuccess'));
                                      loadJournalEntryDataFromDB();
                                      $scope.fileName = '';
                                      citSessionService.dataChanged = false; //设置为false表示在切换页面前数据没有变更,不需要提示
                                  }).error(function () {
                                      logDto.UpdateState = $translate.instant('ImportFail');
                                      vatOperationLogService.addOperationLog(logDto);
                                  });
                              }
                          }
                      }

                  }).error(function () {
                      SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                  });
              }

          });
     }


     //获取验证信息
     var getValidationList = function () {
         var deferred = $q.defer();
         vatImportService.getValidationDtoInfo(enums.validationType.JournalEntry, curPeriod).success(function (data) {
             if (data.length > 0) {
                 var index = 1;
                 data.forEach(function (v) {
                     v.index = index++;
                 });
                 $scope.errorList = data;
                 $scope.gridOptionsErrorMsg.data = data;
             } else {
                 $scope.errorList = [];
                 $scope.gridOptionsErrorMsg.data = [];
             }
             deferred.resolve();
         });

         return deferred.promise;
     }


     var showErrTab = function () {
         $scope.ImportErrorTab = true; //默认显示顶部block
         $scope.ImportErrorTag = true; //默认隐藏下方的错误信息列表
         $scope.errorMsg = $translate.instant('ImportErrorMsg').formatObj({
             "NumberOfError": $scope.errorList.length
         });

     };


     var setErrorWrapCssDefault = function () {
         $('#content-resizer').css('bottom', '10px');

         $('#topIcon').css({
             bottom: '-501px'
         });

         $('.error-info-wrapper').css('height', '0px');
     };

     
     //显示图标
     var errorLevelToString = function (errorLevel) {
         if (errorLevel === 0) {
             return '/app-resources/images/vat/error.png';
         }
         if (errorLevel === 1) {
             return '/app-resources/images/vat/warning.png';
         }
         if (errorLevel === 2) {
             return '/app-resources/images/vat/tips.png';
         } else {
             return '/app-resources/images/vat/tips.png';
         }
     };


     //显示分录明细
     var showJournalEntryModal = function (typeid, items) {
         var data = JSON.parse(items);
         $scope.devgridDataSource = data;
         //组装列
         var columns = [];
         columns.push({
             caption: $translate.instant('JournalPZRQ'),
             dataField: "Date",
             dataType: "date",
             width: 100
         });
         //如果期间不为null,则加入期间列
         if (data[0].Period != null) {
             columns.push({
                 caption: $translate.instant('JournalQJ'),
                 dataField: "Period",
                 width: 50
             });
         }
         columns.push({
             caption: $translate.instant('JournalPZLX'),
             dataField: "Group",
             width: 160
         }, {
             caption: $translate.instant('JournalPZH'),
             dataField: "VID",
             width: 130
         }, {
             caption: $translate.instant('JournalKMDM'),
             dataField: "AcctCode",
             width: 100
         });
         //如果摘要不为null,则加入摘要列
         if (data[0].Summary != null) {
             columns.push({
                 caption: $translate.instant('JournalZY'),
                 dataField: "Summary",
                 width: 150
             });
         }
         columns.push({
             caption: $translate.instant('JournalJFJE'),
             dataField: "Debit",
             format: {
                 type: 'fixedPoint',
                 precision: 2
             },
             width: 100
         }, {
             caption: $translate.instant('JournalDFJE'),
             dataField: "Credit",
             format: {
                 type: 'fixedPoint',
                 precision: 2
             },
             width: 100
         }, {
             caption: $translate.instant('JournalKHDM'),
             dataField: "CustomerCode",
             width: 100
         }, {
             caption: $translate.instant('JournalFLH'),
             dataField: "ItemID",
             width: 70
         });


         //如果不是重复数据,就展示普通明细弹出框,否则就显示重复数据明细弹出框
         if (typeid !== 52) {
             $scope.gridJournalEntryItemGridOptions = {
                 columns: columns,
                 selection: {
                     mode: "single"
                 },
                 bindingOptions: {
                     "dataSource": "devgridDataSource"
                 },
                 scrolling: {
                     mode: "standard",
                     showScrollbar: "always"
                 },
                 hoverStateEnabled: true,
                 paging: {
                     pageSize: 10
                 }
             }
             $('#jounarEntryItemModal').modal('show');
         } else {
             $scope.deferStatus = true;
             $scope.filterCondition = ["IsDuplicate", "=", true];

             $scope.gridJournalEntryDuplicateItemGridOptions = {
                 columns: columns,
                 bindingOptions: {
                     "dataSource.store.data": "devgridDataSource",
                     "selection.deferred": "deferStatus",
                     "selectionFilter": "filterCondition"
                 },
                 dataSource: {
                     store: {
                         type: "array",
                         key: 'VoucherID'
                     }
                 },
                 selection: {
                     selectAllMode: "allPages",
                     showCheckBoxesMode: "always",
                     mode: "multiple"
                 },
                 scrolling: {
                     mode: "standard",
                     showScrollbar: "always"
                 },
                 hoverStateEnabled: true,
                 paging: {
                     pageSize: 10
                 }
             }

             $('#jounarEntryDuplicateItemModal').modal('show');
         }
     };


     //删除重复数据
     var deleteDuplicateData = function () {
         var dataGrid = $('#gridJournalEntryDuplicateItemGrid').dxDataGrid("instance");

         var deleteList = [];
         dataGrid.getSelectedRowsData().done(function (rowData) {
             for (var i = 0; i < rowData.length; i++) {
                 deleteList.push(rowData[i].AcctCode);
             }
         });



         dataGrid.getSelectedRowKeys().done(function (keys) {
             if (keys && keys.length === 0) {
                 SweetAlert.warning($translate.instant('DeleteEmptyWarning'));
                 return;
             }

             logDto.ID = PWC.newGuid();
             logDto.CreateTime = new Date();
             logDto.UpdateTime = new Date();
             logDto.OperationContent = deleteList.join(",");
             logDto.OperationName = $translate.instant('DeleteDuplicateData');
             logDto.OperationType = enums.vatLogOperationTypeEnum.DeleteDuplicate;

             vatImportService.deleteJournalEntryData(keys).success(function (data) {
                 if (data && data.result) {
                     //删除数据后重新校验          
                     vatImportService.validateJournalEntryByPeriods().success(function () {
                         logDto.UpdateState = $translate.instant('DeleteSuccess');
                         vatOperationLogService.addOperationLog(logDto);

                         loadJournalEntryDataFromDB();
                         $('#jounarEntryDuplicateItemModal').modal('hide');
                         SweetAlert.success($translate.instant('DeleteSuccess'));
                         //获取错误列表信息
                         getValidationList().then(function () {
                             if ($scope.errorList.length > 0) {
                                 showErrTab();
                                 $scope.toggleErrorTab();

                                 //当有错误信息时,显示错误信息表
                                 $scope.showErrorTable = true;
                             } else {
                                 $scope.ImportErrorTab = false;
                                 $scope.ImportErrorTag = false;
                             }
                         });

                     });
                 }
             }).error(function () {
                 logDto.UpdateState = $translate.instant('DeleteFailed');
                 vatOperationLogService.addOperationLog(logDto);
                 SweetAlert.error($translate.instant('PleaseContactAdministrator'));
             });
         });


     };


     //弹出期间选择框,清空数据
     var clearJournalEntryData = function () {
         if (curPeriod === constant.WholeYearPeriod) {
             showPeriodDrapDown();
         }
         else {
             $scope.selectedPeriod = curPeriod;
             startToDeleteJe();
         }
         
     };


     //删除JE
     var startToDeleteJe = function () {
         if (curPeriod === constant.WholeYearPeriod && ( _.isUndefined($scope.selectedPeriod) || _.isNull($scope.selectedPeriod))) {
             SweetAlert.warning($translate.instant('SelectPeriodDelete'));
         } else {
             var alertMsg = curPeriod === constant.WholeYearPeriod ? $translate.instant('JournalEntryClearWarning')
                 : $translate.instant('JournalEntryClearTips')
             swal({
                 title: "warning!",
                 text: alertMsg,
                 type: "warning",
                 showCancelButton: true,
                 confirmButtonColor: "#DD6B55",
                 confirmButtonText: $translate.instant('Yes'),
                 cancelButtonText: $translate.instant('No'),
                 closeOnConfirm: true,
                 closeOnCancel: true
             }, function (isConfirm) {
                 if (isConfirm) {
                     logDto.ID = PWC.newGuid();
                     logDto.CreateTime = new Date();
                     logDto.UpdateTime = new Date();
                     logDto.OperationContent = '';
                     logDto.OperationName = $translate.instant('ClearTrialBalance');
                     logDto.OperationType = enums.vatLogOperationTypeEnum.ClearData;

                     vatImportService.clearJournalEntryData($scope.selectedPeriod).success(function (data) {
                         if (data && data.result) {
                             logDto.UpdateState = $translate.instant('ClearSuccess');
                             vatOperationLogService.addOperationLog(logDto);
                             //todo:
                             vatCommonService.clearDataSetProjectStatusSimple(projectDbName, curPeriod, constant.DictionaryDictKey.WFImportJournalEntry, enums.FinishStatusEnum.NotFinished);
                             vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isEntryImport, false);
                             //$log.debug("clear entry clearJournalEntryData: " + citSessionService.project.importSubStatus.isEntryImport);
                             SweetAlert.success($translate.instant('ClearSuccess'));
                             loadJournalEntryDataFromDB();
                             $scope.isShowImportTotalBtn = true;
                         } else {
                             logDto.UpdateState = $translate.instant('ClearFailed');
                             vatOperationLogService.addOperationLog(logDto);
                             SweetAlert.warning($translate.instant('ClearFailed'));
                         }

                         $scope.selectedPeriod = null;
                         if (curPeriod === constant.WholeYearPeriod) {
                             $scope.closePeriodSelectModal();
                         }
                         

                     }).error(function () {
                         logDto.UpdateState = $translate.instant('ClearFailed');
                         vatOperationLogService.addOperationLog(logDto);
                         $scope.selectedPeriod = null;
                         if (curPeriod === constant.WholeYearPeriod) {
                             $scope.closePeriodSelectModal();
                         }
                         SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                     });
                 }

             });
         }
     }


     //刷新数据,实质是重新校验数据
     var refreshJournalEntryData = function () {
         logDto.ID = PWC.newGuid();
         logDto.CreateTime = new Date();
         logDto.UpdateTime = new Date();
         logDto.OperationContent = '';
         logDto.OperationName = $translate.instant('RefreshValidationData');
         logDto.OperationType = enums.vatLogOperationTypeEnum.Refresh;

         vatImportService.validateJournalEntryByPeriods().success(function () {
             logDto.UpdateState = $translate.instant('RefreshSuccess');
             vatOperationLogService.addOperationLog(logDto);

             loadJournalEntryDataFromDB();
             //获取错误列表信息
             getValidationList().then(function () {
                 if ($scope.errorList.length > 0) {
                     showErrTab();
                     $scope.toggleErrorTab();

                     //当有错误信息时,显示错误信息表
                     $scope.showErrorTable = true;
                 } else {
                     $scope.ImportErrorTab = false;
                     $scope.ImportErrorTag = false;
                 }
             });

         }).error(function () {
             logDto.UpdateState = $translate.instant('RefreshTbFail');
             vatOperationLogService.addOperationLog(logDto);

             SweetAlert.error($translate.instant('PleaseContactAdministrator'));
         });;
     };


     //日志
     var showOperateLogPop = function () {
         $scope.isShowLog = true;
     };


     var initPagingControl = function (totalItemsCount) {
         $scope.pagingOptions.totalItems = totalItemsCount;
     }


     //显示期间选择弹出框
     var showPeriodDrapDown = function () {
         $scope.modalInstance = $uibModal.open({
             animation: false,
             ariaLabelledBy: 'modal-title',
             ariaDescribedBy: 'modal-body',
             templateUrl: 'je-model-period-dropdown.html',
             scope: $scope,
             windowClass: "je-model-period-dropdow-popup"
         });

         $scope.closePeriodSelectModal = function () {
             $scope.modalInstance.dismiss('cancel');
         };

         $scope.selectBox = {
             simple: {
                 dataSource: $scope.jePeriods,
                 displayExpr: "Period",
                 valueExpr: "ID",
                 searchEnabled: false,
                 placeholder: $translate.instant('PleaseSelectPeriod'),
                 noDataText: $translate.instant('NoDataToDispaly'),
                 maxLength: 2,
                 onSelectionChanged: function (e) {
                     $log.debug(e);
                     $scope.selectedPeriod = e.selectedItem.Period;
                 }
             }
         };

         vatImportService.getJePeriods().success(function (re) {
             if (re.result) {
                 $scope.jePeriods = [];
                 var id = 1;
                 $.each(re.data, function (index, item) {
                     var periodDto = {
                         ID: -1,
                         Period: -1
                     };
                     periodDto.ID = id++;
                     periodDto.Period = item;
                     $scope.jePeriods.push(periodDto);
                 });

                 $("#jePeriodSelectBox").dxSelectBox("instance").option("dataSource", $scope.jePeriods);
             }

         }).error(function () {
             SweetAlert.error($translate.instant('PleaseContactAdministrator'));
         });
     }


     //编辑状态时,按钮区域的样式
     var setButtonWrapStyle = function () {
         if ($scope.showImportTable) {
             return { width: "100%" };
         }
     };


     //初始化错误提示grid
     var initErrorMsgGrid = function () {

         $scope.gridOptionsErrorMsg = {
             enableColumnResizing: true,
             rowHeight: constant.UIGrid.rowHeight,
             selectionRowHeaderWidth: constant.UIGrid.rowHeight,
             enableSorting: false,
             enableColumnMenus: false,
             virtualizationThreshold: 50, //默认加载50条数据,避免在数据展示时,只显示前面4条
             enableHorizontalScrollbar: uiGridConstants.scrollbars.enableHorizontalScrollbar,
             enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,
             columnDefs: [{
                 name: ' ',
                 width: '5%',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span><img data-ng-src="{{grid.appScope.errorLevelToString(row.entity.errorLevel)}}"><span></div>'
             }, {
                 name: $translate.instant('ImportErrorPopUpNoCol'),
                 width: '5%',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.index}}<span></div>'
             }, {
                 name: $translate.instant('ErrorResult'),
                 width: '30%',
                 cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.validationResult}}<span></div>'
             },

              {
                  name: $translate.instant('ImportErrorPopUpErrorCountCol'),
                  width: '10%',
                  cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.number}}<span></div>'
              },

              {
                  name: $translate.instant('InvoiceQJ'),
                  width: '5%',
                  cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.periodId}}<span></div>'
              }, {
                  name: $translate.instant('ErrorDetail'),
                  width: '10%',
                  cellTemplate: '<div class="ui-grid-cell-contents"><a ng-click="grid.appScope.showJournalEntryModal(row.entity.erpCheckTypeId, row.entity.validationDetails)">{{"ViewDetails" | translate}}</a></div>'
              }, {
                  name: $translate.instant('ValidationTips'),
                  width: '35%',
                  cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.validationTips}}" data-ng-bind-html="row.entity.validationTips"></span></div>'
              }

             ],
             onRegisterApi: function (gridApi) {
                 $scope.errorGridApi = gridApi;

                 $interval(function () {
                     $scope.errorGridApi.core.handleWindowResize();
                 }, 500, 60 * 60 * 8);
             }
         };
     };
     

     //初始化JE展示grid
     var initJeGrid = function () {
         $scope.gridOptionsJournalEntry = {
             enableColumnResizing: true,
             rowHeight: constant.UIGrid.rowHeight,
             //selectionRowHeaderWidth: constant.UIGrid.rowHeight,
             enableSorting: false,
             enableColumnMenus: false,
             flatEntityAccess: true,
             //virtualizationThreshold: 50,//默认加载50条数据,避免在数据展示时,只显示前面4条
             //enableHorizontalScrollbar: uiGridConstants.scrollbars.enableHorizontalScrollbar,
             //enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,
             onRegisterApi: function (gridApi) {
                 $scope.gridApi = gridApi;

                 $interval(function () {
                     $scope.gridApi.core.handleWindowResize();
                 }, 500, 60 * 60 * 8);
             }
         };
     };


     $scope.getGridHeight = function () {
         if ($scope.isLoadComplete) {
             return {
                 height: ($('.journal-entry-grid-wrapper').height()) + "px"
             };
         } else {
             return {
                 height: 0 + "px"
             };
         }
     };


     $scope.toggleErrorTab = function () {
         $scope.ImportErrorTag = !$scope.ImportErrorTag;

         // topIcon and content-resize gapBottom 15px
         if (!$scope.ImportErrorTag) {
             setErrorWrapCssDefault();
         } else {

             if (parseInt($('#content-resizer').css('bottom')) < 100) {
                 $('#content-resizer').css('bottom', '130px');

                 $('#topIcon').css({
                     bottom: '-381px'
                 });

                 $('.error-info-wrapper').css('height', '130px');
             }
         }
     };


     $scope.getErrorGridHeight = function () {
         if ($scope.isLoadComplete) {
             var y = $("#error-info-wrapper").height();

             // Enough space
             if (y > constant.UIGrid.gapHeight) {
                 y = y - constant.UIGrid.gapHeight;
                 return {
                     height: y + "px"
                 };
             } else {

                 return {
                     height: '0px'
                 };
             }
         }

         return {};
     };


     $scope.pagingService = {
         refreshInvoiceDataGrid: function () {
             $log.debug("refreshInvoiceDataGrid");
             loadJournalEntryDataFromDB();
         },
     };

     
     (function initialize() {
         $log.debug('importJournalEntryController.ctor()...');

         $scope.errorMsgMap = [];
         $scope.journalEntryFileName = '';
         $scope.selectedColumnMap = [];
         $scope.journalEntryColumns = [];
         $scope.initJournalEntryColumnsIndex = [];
         $scope.startRowList = [];
         $scope.isShowImportTotalBtn = true;
         $scope.changeJournalEntrySheet = changeJournalEntrySheet;
         $scope.mappingColumn = mappingColumn;
         $scope.importJournalEntryData = importJournalEntryData;
         $scope.errorLevelToString = errorLevelToString;
         $scope.showJournalEntryModal = showJournalEntryModal;
         $scope.deleteDuplicateData = deleteDuplicateData;
         $scope.clearJournalEntryData = clearJournalEntryData;
         $scope.refreshJournalEntryData = refreshJournalEntryData;
         $scope.showOperateLogPop = showOperateLogPop;
         $scope.startToDeleteJe = startToDeleteJe;
         $scope.setButtonWrapStyle = setButtonWrapStyle;
         $scope.sheetData = {
             sheetNameList: [],
             dataList: [],
             selectedSheetIndex: 0
         };
         $scope.sheetInfo = {
             selectedSheetName: '',
             selectedSheetIndex: 0,
             topRowNumber: 0
         };

         initErrorMsgGrid();
         initJeGrid();
         initColumns();
         loadJournalEntryDataFromDB();
                
         $scope.$watch('journalEntryFileName', function (newValue, oldValue) {
             if (newValue && newValue !== oldValue) {
                 updateJournalEntryFileName(newValue);
                 doUploadJournalEntryFile($scope.journalEntryFileName);
                 $scope.ImportErrorTab = false;
                 $scope.ImportErrorTag = false;
                 $('#StartRowNum').val('2');
                 //$scope.ImportFlag = true;
             }
         });

         $timeout(function () {
             $scope.isLoadComplete = true;
         }, 500);
     })();
 }
]);
commonModule.directive('importJournalEntry', ['$log',
    function ($log) {
        'use strict';
        $log.debug('importJournalEntry.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/import/import-journal-entry/import-journal-entry.html' + '?_=' + Math.random(),
            scope: {
                serviceTypeId: "=?",
                periodId: "=?"
            },
            controller: 'importJournalEntryController',
            link: function (scope, element) {

            }
        };
    }
]).filter('propsFilter', function () {
    return function (items, props) {
        var out = [];

        if (angular.isArray(items)) {
            var keys = Object.keys(props);

            items.forEach(function (item) {
                var itemMatches = false;

                for (var i = 0; i < keys.length; i++) {
                    var prop = keys[i];
                    var text = props[prop].toLowerCase();
                    if (!_.isUndefined(item[prop])) {
                        if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
                            itemMatches = true;
                            break;
                        }
                    }                  
                }

                if (itemMatches) {
                    out.push(item);
                }
            });
        } else {
            // Let the output be the input untouched
            out = items;
        }

        return out;
    };
});
commonModule.controller('importTBController', ['$scope', '$log', '$translate', '$timeout', '$q', '$interval'
    , 'apiInterceptor', 'Upload', 'vatImportService', 'SweetAlert', 'uiGridConstants', '$uibModal'
    , 'vatSessionService', 'enums', 'vatOperationLogService'
    , 'projectService', 'vatCommonService',
    function ($scope, $log, $translate, $timeout, $q, $interval
        , apiInterceptor, Upload, vatImportService, SweetAlert, uiGridConstants, $uibModal
        , vatSessionService, enums, vatOperationLogService
        , projectService, vatCommonService) {
        'use strict';

        var successCount = 0;
        var uploadUrl = apiInterceptor.vatWebApiHostUrl + '/FileUpload/NewFile';
        var _BlankChar = $translate.instant('PleaseSelectColumn');
        var resumable = true;
        var comment = vatSessionService.project.name + " " + vatSessionService.project.year + "年" + vatSessionService.month + "月";
        var projectDbName = vatSessionService.project.dbName;
        var servicePeriods = [];
     
        $scope.period = $scope.periodId;
        $scope.moduleid = enums.vatModuleEnum.Import_TrialBalance;
        $scope.chunkSize = 100000;
        $scope.success = false;      
        $scope.showErrorTable = false;
        $scope.showInitTable = false;
        $scope.showImportTable = false
        $scope.isSelectPeriod = true;
        $scope.isShowImportTotalBtn = true;
        $scope.projectID = vatSessionService.project.id;
        $scope.startRowNum = 2;
        $scope.validationType = 0;
        $scope.sheetData = { sheetNameList: [], dataList: [], selectedSheetIndex: 0 };
        $scope.sheetInfo = { selectedSheetName: '', selectedSheetIndex: 0 };
        $scope.balanceInputList = [];
        $scope.toInputList = [];       
        $scope.importEnum = { Import: 0, CoverImport: 1, AddImport: 2 }; //导入方式    
        $scope.selectedPeriod = null;
        $scope.showTotalSecondRow = false;


        //写日志
        var logDto = {
            ID: '',
            OperationName: '',
            ModuleID: $scope.moduleid,
            OperationObject: $translate.instant('MyTrialBalanceTitle'),
            OperationType: '',
            OperationContent: '',
            OriginalState: '',
            UpdateState: '',
            CreatorID: vatSessionService.logUser.ID,
            Comment: comment,
            IP: '',
            Period: $scope.period,
        };

        //初始化ack-pagination
        $scope.pagingOptions = {
            pageIndex: 1, //当前页码
            totalItems: 0, //总数据
            totalPages: 10, //总页数
            maxSize: 5, //分页数字的限制。
            pageSize: constant.page.pageSizeArrary[3], //每页多少条数据,100条
            pageSizeString: constant.page.pageSizeArrary[3].toString(),
            firstPage: $translate.instant('PagingFirstPage'),
            previousPage: $translate.instant('PagingPreviousPage'),
            nextPage: $translate.instant('PagingNextPage'),
            lastPage: $translate.instant('PagingLastPage'),
        };

        //初始化查询参数
        $scope.queryParams = {
            pageInfo: {
                totalCount: 0,
                pageIndex: 0,
                pageSize: 0,
                totalPage: 0,
            },
            periodId: $scope.period,
            serviceTypeId: $scope.serviceTypeId,
            projectId: $scope.projectID
        };


        $scope.totalData = {
            totalNumber: 0,
            begDebitTotal: 0,
            begCreditTotal: 0,
            endDebitTotal: 0,
            endCreditTotal: 0,
            begBalTotal: 0,
            endBalTotal: 0,
            debitTotal: 0,
            creditTotal: 0,
        };

        $scope.showTotalValue = {
            showBegDebitBal: false,
            showBegCreditBal: false,
            showEndDebitBal: false,
            showEndCreditBal: false
        };


        //分页获取数据
        $scope.eventService = {
            refreshInvoiceDataGrid: function () {
                $log.debug("refreshInvoiceDataGrid");
                GetBalanceList();
            },
        };

        //初始化GridView
        var initGirdView = {
            initBalanceOuput: function () {
                return {
                    rowHeight: constant.UIGrid.rowHeight,
                    selectionRowHeaderWidth: constant.UIGrid.selectionRowHeaderWidth,
                    enableSorting: false,
                    enableColumnMenus: false,
                    enableHorizontalScrollbar: uiGridConstants.scrollbars.enableHorizontalScrollbar,
                    enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,
                    columnDefs: [],
                    onRegisterApi: function (gridApi) {
                        $scope.gridApi = gridApi;

                        $interval(function () {
                            $scope.gridApi.core.handleWindowResize();
                        }, 500, 60 * 60 * 8);
                    }
                }
            },
            initErrorMsg: function () {
                return {
                    rowHeight: constant.UIGrid.rowHeight,
                    selectionRowHeaderWidth: constant.UIGrid.selectionRowHeaderWidth,
                    enableSorting: false,
                    enableColumnMenus: false,
                    enableHorizontalScrollbar: uiGridConstants.scrollbars.enableHorizontalScrollbar,
                    enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,
                    columnDefs: [
                        {
                            name: $translate.instant('Icon'), width: '5%', cellTemplate: '<div class="ui-grid-cell-contents"><span><img data-ng-src="{{grid.appScope.errorLevelToString(row.entity.errorLevel)}}"><span></div>'
                        },
                        {
                            name: $translate.instant('SequenceNo'), width: '5%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.index}}<span></div>'
                        },
                        {
                            name: $translate.instant('InvoiceQJ'), width: '5%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.periodId}}<span></div>'
                            , visible: $scope.serviceTypeId === constant.serviceType.CIT
                        },
                        {
                            name: $translate.instant('ErrorResult'), width: '20%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.validationResult}}<span></div>'
                        },
                        {
                            name: $translate.instant('ErrorCount'), width: '10%', cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.number}}<span></div>'
                        },
                        {
                            name: $translate.instant('ErrorDetail'), width: '35%', cellTemplate: dealDetail(),
                        },
                        {
                            name: $translate.instant('ValidationTips'), width: '25%', cellTemplate: '<div class="ui-grid-cell-contents" title="{{row.entity.validationTips}}"><span>{{row.entity.validationTips}}<span></div>'
                        },
                    ],
                    onRegisterApi: function (gridApi) {
                        $scope.errorGridApi = gridApi;

                        $interval(function () {
                            $scope.errorGridApi.core.handleWindowResize();
                        }, 500, 60 * 60 * 8);
                    }
                }
            }
        }


        //初始化列数据
        var initColumns = function () {
            //初始化进项发票汇总表列名
            $scope.mapNameList = [
                $translate.instant('PleaseSelectColumn'),
                $translate.instant('AccountCode'),
                $translate.instant('PeriodId'),
                $translate.instant('CustomerCode'),
                $translate.instant('BegDebitBal'),
                $translate.instant('BegCreditBal'),
                $translate.instant('EndDebitBal'),
                $translate.instant('EndCreditBal'),
                $translate.instant('DebitBal'),
                $translate.instant('CreditBal'),
                $translate.instant('BegBal'),
                $translate.instant('EndBal')
            ];
        };


        //上传文件
        var uploadfile = function (file) {
            if (file) {
                successCount = 0;
                if (!file.$error) {
                    var tempFileName = PWC.newGuid() + '.dat';
                    var token = $('input[name="__RequestVerificationToken"]').val();
                    Upload.upload({
                        url: uploadUrl,
                        data: {
                            cancel: false,
                            filename: file.name,
                            tempFileName: tempFileName,
                            file: file
                        },
                        resumeChunkSize: resumable ? $scope.chunkSize : null,
                        headers: {
                            'Access-Control-Allow-Origin': '*',
                            Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken
                        },
                        __RequestVerificationToken: token,
                        withCredentials: true
                    }).then(uploadSuccess);
                }
            }
        };


        //上传成功
        var uploadSuccess = function (resp) {
            successCount++;
            if (successCount === 1) {
                $scope.tempFileName = resp.data;
                changeSheet(0);
            }
        };


        //选择sheet
        var changeSheet = function (selectedSheet) {
            var sheetIndex = _.findIndex($scope.sheetData.sheetNameList, function (num) {
                return num.name === selectedSheet.name;
            })
            $scope.sheetInfo.selectedSheetIndex = sheetIndex === -1 ? 0 : sheetIndex;
            refreshTable();
        };


        //刷新列表
        var refreshTable = function () {
            //在切换显示页面导入数据时,直接设置初始化数据ui-grid表不可见,错误信息不可见
            //导入数据表格可见 
            $scope.showErrorTable = false;
            if (_.isString($scope.tempFileName)) {
                $scope.sheetData = { sheetNameList: [], dataList: [], selectedSheetIndex: 0 };
                $scope.selectedMappingList = [];
                $scope.gridOptionsBalanceOuput.data = [];
                vatImportService.getFileContent($scope.tempFileName, $scope.sheetInfo.selectedSheetIndex, 0).success(function (data) {
                    if (data.result === false) {
                        $scope.showInitTable = true;
                        $scope.showImportTable = false;
                        initTableTitle();
                        SweetAlert.warning(data.resultMsg);
                    }
                    else {
                        $scope.showInitTable = false;
                        $scope.showImportTable = true
                    }
                    $scope.sheetData = data;
                    //加入index序号
                    var index = 1;
                    data.dataList.forEach(function (v) {
                        v.index = index++;
                    });
                    var sheetNameObjectArray = [];
                    data.sheetNameList.forEach(function (v) {
                        sheetNameObjectArray.push({ 'name': v });
                    });
                    $scope.sheetData.sheetNameList = sheetNameObjectArray;
                    $scope.sheetInfo.selectedSheetName = $scope.sheetData.sheetNameList[$scope.sheetInfo.selectedSheetIndex];
                    initColumns();
                    vatSessionService.dataChanged = true;

                }).error(function () {
                    SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                });
            }
        };


        //发票信息汇总数据表选择列名事件
        //parentIndex:当前列号
        //index:下拉列表中选项的序号
        var changeMapping = function (parentIndex, index, colName) {
            if (colName) {
                var newColumn = $scope.mapNameList[index];
                var oldColumn = $scope.selectedMappingList[parentIndex];

                //如果新的选择项与老的选择项一致,则不进行操作
                if (oldColumn === newColumn) {
                    return;
                }
                else {
                    $scope.selectedMappingList[parentIndex] = colName;

                    if (colName !== $translate.instant('PleaseSelectColumn')) {
                        //如果当前选择的不是"请选择列名",则将选项从数组中移除
                        $scope.mapNameList.splice(index, 1);

                        if (oldColumn && oldColumn !== $translate.instant('PleaseSelectColumn')) {
                            //将老的选项追加到选项列表中
                            $scope.mapNameList.push(oldColumn);
                        }
                    }
                    else {
                        //如果当前选中的是"请选择列名",则将该列原来的列名追加到选项列表中
                        if (oldColumn) {
                            $scope.mapNameList.push(oldColumn);
                        }
                    }
                }
            }
            $log.debug($scope.selectedMappingList);
        };


        //转换没有选中的列值
        var undefinedStringToNull = function (i, stringName) {
            var data = $scope.sheetData.dataList[i][$.inArray($translate.instant(stringName), $scope.selectedMappingList)];
            if (_.isUndefined(data)) {
                return null;
            }
            else {
                if (PWC.isNullOrEmpty(data)) {
                    return "";
                }
                else {
                    return data;
                }
            }
        }


        //转换没有选中的列值
        var undefinedNumToNull = function (i, stringName) {
            var data = $scope.sheetData.dataList[i][$.inArray($translate.instant(stringName), $scope.selectedMappingList)];
            if (_.isUndefined(data)) {
                return null;
            }
            else {
                if (PWC.isNullOrEmpty(data)) {
                    return 0;
                }
                else {
                    return data;
                }
            }
        }


        //验证每行数据类型
        var valueTypeValidation = function (balanceinputlist) {
            var AccountCodeOverLengthMsg = '';
            var AccountCodeNullMsg = '';
            var PeriodMsg = '';
            var BegDebitBalMsg = '';
            var BegCreditBalMsg = '';
            var DebitBalMsg = '';
            var CreditBalMsg = '';
            var EndDebitBalMsg = '';
            var EndCreditBalMsg = '';
            var BegBalMsg = '';
            var EndBalMsg = '';
            var NumlengthMsg = '';

            var AccountCodeOverLengthCount = 0;
            var AccountCodeNullCount = 0;
            var PeriodCount = 0;
            var BegDebitBalCount = 0;
            var BegCreditBalCount = 0;
            var DebitBalCount = 0;
            var CreditBalCount = 0;
            var EndDebitBalCount = 0;
            var EndCreditBalCount = 0;
            var BegBalCount = 0;
            var EndBalCount = 0;
            var NumLengthCount = 0;
            //验证前,将错误数据清空
            $scope.errorMsgMap = [];
            for (var i = 0; i < balanceinputlist.length; i++) {
                var m = balanceinputlist[i];

                if (PWC.isNullOrEmpty(m.AcctCode)) {
                    AccountCodeNullMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('AccountCodeNullMag') + '<br />';
                    AccountCodeNullCount++;
                }
                if (m.AcctCode !== null && m.AcctCode.length > 50) {
                    AccountCodeOverLengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('AccountCodeOverLengthMag') + '<br />';
                    AccountCodeOverLengthCount++;
                }
                if (m.MonthId !== null) {
                    if (!PWC.isInteger(m.MonthId)) {
                        PeriodMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('PeriodErrorMag') + '<br />';
                        PeriodCount++;
                    }
                    else if (PWC.isInteger(m.MonthId) && (parseInt(m.MonthId) < 1 || parseInt(m.MonthId) > 12)) {
                        NumlengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('PeriodId') + $translate.instant('PeriodOverLengthMsg') + '<br />';
                        NumLengthCount++;
                    }
                }

                if (m.BegDebitBal !== null) {
                    if (isNaN(parseFloat(m.BegDebitBal))) {
                        BegDebitBalMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('BegDebitBalMsg') + '<br />';
                        BegDebitBalCount++;
                    }
                    //else if (parseFloat(m.BegDebitBal) < constant.startNum || parseFloat(m.BegDebitBal) > constant.endNum) {
                    //    NumlengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('BegDebitBal') + $translate.instant('NumOverLengthMsg') + '<br />';
                    //    NumLengthCount++;
                    //}
                    else {
                        m.BegDebitBal = PWC.round(m.BegDebitBal, 2);
                    }


                }
                if (m.BegCreditBal !== null) {
                    if (isNaN(parseFloat(m.BegCreditBal))) {
                        BegCreditBalMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('BegCreditBalMsg') + '<br />';
                        BegCreditBalCount++;
                    }
                    //else if (parseFloat(m.BegCreditBal) < constant.startNum || parseFloat(m.BegCreditBal) > constant.endNum) {
                    //    NumlengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('BegCreditBal') + $translate.instant('NumOverLengthMsg') + '<br />';
                    //    NumLengthCount++;
                    //}
                    else {
                        m.BegCreditBal = PWC.round(m.BegCreditBal, 2);
                    }
                }
                if (m.DebitBal !== null) {
                    if (isNaN(parseFloat(m.DebitBal))) {
                        DebitBalMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('DebitBalMsg') + '<br />';
                        DebitBalCount++;
                    }
                    //else if (parseFloat(m.DebitBal) < constant.startNum || parseFloat(m.DebitBal) > constant.endNum) {
                    //    NumlengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('DebitBal') + $translate.instant('NumOverLengthMsg') + '<br />';
                    //    NumLengthCount++;
                    //}
                    else {
                        m.DebitBal = PWC.round(m.DebitBal, 2);
                    }
                }
                if (m.CreditBal !== null) {
                    if (isNaN(parseFloat(m.CreditBal))) {
                        CreditBalMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('CreditBalMsg') + '<br />';
                        CreditBalCount++;
                    }
                    //else if (parseFloat(m.CreditBal) < constant.startNum || parseFloat(m.CreditBal) > constant.endNum) {
                    //    NumlengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('CreditBal') + $translate.instant('NumOverLengthMsg') + '<br />';
                    //    NumLengthCount++;
                    //}
                    else {
                        m.CreditBal = PWC.round(m.CreditBal, 2);
                    }
                }
                if (m.EndDebitBal !== null) {
                    if (isNaN(parseFloat(m.EndDebitBal))) {
                        EndDebitBalMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('EndDebitBalMsg') + '<br />';
                        EndDebitBalCount++;
                    }
                    //else if (parseFloat(m.EndDebitBal) < constant.startNum || parseFloat(m.EndDebitBal) > constant.endNum) {
                    //    NumlengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('EndDebitBal') + $translate.instant('NumOverLengthMsg') + '<br />';
                    //    NumLengthCount++;
                    //}
                    else {
                        m.EndDebitBal = PWC.round(m.EndDebitBal, 2);
                    }
                }
                if (m.EndCreditBal !== null) {
                    if (isNaN(parseFloat(m.EndCreditBal))) {
                        EndCreditBalMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('EndCreditBalMsg') + '<br />';
                        EndCreditBalCount++;
                    }
                    //else if (parseFloat(m.EndCreditBal) < constant.startNum || parseFloat(m.EndCreditBal) > constant.endNum) {
                    //    NumlengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('EndCreditBal') + $translate.instant('NumOverLengthMsg') + '<br />';
                    //    NumLengthCount++;
                    //}
                    else {
                        m.EndCreditBal = PWC.round(m.EndCreditBal, 2);
                    }
                }
                if (m.BegBal !== null) {
                    if (isNaN(parseFloat(m.BegBal))) {
                        BegBalMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('BegBalMsg') + '<br />';
                        BegBalCount++;
                    }
                    //else if (parseFloat(m.BegBal) < constant.startNum || parseFloat(m.BegBal) > constant.endNum) {
                    //    NumlengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('BegBal') + $translate.instant('NumOverLengthMsg') + '<br />';
                    //    NumLengthCount++;
                    //}
                    else {
                        m.BegBal = PWC.round(m.BegBal, 2);
                    }
                }
                if (m.EndBal !== null) {
                    if (isNaN(parseFloat(m.EndBal))) {
                        EndBalMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('EndBalMsg') + '<br />';
                        EndBalCount++;
                    }
                    //else if (parseFloat(m.EndBal) < constant.startNum || parseFloat(m.EndBal) > constant.endNum) {
                    //    NumlengthMsg += $translate.instant('LineNum') + ':' + m.SeqNum + ',' + $translate.instant('EndBal') + $translate.instant('NumOverLengthMsg') + '<br />';
                    //    NumLengthCount++;
                    //}
                    else {
                        m.EndBal = PWC.round(m.EndBal, 2);
                    }
                }
            }


            if (AccountCodeNullMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('AccountCodeNullType'),
                        'errorCount': AccountCodeNullCount,
                        'errorContent': AccountCodeNullMsg
                    });
            }
            if (AccountCodeOverLengthMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('AccountCodeOverLengthType'),
                        'errorCount': AccountCodeOverLengthCount,
                        'errorContent': AccountCodeOverLengthMsg
                    });
            }
            if (NumLengthCount > 0) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('NumOutRangeErrorType'),
                        'errorCount': NumLengthCount,
                        'errorContent': NumlengthMsg
                    });
            }
            if (PeriodMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('PeriodErrorType'),
                        'errorCount': PeriodCount,
                        'errorContent': PeriodMsg
                    });
            }
            if (BegDebitBalMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('BegDebitBalType'),
                        'errorCount': BegDebitBalCount,
                        'errorContent': BegDebitBalMsg
                    });
            }
            if (BegCreditBalMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('BegCreditBalType'),
                        'errorCount': BegCreditBalCount,
                        'errorContent': BegCreditBalMsg
                    });
            }
            if (CreditBalMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('CreditBalType'),
                        'errorCount': CreditBalCount,
                        'errorContent': CreditBalMsg
                    });
            }
            if (DebitBalMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('DebitBalType'),
                        'errorCount': DebitBalCount,
                        'errorContent': DebitBalMsg
                    });
            }
            if (EndDebitBalMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('EndDebitBalType'),
                        'errorCount': EndDebitBalCount,
                        'errorContent': EndDebitBalMsg
                    });
            }
            if (EndCreditBalMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('EndCreditBalType'),
                        'errorCount': EndCreditBalCount,
                        'errorContent': EndCreditBalMsg
                    });
            }
            if (BegBalMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('BegBalType'),
                        'errorCount': BegBalCount,
                        'errorContent': BegBalMsg
                    });
            }
            if (EndBalMsg) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('EndBalType'),
                        'errorCount': EndBalCount,
                        'errorContent': EndBalMsg
                    });
            }
            if ($scope.errorMsgMap.length > 0) {
                $('#errorListModal').modal('show');
                return false;
            }
            return true;
        }


        //验证是否选中了正确的列名
        var validationColumnMapping = function () {
            $scope.errorMsgMap = [];
            //0.判断选择的开始导入行是否大于实际数据行
            if (PWC.isNullOrEmpty($scope.startRowNum)) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('StartRowError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('StartRowNull')
                    });
            }
            if (parseInt($scope.startRowNum) > $scope.sheetData.dataList.length) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('StartRowError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('StartRowNumberCheckMsg')
                    });
            }
            //1.科目代码必选
            if ($scope.selectedMappingList.indexOf($translate.instant('AccountCode')) === -1) {
                //errorMsg += $translate.instant('NoAccountCode') + '\n';           
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('SelectColumnError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('NoAccountCode')
                    });
            }
            //借方期初,贷方期初同时必选
            if (($scope.selectedMappingList.indexOf($translate.instant('BegDebitBal')) === -1 &&
                $scope.selectedMappingList.indexOf($translate.instant('BegCreditBal')) !== -1)
                || ($scope.selectedMappingList.indexOf($translate.instant('BegDebitBal')) !== -1 &&
                    $scope.selectedMappingList.indexOf($translate.instant('BegCreditBal')) === -1)) {

                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('SelectColumnError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('Condition1')
                    });
            }
            //借方发生额,贷方发生额同时必选
            if (($scope.selectedMappingList.indexOf($translate.instant('DebitBal')) === -1 &&
                $scope.selectedMappingList.indexOf($translate.instant('CreditBal')) !== -1)
                || ($scope.selectedMappingList.indexOf($translate.instant('DebitBal')) !== -1 &&
                    $scope.selectedMappingList.indexOf($translate.instant('CreditBal')) === -1)) {

                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('SelectColumnError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('Condition6')
                    });
            }
            //借方期末,贷方期末同时必选
            if (($scope.selectedMappingList.indexOf($translate.instant('EndDebitBal')) === -1 &&
                $scope.selectedMappingList.indexOf($translate.instant('EndCreditBal')) !== -1)
                || ($scope.selectedMappingList.indexOf($translate.instant('EndDebitBal')) !== -1 &&
                    $scope.selectedMappingList.indexOf($translate.instant('EndCreditBal')) === -1)) {

                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('SelectColumnError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('Condition7')
                    });
            }
            //2.期初余额必选或者(借方期初,贷方期初)必选
            if (!($scope.selectedMappingList.indexOf($translate.instant('BegBal')) !== -1 ||
                $scope.selectedMappingList.indexOf($translate.instant('BegDebitBal')) !== -1 &&
                $scope.selectedMappingList.indexOf($translate.instant('BegCreditBal')) !== -1)) {

                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('SelectColumnError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('Condition2')
                    });
            }
            //3.(借方发生额,贷方发生额)或者(借方期末,贷方期末)或者 期末余额 必选 
            if (!($scope.selectedMappingList.indexOf($translate.instant('DebitBal')) !== -1
                && $scope.selectedMappingList.indexOf($translate.instant('CreditBal')) !== -1
                || $scope.selectedMappingList.indexOf($translate.instant('EndDebitBal')) !== -1
                && $scope.selectedMappingList.indexOf($translate.instant('EndCreditBal')) !== -1
                || $scope.selectedMappingList.indexOf($translate.instant('EndBal')) !== -1)
            ) {

                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('SelectColumnError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('Condition3')
                    });
            }
            //4.期初余额与借方期初,贷方期初不能同时选
            if ($scope.selectedMappingList.indexOf($translate.instant('BegBal')) !== -1 &&
                $scope.selectedMappingList.indexOf($translate.instant('BegDebitBal')) !== -1 &&
                $scope.selectedMappingList.indexOf($translate.instant('BegCreditBal')) !== -1) {

                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('SelectColumnError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('Condition4')
                    });
            }
            //5.期末余额与借方期末,贷方期末不能同时选
            if ($scope.selectedMappingList.indexOf($translate.instant('EndBal')) !== -1 &&
                $scope.selectedMappingList.indexOf($translate.instant('EndDebitBal')) !== -1 &&
                $scope.selectedMappingList.indexOf($translate.instant('EndCreditBal')) !== -1) {

                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('SelectColumnError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('Condition5')
                    });
            }

            //6. CIT时期间必须
            if ($scope.serviceTypeId === constant.serviceType.CIT
                && $scope.selectedMappingList.indexOf($translate.instant('PeriodId')) === -1) {
                $scope.errorMsgMap.push(
                    {
                        'errorType': $translate.instant('SelectColumnError'),
                        'errorCount': 1,
                        'errorContent': $translate.instant('PeriodColumnRequired')
                    });
            }

            if ($scope.errorMsgMap.length > 0) {
                $('#errorListModal').modal('show');
                return false;
            }
            return true;
        }


        //验证数据
        var validationTbData = function () {
            var defer = $q.defer();
            $scope.balanceInputList = [];
            for (var i = $scope.startRowNum - 1; i < $scope.sheetData.dataList.length; i++) {
                var balanceDto = {
                    'SeqNum': i + 1,
                    'BalanceId': PWC.newGuid(),
                    'PeriodId': undefinedStringToNull(i, 'PeriodId'),
                    'AcctCode': undefinedStringToNull(i, 'AccountCode'),
                    'CustomerCode': undefinedStringToNull(i, 'CustomerCode'),
                    'MonthId': undefinedStringToNull(i, 'PeriodId'),
                    'BegDebitBal': undefinedNumToNull(i, 'BegDebitBal'),
                    'BegCreditBal': undefinedNumToNull(i, 'BegCreditBal'),
                    'DebitBal': undefinedNumToNull(i, 'DebitBal'),
                    'CreditBal': undefinedNumToNull(i, 'CreditBal'),
                    'EndDebitBal': undefinedNumToNull(i, 'EndDebitBal'),
                    'EndCreditBal': undefinedNumToNull(i, 'EndCreditBal'),
                    'BegBal': undefinedNumToNull(i, 'BegBal'),
                    'EndBal': undefinedNumToNull(i, 'EndBal'),
                };
                $scope.balanceInputList.push(balanceDto);
            }

            if ($scope.serviceTypeId === constant.serviceType.CIT) {
                $scope.isSelectPeriod = $scope.balanceInputList[0].MonthId !== null ? true : false;
                var isOk = valueTypeValidation($scope.balanceInputList);
                defer.resolve(isOk);
                return defer.promise;

            }
            else if ($scope.serviceTypeId === constant.serviceType.VAT) {
                if ($scope.balanceInputList[0].MonthId === null) {//没有选中月份,默认导入所有期间
                    $scope.isSelectPeriod = false;
                    swal({
                        title: "warning!",
                        text: $translate.instant('NoPeriod'),
                        type: "warning",
                        showCancelButton: true,
                        confirmButtonColor: "#DD6B55",
                        confirmButtonText: $translate.instant('Yes'),
                        cancelButtonText: $translate.instant('No'),
                        closeOnConfirm: true,
                        closeOnCancel: true
                    },
                        function (isConfirm) {
                            $timeout(function () {
                                if (isConfirm) {
                                    var isok = valueTypeValidation($scope.balanceInputList);
                                    defer.resolve(isok);
                                }
                                else {
                                    defer.resolve(false);
                                }
                            }, 300);
                        });

                    return defer.promise;
                }
                else {
                    $scope.isSelectPeriod = true;
                    var isSame = true;
                    $scope.balanceInputList.forEach(function (m) {
                        if (m.MonthId !== m.PeriodId.toString()) {
                            isSame = false;
                        }
                    });
                    if (isSame === false) { //是否只导入当前月份数据
                        swal({
                            title: "warning!",
                            text: $translate.instant('PeriodDifferenceTip'),
                            type: "warning",
                            showCancelButton: true,
                            confirmButtonColor: "#DD6B55",
                            confirmButtonText: $translate.instant('Yes'),
                            cancelButtonText: $translate.instant('No'),
                            closeOnConfirm: true,
                            closeOnCancel: true
                        },
                            function (isConfirm) {
                                $timeout(function () {
                                    if (isConfirm) {
                                        var isOk = valueTypeValidation($scope.balanceInputList);
                                        defer.resolve(isOk);
                                    }
                                    else {
                                        defer.resolve(false);
                                    }
                                }, 300);
                            });
                        return defer.promise;
                    }
                    else {
                        var isOk = valueTypeValidation($scope.balanceInputList);
                        defer.resolve(isOk);
                        return defer.promise;
                    }
                }
            }



        }


        //获取要导入数据, 并通过期间过滤数据
        var getImportTbList = function (isSelect) {
            var importList = [];
            if (isSelect) {
                $scope.balanceInputList.forEach(function (m) {
                    if (filterImportData(m)) {
                        var balanceDto = {
                            'BalanceId': m.BalanceId,
                            'PeriodId': m.PeriodId,
                            'AcctCode': m.AcctCode,
                            'CustomerCode': m.CustomerCode,
                            'MonthId': m.PeriodId,
                            'BegDebitBal': m.BegDebitBal,
                            'BegCreditBal': m.BegCreditBal,
                            'DebitBal': m.DebitBal,
                            'CreditBal': m.CreditBal,
                            'EndDebitBal': m.EndDebitBal,
                            'EndCreditBal': m.EndCreditBal,
                            'BegBal': m.BegBal,
                            'EndBal': m.EndBal,
                        };
                        importList.push(balanceDto);
                    }
                });
            }
            else {
                $scope.balanceInputList.forEach(function (m) {
                    //VAT没有选择‘期间列’,所有导入数据的期间为$scope.period
                    //CIT没有选择‘期间列’,所有导入数据的期间为它本身的期间值
                    var tempPeriodId = $scope.serviceTypeId === constant.serviceType.VAT ? $scope.period : m.PeriodId
                    var balanceDto = {
                        'BalanceId': m.BalanceId,
                        'PeriodId': tempPeriodId,
                        'AcctCode': m.AcctCode,
                        'CustomerCode': m.CustomerCode,
                        'MonthId': null,
                        'BegDebitBal': m.BegDebitBal,
                        'BegCreditBal': m.BegCreditBal,
                        'DebitBal': m.DebitBal,
                        'CreditBal': m.CreditBal,
                        'EndDebitBal': m.EndDebitBal,
                        'EndCreditBal': m.EndCreditBal,
                        'BegBal': m.BegBal,
                        'EndBal': m.EndBal,
                    };
                    importList.push(balanceDto);
                });
            }
            if (importList.length === 0) {
                SweetAlert.warning($translate.instant('NoTbDataToImport'));
                return false;
            }
            else {
                $scope.toInputList = importList;
                return true;
            }

        }


        //根据PeriodId过滤数据
        var filterImportData = function (m) {
            var filterData = false;
            if ($scope.serviceTypeId === constant.serviceType.VAT) {
                filterData = m.MonthId === m.PeriodId
                    && m.PeriodId === $scope.period.toString();

            } else if ($scope.serviceTypeId === constant.serviceType.CIT) {
                filterData = m.MonthId === m.PeriodId;
            }

            return filterData;
        }


        //上传导入,并进行计算
        var importBalanceList = function (importType) {
            logDto.ID = PWC.newGuid();
            logDto.CreateTime = new Date();
            logDto.UpdateTime = new Date();
            logDto.OperationContent = $scope.fileName;
            if (importType === $scope.importEnum.Import) {
                logDto.OperationName = $translate.instant('ImportTrialBalance');
                logDto.OperationType = enums.vatLogOperationTypeEnum.Import;
            }
            else if (importType === $scope.importEnum.CoverImport) {
                logDto.OperationName = $translate.instant('CoverImportTrialBalance');
                logDto.OperationType = enums.vatLogOperationTypeEnum.CoverImport;
            }
            else if (importType === $scope.importEnum.AddImport) {
                logDto.OperationName = $translate.instant('AddImportTrialBalance');
                logDto.OperationType = enums.vatLogOperationTypeEnum.AddImport;
            }

            vatImportService.importBalanceList($scope.toInputList, importType, $scope.serviceTypeId).success(function (rsp) {
                if (rsp.result) {
                    var queryImportDto = {
                        serviceTypeId: $scope.serviceTypeId,
                        periods: servicePeriods,
                        projectId: $scope.projectID,
                        importTypeId: enums.TbImportTypeEnum.TbImported
                    }

                    //修改项目状态
                    vatImportService.updatePeriodStatus(queryImportDto).success(function () {
                        refreshByService.refreshSuccess(enums.optionType.Import);
                        vatCommonService.importSetProjectStatus(projectDbName, $scope.period, constant.DictionaryDictKey.WFImportBalanceTable
                            , enums.FinishStatusEnum.Finished);
                        vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isTbImport, true);
                        $scope.fileName = '';
                        showTotalValue($scope.toInputList[0]);
                    });
                }
                else {
                    logDto.UpdateState = $translate.instant('ImportFail');
                    vatOperationLogService.addOperationLog(logDto);
                    SweetAlert.error($translate.instant('ImportFail'));
                }
            }).error(function () {
                logDto.UpdateState = $translate.instant('ImportFail');
                vatOperationLogService.addOperationLog(logDto);
                SweetAlert.error($translate.instant('PleaseContactAdministrator'));
            });
        }


        //是否已经导入财务数据
        var isImportedErpData = function (importtype) {
            servicePeriods = [];
            if ($scope.serviceTypeId === constant.serviceType.VAT) {
                servicePeriods = [$scope.period];
            }
            else if ($scope.serviceTypeId === constant.serviceType.CIT) {
                servicePeriods = _.chain($scope.toInputList).map(function (item) { return item.PeriodId }).uniq().value();
            }

            var queryImportDto = {
                serviceTypeId: $scope.serviceTypeId,
                periods: servicePeriods,
                projectId: $scope.projectID
            }

            vatImportService.getProjectImportType(queryImportDto).success(function (re) {
                if (re.result) {
                    //var periods = _.chain($scope.toInputList).map(function (item) { return item.PeriodId }).uniq().value();
                    var importedErpData = _.find(re.data, function (item) { return item.importType === enums.projectImportType.ErpImported });
                    if (!_.isUndefined(importedErpData)) {
                        swal({
                            title: "warning!",
                            text: $translate.instant('ImportTypeTip'),
                            type: "warning",
                            showCancelButton: true,
                            confirmButtonText: $translate.instant('Yes'),
                            cancelButtonText: $translate.instant('No'),
                            closeOnConfirm: true,
                            closeOnCancel: true
                        },
                            function (isConfirm) {
                                $timeout(function () {
                                    //清除财务数据
                                    if (isConfirm) {
                                        vatImportService.clearTableByPeriods(servicePeriods).success(function (re) {
                                            if (re.result && re.data) {
                                                importBalanceList(importtype);
                                            }
                                        }).error(function () {
                                            SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                                        });
                                    }
                                }, 300);
                            });
                    }
                    else {
                        importBalanceList(importtype);
                    }
                }
            }).error(function () {
                SweetAlert.error($translate.instant('PleaseContactAdministrator'));
            });
        };


        //导入事件
        var doUploadTbResult = function (importType) {
            if (vatSessionService.project.projectStatusList[$scope.period] >= constant.ProjectStatusEnum.AccountMapSubmitted) {
                swal({
                    title: "warning!",
                    text: $translate.instant('IsConfirmToReImport').formatObj({ status: vatCommonService.getProjectStautsEnumDesc(vatSessionService.project.projectStatusList[$scope.period]) }),
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonColor: "#DD6B55",
                    confirmButtonText: $translate.instant('Yes'),
                    cancelButtonText: $translate.instant('No'),
                    closeOnConfirm: true,
                    closeOnCancel: true
                },
                    function (isConfirm) {
                        $timeout(function () {
                            if (isConfirm) {
                                $log.debug("doUploadTbResult confirmed");
                                uploadTbResult(importType);
                            }
                            else {
                                swal.close();
                            }
                        }, 300);
                    });
            }
            else {
                uploadTbResult(importType);
            }

        }


        var uploadTbResult = function (importType) {
            if ($scope.sheetData.dataList.length == 0) {
                SweetAlert.warning($translate.instant('PleaseSelectFileFirst'));
                return;
            }

            //列名对应验证
            if (validationColumnMapping()) {
                //数据类型验证 
                validationTbData().then(function (isSuccess) {
                    if (isSuccess) {
                        //获取要导入的数据
                        if (getImportTbList($scope.isSelectPeriod)) {
                            //财务账提示
                            isImportedErpData(importType);
                        }
                    }
                });
            }
        }


        //显示图标
        var errorLevelToString = function (errorLevel) {
            if (errorLevel === 0) {
                return '/app-resources/images/vat/error.png';
            }
            if (errorLevel === 1) {
                return '/app-resources/images/vat/warning.png';
            }
            if (errorLevel === 2) {
                return '/app-resources/images/vat/tips.png';
            }
            else {
                return '/app-resources/images/vat/tips.png';
            }
        }


        //显示明细
        var dealDetail = function () {
            return '<div ng-if="row.entity.isShowDetail === 1" class="ui-grid-cell-contents"><span><a  ng-click="grid.appScope.openTab(row.entity.erpCheckTypeId,row.entity.validationDetails)">错误明细</a><span></div>' +
                '<div  ng-if="row.entity.isShowDetail !== 1" class="ui-grid-cell-contents" title="{{row.entity.validationDetails}}"><span>{{row.entity.validationDetails}}<span></div>';
        }


        //显示重复验证明细界面
        var dispalyduplicatedValidation = function (data) {
            $scope.detailData = data;
            $scope.dupColumns = [];
            $scope.dupColumns.push({
                caption: $translate.instant('AccountCode'),
                dataField: "AcctCode",
                width: 100
            });
            $scope.dupColumns.push({
                caption: $translate.instant('AccountName'),
                dataField: "AccountName",
                width: 120
            });
            if (data[0].MonthId !== null) {
                $scope.dupColumns.push({
                    caption: $translate.instant('PeriodId'),
                    dataField: "MonthId",
                    width: 100
                });
            }
            if (data[0].BegBal !== null) {
                $scope.dupColumns.push({
                    caption: $translate.instant('BegBal'),
                    dataField: "BegBal",
                    format: { type: 'fixedPoint', precision: 2 },
                    width: 100
                });
            }
            if (data[0].BegDebitBal !== null) {
                $scope.dupColumns.push({
                    caption: $translate.instant('BegDebitBal'),
                    dataField: "BegDebitBal",
                    format: { type: 'fixedPoint', precision: 2 },
                    width: 100
                });
            }
            if (data[0].BegCreditBal !== null) {
                $scope.dupColumns.push({
                    caption: $translate.instant('BegCreditBal'),
                    dataField: "BegCreditBal",
                    format: { type: 'fixedPoint', precision: 2 },
                    width: 100
                });
            }
            if (data[0].DebitBal !== null) {
                $scope.dupColumns.push({
                    caption: $translate.instant('DebitBal'),
                    dataField: "DebitBal",
                    format: { type: 'fixedPoint', precision: 2 },
                    width: 100
                });
            }
            if (data[0].CreditBal !== null) {
                $scope.dupColumns.push({
                    caption: $translate.instant('CreditBal'),
                    dataField: "CreditBal",
                    format: { type: 'fixedPoint', precision: 2 },
                    width: 100
                });
            }
            if (data[0].EndDebitBal !== null) {
                $scope.dupColumns.push({
                    caption: $translate.instant('EndDebitBal'),
                    dataField: "EndDebitBal",
                    format: { type: 'fixedPoint', precision: 2 },
                    width: 100
                });
            }
            if (data[0].EndCreditBal !== null) {
                $scope.dupColumns.push({
                    caption: $translate.instant('EndCreditBal'),
                    dataField: "EndCreditBal",
                    format: { type: 'fixedPoint', precision: 2 },
                    width: 100
                });
            }
            if (data[0].EndBal !== null) {
                $scope.dupColumns.push({
                    caption: $translate.instant('EndBal'),
                    dataField: "EndBal",
                    format: { type: 'fixedPoint', precision: 2 },
                    width: 100
                });
            }

            $scope.filterCondition = ["IsDuplicate", "=", true];
            $scope.gridDuplicatedOptions = {
                allowColumnResizing: true,
                bindingOptions: {
                    "dataSource.store.data": "detailData",
                    //"selection.deferred": "deferStatus",
                    "selectionFilter": "filterCondition",
                    "columns": "dupColumns"
                },
                dataSource: { store: { type: "array", key: 'BalanceId' } },
                columns: $scope.dupColumns,
                selection: {
                    mode: "multiple",
                    selectAllMode: "allPages",
                    showCheckBoxesMode: "always",
                    deferred: true
                },
                hoverStateEnabled: true,
                paging: { pageSize: 10 },
            }
            $('#duplicatedValidationModal').modal('show');
        }


        //显示本月与上月验证明细界面
        var dispalyPeriodValidation = function (data) {
            $scope.devgridDataSource = data;

            $scope.gridPeriodOptions = {
                columnAutoWidth: true,
                columns: [
                    {
                        caption: $translate.instant('AccountCode'),
                        dataField: "AcctCode",
                        textalign: "center",
                    },
                    {
                        caption: $translate.instant('LastMonth'),
                        alignment: 'center',
                        columns: [
                            {
                                caption: $translate.instant('EndBal'),
                                dataField: "EndBal",
                                format: { type: 'fixedPoint', precision: 2 },
                            },
                            {
                                caption: $translate.instant('EndDebitBal'),
                                dataField: "EndDebitBal",
                                format: { type: 'fixedPoint', precision: 2 },
                            },
                            {
                                caption: $translate.instant('EndCreditBal'),
                                dataField: "EndCreditBal",
                                format: { type: 'fixedPoint', precision: 2 },
                            },
                        ]
                    },
                    {
                        caption: $translate.instant('CurrentMonth'),
                        alignment: 'center',
                        columns: [
                            {
                                caption: $translate.instant('BegBal'),
                                dataField: "BegBal",
                                format: { type: 'fixedPoint', precision: 2 },

                            },
                            {
                                caption: $translate.instant('BegDebitBal'),
                                dataField: "BegDebitBal",
                                format: { type: 'fixedPoint', precision: 2 },
                            },
                            {
                                caption: $translate.instant('BegCreditBal'),
                                dataField: "BegCreditBal",
                                format: { type: 'fixedPoint', precision: 2 },
                            },
                        ]
                    },
                ],
                bindingOptions: {
                    "dataSource": "devgridDataSource"
                    //"dataSource.store.data": "devgridDataSource",
                },
                hoverStateEnabled: true,
                paging: {
                    pageSize: 10
                }
            }
            $('#periodValidationModal').modal('show');

        }


        //月份验证信息
        var openTab = function (errorType, rowdata) {
            var data = JSON.parse(rowdata);
            if (errorType === 31) {
                dispalyPeriodValidation(data);
            }
            else if (errorType === 39) {
                dispalyduplicatedValidation(data);
            }
        }


        //删除重复数据
        var deleteDupData = function () {
            var dataGrid = $('#gridDuplicatedValidation').dxDataGrid("instance");
            var deleteList = [];
            dataGrid.getSelectedRowsData().done(function (rowData) {
                for (var i = 0; i < rowData.length; i++) {
                    deleteList.push(rowData[i].AcctCode);
                }
            });
            dataGrid.getSelectedRowKeys().done(function (keys) {
                if (keys && keys.length === 0) {
                    SweetAlert.warning($translate.instant('DeleteEmptyWarning'));
                    return;
                }

                logDto.ID = PWC.newGuid();
                logDto.CreateTime = new Date();
                logDto.UpdateTime = new Date();
                logDto.OperationContent = deleteList.join(",");
                logDto.OperationName = $translate.instant('DeleteDuplicateData');
                logDto.OperationType = enums.vatLogOperationTypeEnum.DeleteDuplicate;

                vatImportService.deleteDuplicateTbData(keys).success(function (rsp) {
                    if (rsp === true) {
                        logDto.UpdateState = $translate.instant('DeleteSuccess');
                        vatOperationLogService.addOperationLog(logDto);
                        refreshByService.callRefresh($scope.serviceTypeId, enums.optionType.DeleteDuplicate);
                    }
                    else {
                        logDto.UpdateState = $translate.instant('DeleteFailed');
                        vatOperationLogService.addOperationLog(logDto);
                    }

                }).error(function () {
                    logDto.UpdateState = $translate.instant('DeleteFailed');
                    vatOperationLogService.addOperationLog(logDto);
                    SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                });
            });
        }


        //刷新操作
        var refreshTbData = function () {
            logDto.ID = PWC.newGuid();
            logDto.CreateTime = new Date();
            logDto.UpdateTime = new Date();
            logDto.OperationContent = '';
            logDto.OperationName = $translate.instant('RefreshValidationData');
            logDto.OperationType = enums.vatLogOperationTypeEnum.Refresh;
            refreshByService.callRefresh($scope.serviceTypeId, enums.optionType.Refresh);
        }


        //开始清空数据
        var clearTbData = function () {
            if ($scope.serviceTypeId === constant.serviceType.CIT) {
                showPeriodDrapDown();
            }

            if ($scope.serviceTypeId === constant.serviceType.VAT) {
                $scope.selectedPeriod = $scope.period;
                deleteTbData();
            }

        };


        //清空数据
        var deleteTbData = function () {
            if ($scope.serviceTypeId === constant.serviceType.CIT
                && _.isNull($scope.selectedPeriod)) {
                SweetAlert.warning($translate.instant('SelectPeriodDelete'));
                return;
            }

            var alterMsg = $scope.serviceTypeId === constant.serviceType.CIT ? $translate.instant('ClearDataCITWarning')
                : $translate.instant('ClearDataVATWarning');

            swal({
                title: "warning!",
                text: alterMsg,
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                confirmButtonText: $translate.instant('Yes'),
                cancelButtonText: $translate.instant('No'),
                closeOnConfirm: true,
                closeOnCancel: true
            },
                function (isConfirm) {
                    $timeout(function () {
                        if (isConfirm) {
                            logDto.ID = PWC.newGuid();
                            logDto.CreateTime = new Date();
                            logDto.UpdateTime = new Date();
                            logDto.OperationContent = '';
                            logDto.OperationName = $translate.instant('ClearTrialBalance');
                            logDto.OperationType = enums.vatLogOperationTypeEnum.ClearData;

                            var dto = {
                                serviceTypeId: $scope.serviceTypeId,
                                periods: [$scope.selectedPeriod],
                                projectId: $scope.projectID
                            }
                            vatImportService.clearServiceTbData(dto).success(function (data) {
                                if (data) {
                                    var queryImportDto = {
                                        serviceTypeId: $scope.serviceTypeId,
                                        periods: [$scope.selectedPeriod],
                                        projectId: $scope.projectID,
                                        importTypeId: enums.TbImportTypeEnum.UnImported
                                    }

                                    //修改项目状态
                                    vatImportService.updatePeriodStatus(queryImportDto).success(function () {
                                        $scope.selectedPeriod = null;
                                        if ($scope.serviceTypeId === constant.serviceType.CIT) {
                                            $scope.closePeriodSelectModal();
                                        }
                                        resetTotalValue();
                                        refreshByService.callRefresh($scope.serviceTypeId, enums.optionType.Clear);
                                        vatCommonService.clearProjectStatus(projectDbName, $scope.period, constant.DictionaryDictKey.WFImportBalanceTable
                                            , enums.FinishStatusEnum.NotFinished);
                                        vatCommonService.setImportSubStatus(enums.VatImportSubStatus.isTbImport, false);
                                    });
                                }
                                else {
                                    $scope.selectedPeriod = null;
                                    if ($scope.serviceTypeId === constant.serviceType.CIT) {
                                        $scope.closePeriodSelectModal();
                                    }
                                    logDto.UpdateState = $translate.instant('ClearFailed');
                                    vatOperationLogService.addOperationLog(logDto);
                                    SweetAlert.warning($translate.instant('ClearFailed'));
                                }
                            }).error(function () {
                                logDto.UpdateState = $translate.instant('ClearFailed');
                                vatOperationLogService.addOperationLog(logDto);
                                SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                            });
                        }
                        else {
                            return;
                        }
                    }, 300);
                });
        }


        var getGridHeight = function () {
            if ($scope.isLoadComplete) {
                return { height: ($('.balance-ouput-grid-wrapper').height()) + "px" };
            }
            else {
                return { height: 0 + "px" };
            }
        };


        var getErrorGridHeight = function () {
            if ($scope.isLoadComplete) {
                var y = $("#error-info-wrapper").height();
                // Enough space
                if (y > constant.UIGrid.gapHeight) {
                    y = y - constant.UIGrid.gapHeight;
                    return { height: y + "px" };
                } else {

                    return { height: '0px' };
                }
            }
            return {};
        };


        //获取tb数据
        var GetBalanceList = function () {
            $scope.queryParams.pageInfo = {
                totalCount: $scope.pagingOptions.totalItems,
                pageIndex: $scope.pagingOptions.pageIndex,
                pageSize: $scope.pagingOptions.pageSize,
                totalPage: 0,
            };

            vatImportService.queryTrialBalanceData($scope.queryParams).success(function (retData) {
                if (retData) {
                    var data = retData.list;
                    $scope.isShowImportTotalBtn = false;
                    GetValidationList();
                    initPagingControl(retData.pageInfo.totalCount);
                    var index = 1;
                    data.forEach(function (v) {
                        v.index = index++;
                        v.begDebitBal = PWC.round(v.begDebitBal, 2);
                        v.begCreditBal = PWC.round(v.begCreditBal, 2);
                        v.begBal = PWC.round(v.begBal, 2);
                        v.debitBal = PWC.round(v.debitBal, 2);
                        v.creditBal = PWC.round(v.creditBal, 2);
                        v.endDebitBal = PWC.round(v.endDebitBal, 2);
                        v.endCreditBal = PWC.round(v.endCreditBal, 2);
                        v.endBal = PWC.round(v.endBal, 2);
                    });
                    $scope.gridOptionsBalanceOuput.data = data;
                    $scope.totalData.totalNumber = retData.pageInfo.totalCount;
                    $scope.totalData.begDebitTotal = _.isNull(retData.calculateData.begDebitBal) ? PWC.round("0.00",2)   
                                                       : PWC.round(retData.calculateData.begDebitBal, 2);
                    $scope.totalData.begCreditTotal = _.isNull(retData.calculateData.begCreditBal) ? PWC.round("0.00", 2)
                                                       : PWC.round(retData.calculateData.begCreditBal, 2);
                    $scope.totalData.endDebitTotal = _.isNull(retData.calculateData.endDebitBal) ? PWC.round("0.00", 2)
                                                       : PWC.round(retData.calculateData.endDebitBal, 2);
                    $scope.totalData.endCreditTotal = _.isNull(retData.calculateData.endCreditBal) ? PWC.round("0.00", 2)
                                                      : PWC.round(retData.calculateData.endCreditBal, 2);
                    $scope.totalData.begBalTotal = _.isNull(retData.calculateData.begBal) ? PWC.round("0.00", 2)
                                                   : PWC.round(retData.calculateData.begBal, 2);
                    $scope.totalData.endBalTotal = _.isNull(retData.calculateData.endBal) ? PWC.round("0.00", 2)
                                                    : PWC.round(retData.calculateData.endBal, 2);
                    $scope.totalData.debitTotal = _.isNull(retData.calculateData.debitBal) ? PWC.round("0.00", 2)
                                                   : PWC.round(retData.calculateData.debitBal, 2);
                    $scope.totalData.creditTotal = _.isNull(retData.calculateData.creditBal) ? PWC.round("0.00", 2)
                                                    : PWC.round(retData.calculateData.creditBal, 2);
                    if (data.length > 0) {
                        initGridBalanceOuputColumn(data);
                    }
                    else {
                        initTableTitle();
                    }


                    $log.debug("获取数据成功");
                }

            }).error(function () {
                SweetAlert.error($translate.instant('PleaseContactAdministrator'));
            });
        }


        //初始化columns
        var initGridBalanceOuputColumn = function (data) {
            $scope.gridOptionsBalanceOuput.columnDefs = [];
            $scope.gridOptionsBalanceOuput.columnDefs.push
                ({
                    name: $translate.instant('SequenceNo'), width: '5%', headerCellClass: '',
                    cellTemplate: '<div class="ui-grid-cell-contents " title="{{row.entity.index}}"><span>{{row.entity.index}}<span></div>'
                });

            if (data[0].monthId !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('PeriodId'), headerCellClass: '',
                        cellTemplate: '<div class="ui-grid-cell-contents " title="{{row.entity.monthId}}"><span>{{row.entity.monthId}}<span></div>'
                    });
            }

            if (data[0].customerCode !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('CustomerCode'), headerCellClass: '',
                        cellTemplate: '<div class="ui-grid-cell-contents " title="{{row.entity.customerCode}}"><span>{{row.entity.customerCode}}<span></div>'
                    });
            }

            if (data[0].acctCode !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('AccountCode'), headerCellClass: '',
                        cellTemplate: '<div class="ui-grid-cell-contents" title="{{row.entity.acctCode}}"><span>{{row.entity.acctCode}}<span></div>'
                    });
            }

            $scope.gridOptionsBalanceOuput.columnDefs.push(
                {
                    name: $translate.instant('AccountName'), headerCellClass: '',
                    cellTemplate: '<div class="ui-grid-cell-contents" title="{{row.entity.accountName}}"><span>{{row.entity.accountName}}<span></div>'
                });
            if (data[0].begDebitBal !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('BegDebitBal'), headerCellClass: 'right',
                        cellTemplate: '<div class="ui-grid-cell-contents right" title="{{row.entity.begDebitBal}}"><span>{{row.entity.begDebitBal}}<span></div>'
                    });
            }
            if (data[0].begCreditBal !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('BegCreditBal'), headerCellClass: 'right',
                        cellTemplate: '<div class="ui-grid-cell-contents right" title="{{row.entity.begCreditBal}}"><span>{{row.entity.begCreditBal}}<span></div>'
                    });
            }
            if (data[0].begBal !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('BegBal'), headerCellClass: 'right',
                        cellTemplate: '<div class="ui-grid-cell-contents right" title="{{row.entity.begBal}}"><span>{{row.entity.begBal}}<span></div>'
                    });
            }
            if (data[0].debitBal !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('DebitBal'), headerCellClass: 'right',
                        cellTemplate: '<div class="ui-grid-cell-contents right" title="{{row.entity.debitBal}}"><span>{{row.entity.debitBal}}<span></div>'
                    });
            }
            if (data[0].creditBal !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('CreditBal'), headerCellClass: 'right',
                        cellTemplate: '<div class="ui-grid-cell-contents right" title="{{row.entity.creditBal}}"><span>{{row.entity.creditBal}}<span></div>'
                    });
            }
            if (data[0].endDebitBal !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('EndDebitBal'), headerCellClass: 'right',
                        cellTemplate: '<div class="ui-grid-cell-contents right" title="{{row.entity.endDebitBal}}"><span>{{row.entity.endDebitBal}}<span></div>'
                    });
            }
            if (data[0].endCreditBal !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('EndCreditBal'), headerCellClass: 'right',
                        cellTemplate: '<div class="ui-grid-cell-contents right" title="{{row.entity.endCreditBal}}"><span>{{row.entity.endCreditBal}}<span></div>'
                    });
            }
            if (data[0].endBal !== null) {
                $scope.gridOptionsBalanceOuput.columnDefs.push(
                    {
                        name: $translate.instant('EndBal'), headerCellClass: 'right',
                        cellTemplate: '<div class="ui-grid-cell-contents right" title="{{row.entity.endBal}}"><span>{{row.entity.endBal}}<span></div>'
                    });
            }

            showTotalValue(data[0]);

        };


        var initBalanceDataFromDB = function () {
            $scope.showInitTable = true;
            $scope.showImportTable = false;
            vatSessionService.dataChanged = false;
            $scope.gridOptionsBalanceOuput.data = [];
            $scope.sheetData = { sheetNameList: [], dataList: [], selectedSheetIndex: 0 };
            //判断当前导入数据类型
            vatImportService.isImportData($scope.projectID, enums.projectImportType.TbImported)
                .success(function (re) {
                    if (re.result) {
                        if (re.data) {
                            GetBalanceList();
                        } else {
                            initTableTitle();
                        }
                    }
                }).error(function () {
                    SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                });
        }


        //初始化列名
        var initTableTitle = function () {
            $scope.gridOptionsBalanceOuput.columnDefs = [];
            $scope.gridOptionsBalanceOuput.columnDefs.push({
                name: $translate.instant('SequenceNo'), headerCellClass: 'right', width: '5%',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.index}}<span></div>'
            });
            $scope.gridOptionsBalanceOuput.columnDefs.push({
                name: $translate.instant('AccountCode'), headerCellClass: 'right',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.acctCode}}<span></div>'
            });
            $scope.gridOptionsBalanceOuput.columnDefs.push({
                name: $translate.instant('BegDebitBal'), headerCellClass: 'right',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.begDebitBal}}<span></div>'
            });
            $scope.gridOptionsBalanceOuput.columnDefs.push({
                name: $translate.instant('BegCreditBal'), headerCellClass: 'right',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.begCreditBal}}<span></div>'
            });
            $scope.gridOptionsBalanceOuput.columnDefs.push({
                name: $translate.instant('DebitBal'), headerCellClass: 'right',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.debitBal}}<span></div>'
            });
            $scope.gridOptionsBalanceOuput.columnDefs.push({
                name: $translate.instant('CreditBal'), headerCellClass: 'right',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.creditBal}}<span></div>'
            });
            $scope.gridOptionsBalanceOuput.columnDefs.push({
                name: $translate.instant('EndDebitBal'), headerCellClass: 'right',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.endDebitBal}}<span></div>'
            });
            $scope.gridOptionsBalanceOuput.columnDefs.push({
                name: $translate.instant('EndCreditBal'), headerCellClass: 'right',
                cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.endCreditBal}}<span></div>'
            });
        }


        //获取验证信息
        var GetValidationList = function () {
            vatImportService.getServiceValidationList($scope.validationType, $scope.period, $scope.serviceTypeId, $scope.projectID).success(function (data) {
                if (data.length > 0) {
                    var index = 1;
                    data.forEach(function (v) {
                        v.index = index++;
                    });
                    $scope.errorList = data;
                    $scope.gridOptionsErrorMsg.data = data;

                    showErrTab();
                    $scope.toggleErrorTab();
                    $scope.showErrorTable = true;
                }
                else {
                    $scope.errorList = [];
                    $scope.gridOptionsErrorMsg.data = [];
                    $scope.showErrorTable = false;
                    $scope.ImportErrorTab = false;
                    $scope.ImportErrorTag = false;
                }
            }).error(function () {
                SweetAlert.error($translate.instant('PleaseContactAdministrator'));
            });
        }


        //显示验证信息
        var toggleErrorTab = function () {
            $scope.ImportErrorTag = !$scope.ImportErrorTag;

            // topIcon and content-resize gapBottom 15px
            if (!$scope.ImportErrorTag) {
                setErrorWrapCssDefault();
            } else {

                if (parseInt($('#content-resizer').css('bottom')) < 100) {
                    $('#content-resizer').css('bottom', '150px');

                    $('#topIcon').css({ bottom: '-381px' });

                    $('.error-info-wrapper').css('height', '150px');
                }
            }
        };


        var setErrorWrapCssDefault = function () {
            $('#content-resizer').css('bottom', '0px');

            $('#topIcon').css({ bottom: '-501px' });

            $('.error-info-wrapper').css('height', '0px');
        };


        var showErrTab = function() {
            $scope.ImportErrorTab = true;
            $scope.ImportErrorTag = true;
            $scope.errorMsg = $translate.instant('ImportErrorMsg').formatObj({ "NumberOfError": $scope.errorList.length });
        };


        //加载文档后操作
        var initImportFile = function (fileName) {
            var arr = fileName.name.split('.');
            if (arr[arr.length - 1] !== 'xls' && arr[arr.length - 1] !== 'xlsx') {
                SweetAlert.warning($translate.instant('ImportFileInvalidType'));
                return;
            }
            $scope.fileName = fileName.name;
            uploadfile($scope.fileNameWrapper);
            //初始化数据
            $scope.selectedMappingList = [];
            initColumns();
            $scope.ImportErrorTab = false;
            $scope.ImportErrorTag = false;
        }


        //日志
        var showOperateLogPop = function () {
            $scope.isShowLog = true;
        };


        var initPagingControl = function (totalItemsCount) {
            $scope.pagingOptions.totalItems = totalItemsCount;
        }


        // 检查用户机构权限
        var checkUserOrganizationPermissionList = function () {

            var list = [];

            var userManageTemp = constant.vatPermission.dataImport.balanceSheet;
            list.push(userManageTemp.importCode);
            $scope.hasImportPermission = false;
            $scope.$root.checkUserOrganizationPermissionList(list).success(function (data) {
                $scope.hasImportPermission = data[userManageTemp.importCode];
            });
        };


        //控制明细信息中删除权限
        var getUserPermission = function () {
            var list = [];
            var code = constant.vatPermission.dataImport.balanceSheet.importCode;
            list.push(code);

            $scope.$root.checkUserOrganizationPermissionList(list).success(function (data) {
                $scope.hasEditPermission = data[code];
            });
        };


        var setButtonWrapStyle = function () {
            if ($scope.fileName) {
                return { width: "100%" };
            }
        };


        //显示期间选择弹出框
        var showPeriodDrapDown = function () {
            $scope.modalInstance = $uibModal.open({
                animation: false,
                ariaLabelledBy: 'modal-title',
                ariaDescribedBy: 'modal-body',
                templateUrl: 'tb-model-period-dropdown.html',
                scope: $scope,
                windowClass: "tb-model-period-dropdow-popup"
            });

            $scope.closePeriodSelectModal = function () {
                $scope.modalInstance.dismiss('cancel');
            };

            $scope.selectBox = {
                simple: {
                    dataSource: $scope.tbPeriods,
                    displayExpr: "Period",
                    valueExpr: "ID",
                    searchEnabled: false,
                    placeholder: $translate.instant('PleaseSelectPeriod'),
                    noDataText: $translate.instant('NoDataToDispaly'),
                    maxLength: 2,
                    onSelectionChanged: function (e) {
                        $scope.selectedPeriod = e.selectedItem.Period;
                    }
                }
            };

            vatImportService.getTBImportedPeriods($scope.projectID, $scope.serviceTypeId).success(function (data) {
                if (data) {
                    $scope.tbPeriods = [];
                    var id = 1;
                    $.each(data, function (index, item) {
                        var periodDto = { ID: -1, Period: -1 };
                        periodDto.ID = id++;
                        periodDto.Period = item;
                        $scope.tbPeriods.push(periodDto);
                    });

                    $("#tbPeriodSelectBox").dxSelectBox("instance").option("dataSource", $scope.tbPeriods);
                }

            }).error(function () {
                SweetAlert.error($translate.instant('PleaseContactAdministrator'));
            });
        };


        //重置汇总数据为0
        var resetTotalValue = function () {
            if ($scope.serviceTypeId === constant.serviceType.VAT) {
                $scope.totalData.totalNumber = 0;
                $scope.totalData.begDebitTotal = 0;
                $scope.totalData.begCreditTotal = 0;
                $scope.totalData.endDebitTotal = 0;
                $scope.totalData.endCreditTotal = 0;
                $scope.totalData.begBalTotal = 0;
                $scope.totalData.endBalTotal = 0;
                $scope.totalData.debitTotal = 0;
                $scope.totalData.creditTotal = 0;
            }
        };


        //设置汇总数据的显示
        var showTotalValue = function (data) {
            $scope.showTotalValue.showBegDebitBal = !_.isNull(data.begDebitBal) ? true : false;
            $scope.showTotalValue.showBegCreditBal = !_.isNull(data.begCreditBal) ? true : false;
            $scope.showTotalValue.showEndDebitBal = !_.isNull(data.endDebitBal) ? true : false;
            $scope.showTotalValue.showEndCreditBal = !_.isNull(data.endCreditBal) ? true : false;
            $scope.showTotalSecondRow = $scope.showTotalValue.showBegDebitBal || $scope.showTotalValue.showBegCreditBal
                                      || $scope.showTotalValue.showEndDebitBal || $scope.showTotalValue.showEndCreditBal
                                       ? true : false;
           

        };

        var setGridStyle = function () {
            if ($scope.showTotalSecondRow) {
                return { 'margin-top': '60px' }
            }
            else {
                return { 'margin-top': '55px' }
            }
        }

        var refreshByService = {
            //VAT刷新数据,重新计算
            vatRefresh: function (operation) {
                vatImportService.refreshTrialBalance($scope.period, $scope.serviceTypeId).success(function (data) {
                    if (data === true) {
                        refreshByService.refreshSuccess(operation);
                    }
                    else {
                        refreshByService.refreshFail();

                    }
                }).error(function () {
                    SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                });
            },

            //CIT刷新数据,重新计算
            citRefresh: function (operation) {
                vatImportService.getTBImportedPeriods($scope.projectID, $scope.serviceTypeId).success(function (data) {
                    if (!_.isUndefined(data)) {
                        var citImportedPeriods = [];
                        var id = 1;
                        $.each(data, function (index, item) {
                            citImportedPeriods.push(item);
                        });
                        var importDto = { periods: citImportedPeriods, serviceTypeId: $scope.serviceTypeId };
                        vatImportService.refreshTrialBalancePeriods(importDto)
                            .success(function (data) {
                                if (data) {
                                    refreshByService.refreshSuccess(operation);
                                }
                                else {
                                    refreshByService.refreshFail();
                                }
                            }).error(function () {
                                SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                            });
                    }

                }).error(function () {
                    SweetAlert.error($translate.instant('PleaseContactAdministrator'));
                })
            },

            //只获取TB数据,不计算
            refreshSuccess: function (operation) {
                var successMsg = "";
                if (operation === enums.optionType.DeleteDuplicate) {
                    $('#duplicatedValidationModal').modal('hide');
                    successMsg = $translate.instant('DeleteSuccess');
                }

                if (operation === enums.optionType.Refresh) {
                    logDto.UpdateState = $translate.instant('RefreshSuccess');
                    vatOperationLogService.addOperationLog(logDto);
                    successMsg = $translate.instant('RefreshSuccess');
                }

                if (operation === enums.optionType.Clear) {
                    logDto.UpdateState = $translate.instant('ClearSuccess');
                    vatOperationLogService.addOperationLog(logDto);
                    successMsg = $translate.instant('ClearSuccess');
                }

                if (operation === enums.optionType.Import) {
                    logDto.UpdateState = $translate.instant('ImportSuccess');
                    vatOperationLogService.addOperationLog(logDto);
                    successMsg = $translate.instant('ImportSuccess');
                }

                SweetAlert.success(successMsg);
                initBalanceDataFromDB();
            },

            refreshFail: function () {
                logDto.UpdateState = $translate.instant('RefreshTbFail');
                vatOperationLogService.addOperationLog(logDto);
                SweetAlert.warning($translate.instant('RefreshTbFail'));
            },

            callRefresh: function (serviceTypeId, operation) {
                if (serviceTypeId === constant.serviceType.VAT) {
                    refreshByService.vatRefresh(operation);
                }

                if (serviceTypeId === constant.serviceType.CIT) {
                    refreshByService.citRefresh(operation);
                }
            }

        };

        //开始
        (function initialize() {
            $log.debug('ImportTBController.ctor()...');
            checkUserOrganizationPermissionList();
            $scope.changeSheet = changeSheet;
            $scope.changeMapping = changeMapping;
            $scope.doUploadTbResult = doUploadTbResult;
            $scope.deleteDupData = deleteDupData;
            $scope.refreshTbData = refreshTbData;
            $scope.deleteTbData = deleteTbData;
            $scope.clearTbData = clearTbData;
            $scope.initPagingControl = initPagingControl;
            $scope.setButtonWrapStyle = setButtonWrapStyle;
            $scope.errorLevelToString = errorLevelToString;
            $scope.openTab = openTab;
            $scope.getGridHeight = getGridHeight;
            $scope.getErrorGridHeight = getErrorGridHeight;
            $scope.toggleErrorTab = toggleErrorTab;
            $scope.showOperateLogPop = showOperateLogPop;
            $scope.gridOptionsBalanceOuput = initGirdView.initBalanceOuput();
            $scope.gridOptionsErrorMsg = initGirdView.initErrorMsg();
            $scope.setGridStyle = setGridStyle;
            getUserPermission();
            initBalanceDataFromDB();
                         
          

            $scope.$watch('fileNameWrapper', function (newValue, oldValue) {
                if (newValue !== null && newValue !== oldValue) {
                    initImportFile(newValue);
                }
            });

            $timeout(function () {
                $scope.isLoadComplete = true;
            }, 500);
        })();
    }
]);
commonModule.directive('importTrialBalance', ['$log',
    function ($log) {
        'use strict';    
        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/import/import-trialbalance/import-trialbalance.html' + '?_=' + Math.random(),
            scope: {
                serviceTypeId: "=?",
                periodId: "=?"
            },
            controller: 'importTBController',
            link: function (scope, element) {

            }
        };
         
    }
]); 
commonModule.
controller('indexMultiSelectorController', ['$scope', 'indexAnalysisDetailService',
    function($scope, indexAnalysisDetailService) {

        // 本页面常量
        var thisConstant = {
            indexMultiSelectorTreeView: 'indexMultiSelectorTreeView',
        };

        var treeView;

        // 数据
        var thisData = {
            selectedIndexSet: {},
        };

        // 主模块
        var mainModule = {

            // 加载数据并显示
            loadData: function() {

                if (!$scope.selectIdList) {
                    $scope.selectIdList = [];
                }

                indexAnalysisDetailService.getIndexAnalysisDropDownList().success(function(data) {
                    thisData.indexList = data;
                    mainModule.drawdxDropDownBox(data);
                });
            },

            // 绘制dxDropDownBox
            drawdxDropDownBox: function(dataArray) {

                var syncTreeViewSelection = function(treeView, value) {
                    if (!value) {
                        treeView.unselectAll();
                        return;
                    }

                    value.forEach(function(key) {
                        treeView.selectItem(key);
                    });

                    $scope.selectIndexList = _.filter(thisData.indexList, function(row) {
                        return value.indexOf(row.id) > -1 && !row.parentId;
                    });

                    // console.log(JSON.stringify($scope.selectIndexList));
                };

                $("#" + thisConstant.indexMultiSelectorTreeView).dxDropDownBox({
                    value: $scope.selectIdList,
                    valueExpr: "id",
                    displayExpr: "name",
                    placeholder: "",
                    showClearButton: true,
                    dataSource: dataArray,
                    contentTemplate: function(e) {
                        var value = e.component.option("value"),
                            $treeView = $("<div>").dxTreeView({
                                dataSource: e.component.option("dataSource"),
                                dataStructure: "plain",
                                keyExpr: "id",
                                parentIdExpr: "parentId",
                                selectionMode: "multiple",
                                displayExpr: "name",
                                selectByClick: true,
                                onContentReady: function(args) {
                                    syncTreeViewSelection(args.component, value);
                                },
                                selectNodesRecursive: true,
                                showCheckBoxesMode: "normal",
                                onItemSelectionChanged: function(args) {
                                    var value = args.component.getSelectedNodesKeys();

                                    e.component.option("value", value);
                                }
                            });

                        treeView = $treeView.dxTreeView("instance");

                        e.component.on("valueChanged", function(args) {
                            var value = args.value;
                            syncTreeViewSelection(treeView, value);
                        });

                        return $treeView;
                    }
                });
            },

        };

        (function() {
            mainModule.loadData();

        })();

    }
]);

// Model select tree view, select multiple models with checkboxes
commonModule.directive('indexMultiSelector', ['$log', '$translate',
    function ($log, $translate) {
        'use strict';
        $log.debug('indexMultiSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/index-multi-selector/index-multi-selector.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'indexMultiSelectorController',
            scope: {
                selectIndexList:'=?',
                selectIdList:'=?',
            },
            link: function (scope, element) {
                
            }
        };
    }
]);
commonModule.
controller('invoiceExaminationModalController', ['SweetAlert', '$scope', '$log', '$translate', '$location', '$timeout', '$interval', '$uibModal','$document','InvoiceManageService',
    function (SweetAlert, $scope, $log, $translate, $location, $timeout, $interval, $uibModal, $document, InvoiceManageService) {


        $scope.isShow = false;

        $scope.remarksOptions = {
            bindingOptions: {
                value: 'invoiceEntity.comments'
            },
        };
        //模态框
        $scope.modalService = {
            modalInstance: null,
            open: function () {
                var parentSelector = '.invoice-examination-modal-wrapper';
                var parentElem = parentSelector ? angular.element($document[0].querySelector(parentSelector)) : undefined;

                var modalInstance = $uibModal.open({
                    animation: true,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'invoiceExaminationTemplate.html',
                    scope: $scope,
                    backdrop: 'static',
                    windowClass: 'invoice-examination-modal-wrapper',
                    appendTo: parentElem,
                });

                $scope.modalService.modalInstance = modalInstance;
            },
            //手动验真
            invoceExamination: function () {
                if ($scope.modalService.modalInstance) {
                    $scope.isShow = false;

                    var invoiceList = [];
                   // $scope.invoiceEntity.comments = $scope.comments;
                    invoiceList.push($scope.invoiceEntity);

                    //手动验真
                    InvoiceManageService.invoiceManualExamination(invoiceList).success(function (res) {
                        if (_.isFunction($scope.refreshTable)) {
                            $scope.refreshTable();
                        }
                        SweetAlert.success("验真成功");
                        $scope.modalService.modalInstance.close();
                    }).error(function () {
                        SweetAlert.error('', $translate.instant('CommonFail'));
                    });
                }
            },
            //退票
            invoiceRefund: function () {
                if ($scope.modalService.modalInstance) {
                    $scope.isShow = false;

                    var selectedInvoiceIDList = [];
                   // $scope.invoiceEntity.comments = $scope.comments;
                    selectedInvoiceIDList.push($scope.invoiceEntity.id);

                    var status = constant.inputInvoice.statusType.InvoiceHasRefund.id;

                    InvoiceManageService.updateInvoiceStatus(status, selectedInvoiceIDList).success(function (data) {
                        if (data) {
                            if (_.isFunction($scope.refreshTable)) {
                                $scope.refreshTable();
                                SweetAlert.success("退票成功");
                                $scope.modalService.modalInstance.close();
                            }
                        }
                    }).error(function () {
                        SweetAlert.error('', $translate.instant('CommonFail'));
                    });
                }
            },
        
            cancel: function () {
                if ($scope.modalService.modalInstance) {
                    $scope.isShow = false;
                    $scope.modalService.modalInstance.dismiss('cancel');
                }
            }
        };

        (function initialize() {
            $log.debug('invoiceExaminationModalController.ctor()...');

         
            $scope.$watch('isShow', function (newValue, oldValue) {
                if (newValue) {
                    $scope.modalService.open();
                }
            });
        })();
    }
]);

commonModule.directive('invoiceExaminationModal', ['$log',
    function ($log) {
        'use strict'; 
        $log.debug('invoiceExaminationModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/invoice-examination-modal/invoice-examination-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'invoiceExaminationModalController',
            scope:
            {
                isShow: '=',
                refreshTable: '&',
                invoiceEntity:'=?',
            }
        };
    }
]);
commonModule.
controller('invoiceManualAddModalController', ['SweetAlert', '$scope', '$log', '$translate', '$location', '$timeout', '$interval', '$uibModal',
    function (SweetAlert, $scope, $log, $translate, $location, $timeout, $interval, $uibModal) {

        $scope.animationsEnabled = true;
        var templateUrl = '';
        $scope.isShow = false;
        $scope.pleaseSelect = $translate.instant("ChoosePlaceholder");
        $scope.pleaseInput = ''; //$translate.instant('InputPlaceholder'),
        $scope.invoiceEntityOptions = {}
        $scope.invoiceEntity = {};
        //当前页面的事件
        var thisPageService = {
            //保存NIS数据
            saveNisData: function (modalInstance) {
               // SweetAlert.swal('保存Nis数据成功!');
                modalInstance.close($scope.invoiceEntity);
                modalInstance.dismiss('cancel');
             
            }
        };

        //当前modal的服务
        var thisModalService = {
            createInstance: function () {

                //实例化一个modal并打开
                var modalInstance = $uibModal.open({
                    animation: true,
                    templateUrl: 'addNewInvoiceTemplate.html',
                    scope: $scope,
                    backdrop: 'static',  //点击父页面不会自动关闭 
                    windowClass: 'invoice-manual-add-modal-wrapper',
                    //resolve: {
                    //    items: function () {//items是一个回调函数
                    //        return $scope.items;//这个值会被模态框的控制器获取到
                    //    }
                    //}
                });

                //modal关闭之后接收返回值的函数
                modalInstance.result.then(function (data) {
                    //设置isShow变量为false
                    $scope.isUpdate = true;
                    $scope.operateType = null;
                    $scope.invoiceEntity = data;//模态框的返回值

                }, function () {
                    $log.info('Modal dismissed at: ' + new Date());
                });

                //点击modal窗口上的确定事件
                $scope.save = function () {                 
                    thisPageService.saveNisData(modalInstance);
                };


                //点击modal窗口上的取消事件
                $scope.cancel = function () {
                    $scope.operateType = null;
                    modalInstance.dismiss('cancel');
                };

            }
        };

        //文本框初始化
        var initTextBoxContorls = function () {

            var isShowClearButton = false;

            $scope.invoiceEntityOptions = {
                //1. 发票代码
                txtInvoiceCodeOptions: {
                    bindingOptions: {
                        value: 'invoiceEntity.invoiceCode',
                    },
                    placeholder: $scope.pleaseInput,
                    showClearButton: isShowClearButton,
                },
                //2. 票面金额 (含税
                txtAmountOptions: {
                    bindingOptions: {
                        value: 'invoiceEntity.amount',
                    },
                    placeholder: $scope.pleaseInput,
                    showClearButton: isShowClearButton,
                },
                //3. 发票号码
                txtInvoiceNumberOptions: {
                    bindingOptions: {
                        value: 'invoiceEntity.invoiceNumber',
                    },
                    placeholder: $scope.pleaseInput,
                    showClearButton: isShowClearButton,
                },
                //4. 税额
                //txtTaxAmountOptions: {
                //    bindingOptions: {
                //        value: 'invoiceEntity.taxAmount',
                //    },
                //    placeholder: $scope.pleaseInput,
                //    showClearButton: isShowClearButton,
                //},
                ////5. 购方税号
                //txtBuyerTaxNumberOptions: {
                //    bindingOptions: {
                //        value: 'invoiceEntity.buyerTaxNumber',
                //    },
                //    placeholder: $scope.pleaseInput,
                //    showClearButton: isShowClearButton,
                //},
                //6. 开票日期
                txtInvoiceDateOptions: {
                    bindingOptions: {
                        value: 'invoiceEntity.invoiceDate',
                    },
                    displayFormat:constant.date.dateFormat,
                    placeholder: $scope.pleaseInput,
                    showClearButton: isShowClearButton,
                },
                ////7. 消方税号
                //txtSellerTaxNumberOptions: {
                //    bindingOptions: {
                //        value: 'invoiceEntity.sellerTaxNumber',
                //    },
                //    placeholder: $scope.pleaseInput,
                //    showClearButton: isShowClearButton,
                //},
                txtRemarksOptions: {
                    bindingOptions: {
                        value: 'invoiceEntity.remarks'
                    },
                    //displayFormat:
                    placeholder: $scope.pleaseInput,
                    showClearButton: isShowClearButton,
                },
            }
        };


        (function initialize() {
            $log.debug('invoiceManualAddModalController.ctor()...');
            initTextBoxContorls();
            //thisModalService.createInstance();

            $scope.$watch('operateType', function (newValue, oldValue) {
                if (newValue) {

                    thisModalService.createInstance();

                    //if (newValue == constant.Operation.Add) {
                    //    thisModalService.createInstance();
                    //}
                    //else if (newValue == constant.Operation.Edit) {
                    //    thisModalService.createInstance();
                    //}
                }
            });
        })();
    }
]);

commonModule.directive('invoiceManualAddModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('invoiceRelevanceModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/invoice-manual-add-modal/invoice-manual-add-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'invoiceManualAddModalController',
            scope:
            {
                invoiceEntity: '=?',
                isUpdate: '=?',
                operateType: '=?',
            }
        };
    }
]);
commonModule.
controller('invoiceRelevanceModalController', ['SweetAlert', '$scope', '$log', '$translate', '$location', '$timeout', '$interval', '$uibModal',
    function (SweetAlert, $scope, $log, $translate, $location, $timeout, $interval, $uibModal) {

        $scope.items = ['item1', 'item2', 'item3'];
        $scope.animationsEnabled = true;
        var templateUrl = '';
        $scope.isShow = false;
        $scope.selected = {
            item: $scope.items[0]
        };

        //当前选中的发票
        $scope.currentInvoice = '';

        //初始化NIS模板页面控件
        var initNISPageControl = function () {
            var simpleProducts = [
                "原料采购",
                "非原料集中采购",
                "报销"
            ];
            //发票来源
            $("#invoiceSourceNIS").dxSelectBox({
                items: simpleProducts
            });
            //收货单号输入框
            $("#acceptNOsNIS").dxTextBox({
                value: "",
                placeholder: "请输入收货单号",
            });
            //商品种类
            $("#productTypeNIS").dxSelectBox({
                items: ["原料"],
                value: '原料',
                readOnly: true
            });
            //是否计入进项税额
            $("#isIncludedInTaxAmountNIS").dxSelectBox({
                items: ['是', '否'],
                value: '是',
                readOnly: true
            });
        };

        //初始化CSSP-四家模板页面控件
        var initCSSPFourPageControl = function () {
            var sales =
                [{ "orderId": 10248 },
                { "orderId": 10249 },
                { "orderId": 10250 },
                { "orderId": 10251 }];
            var simpleProducts = [
                "原料采购",
                "非原料集中采购",
                "报销"
            ];
            //发票来源
            $("#invoiceSourceCSSPFour").dxSelectBox({
                items: simpleProducts
            });
            //采购单号输入框
            $("#purchaseOrderCSSPFour").dxTextBox({
                value: "",
                placeholder: "请输入采购单号",
            });
            //商品种类
            $("#productTypeCSSPFour").dxSelectBox({
                items: ["原料"],
                value: '原料',
                readOnly: true
            });
            //是否计入进项税额
            $("#isIncludedInTaxAmountCSSPFour").dxSelectBox({
                items: ['是', '否'],
                value: '是',
                readOnly: true
            });
            //初始化公司代码code
            var dataGrid = $("#company-code-container").dxDataGrid({
                dataSource: sales,
                selection: {
                    mode: "multiple",
                    showCheckBoxesMode: 'always'
                },
                paging: {
                    pageSize: 10
                },
                filterRow: {
                    visible: true
                },
                columns: [{
                    dataField: "orderId",
                    caption: "公司代码",
                    width: 150
                }]
            }).dxDataGrid("instance");
            //初始化成本中心code
            var dataGrid = $("#cost-center-container").dxDataGrid({
                dataSource: sales,
                selection: {
                    mode: "multiple",
                    showCheckBoxesMode: 'always'
                },
                paging: {
                    pageSize: 10
                },
                filterRow: {
                    visible: true
                },
                columns: [{
                    dataField: "orderId",
                    caption: "成本中心",
                    width: 150
                }]
            }).dxDataGrid("instance");
            
            //凭证号输入框
            $("#voucherNoCSSPFour").dxTextBox({
                value: "",
                placeholder: "请输入凭证号",
            });
        };

        //初始化CSSP模板页面控件
        var initCSSPPageControl = function () {
            var simpleProducts = [
                "原料采购",
                "非原料集中采购",
                "报销"
            ];
            //发票来源
            $("#invoiceSourceCSSP").dxSelectBox({
                items: simpleProducts
            });
            //采购单号输入框
            $("#purchaseOrderCSSP").dxTextBox({
                value: "",
                placeholder: "请输入采购单号",
            });
            //商品种类
            $("#productTypeCSSP").dxSelectBox({
                items: ["原料"],
                value: '原料',
                readOnly: true
            });
            //强制应税checkbox
            $("#forceTaxCheckboxCSSP").dxCheckBox({
                value: true,
                width: 80,
                text: "强制应税"
            });

            //强制应税原因
            $("#forceTaxReasonCSSP").dxTextArea({
                value: '',
                height: 90
            })

            //是否计入进项税额
            $("#isIncludedInTaxAmountCSSP").dxSelectBox({
                items: ['是', '否'],
                value: '是',
                readOnly: true
            });

            //凭证号输入框
            $("#voucherNoCSSP").dxTextBox({
                value: "",
                placeholder: "请输入凭证号",
            });
        };

        //初始化报销模板页面控件
        var initApplyForReimbursementPageControl = function () {
            var simpleProducts = [
                "原料采购",
                "非原料集中采购",
                "报销"
            ];
            //发票来源
            $("#invoiceSourceReibursement").dxSelectBox({
                items: simpleProducts
            });
            //员工编号输入框
            $("#purchaseOrderReibursement").dxTextBox({
                value: "",
                placeholder: "请输入员工编号",
            });
            //商品种类
            $("#productTypeReibursement").dxSelectBox({
                items: ["原料"],
                value: '原料',
                readOnly: true
            });

            //是否计入进项税额
            $("#isIncludedInTaxAmountReibursement").dxSelectBox({
                items: ['是', '否'],
                value: '是',
                readOnly: true
            });

            //凭证号输入框
            $("#voucherNoReibursement").dxTextBox({
                value: "",
                placeholder: "请输入凭证号",
            });
        };

        //当前页面的事件
        var thisPageService = {
            //保存NIS数据
            saveNisData: function (modalInstance) {
                SweetAlert.swal('保存Nis数据成功!');
                modalInstance.close($scope.selected.item);
                modalInstance.dismiss('cancel');
            }
        };


        //当前modal的服务
        var thisModalService = {
            createInstance: function () {
                //判断当前需要打开的是哪一个modal
                if ($scope.relevanceType == 1) {
                    //NIS模板
                    templateUrl = 'relevance-nis.html';
                }
                else if ($scope.relevanceType == 2) {
                    //CSSP-四家模板
                    templateUrl = 'relevance-cssp-four.html';
                }
                else if ($scope.relevanceType == 3) {
                    //CSSP
                    templateUrl = 'relevance-cssp.html';
                }
                else if ($scope.relevanceType == 4) {
                    //报销
                    templateUrl = 'relevance-apply-for-reimbursement.html';
                }

                //实例化一个modal并打开
                var modalInstance = $uibModal.open({
                    animation: true,
                    templateUrl: templateUrl,
                    scope: $scope,
                    backdrop: 'static',
                    windowClass: 'invoice-relevance-modal-wrapper',
                    resolve: {
                        items: function () {//items是一个回调函数
                            return $scope.items;//这个值会被模态框的控制器获取到
                        }
                    }
                });

                //modal关闭之后接收返回值的函数
                modalInstance.result.then(function (data) {
                    //设置isShow变量为false
                    $scope.isShow = false;
                    //设置关联的类型为-1
                    $scope.relevanceType = -1;
                    $scope.selected = data;//模态框的返回值

                }, function () {
                    $log.info('Modal dismissed at: ' + new Date());
                });

                //点击modal窗口上的确定事件
                $scope.save = function () {
                    if ($scope.relevanceType == 1) {
                        thisPageService.saveNisData(modalInstance);
                    }
                };


                //点击modal窗口上的取消事件
                $scope.cancel = function () {
                    //设置isShow变量为false
                    $scope.isShow = false;
                    //设置关联的类型为-1
                    $scope.relevanceType = -1;
                    modalInstance.dismiss('cancel');
                };

            }
        };





        (function initialize() {
            $log.debug('invoiceRelevanceModalController.ctor()...');

            $scope.$watch('isShow', function (newValue, oldValue) {
                if (newValue === true) {
                    thisModalService.createInstance();
                    $timeout(function () {
                        if ($scope.relevanceType == 1) {
                            initNISPageControl();
                        }
                        else if ($scope.relevanceType == 2) {
                            initCSSPFourPageControl();
                        }
                        else if ($scope.relevanceType == 3) {
                            initCSSPPageControl();
                        }
                        else if ($scope.relevanceType == 4) {
                            initApplyForReimbursementPageControl();
                        }
                    }, 500);

                }
            });
        })();
    }
]);

commonModule.directive('invoiceRelevanceModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('invoiceRelevanceModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/invoice-relevance-modal/invoice-relevance-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'invoiceRelevanceModalController',
            scope:
            {
                isShow: '=',
                relevanceType: '=',
                relevanceDataModel: '='
            }
        };
    }
]);
commonModule.controller('invoiceTableTemplateController', ['$log', '$scope', '$translate', 'InvoiceManageService', 'SweetAlert',
function ($log, $scope, $translate,InvoiceManageService, SweetAlert) {
    "use strict";
    $log.debug('invoiceTableTemplateController.ctor()...');
    var loadDetail=function(){
        InvoiceManageService.getInputInvoiceItemList($scope.invoice.id).success(function (response) {
            $scope.invoice.items = response;
        }).error(function () {
            SweetAlert.error('', $translate.instant('CommonFail'));
        });
    };
     (function initialize() {
         if ($scope.isLoadDetail) {
             loadDetail();
         }
     })();
}]);
commonModule.directive('invoiceTableTemplate', ['$log', '$translate',
    function ($log, $translate) {
        'use strict';
        $log.debug('invoiceTableTemplate.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/invoice-table-template/invoice-table-template.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'invoiceTableTemplateController',
            scope: {
                invoice: '=',
                //是否需要加载明细,如果Invoice中不包含,请值为true
                isLoadDetail:'=?'
            },
            link: function (scope, element) {
               
            }
        };
    }
]);
// key value select tree view, select key value pair(s) with checkbox(es)
commonModule.directive('keyValueSelector', ['$log', '$q', '$timeout', '$translate', 'KeyValueConfigService',
    function ($log, $q, $timeout, $translate, KeyValueConfigService) {
        'use strict';
        $log.debug('keyValueSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/key-value-selector/key-value-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                isShow: '=',
                title: '=',
                selectorOptions: '=?',
                selectorApi: '=?', // In: onSelectorClose, onSelectorConfirm; Out: getSelection
                selectedKeyCode: '='
            },
            link: function (scope, element, attrs) {
                $log.debug('keyValueSelector.link()...');

                var newSelectionIndicies = [];
                var gridInstance = null;
                scope.keyValueDataSource = [];

                // Handle id of the element to make sure it is unique.
                // keyValueSelector is used to add the style tag to work-around
                // DX grid height issue
                if (_.isEmpty(attrs['id'])) {
                    var randomStr = Math.random().toString().replace(/\./g, '');
                    element.attr('id', 'grid' + randomStr);
                    scope.gridSelector = '#grid' + randomStr;
                }
                else {
                    scope.gridSelector = '#' + attrs['id'];
                }

                // Register api functions in internalApi
                // If selectorApi passed is not undefined, we will use it as internalApi
                scope.internalApi = scope.selectorApi || {};

                // Work-around for DX grid height issue.
                element.find('.modal').on('shown.bs.modal', function () {
                    scope.getDataGrid().refresh();
                });

                // Clear selected key value pairs and related rows. 
                var resetSelection = function () {
                    scope.getDataGrid().clearSelection();

                };

                var scrollToRowElement = function (gridInstance) {
                    if (newSelectionIndicies.length > 0) {
                        var scrollable = gridInstance.getScrollable();
                        var selectedRowElements = gridInstance.getCellElement(newSelectionIndicies[0], 0);
                        $timeout(function () {
                            scrollable.scrollToElement(selectedRowElements.parent());
                        });
                        newSelectionIndicies = [];
                    }
                };

                var selectRow = function (gridInstance, selectedObj) {
                    var dataSourceInstance = $.extend({}, gridInstance.getDataSource());
                    dataSourceInstance.paginate(false);
                    var absoluteRowIndex = 0;
                    dataSourceInstance.load().done(function (result) {
                        absoluteRowIndex = _.findIndex(result, function (item) {
                            return angular.equals(item, selectedObj);
                        });
                        if (absoluteRowIndex >= 0) {
                            var pgSize = gridInstance.pageSize();
                            var pageIndex = Math.floor(absoluteRowIndex / pgSize);
                            var visibleRowIndex = absoluteRowIndex - (pageIndex * pgSize);
                            newSelectionIndicies = [visibleRowIndex];
                            gridInstance.beginUpdate();
                            var key = gridInstance.keyOf(result[absoluteRowIndex]);
                            gridInstance.selectRows([key], true);

                            if (pageIndex !== gridInstance.pageIndex()) {
                                gridInstance.pageIndex(pageIndex);
                            } else {
                                //当前页内容发生改变时才会触发 onContentReady 事件,所以当选择的焦点行就在当前显示页的时候,需要主动执行一次 scrollToRowElement
                                scrollToRowElement(gridInstance);
                            }
                            gridInstance.endUpdate();
                        }
                    }).fail(function (error) {
                        console.log(error);
                    });
                };
                scope.gridOptions = {
                    bindingOptions: {
                        dataSource: {
                            deep: false,
                            dataPath: 'keyValueDataSource'
                        },
                        height: 'selectorOptions.gridHeight',
                        width: 'selectorOptions.gridWidth',
                        'paging.pageSize': 'selectorOptions.pageSize'
                    },
                    columns: [
                        {
                            dataField: 'id',
                            visible: false
                        }, {
                            caption: $translate.instant('KeyName'),
                            dataField: 'name'
                        }, {
                            caption: $translate.instant('DataSourceName'),
                            dataField: 'dataSourceStr'
                        }, {
                            caption: $translate.instant('Formula'),
                            dataField: 'formula'
                        }, {
                            caption: $translate.instant('Description'),
                            dataField: 'description'
                        }, {
                            caption: $translate.instant('ApplicationScope'),
                            calculateCellValue: function (rowData) {
                                return $translate.instant(rowData.scopeSummary);
                            },
                            calculateFilterExpression: function (filterValue, selectedFilterOperation) {
                                return [this.calculateCellValue, selectedFilterOperation || 'contains', filterValue];
                            }
                        }, {
                            caption: $translate.instant('ApplyService'),
                            dataField: 'serviceTypes'
                        }
                    ],
                    loadPanel: {
                        enabled: false
                    },
                    pager: {
                        showNavigationButtons: true
                    },
                    scrolling: {
                        mode: "standard"
                    },
                    searchPanel: {
                        visible: true,
                        width: 240
                    },
                    selection: {
                        mode: 'single',
                        deferred: false
                    },
                    sorting: {
                        mode: 'single'
                    },
                    filterRow: {
                        visible: true
                    },
                    allowColumnResizing: true,
                    hoverStateEnabled: true,
                    showBorders: true,
                    showRowLines: true,
                    showColumnLines: true,
                    onContentReady: function (e) {
                        scrollToRowElement(e.component);
                        gridInstance = e.component;
                    }
                };

                var loadData = function () {
                    return KeyValueConfigService.getAll().then(function (res) {
                        if (res.data && res.data.length > 0) {
                            res.data.forEach(function (item) {
                                if (item.dataSource) {
                                    var arr = item.dataSource.split('_');
                                    if (arr.length >= 2) {
                                        item.dataSourceStr = arr[1];
                                    }
                                }
                            });
                        }
                        scope.keyValueDataSource = res.data;
                        return $q.when(scope.keyValueDataSource);
                    }, function (response) {
                        return $q.reject($translate.instant("DataLoadingError"));
                    });
                };

                // Adjust the selector options
                var adjustOptions = function () {

                    // Adjust the CSS styles of the selector, currently only support width, height, top and left.

                    var width = 730;

                    var computeWidth = parseInt(window.window.innerWidth * 0.7);

                    if (computeWidth > width && computeWidth < 1500) {
                        width = computeWidth;
                    }


                    scope.selectorOptions = _.extend({
                        // Default options
                        height: 556,
                        width: width,
                        pageSize: 7
                    }, scope.selectorOptions);
                    if (_.isNumber(scope.selectorOptions.height)) {
                        scope.selectorOptions.gridHeight = scope.selectorOptions.height > 145
                            ? (scope.selectorOptions.height - 145) : 1;
                    }

                    if (_.isNumber(scope.selectorOptions.width)) {
                        scope.selectorOptions.gridWidth = scope.selectorOptions.width - 30;
                    }

                    scope.cssOptions = _.pick(scope.selectorOptions, 'width', 'height', 'top', 'left');
                };

                var getSelectionRowData = function () {
                    var selectedRows = gridInstance.getSelectedRowsData();
                    return selectedRows.length ? selectedRows[0] : null;
                };

                scope.getDataGrid = function () {
                    return element.find(".key-value-selector-grid").dxDataGrid("instance");
                };

                scope.selectorClose = function () {
                    if (scope.internalApi && _.isFunction(scope.internalApi.onSelectorClose)) {
                        scope.internalApi.onSelectorClose();
                    }

                    scope.isShow = false;
                };

                scope.selectorConfirm = function () {
                    var selectedRow = getSelectionRowData();
                    scope.selectedKeyCode = selectedRow === null ? null : selectedRow.keyCode;

                    if (scope.internalApi && _.isFunction(scope.internalApi.onSelectorConfirm)) {
                        scope.internalApi.onSelectorConfirm();
                    }

                    scope.isShow = false;
                };

                scope.$watch('isShow', function (newValue, oldValue) {
                    if (newValue) {
                        // refresh the dxDataGrid data source every time when the modal is opening
                        loadData().then(function (data) {
                            //refresh dxDataGrid,so we need user give the selected item id
                            element.children('.modal').modal('show');
                            if (scope.internalApi) {
                                scope.internalApi.getSelection = getSelectionRowData;
                            }

                            resetSelection();

                            //获取指定的选中行,并高亮焦点显示该行
                            var absoluteRowIndex = _.findIndex(data, function (item) { return item.keyCode === scope.selectedKeyCode; });
                            if (gridInstance) {
                                gridInstance.refresh();
                                if (absoluteRowIndex >= 0) {
                                    selectRow(gridInstance, data[absoluteRowIndex]);
                                }
                                else if (data.length > 0) {
                                    gridInstance.pageIndex(0);
                                }
                            }

                            $(".key-value-selector-wrapper .modal-content").draggable({ cursor: "cursor", scroll: true, cancel: '.btn, input, .form-control, .key-value-selector-grid, .close' });
                        });
                    }
                });

                adjustOptions();
            }
        };
    }
]);
commonModule.controller('mentionInputController', ['$scope', '$q', '$log', '$interval', '$timeout', '$translate',
    function ($scope, $q, $log, $interval, $timeout, $translate) {
        'use strict';

        $log.debug('mentionInputController.ctor()...');

        var searchKeyValue = function (term) {
            var searchedList = [];
            if (!_.isEmpty($scope.keyValueList)) {
                searchedList = _.filter($scope.keyValueList, function (tag) {
                    return tag
                        && (tag.code.toUpperCase().indexOf(term.toUpperCase()) >= 0
                        || $scope.showName && tag.name && tag.name.toUpperCase().indexOf(term.toUpperCase()) >= 0);
                });
            }

            $scope.searchedKeyValueList = searchedList;
            return $q.when(searchedList);
        };

        var searchFormula = function (term) {
            var searchedList = [];
            if (!_.isEmpty($scope.formulaList)) {
                searchedList = _.filter($scope.formulaList, function (tag) {
                    return tag && tag.code.toUpperCase().indexOf(term.toUpperCase()) >= 0;
                });
            }

            $scope.searchedFormulaList = searchedList;
            return $q.when(searchedList);
        };

        (function initialize() {
            $log.debug('mentionInputController.initialize()...');

            // keyValueList is the list of all candidate mention items, searchedKeyValueList is the list filtered by 
            $scope.searchedKeyValueList = angular.copy($scope.keyValueList);
            $scope.searchKeyValue = searchKeyValue;
            $scope.searchedFormulaList = angular.copy($scope.formulaList);
            $scope.searchFormula = searchFormula;
        })();
    }
]);
// twitter-like mention input
// For ment.io, refer to https://github.com/jeff-collins/ment.io
commonModule
    .directive('contenteditable', ['$rootScope', '$translate', 'mentioUtil', function ($rootScope, $translate, mentioUtil) {
        return {
            restrict: 'A', // only activate on element attribute
            require: ['?ngModel', '^?mentionInput'], // get a hold of NgModelController and parent directive
            link: function (scope, element, attrs, ctrl) {
                if (!ctrl) return;

                var ngModel = ctrl[0];
                var mentionInput = ctrl[1];

                // do nothing if no ng-model or not in mention-input directive
                if (!ngModel || !mentionInput) {
                    return;
                }

                var nameStr = $translate.instant('Name');
                var descStr = $translate.instant('Description');
                var keyCodeExp = /@[A-Za-z0-9\.]+?\s/g; // like @VAT.ZPXSE.17
                var formulaExp = /[A-Za-z_]+[A-Za-z0-9_]*\([^\(\)]*\)/g; // like BB("VAT001", 1, 1, 0)
                var tagExp = /<[^>]+?>/g; // like <a>, <span style=''>, <br/>
                //var otherTagExp = /(?!<pre(>|<\/>|\s.*>))<[^>]+?>/g; // like <a>, <span style=''>, <br/>

                scope.isValid = true;

                var read = function () {
                    if (mentioUtil.clearEmptyTextNode) {
                        mentioUtil.clearEmptyTextNode(element[0]);
                    }

                    // If show-name is true, replace code with name; otherwise do nothing.
                    var txt = element.text();
                    if (scope.showName) {
                        var pres = element.find('pre').toArray();
                        pres.forEach(function (e) {
                            if (angular.element(e).attr('data-type') === '0') {
                                var code = angular.element(e).attr('data-code');
                                if (code) {
                                    txt = txt.replace(angular.element(e).text(), code + ' ');
                                }
                            }
                        });
                    }

                    if (txt) { // replace &nbsp; and \r, \n if exist
                        txt = txt.replace(/\xA0/g, ' ').replace(/\n/g, '').replace(/\r/g, '');
                        txt = _.unescape(txt);
                    }

                    ngModel.$setViewValue(txt);
                };

                var customValidator = function (ngModelValue) {
                    if (_.isFunction(scope.customValidator)) {
                        scope.isValid = scope.customValidator({
                            'value': ngModelValue,
                            'ngModel': ngModel
                        });
                    }

                    return ngModelValue;
                };

                ngModel.$parsers.unshift(customValidator);
                ngModel.$formatters.unshift(customValidator);

                // Specify how UI should be updated
                ngModel.$render = function () {
                    // trans between $viewValue and element html
                    // $viewValue sample: @CH.BQ.QCYE +@VAT.ZPXSE.17
                    // element html sample:<pre>@CH.BQ.QCYE </pre>+<pre>@VAT.ZPXSE.17 </pre>
                    var viewValue = ngModel.$viewValue;
                    viewValue = _.escape(viewValue);
                    var matches = viewValue ? viewValue.match(keyCodeExp) : [];
                    if (matches) {
                        matches = _.uniq(matches);
                        matches.forEach(function (m) {
                            var patt = new RegExp(m, "g");
                            var item;
                            if (!_.isEmpty(scope.keyValueList)) {
                                item = _.findWhere(scope.keyValueList, { code: $.trim(m) });
                            }

                            if (!_.isEmpty(item) && !_.isEmpty(item.code)) {
                                if (scope.showName) {
                                    viewValue = viewValue.replace(patt, '<pre data-type="0" title="' + item.description
                                        + '" data-code="' + item.code + '" contenteditable="false">' + '@' + item.name + ' </pre>');
                                }
                                else {
                                    viewValue = viewValue.replace(patt, '<pre data-type="0" title="' + nameStr + ':' + item.name + '&#10;'
                                        + descStr + ':' + item.description + '" contenteditable="false">' + item.code + ' </pre>');
                                }
                            }
                            else {
                                viewValue = viewValue.replace(patt, '<pre data-type="0" contenteditable="false">' + $.trim(m) + ' </pre>');
                            }
                        });
                    }

                    matches = viewValue ? viewValue.match(formulaExp) : [];
                    if (matches) {
                        matches.forEach(function (m) {
                            var firstBracketIdx = m.indexOf('(');
                            var formulaName = m.substring(0, firstBracketIdx);
                            var paramStr = m.substring(firstBracketIdx + 1);
                            var item;
                            if (!_.isEmpty(scope.formulaList)) {
                                item = _.findWhere(scope.formulaList, { code: formulaName });
                            }

                            if (!_.isEmpty(item) && !_.isEmpty(item.code)) {
                                viewValue = viewValue.replace(m, '<pre data-type="1" data-description="' + item.description + '" data-name="' + item.name
                                    + '" data-code="' + item.code + '" contenteditable="inherit"><span contenteditable="false">'
                                    + item.code + '(</span>' + paramStr + '</pre>');
                            }
                        });
                    }

                    element.html(viewValue || '');
                };

                // Listen for change events to enable binding
                element.on('blur keyup change', function () {
                    if (!$rootScope.$$phase) {
                        scope.$apply(read);
                    }
                    else {
                        read();
                    }
                });
            }
        };
    }])
    .directive('mentionInput', ['$rootScope', '$log', '$translate', 'mentioUtil', 'enums',
    function ($rootScope, $log, $translate, mentioUtil, enums) {
        'use strict';
        $log.debug('mentionInput.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/mention-input/mention-input.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                inputClass: '@',
                inputId: '@',
                ngModelVal: '=ngModel',
                inputReadonly: '=',
                includeBtn: '=',
                showName: '=',
                keyValueList: '=*mentionList',
                formulaList: '=*',
                displayMode: '=?', // input or textarea
                mentionApi: '=?',
                firedName: '=?',
                firedTagType: '=?',
                firedFormulaParams: '=?',
                btnClick: '&',
                btn2Click: '&',
                customValidator: '&',
                doubleClick: '&',
                inputFocus: '&',
                inputBlur: '&'
            },
            controller: 'mentionInputController',
            link: function (scope, element, attr) {
                // Register api functions in internalApi
                // If selectorApi passed is not undefined, we will use it as internalApi
                scope.internalApi = scope.mentionApi || {};
                scope.rangeInfo = {};
                
                var content = element.find('.mention-input-content');
                var nameStr = $translate.instant('Name');
                var descStr = $translate.instant('Description');

                // Set input classes
                var classAttrs = scope.inputClass;
                if (!_.isEmpty(classAttrs)) {
                    content.addClass(classAttrs);
                }

                scope.$watch('inputReadonly', function (newValue, oldValue) {
                    if (!newValue) {
                        content.attr('contenteditable', true);
                    }
                    else if (!oldValue) {
                        content.attr('contenteditable', false);
                    }
                });

                scope.$watch('rangeInfo', function (newValue, oldValue) {
                    if (newValue) {
                        getFiredFormulaInfo();
                    }
                });

                // Build tag for selected key value item
                var getKeyValueText = function (item) {
                    var rtn;
                    if (!_.isEmpty(item) && !_.isEmpty(item.code)) {
                        if (scope.showName) {
                            rtn = '<pre data-type="0" title="' + item.description + '" data-code="' + item.code
                                + '" contenteditable="false">' + '@' + item.name + ' </pre>';
                        }
                        else {
                            rtn = '<pre data-type="0" title="' + nameStr + ':' + item.name + '&#10;' + descStr + ':' + item.description
                                + '" contenteditable="false">' + item.code + ' </pre>';
                        }
                    }
                    else {
                        rtn = '<pre contenteditable="false">' + (item.code || ('@' + item.label)) + ' </pre>';
                    }

                    return rtn;
                };

                // Build tag for selected formula item
                var getFormulaText = function (item) {
                    var rtn;
                    if (!_.isEmpty(item) && !_.isEmpty(item.code)) {
                        rtn = '<pre data-type="1" data-description="' + item.description + '" data-name="' + item.name
                            + '" data-code="' + item.code + '" contenteditable="inherit"><span contenteditable="false">'
                            + item.code + '(</span>)</pre>';
                    }
                    else {
                        rtn = item.code || item.label;
                    }

                    return rtn;
                };

                // multiple types of elements can be selected:
                // <pre contenteditable='false'>@QCYE</pre>
                // <pre contenteditable='inherit'><span contenteditable='false'>BB</span>(1,2,3,4)</pre>
                var getStartEndInfo = function (range) {
                    var rtn = null;

                    if (!range) {
                        var selection = window.getSelection();
                        try {
                            range = selection.getRangeAt(0);
                        }
                        catch (ex) {

                        }

                        if (!range) {
                            return rtn;
                        }
                    }

                    // Only workable with range objects.
                    if (Object.prototype.toString.call(range).indexOf('Range') >= 0) {
                        rtn = {
                            startEle: range.startContainer,
                            endEle: range.endContainer,
                            startOffset: range.startOffset, // The selection offset in the startEle, -1 represents the whole element is selected.
                            endOffset: range.endOffset // The selection offset in the endEle, -1 represents the whole element is selected.
                        }

                        var curNode = rtn.startEle;
                        for (var i = 0; i < 3; i++) {
                            if (!curNode || curNode === content[0]) {
                                break;
                            }

                            curNode = curNode.parentNode;
                        }

                        if (curNode !== content[0]) {
                            rtn.startEle = null;
                            rtn.startOffset = -1;
                        }

                        curNode = rtn.endEle;
                        for (var i = 0; i < 3; i++) {
                            if (!curNode || curNode === content[0]) {
                                break;
                            }

                            curNode = curNode.parentNode;
                        }

                        if (curNode !== content[0]) {
                            rtn.endEle = null;
                            rtn.endOffset = -1;
                        }

                        // End element in the range is the contenteditable div itself
                        // That means the real end element is the last element on or before the endOffset.
                        if (rtn.endEle === content[0]) {
                            rtn.endEle = rtn.endOffset <= 0
                                ? null : rtn.endEle.childNodes[rtn.endOffset - 1];
                            rtn.endOffset = -1;
                        }

                        // Ignore empty #text
                        while (rtn.endEle && rtn.endEle.nodeType === enums.domNodeType.text
                            && rtn.endEle.nodeValue === '') {
                            rtn.endEle = rtn.endEle.previousSibling;
                            rtn.endOffset = -1;
                        }

                        // #text not empty , get its parent. If parent is not contenteditable div itself,
                        // set endEle to the parent element.
                        if (rtn.endEle && rtn.endEle.nodeType === enums.domNodeType.text) {
                            var parentEle = rtn.endEle.parentNode;
                            if (!parentEle.isContentEditable) {
                                // For IE, the startContainer/endContainer are always #text
                                // even if actually it is an element
                                rtn.endEle = parentEle;
                            }
                            else if (rtn.endOffset === 0 && parentEle === content[0]) {
                                // endOffset === 0 means the #text is next to the real endEle
                                rtn.endEle = rtn.endEle.previousSibling;
                                if (rtn.endEle) {
                                    if (rtn.endEle.nodeType === enums.domNodeType.text) {
                                        rtn.endOffset = rtn.endEle.length;
                                    }
                                    else {
                                        rtn.endOffset = -1;
                                    }
                                }
                            }
                            else if (rtn.endOffset < 0) {
                                // endOffset < 0 means the range.endOffset is actually the offset of #text in its parent
                                // set endOffset to the end of #text
                                rtn.endOffset = rtn.endEle.length;
                            }
                        }

                        // Start element in the range is the contenteditable div itself
                        // That means the real start element is the first element on or after the startOffset.
                        if (rtn.startEle === content[0]) {
                            rtn.startEle = rtn.startOffset >= rtn.startEle.childNodes.length
                                ? null : rtn.startEle.childNodes[rtn.startOffset];
                            rtn.startOffset = -1;
                        }

                        // Ignore empty #text
                        while (rtn.startEle && rtn.startEle.nodeType === enums.domNodeType.text
                            && rtn.startEle.nodeValue === '') {
                            rtn.startEle = rtn.startEle.nextSibling;
                            rtn.startOffset = -1;
                        }

                        // #text not empty , get its parent. If parent is not contenteditable div itself,
                        // set startEle to the parent element.
                        if (rtn.startEle && rtn.startEle.nodeType === enums.domNodeType.text) {
                            var parentEle = rtn.startEle.parentNode;
                            if (!parentEle.isContentEditable) {
                                // For IE, the startContainer/endContainer are always #text
                                // even if actually it is an element
                                rtn.startEle = parentEle;
                            }
                            else if (rtn.startOffset === rtn.startEle.length && parentEle === content[0]) {
                                // startOffset === startEle.length means the #text is previous to the real startEle
                                rtn.startEle = rtn.startEle.nextSibling;
                                if (rtn.startEle) {
                                    if (rtn.startEle.nodeType === enums.domNodeType.text) {
                                        rtn.startOffset = 0;
                                    }
                                    else {
                                        rtn.startOffset = -1;
                                    }
                                }
                            }
                            else if (rtn.startOffset < 0) {
                                // startOffset < 0 means the range.startOffset is actually the offset of #text in its parent
                                // set startOffset to the start of #text
                                rtn.startOffset = 0;
                            }
                        }
                    }

                    return rtn;
                };

                var getFiredFormulaInfo = function () {
                    if (!attr.firedName || !attr.firedFormulaParams) {
                        return;
                    }

                    var selection = window.getSelection();
                    var range;
                    try {
                        range = selection.getRangeAt(0);
                    }
                    catch (ex) {

                    }

                    if (!range) {
                        getFiredFormulaByElement(null);
                        return;
                    }

                    $log.debug(range);

                    var startEndInfo = getStartEndInfo(range);

                    $log.debug(startEndInfo);

                    if (!startEndInfo) {
                        getFiredFormulaByElement(null);
                        return;
                    }

                    if (startEndInfo.startEle && startEndInfo.startEle.parentNode !== content[0]) {
                        startEndInfo.startEle = startEndInfo.startEle.parentNode;
                    }

                    if (startEndInfo.endEle && startEndInfo.endEle.parentNode !== content[0]) {
                        startEndInfo.endEle = startEndInfo.endEle.parentNode;
                    }

                    if (range.startContainer !== range.endContainer
                        && startEndInfo.startEle !== startEndInfo.endEle) {
                        getFiredFormulaByElement(null);
                    }
                    else if (range.startContainer === range.endContainer) { // caret between two elements
                        if (startEndInfo.endEle && startEndInfo.endEle.nodeType !== enums.domNodeType.text) {
                            getFiredFormulaByElement(startEndInfo.endEle);
                        }
                        else if (startEndInfo.startEle && startEndInfo.startEle.nodeType !== enums.domNodeType.text) {
                            getFiredFormulaByElement(startEndInfo.startEle);
                        }
                        else {
                            getFiredFormulaByElement(null);
                        }
                    }
                    else if (startEndInfo.endEle && startEndInfo.endEle.nodeType !== enums.domNodeType.text) { // Same element, not #text
                        getFiredFormulaByElement(startEndInfo.endEle);
                    }
                    else {
                        getFiredFormulaByElement(null);
                    }
                };

                var getFiredFormulaByElement = function (ele) {
                    if (!ele) {
                        scope.firedName = '';
                        scope.firedFormulaParams = '';
                        scope.firedTag = null;
                    }
                    else {
                        var wrappedEle = angular.element(ele);
                        if (wrappedEle.attr('data-type') === '1') {
                            var firedFormulaParams = wrappedEle.text();
                            var firstBracketPos = firedFormulaParams.indexOf('(');
                            if (firstBracketPos > 0) {
                                scope.firedName = wrappedEle.attr('data-code');
                                firedFormulaParams = firedFormulaParams.substring(firstBracketPos + 1, firedFormulaParams.length);
                                scope.firedFormulaParams = firedFormulaParams;
                                scope.firedTag = ele;
                                scope.firedTagType = wrappedEle.attr('data-type');
                            }
                            else {
                                scope.firedName = '';
                                scope.firedFormulaParams = '';
                                scope.firedTag = null;
                            }
                        }
                        else {
                            var firedName = wrappedEle.attr('data-code');
                            if (firedName && firedName.length > 1 && firedName.charAt(0) === '@') {
                                firedName = firedName.substring(1);
                                scope.firedName = firedName;
                                scope.firedFormulaParams = '';
                                scope.firedTag = ele;
                                scope.firedTagType = wrappedEle.attr('data-type');
                            }
                        }
                    }
                };

                var deleteRange = function (startEndInfo) {
                    if (startEndInfo && startEndInfo.startEle && startEndInfo.endEle) {
                        // If part of the range is out of the editor, block this operation.
                        if (startEndInfo.startEle.parentNode !== content[0]
                            && (!startEndInfo.startEle.parentNode || startEndInfo.startEle.parentNode.parentNode !== content[0])
                            || startEndInfo.endEle.parentNode !== content[0]
                            && (!startEndInfo.endEle.parentNode || startEndInfo.endEle.parentNode.parentNode !== content[0])) {
                            return;
                        }

                        var startEle = startEndInfo.startEle;
                        var startOffset = startEndInfo.startOffset;
                        var endEle = startEndInfo.endEle;
                        var endOffset = startEndInfo.endOffset;

                        // Delete the elements between start element and end element
                        // If start element and end element are not in the same level or not in same parent, treat both children of content[0].
                        if (startEle.parentNode !== content[0] && endEle.parentNode !== content[0] && startEle.parentNode !== endEle.parentNode) {
                            startEle = startEle.parentNode;
                            endEle = endEle.parentNode;
                        }
                        else if (startEle.parentNode !== content[0] && endEle.parentNode === content[0]) {
                            startEle = startEle.parentNode;
                        }
                        else if (endEle.parentNode !== content[0] && startEle.parentNode === content[0]) {
                            endEle = endEle.parentNode;
                        }

                        var curEle = startEle;
                        var toDeleteNodes = [];
                        if (curEle !== endEle) {
                            while (curEle.nextSibling !== endEle && curEle.nextSibling) {
                                curEle = curEle.nextSibling;
                                toDeleteNodes.push(curEle);
                            }

                            toDeleteNodes.forEach(function (n) {
                                if (n.parentNode === content[0]) {
                                    n.parentNode.removeChild(n);
                                }
                            });
                        }

                        // If selection is in a #text node, delete the selected content
                        if (startEle.nodeType === enums.domNodeType.text
                            && startEle === endEle) {
                            startEle.deleteData(startOffset, endOffset - startOffset);
                        }
                        else {
                            // If selection start or end is not #text, just delete the element directly; otherwise delete the selected content
                            if (startEle.nodeType !== enums.domNodeType.text) {
                                if (startEle.parentNode === content[0]) {
                                    content[0].removeChild(startEle);
                                }
                                else if (startEle.parentNode && startEle.parentNode.parentNode === content[0]) {
                                    content[0].removeChild(startEle.parentNode);
                                }
                            }
                            else {
                                startEle.deleteData(startOffset, startEle.length - startOffset);
                            }

                            if (endEle.nodeType !== enums.domNodeType.text) {
                                if (endEle.parentNode === content[0]) {
                                    content[0].removeChild(endEle);
                                }
                                else if (endEle.parentNode && endEle.parentNode.parentNode === content[0]) {
                                    content[0].removeChild(endEle.parentNode);
                                }
                            }
                            else {
                                endEle.deleteData(0, endOffset);
                            }
                        }
                    }
                };

                // <div contenteditable>""|"text1"|""|<pre>"" "preText" "" "" </pre>|""|" "|"" </div>
                var handleBackspace = function (e) {
                    e.preventDefault();
                    var selection = window.getSelection();
                    var range;
                    try {
                        range = selection.getRangeAt(0);
                    }
                    catch (ex) {

                    }

                    var startEndInfo = getStartEndInfo(range);
                    if (startEndInfo) {
                        // selection type is caret
                        if (range.startContainer === range.endContainer
                            && range.startOffset === range.endOffset
                            && startEndInfo.endEle) {

                            if (startEndInfo.endEle.nodeType === enums.domNodeType.text) {
                                if (startEndInfo.endOffset > 0) { // Delete character before caret
                                    startEndInfo.endEle.deleteData(startEndInfo.endOffset - 1, 1);
                                }
                            }
                            else {
                                if (startEndInfo.endEle.parentNode === content[0]) {
                                    content[0].removeChild(startEndInfo.endEle);
                                }
                                else if (startEndInfo.endEle.parentNode
                                    && startEndInfo.endEle.parentNode.parentNode === content[0]) {
                                    content[0].removeChild(startEndInfo.endEle.parentNode);
                                }
                            }
                        }
                        else { // selection type is range
                            deleteRange(startEndInfo);
                        }
                    }

                    content.trigger('keyup');
                };

                var handleDelete = function (e) {
                    e.preventDefault();
                    var selection = window.getSelection();
                    var range;
                    try {
                        range = selection.getRangeAt(0);
                    }
                    catch (ex) {

                    }

                    var startEndInfo = getStartEndInfo(range);
                    if (startEndInfo) {
                        // selection type is caret
                        if (range.startContainer === range.endContainer
                            && range.startOffset === range.endOffset
                            && startEndInfo.startEle) {

                            if (startEndInfo.startEle.nodeType === enums.domNodeType.text) {
                                if (startEndInfo.startOffset < startEndInfo.startEle.length) { // Delete character after caret
                                    startEndInfo.startEle.deleteData(startEndInfo.startOffset, 1);
                                }
                            }
                            else {
                                if (startEndInfo.startEle.parentNode === content[0]) {
                                    content[0].removeChild(startEndInfo.startEle);
                                }
                                else if (startEndInfo.startEle.parentNode
                                    && startEndInfo.startEle.parentNode.parentNode === content[0]) {
                                    content[0].removeChild(startEndInfo.startEle.parentNode);
                                }
                            }
                        }
                        else { // selection type is range
                            deleteRange(startEndInfo);
                        }
                    }

                    content.trigger('keyup');
                };

                var isValid = function () {
                    return scope.isValid;
                };

                if (scope.internalApi) {
                    scope.internalApi.isValid = isValid;
                    scope.internalApi.triggerValidator = function (val, field) {
                        if (_.isFunction(scope.customValidator)) {
                            scope.isValid = scope.customValidator({
                                'value': val,
                                'ngModel': field
                            });
                        }
                    };
                }

                content.bind('keydown', function (e) {
                    if (scope.inputReadonly) {
                        return;
                    }

                    // Clear empty text node in contenteditable to make sure mentio work.
                    // And after empty text been cleared, Enter does not work issue is fixed. Why???
                    mentioUtil.clearEmptyTextNode(content[0]);

                    // Since backspace in IE11 will delete characters in contenteditable="false" elements,
                    // we have to add custom backspace handler.
                    switch (e.keyCode) {
                        case enums.keyCode.enter: // prevent the default behaviour of return key pressed
                            e.preventDefault();
                            break;
                        case enums.keyCode.backspace:
                            handleBackspace(e);
                            break;
                        case enums.keyCode.delete:
                            handleDelete(e);
                            break;
                        default:
                            break;
                    }
                });

                // Fix issue - <pre contenteditable="false"></pre> can be modified in IE11
                content.bind('keypress', function (e) {
                    if (scope.inputReadonly || e.ctrlKey || e.metaKey || e.altKey) {
                        return;
                    }

                    var selection = window.getSelection();
                    var range;
                    try {
                        range = selection.getRangeAt(0);
                    }
                    catch (ex) {

                    }

                    var startEndInfo = getStartEndInfo(range);
                    if (startEndInfo && startEndInfo.endEle) {
                        // selection type is caret
                        if (range.startContainer === range.endContainer
                            && range.startOffset === range.endOffset) {
                            // caret is not in #text, but after or in a <pre> node in contenteditable
                            if (startEndInfo.endEle.nodeType !== enums.domNodeType.text
                                && startEndInfo.endEle.parentNode === content[0]) {
                                // caret after <span> node in <pre> node, only appear in IE.
                                if (startEndInfo.endOffset === 1
                                    && startEndInfo.childNodes
                                    && startEndInfo.childNodes[0] !== enums.domNodeType.text) {
                                    return;
                                }

                                // Find the offset of the node in contenteditable
                                var offset = -1;
                                for (offset = 0; offset < content[0].childNodes.length; offset++) {
                                    var n = content[0].childNodes[offset];
                                    if (n === startEndInfo.endEle) {
                                        break;
                                    }
                                }

                                if (offset < 0) {
                                    // Cannot find the node offset, it may not be in the contenteditable
                                    return;
                                }

                                // caret is at the beginning of editable <pre> node, only appear in IE.
                                if (startEndInfo.endOffset === 0 && offset === 0 && startEndInfo.endEle.childNodes.length > 0
                                    && startEndInfo.endEle.childNodes[0] !== enums.domNodeType.text) {
                                    // Add the key to the left of the node.
                                    //e.preventDefault();
                                    var txtNode = document.createTextNode('\xA0');
                                    //var newRange = document.createRange();
                                    var maxLength = content[0].childNodes ? content[0].childNodes.length : 0;
                                    range.setStart(content[0], 0);
                                    range.setEnd(content[0], 0);
                                    range.insertNode(txtNode);
                                    range.collapse(false);
                                    range = range.cloneRange();
                                    range.setStart(txtNode, 0);
                                    range.setEnd(txtNode, txtNode.length);
                                    //range.collapse(true);
                                    selection.removeAllRanges();
                                    selection.addRange(range);
                                }
                                else {
                                    // Add the key to the right of the node.
                                    //e.preventDefault();
                                    var txtNode = document.createTextNode('\xA0');
                                    //var newRange = document.createRange();
                                    var maxLength = content[0].childNodes ? content[0].childNodes.length : 0;
                                    range.setStart(content[0], maxLength > offset ? (offset + 1) : maxLength);
                                    range.setEnd(content[0], maxLength > offset ? (offset + 1) : maxLength);
                                    range.insertNode(txtNode);
                                    range.collapse(false);
                                    range = range.cloneRange();
                                    range.setStart(txtNode, 0);
                                    range.setEnd(txtNode, txtNode.length);
                                    //range.collapse(true);
                                    selection.removeAllRanges();
                                    selection.addRange(range);
                                }
                            }
                            // caret is in #text, but in the end of the text node in editable <pre> node in contenteditable
                            else if (startEndInfo.endEle.nodeType === enums.domNodeType.text
                                && startEndInfo.endEle.parentNode
                                && startEndInfo.endEle.parentNode.parentNode === content[0]
                                && startEndInfo.endEle.length === range.endOffset) {
                                // Find the offset of the node in contenteditable
                                var offset = -1;
                                for (offset = 0; offset < content[0].childNodes.length; offset++) {
                                    var n = content[0].childNodes[offset];
                                    if (n === startEndInfo.endEle.parentNode) {
                                        break;
                                    }
                                }

                                if (offset < 0) {
                                    // Cannot find the node offset, it may not be in the contenteditable
                                    return;
                                }

                                // Add the key to the right of the node.
                                //e.preventDefault();
                                var txtNode = document.createTextNode('\xA0');
                                //var newRange = range.cloneRange();
                                var maxLength = content[0].childNodes ? content[0].childNodes.length : 0;
                                range.setStart(content[0], maxLength > offset ? (offset + 1) : maxLength);
                                range.setEnd(content[0], maxLength > offset ? (offset + 1) : maxLength);
                                range.insertNode(txtNode);
                                range.collapse(false);
                                range = range.cloneRange();
                                range.setStart(txtNode, txtNode.length);
                                range.collapse(true);
                                selection.removeAllRanges();
                                selection.addRange(range);
                            }
                            // caret is at the beginning of <span> node in editable <pre>, only appear in IE.
                            else if (startEndInfo.endEle.nodeType !== enums.domNodeType.text
                                && startEndInfo.endEle.parentNode
                                && startEndInfo.endEle.parentNode.parentNode === content[0]
                                && 0 === range.endOffset) {
                                // Find the offset of the node in contenteditable
                                var offset = -1;
                                for (offset = 0; offset < content[0].childNodes.length; offset++) {
                                    var n = content[0].childNodes[offset];
                                    if (n === startEndInfo.endEle.parentNode) {
                                        break;
                                    }
                                }

                                if (offset < 0) {
                                    // Cannot find the node offset, it may not be in the contenteditable
                                    return;
                                }

                                // Add the key to the left of <pre> node.
                                //e.preventDefault();
                                var txtNode = document.createTextNode('\xA0');
                                //var newRange = document.createRange();
                                range.setStart(content[0], offset);
                                range.setEnd(content[0], offset);
                                range.insertNode(txtNode);
                                range.collapse(false);
                                range = range.cloneRange();
                                range.setStart(txtNode, offset);
                                range.setEnd(txtNode, offset + txtNode.length);
                                //range.collapse(true);
                                selection.removeAllRanges();
                                selection.addRange(range);
                            }
                        }
                        else if (startEndInfo.startEle.nodeType !== enums.domNodeType.text
                            || startEndInfo.endEle.nodeType !== enums.domNodeType.text) {
                            // selection type is range and startEle or EndEle is not #text,
                            // then prevent the operation.
                            e.preventDefault();
                        }
                    }
                });

                var onDoubleClick = function () {
                    if (_.isFunction(scope.doubleClick)) {
                        if (_.isEmpty(scope.firedTag)) {
                            $log.debug('dblclick event: get fired formula');
                            getFiredFormulaInfo();
                        }

                        scope.doubleClick({
                            '$event': {
                                tagInfo: scope.firedTag,
                                name: scope.firedName,
                                formulaParams: scope.firedFormulaParams,
                                tagType: scope.firedTagType
                            }
                        });
                    }
                };

                // Block pasting elements
                content.bind('paste', function (e) {
                    e.preventDefault();
                    if (scope.inputReadonly) {
                        return;
                    }

                    var text = null;
                    if (window.clipboardData && clipboardData.setData) {
                        // IE
                        text = window.clipboardData.getData('text');
                    } else {
                        text = (e.originalEvent || e).clipboardData.getData('text/plain');
                    }

                    text = text.replace(/\r/g, '').replace(/\n/g, '');

                    // For IE, only support 11+
                    var selection = window.getSelection();
                    var range;
                    try {
                        range = selection.getRangeAt(0);
                    }
                    catch (ex) {

                    }

                    var startEndInfo = getStartEndInfo(range);
                    if (startEndInfo) {
                        // Block paste operation while selection start or end is not #text node.
                        if (startEndInfo.startEle && startEndInfo.endEle
                            && (startEndInfo.startEle.nodeType !== enums.domNodeType.text
                            || startEndInfo.endEle.nodeType !== enums.domNodeType.text)) {
                            return;
                        }
                        // selection type is not caret, then delete the selected range first.
                        if (range.startContainer !== range.endContainer
                            || range.startOffset !== range.endOffset) {
                            deleteRange(startEndInfo);
                        }

                        var txtNode = document.createTextNode(text);
                        range.insertNode(txtNode);

                        // Preserve the selection
                        range = range.cloneRange();
                        range.setStart(txtNode, txtNode.length);
                        range.collapse(true);
                        selection.removeAllRanges();
                        selection.addRange(range);
                    }

                    content.trigger('keyup');
                });

                content.bind('focus', function (e) {
                    if (_.isFunction(scope.inputFocus)) {
                        scope.inputFocus({
                            '$event': e
                        });
                    }
                });

                content.bind('blur', function (e) {
                    if (_.isFunction(scope.inputBlur)) {
                        scope.inputBlur({
                            '$event': e
                        });
                    }
                });

                scope.getKeyValueText = getKeyValueText;
                scope.getFormulaText = getFormulaText;
                scope.getFiredFormulaInfo = getFiredFormulaInfo;
                scope.onDoubleClick = onDoubleClick;
            }
        };
    }
]);
commonModule.
controller('menuSelectorController', ['$scope', 'menuService', 
    function ($scope, menuService) {

        //toggle tree node
        $scope.toggleMenu = function (scope) {
            scope.toggle();
        };

        function FindParentMenu(menus, id) {
            var parentMenu = null;
            for (var i = 0, len = menus.length; i < len; i++) {
               
                if (menus[i].id === id) {
                    parentMenu = menus[i];
                    break;
                } else if (menus[i].subMenus && menus[i].subMenus.length > 0)
                {                     
                    parentMenu = FindParentMenu(menus[i].subMenus, id);
                    if (parentMenu != null)
                        break;
                }
            }           
            return parentMenu;
        };

        function CheckedParentMenu(menus, id) {
            var parentObj = FindParentMenu(menus, id);

            if (parentObj) {
                var allCheck = true;
                for (var i = 0, len = parentObj.subMenus.length; i < len; i++) {
                    if (!parentObj.subMenus[i].isChecked) {
                        allCheck = false;
                        break;
                    }
                }
                if (allCheck) {
                    parentObj.isChecked = true;
                    $scope.checkedMenusNameSet[id] = parentObj.name;
                    if (parentObj.parentID && $.inArray(parentObj.parentID + "", $scope.selectedMenuCodes) === -1) {
                        CheckedParentMenu($scope.menuData, parentObj.parentID);
                    }
                }

            } else {
                console.error("Not found the parent authority.");
            }
        };

        function UnCheckParentMenu(menus, id) {

            var parentObj = FindParentMenu(menus, id);
            if (parentObj) {
                parentObj.isChecked = false;
                delete $scope.checkedMenusNameSet[id];
                if (parentObj.parentID && $.inArray(parentObj.parentID + "", $scope.selectedMenuCodes) !== -1) {
                    UnCheckParentMenu($scope.menuData, parentObj.parentID);

                }
            } else {
                console.error("Not found the parent authority.");
            }

        };

        $scope.toggleMenuSub = function (menu) {
            if (menu.isChecked) {
                $scope.checkedMenusNameSet[menu.id] = menu.name;
                if (menu.parentID && $.inArray(menu.parentID + "", $scope.selectedMenuCodes) === -1) {
                    CheckedParentMenu($scope.menuData, menu.parentID);
                }
            }
            else {

                delete $scope.checkedMenusNameSet[menu.id];
                //if the menu is child menu, and parent menu is checked, need to uncheck parent menu
                if (menu.parentID && $.inArray(menu.parentID + "", $scope.selectedMenuCodes) !== -1) {
                    UnCheckParentMenu($scope.menuData, menu.parentID);
                }
            }

            $scope.selectedMenuCodes = _.keys($scope.checkedMenusNameSet);
            $scope.selectedMenuNames = _.values($scope.checkedMenusNameSet);

            if (!menu.subMenus) {
                return;
            }
            menu.subMenus.forEach(function (d) {
                d.isChecked = menu.isChecked;
                $scope.toggleMenuSub(d);
            });
        };

        $scope.getSelectedOrgDisplayText = function () {
            if ($scope.selectedMenuNames !== "") {
                return $scope.selectedMenuNames;
            }
            else {
                return '';
            }
        };

        function checkSelectMenu(menuArray) {

            menuArray.forEach(function (menu) {
                if ($scope.selectedMenuNames.indexOf(menu.name) > -1) {
                    menu.isChecked = true; // drop dirty data: $scope.$digest();                  
                  
                    $scope.checkedMenusNameSet[menu.id] = menu.name;

                }
                if (menu.subMenus && menu.subMenus.length > 0) {
                    checkSelectMenu(menu.subMenus);
                }
            });
            $scope.selectedMenuCodes = _.keys($scope.checkedMenusNameSet);
            $scope.selectedMenuNames = _.values($scope.checkedMenusNameSet);
        }

        //fix issue: when re-create dialog, the menu check still keep last status, not refresh;
        $scope.updateMenuChecked = function () {
           
            $scope.checkedMenusNameSet = {};
            //clear all checked status
            $scope.menuData.forEach(function (menu) {
                menu.isChecked = false;
                if (!menu.subMenus || menu.subMenus.length === 0) {
                    return;
                }
                menu.subMenus.forEach(function (subMenu) {

                    subMenu.isChecked = false;

                });

            });
            if ($scope.selectedMenuNames && $scope.selectedMenuNames.length > 0) {
                checkSelectMenu($scope.menuData);
            }
           

        };

       
        $scope.$watch('serviceId', function (newValue, oldValue) {
          
            if (newValue === oldValue) {
                return newValue;
            }

            getMenusByService(newValue);
        });

        function getMenusByService(serviceID) {
            if (serviceID != null && angular.isString(serviceID)) {
                menuService.getMenus(serviceID).success(function (menuData) {
                    $scope.menuData = menuData;
                });
            }
        }
        (function () {

            getMenusByService($scope.serviceId);
            //menu property
            $scope.menuData = [];
            $scope.checkedMenusNameSet = {};

        })();

    }
]);

commonModule.directive('menuSelector', ['$log',
    function ($log) {
        'use strict';
        $log.debug('menuSelector.ctor()...');
        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/menu-multi-selector/menu-multi-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                selectedMenuCodes: '=',
                selectedMenuNames: '=',
                serviceId: '=',
                serviceRequired: '&'
            },
            controller: 'menuSelectorController',
            link: function (scope, element) {

                // in dialog
                element.find('.selector-input').on('click', function () {
                    //console.log('click call....')
                    if (scope.serviceId != null && angular.isString(scope.serviceId)) {
                        scope.updateMenuChecked();
                        scope.$digest();
                        element.find('.menu-tree-container').show();
                    } else {
                        scope.serviceRequired();

                    }   
                });
                $(document).on('click', function () {
                    element.find('.menu-tree-container').hide();
                }).on('click', '.menu-tree-wrapper', function (e) {
                    e.stopPropagation();
                }); 
            }
        };
    }
]);
commonModule.controller('modelAnalysisReportIssueFilterController', ['$scope', '$translate', '$uibModal', 'modelConfigurationService', 'vatPreviewService', '$compile', '$q', 'dxDataGridService',
    function ($scope, $translate, $uibModal, modelConfigurationService, vatPreviewService, $compile, $q, dxDataGridService) {
        'use strict';

        $scope.trans = {
            OTNoDataText: $translate.instant('NoDataText')
        };

        var ENTRY_COLUMNS = [
            {
                alignment: "left",
                dataField: "period",
                caption: $translate.instant('AccountVoucher_DataGrid_ColPeriod'),
                //sortIndex: 0,
                //sortOrder: 'asc',
                width: 65
            },
            {
                alignment: "center",
                dataField: "date",
                dataType: "date",
                format: "yyyy-MM-dd",
                caption: $translate.instant('AccountVoucher_DataGrid_ColDate'),
                //sortIndex: 1,
                //sortOrder: 'asc',
                width: 95
            },
            {
                dataField: "group",
                caption: $translate.instant('AccountVoucher_DataGrid_ColGroup'),
                //sortIndex: 2,
                //sortOrder: 'asc',
                width: 180
            },
            {
                dataField: "vid",
                caption: $translate.instant('AccountVoucher_DataGrid_ColVID'),
                //sortIndex: 3,
                //sortOrder: 'asc',
                width: "20%"
            },
            {
                dataField: "summary",
                caption: $translate.instant('AccountVoucher_DataGrid_ColSummary'),
                width: "30%"
            },
            {
                dataField: "acctCodeAndNameShow",
                caption: $translate.instant('AccountVoucher_DataGrid_ColAcctCodeAndNameShow'),
                width: "20%"
            },
            {
                dataField: "stdCodeAndNameShow",
                caption: $translate.instant('AccountVoucher_DataGrid_ColStdCodeAndNameShow'),
                width: "30%"
            },
            {
                dataField: "debit",
                caption: $translate.instant('AccountVoucher_DataGrid_ColDebit'),
                alignment: "right",
                width: 120
            },
            {
                dataField: "credit",
                caption: $translate.instant('AccountVoucher_DataGrid_ColCredit'),
                alignment: "right",
                width: 120
            }
            //{
            //    dataField: "isFiltered",
            //    caption: "过滤",
            //    alignment: "right",
            //    width: 50
            //}
        ];

        var SINGULAR_VOUCHER_COLUMNS = [
            {
                alignment: "left",
                dataField: "summary",
                caption: $translate.instant('AccountVoucher_DataGrid_ColSummary'),
                width: "30%"
            }, {
                alignment: "left",
                dataField: "acctCodeAndNameShow",
                caption: $translate.instant('AccountVoucher_DataGrid_ColAcctCodeAndNameShow'),
                //sortIndex: 0,
                //sortOrder: 'asc',
                width: "35%"
            }, {
                alignment: "left",
                dataField: "stdCodeAndNameShow",
                caption: $translate.instant('AccountVoucher_DataGrid_ColStdCodeAndNameShow'),
                //sortIndex: 1,
                //sortOrder: 'asc',
                width: "35%"
            }, {
                alignment: "right",
                dataField: "debit",
                caption: $translate.instant('AccountVoucher_DataGrid_ColDebit'),
                width: 170
            }, {
                alignment: "right",
                dataField: "credit",
                caption: $translate.instant('AccountVoucher_DataGrid_ColCredit'),
                width: 170
            }];

        var VOUCHER_COLUMNS = [
            {
                dataField: "period",
                caption: $translate.instant('AccountVoucher_DataGrid_ColPeriod'),
                //sortIndex: 0,
                //sortOrder: 'asc',
                width: 130
            }, {
                alignment: "center",
                dataField: "date",
                dataType: "date",
                caption: $translate.instant('AccountVoucher_DataGrid_ColDate'),
                format: "yyyy-MM-dd",
                //sortIndex: 1,
                //sortOrder: 'asc',
                width: 100
            }, {
                dataField: "group",
                caption: $translate.instant('AccountVoucher_DataGrid_ColGroup'),
                //sortIndex: 2,
                //sortOrder: 'asc',
                width: "50%"
            }, {
                dataField: "vid",
                caption: $translate.instant('AccountVoucher_DataGrid_ColVID'),
                //sortIndex: 3,
                //sortOrder: 'asc',
                width: "50%"
            }, {
                dataField: "debitSum",
                caption: $translate.instant('AccountVoucher_DataGrid_ColDebitSum'),
                alignment: "right",
                width: 170
            }, {
                dataField: "creditSum",
                caption: $translate.instant('AccountVoucher_DataGrid_ColCreditSum'),
                alignment: "right",
                width: 170
            }];

        var VOUCHER_DETAIL_COLUMNS = [
            {
                dataField: "summary",
                caption: $translate.instant('AccountVoucher_DataGrid_ColSummary'),
                width: "50%"
            }, {
                dataField: "acctCodeAndNameShow",
                caption: $translate.instant('AccountVoucher_DataGrid_ColAcctCodeAndNameShow'),
                //sortIndex: 1,
                //sortOrder: 'asc',
                width: "25%"
            }, {
                dataField: "stdCodeAndNameShow",
                caption: $translate.instant('AccountVoucher_DataGrid_ColStdCodeAndNameShow'),
                //sortIndex: 0,
                //sortOrder: 'asc',
                width: "25%"
            }, {
                dataField: "debit",
                caption: $translate.instant('AccountVoucher_DataGrid_ColDebit'),
                alignment: "right",
                width: 170
            }, {
                dataField: "credit",
                caption: $translate.instant('AccountVoucher_DataGrid_ColCredit'),
                alignment: "right",
                width: 170
            }];

        var DEFAULT_PAGE_SIZE = 100;

        //加载分录数据
        var loadEntryData = function () {
            var viewModel = $scope.entry;
            var pagingInfo = {
                pageIndex: viewModel.pagingOptions.pageIndex,
                pageSize: viewModel.pagingOptions.pageSize
            };

            //TODO:前台 modelType 与数据中 Model 的 Type 是否一致,此时数据库中存在 Type != 1 & 2 的情况
            var apiFunc = modelConfigurationService.getEntriesModelResultDetail;
            apiFunc($scope.modelId, $scope.serviceTypeId, $scope.modelType, $scope.periodFrom, $scope.periodTo, pagingInfo, $scope.filterIssue, false).then(function (response) {
                var data = response.data;

                viewModel.debitSum = _.reduce(data, function (sum, x) {
                    return sum + ($.isNumeric(x.debit) ? parseFloat(x.debit) : 0);
                }, 0);
                viewModel.debitSum = PWC.round(viewModel.debitSum);

                viewModel.creditSum = _.reduce(data, function (sum, x) {
                    return sum + ($.isNumeric(x.credit) ? parseFloat(x.credit) : 0);
                }, 0);
                viewModel.creditSum = PWC.round(viewModel.creditSum);

                viewModel.entryCount = data.length;
                viewModel.voucherCount = _.keys(_.groupBy(data, function (item) {
                    return item.period + "_" + item.group + "_" + item.vid;
                })).length;

                $.each(data, function (i, row) {
                    row.debit = PWC.round(row.debit, 2);
                    row.credit = PWC.round(row.credit, 2);
                });

                fillSummaryFields(viewModel);

                viewModel.isLoaded = true;

                selectFilteredItems(viewModel.dataGridInstance);

                viewModel.dataSource = data;
            });
        };

        //加载凭证列表数据
        var loadVoucherData = function () {
            var viewModel = $scope.voucher;
            var pagingInfo = {
                pageIndex: viewModel.pagingOptions.pageIndex,
                pageSize: viewModel.pagingOptions.pageSize
            };

            var apiFunc = modelConfigurationService.getEntriesModelResultDetailByVoucher;
            apiFunc($scope.modelId, $scope.serviceTypeId, $scope.modelType, $scope.periodFrom, $scope.periodTo, pagingInfo, $scope.filterIssue).then(function (response) {
                var data = response.data;

                viewModel.debitSum = PWC.round(data.debitSum, 2);
                viewModel.creditSum = PWC.round(data.creditSum, 2);
                viewModel.voucherCount = data.vidCount;
                viewModel.entryCount = data.itemIDCount;

                data.voucherMainList.forEach(function (row) {
                    row.debitSum = PWC.round(row.debitSum, 2);
                    row.creditSum = PWC.round(row.creditSum, 2);
                });

                fillSummaryFields(viewModel);

                viewModel.isLoaded = true;

                selectFilteredItems(viewModel.dataGridInstance);

                viewModel.dataSource = data.voucherMainList;
            });
        };

        //加载单凭证数据(弹出框 & 凭证列表明细表)
        var loadSingularVoucherDetailData = function (period, voucherNum, group) {
            var apiFunc = modelConfigurationService.getEntriesByVoucher;
            return apiFunc($scope.modelId, $scope.serviceTypeId, $scope.modelType, $scope.periodFrom, $scope.periodTo, period, voucherNum, group, $scope.filterIssue).then(function (response) {
                var data = response.data;

                $.each(data, function (i, item) {
                    item.debit = PWC.round(item.debit, 2);
                    item.credit = PWC.round(item.credit, 2);
                });

                return data
            });
        };

        //创建凭证明细 dataGrid 控件(模板)
        var voucherDetailTemplate = function (container, options) {
            var gridOption = $.extend(true, {}, dxDataGridService.BASIC_GRID_OPTIONS, {
                columns: VOUCHER_DETAIL_COLUMNS,
                dataSource: new DevExpress.data.CustomStore({
                    load: function (loadOptions) {
                        return loadSingularVoucherDetailData(options.data.period, options.data.vid, options.data.group);
                    }
                }),
                onRowPrepared: function (e) {
                    if ($scope.filterIssue && e.rowType == 'data' && e.data && e.data.isDoubt === 1)
                        e.rowElement.addClass('entriesHighLight');
                }
            });

            $("<div>").dxDataGrid(gridOption).appendTo(container);
        };

        var fillSummaryFields = function (viewModel) {
            $scope.entryCount = viewModel.entryCount;
            $scope.voucherCount = viewModel.voucherCount;
            $scope.debitSum = viewModel.debitSum;
            $scope.creditSum = viewModel.creditSum;
        };

        var selectFilteredItems = function (gridInstance) {
            if (!$scope.isFilter)
                return;

            var dataSource = gridInstance.getDataSource();

            gridInstance.clearSelection();
            var selectedItems = _.filter(dataSource.store(), function (item) {
                return item.isFiltered === 1
            });
            if (selectedItems && selectedItems.length > 0) {
                gridInstance.selectRows(selectedItems);
            }
        };

        var checkRequestAccessible = function () {
            return !!$scope.modelId
                && !!$scope.modelType
                && !!$scope.periodFrom
                && !!$scope.periodTo
                && !!$scope.serviceTypeId
                && ($scope.displayMode === 1 || $scope.displayMode === 2);
        };

        //根据当前 "参数" 重新加载数据
        var reloadViewModelData = function () {
            var reModel = $scope.displayMode === 1 ? $scope.voucher : $scope.entry;

            //在数据源重新加载数据后,在 load 里面 fillSummaryFields
            if (!reModel.isLoaded) {
                reModel.pagingOptions.pageIndex = 1;
                if (!(!!$scope.modelId && !!$scope.modelType && !!$scope.periodFrom && !!$scope.periodTo && !!$scope.serviceTypeId && ($scope.displayMode === 1 || $scope.displayMode === 2)))
                    return;

                reModel.getItemsTotalCount();
                $scope.displayMode === 1 ? loadVoucherData() : loadEntryData();
            }
            else {
                fillSummaryFields(reModel);
            }
        };

        $scope.$watchGroup(["modelId", "modelType", "periodFrom", "periodTo", "serviceTypeId"], function (newValue, oldValue) {
            $scope.entry.isLoaded = false;
            $scope.voucher.isLoaded = false;

            reloadViewModelData();
        });

        $scope.$watch("displayMode", function (newValue, oldValue) {
            reloadViewModelData();
        });

        $scope.exportSupported = !!$scope.exportSupported;
        $scope.displayMode = $scope.displayMode || 2;
        $scope.entryCount = 0;
        $scope.voucherCount = 0;
        $scope.debitSum = 0;
        $scope.creditSum = 0;

        /*
        * 为了使切换 "分录" 与 "凭证" 不引起数据重加载,需要注意:
        *   1.summary 数据必须针对 "分录" 与 "凭证" 进行缓存,使切换显示方式时,不用进行远程网络请求
        *   2.分页控件也需要独立设置,切换或进行分页显示时可以"记忆"该模式下的分页信息
        *   3.仅当"分析结果"焦点行发生变化时刷新本模块数据
        *   4.刷新加载数据时仅加载当前显示模式的数据,当切换到的模式下没有数据时,进行数据请求,需要对两个显示方式分别设置 已加载数据的标志值,并在 3 的情景下,重设标志值
        * */

        //分录列表
        $scope.entry = {
            entryCount: 0,
            voucherCount: 0,
            debitSum: 0,
            creditSum: 0,
            dataGridInstance: null,
            dataSource: [],
            dxDataGridOptions: {
                bindingOptions: {
                    dataSource: "entry.dataSource"
                },
                columns: ENTRY_COLUMNS,
                onInitialized: function (e) {
                    $scope.entry.dataGridInstance = e.component;
                    dxDataGridService.fixContentOverflowWithMaxHeight(e.component);
                    dxDataGridService.registerRowDbClick(e.component);
                },
                onRowDbClick: function (e) {
                    $scope.singularVoucher.openEntriesCheckSingularVoucher(e.data.date, e.data.period, e.data.group, e.data.vid);
                },
                onRowPrepared: function (e) {
                    if (!$scope.filterIssue) {
                        if (e.rowType !== 'header' && e.data && e.data.isDoubt === 1)
                            e.rowElement.addClass('entriesHighLight');
                    }
                },
                onSelectionChanged: function (e) {
                    if (!$scope.filterIssue)
                        return;

                    var dataSource = $scope.entry.dxDataGridOptions.dataSource;
                    var selectedItems = [];
                    $.each(e.currentSelectedRowKeys, function (i, selectedItem) {
                        $.each(dataSource._array, function (j, item) {
                            if (item.period === selectedItem.period && item.group === selectedItem.group && item.vid === selectedItem.vid)
                                selectedItems.push(item);
                        });
                    });

                    $scope.entry.dataGridInstance.selectRows(selectedItems);
                }
            },
            isLoaded: false,
            pagingOptions: {
                pageIndex: 1,
                pageSize: DEFAULT_PAGE_SIZE,
                totalItems: 0
            },
            getItemsTotalCount: function () {
                var apiFunc = modelConfigurationService.getEntriesModelResultDetailCount;
                apiFunc($scope.modelId, $scope.serviceTypeId, $scope.modelType, $scope.periodFrom, $scope.periodTo, true).then(function (response) {
                    $scope.entry.pagingOptions.totalItems = response.data;
                });
            }
        };

        //凭证列表
        $scope.voucher = {
            entryCount: 0,
            voucherCount: 0,
            debitSum: 0,
            creditSum: 0,
            dataGridInstance: null,
            dataSource: [],
            dxDataGridOptions: {
                bindingOptions: {
                    dataSource: "voucher.dataSource"
                },
                columns: VOUCHER_COLUMNS,
                masterDetail: {
                    enabled: true,
                    template: voucherDetailTemplate
                },
                onCellPrepared: function (e) {
                    if (e.rowType === "header" && $(e.cellElement).hasClass("dx-command-expand")) {
                        var btn = $("<div class='dx-datagrid-group-closed'></div>");
                        btn.attr("ng-click", "voucher.toggleAllMasterRows($event)");
                        e.cellElement.html($compile(btn)($scope));
                    }
                },
                onInitialized: function (e) {
                    $scope.voucher.dataGridInstance = e.component;
                    dxDataGridService.fixContentOverflowWithMaxHeight(e.component);
                    dxDataGridService.registerRowDbClick(e.component);
                },
                onRowDbClick: function (e) {
                    $scope.singularVoucher.openEntriesCheckSingularVoucher(e.data.date, e.data.period, e.data.group, e.data.vid);
                }
            },
            isLoaded: false,
            pagingOptions: {
                pageIndex: 1,
                pageSize: DEFAULT_PAGE_SIZE,
                totalItems: 0
            },
            getItemsTotalCount: function () {
                var apiFunc = vatPreviewService.voucherSelectAdvancedCount;
                apiFunc('8', true, false, []).then(function (response) {
                    $scope.entry.pagingOptions.totalItems = response.data;
                });
            },
            toggleAllMasterRows: function ($event) {
                var expand = "dx-datagrid-group-closed";
                var collapse = "dx-datagrid-group-opened";
                if ($($event.target).hasClass(expand)) {
                    $scope.voucher.dataGridInstance.expandAll(-1);
                    $($event.target).removeClass(expand);
                    $($event.target).addClass(collapse);
                } else {
                    $scope.voucher.dataGridInstance.collapseAll(-1);
                    $($event.target).removeClass(collapse);
                    $($event.target).addClass(expand);
                }
            }
        };

        //单张凭证详细信息(弹出框)
        $scope.singularVoucher = {
            //凭证日期
            date: null,
            //期间
            period: null,
            //凭证类型
            group: null,
            //凭证号
            voucherNum: null,
            dataGridInstance: null,
            dataSource: [],
            dxDataGridOptions: {
                bindingOptions: {
                    dataSource: "singularVoucher.dataSource"
                },
                columns: SINGULAR_VOUCHER_COLUMNS,
                onInitialized: function (e) {
                    dxDataGridService.fixContentOverflowWithMaxHeight(e.component);
                }
            },
            openEntriesCheckSingularVoucher: function (date, period, group, voucherNum) {
                var singularVoucher = $scope.singularVoucher;
                singularVoucher.date = new Date(date).dateTimeToString("yyyyMMdd");
                singularVoucher.period = period;
                singularVoucher.group = group;
                singularVoucher.voucherNum = voucherNum;
                singularVoucher.modalOpened = false;

                loadSingularVoucherDetailData(period, voucherNum, group).then(function (data) {
                    $scope.singularVoucher.dataSource = data;
                });

                var modalInstance = $uibModal.open({
                    animation: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    backdrop: "static",
                    templateUrl: 'model-analysis-entries-check-singular-voucher.html',
                    scope: $scope,
                    windowClass: "model-analysis-entries-check-singular-voucher"
                });

                singularVoucher.close = function () {
                    modalInstance.dismiss('cancel');
                }
            }
        };

        $scope.exportCurrentPageToExcel = function () {
            console.log("//TODO:尚未实现 exportCurrentPageToExcel");
        };

        $scope.exportAllPageToExcel = function () {
            console.log("//TODO:尚未实现 exportAllPageToExcel");
        };

        (function initialize() {
            $.extend(true, $scope.entry.dxDataGridOptions, dxDataGridService.BASIC_GRID_OPTIONS);
            $.extend(true, $scope.voucher.dxDataGridOptions, dxDataGridService.BASIC_GRID_OPTIONS);
            $.extend(true, $scope.singularVoucher.dxDataGridOptions, dxDataGridService.BASIC_GRID_OPTIONS);
        })();

        //TODO:针对于"总账->明细账"的数据获取,"总账->明细账"的数据获取/count计算/分页/listQueryCondition 等信息获取未实现
        var drillDownDetailVoucherDataLoad = function (pageIndex) {
            var drillDownDetail = $scope.indexAnalysis.drillDownDetail;
            drillDownDetail.curVoucherItemPage = pageIndex;
            drillDownDetail.pagingInfo.pageIndex = pageIndex;
            if (drillDownDetail.displayMode === 1) {
                vatPreviewService.voucherSelectAdvancedByVoucher('8', false, drillDownDetail.pagingInfo, drillDownDetail.listQueryCondition).success(function (listData) {
                    listData.data.debitSum = PWC.round(listData.data.debitSum, 2);
                    listData.data.creditSum = PWC.round(listData.data.creditSum, 2);
                    listData.data.voucherMainList.forEach(function (v) {
                        v.debitSum = PWC.round(v.debitSum, 2);
                        v.creditSum = PWC.round(v.creditSum, 2);
                    });
                    drillDownDetail.dataList = listData.data.voucherMainList;
                    drillDownDetail.voucherCount = listData.data.vidCount;
                    drillDownDetail.entryCount = listData.data.itemIDCount;
                    drillDownDetail.debitSum = listData.data.debitSum;
                    drillDownDetail.creditSum = listData.data.creditSum;
                    //先加载Div
                    $timeout(function () {
                        initIndexDetailVoucherDataGrid();
                    }, 100);

                });
            } else {
                vatPreviewService.voucherSelectAdvancedByEntry('8', false, drillDownDetail.pagingInfo, drillDownDetail.listQueryCondition).success(function (listData) {
                    listData.data.debitSum = PWC.round(listData.data.debitSum, 2);
                    listData.data.creditSum = PWC.round(listData.data.creditSum, 2);
                    listData.data.voucherList.forEach(function (v) {
                        v.debit = PWC.round(v.debit, 2);
                        v.credit = PWC.round(v.credit, 2);
                    });
                    drillDownDetail.dataList = listData.data.voucherList;
                    drillDownDetail.voucherCount = listData.data.vidCount;
                    drillDownDetail.entryCount = listData.data.itemIDCount;
                    drillDownDetail.debitSum = listData.data.debitSum;
                    drillDownDetail.creditSum = listData.data.creditSum;
                    //先加载Div
                    $timeout(function () {
                        initIndexDetailVoucherDataGrid();
                    }, 100);
                });
            }
            computeVoucherItemPage(false);
        };
    }]);

commonModule.directive('modelAnalysisReportIssueFilter', ['$log', function ($log) {
    'use strict';
    return {
        restrict: 'E',
        templateUrl: '/app/common/controls/model-analysis-report-issue-filter/model-analysis-report-issue-filter.html' + '?_=' + Math.random(),
        replace: true,
        scope: {
            exportSupported: "=?",////默认不支持导出
            displayMode: "=?",//默认的显示类型为 2(按凭证显示)
            filterIssue: "=",
            modelId: "=",
            modelType: "=",
            periodFrom: "=",
            periodTo: "=",
            serviceTypeId: "="
        },
        controller: 'modelAnalysisReportIssueFilterController',
        link: function ($scope, $element, $attr) {

        }
    };
}]);
commonModule.controller('modelAnalysisReportController', ['$scope', '$translate', '$uibModal', 'modelConfigurationService', '$compile', '$q', 'dxDataGridService',
    function ($scope, $translate, $uibModal, modelConfigurationService, $compile, $q, dxDataGridService) {
        'use strict';

        $scope.trans = {
            OPCancel: $translate.instant('Cancel'),
            OPConfirm: $translate.instant('Confirm'),
            OPDelete: $translate.instant('Delete'),
            OPDeleteSelected: $translate.instant('DeleteSelected'),
            OPEdit: $translate.instant('Edit'),
            OTAddSuccess: $translate.instant('AddSuccess'),
            OTBoolFalse: $translate.instant('False'),
            OTBoolTrue: $translate.instant('True'),
            OTDeleteConfirm: $translate.instant('ConfirmToDelete'),
            OTDeleteSelected: $translate.instant('DeleteSelected'),
            OTDeleteSuccess: $translate.instant('DeleteSuccess'),
            OTEditSuccess: $translate.instant('EditSuccess'),
            OTNoDataText: $translate.instant('NoDataText'),
            OTSearch: $translate.instant('Search'),
        };

        $scope.isModelBackFill = (typeof $scope.isModelBackFill) === "string" ? $scope.isModelBackFill === "true" : !!$scope.isModelBackFill;

        var ENTRIES_CHECK_COLUMNS = [
            {
                dataField: "showIndex",
                caption: $translate.instant('Model_ColNO'),
                width: "5.5em",
                allowEditing: false,
                alignment: "center",
                visible: !$scope.isModelBackFill
            },
            {
                allowEditing: false,
                alignment: "center",
                dataField: "isException",
                caption: $translate.instant('Model_ColStatus'),
                width: "8em"
            },
            {
                allowEditing: false,
                alignment: "left",
                dataField: "name",
                caption: $translate.instant('ModelName'),
                width: "40%"
            },
            {
                allowEditing: false,
                alignment: "center",
                dataField: "voucherNum",
                caption: $translate.instant('Model_ColVoucherNumberCount'),
                width: "6.5em",
                visible: !$scope.isModelBackFill
            },
            {
                allowEditing: false,
                alignment: "center",
                dataField: "isFilter",
                caption: $translate.instant('Model_ColFilterIssue'),
                width: "6.5em",
                visible: !$scope.isModelBackFill
            },
            {
                allowEditing: false,
                alignment: "center",
                dataField: "voucherDoubts",
                caption: $translate.instant('IssueNumber'),
                width: "5.5em"
            },
            {
                allowEditing: false,
                dataField: "debitRelevantAmt",
                dataType: 'number',
                caption: $translate.instant('Model_ColDebitAcctualAmount'),
                width: "8.5em",
                alignment: "right",
                format: {
                    type: "fixedPoint",
                    precision: 2
                }
            },
            {
                allowEditing: false,
                dataField: "creditRelevantAmt",
                dataType: 'decimal',
                caption: $translate.instant('Model_ColCreditAcctualAmount'),
                width: "8.5em",
                alignment: "right",
                format: {
                    type: "fixedPoint",
                    precision: 2
                }
            },
            {
                allowEditing: false,
                alignment: "left",
                dataField: "description",
                caption: $translate.instant('Model_ColModelDescription'),
                width: "60%",
                visible: !$scope.isModelBackFill
            },
            {
                allowEditing: true,
                alignment: "right",
                dataField: "writeBackData",
                caption: "回填金额",
                dataType: "number",
                width: "8em",
                visible: false,
                format: {
                    type: "fixedPoint",
                    precision: 2
                }
            }
        ];

        var INDEX_ANALYSIS_COLUMNS = [
            {
                alignment: "center",
                dataField: "showIndex",
                caption: $translate.instant('Model_ColNO'),
                width: "5.5em",
                allowEditing: false,
                visible: !$scope.isModelBackFill
            },
            {
                alignment: "center",
                dataField: "isException",
                caption: $translate.instant('Model_ColStatus'),
                width: "8em"
            },
            {
                alignment: "left",
                dataField: "name",
                caption: $translate.instant('ModelName'),
                width: "40%"
            },
            {
                alignment: "center",
                dataField: "mainValue",
                caption: $translate.instant('Model_ColCalculatedValue'),
                width: "6.5em"
            },
            {
                alignment: "left",
                dataField: "description",
                caption: $translate.instant('Model_ColModelDescription'),
                width: "60%",
                visible: !$scope.isModelBackFill
            },
            {
                dataField: "monthExplain",
                caption: $translate.instant('Model_ColMonthlyWarningValue'),
                width: "9.5em",
                alignment: "left"
            },
            {
                alignment: "left",
                dataField: "yearExplain",
                caption: $translate.instant('Model_ColYearWarningValue'),
                width: "9.5em"
            }
        ];

        var INDEX_ANALYSIS_GENERAL_LEDGER_COLUMNS = [
            {
                dataField: "acctCode",
                caption: $translate.instant('AccountVoucher_AccountCode'),
                width: "20%"
            },
            {
                dataField: "accountName",
                caption: $translate.instant('AccountVoucher_AccountName'),
                width: "30%"
            },
            {
                alignment: "center",
                caption: "期初余额",
                columns: [
                    {
                        alignment: "right",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColDebit'),
                        dataField: "begDebitBal",
                        format: {
                            type: "fixedPoint",
                            precision: 2
                        },
                        width: 120
                    },
                    {
                        alignment: "right",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColCredit'),
                        dataField: "begCreditBal",
                        format: {
                            type: "fixedPoint",
                            precision: 2
                        },
                        width: 120
                    }
                ]
            },
            {
                alignment: "center",
                caption: "累计发生额",
                columns: [
                    {
                        alignment: "right",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColDebit'),
                        dataField: "debitBal",
                        format: {
                            type: "fixedPoint",
                            precision: 2
                        },
                        width: 120
                    },
                    {
                        alignment: "right",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColCredit'),
                        dataField: "creditBal",
                        format: {
                            type: "fixedPoint",
                            precision: 2
                        },
                        width: 120
                    }
                ]
            },
            {
                alignment: "center",
                caption: "期末余额",
                columns: [
                    {
                        alignment: "right",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColDebit'),
                        dataField: "endDebitBal",
                        format: {
                            type: "fixedPoint",
                            precision: 2
                        },
                        width: 120
                    },
                    {
                        alignment: "right",
                        caption: $translate.instant('AccountVoucher_DataGrid_ColCredit'),
                        dataField: "endCreditBal",
                        format: {
                            type: "fixedPoint",
                            precision: 2
                        },
                        width: 120
                    }
                ]
            }
        ];

        //检查请求参数是否符合网络请求规范,减少异常的网络访问
        var checkRequestAccessible = function () {
            var accessible = true;
            accessible &= $scope.modelType === 1 || $scope.modelType === 2;
            accessible &= _.isString($scope.categoryId) && !!$scope.categoryId;
            accessible &= _.isString($scope.organizationId) && !!$scope.organizationId;
            accessible &= $.isNumeric($scope.industryId);
            accessible &= $.isNumeric($scope.serviceTypeId);
            accessible &= $.isNumeric($scope.projectYear);
            accessible &= $.isNumeric($scope.periodFrom);
            accessible &= $.isNumeric($scope.periodTo);
            return !!accessible;
        };

        var loadEntriesCheckData = function () {
            var viewModel = $scope.analysisResult.entriesCheck;
            viewModel.dataSource = [];

            var apiFunc = modelConfigurationService.getEntriesModelResultByCategory;
            apiFunc($scope.categoryId, $scope.serviceTypeId, $scope.organizationId, $scope.industryId, $scope.periodFrom, $scope.periodTo).then(function (response) {
                viewModel.dataSource = response.data;
                viewModel.isLoaded = true;
            });
        };

        var loadIndexAnalysisData = function () {
            var viewModel = $scope.analysisResult.indexAnalysis;
            viewModel.dataSource = [];

            var apiFunc = modelConfigurationService.getIndexModelResultByCategory;
            apiFunc($scope.categoryId, $scope.serviceTypeId, $scope.organizationId, $scope.industryId).then(function (response) {
                viewModel.dataSource = response.data;
                viewModel.isLoaded = true;
            });
        };

        //检查请求参数是否符合网络请求规范,减少异常的网络访问
        var checkModelBackFillRequestAccessible = function () {
            var accessible = true;
            accessible &= $scope.modelType === 1 || $scope.modelType === 2;
            accessible &= _.isString($scope.cellDataId) && !!$scope.cellDataId;
            accessible &= $.isArray($scope.modelIdList);
            accessible &= $.isNumeric($scope.projectYear);
            accessible &= $.isNumeric($scope.periodFrom);
            accessible &= $.isNumeric($scope.periodTo);
            return !!accessible;
        };

        var loadModelBackFillEntriesCheckData = function () {
            var viewModel = $scope.analysisResult.entriesCheck;
            viewModel.dataSource = [];

            var paramModel = {
                cellDataId: $scope.cellDataId,
                modelIdList: $scope.modelIdList
            };

            var apiFunc = modelConfigurationService.getEntriesModelResultByCellInfo;
            apiFunc(paramModel).then(function (response) {
                var data = response.data;

                for (var i = 0; i < data.length; i++) {
                    data[i].originalWriteBackData = data[i].writeBackData;
                }

                var hasWriteBackData = _.any(data, function (e) {
                    return !!e.originalWriteBackData;
                });

                if (hasWriteBackData && !!viewModel.dataGridInstance) {
                    viewModel.dataGridInstance.columnOption("writeBackData", "visible", true);
                }

                viewModel.dataSource = data;
                viewModel.isLoaded = true;
            });
        };

        var loadModelBackFillIndexAnalysisData = function () {
            var viewModel = $scope.analysisResult.indexAnalysis;
            viewModel.dataSource = [];

            var apiFunc = modelConfigurationService.getIndexModelResultByCellInfo;
            apiFunc($scope.modelIdList).then(function (reason) {
                viewModel.dataSource = reason.data;
                viewModel.isLoaded = true;
            });
        };

        var loadIndexAnalysisGeneralLedgerData = function () {
            var glViewModel = $scope.indexAnalysisGeneralLedger;
            glViewModel.dataSource = [];

            var apiFunc = modelConfigurationService.getGL;
            apiFunc(glViewModel.resultId, glViewModel.periodFrom, glViewModel.periodTo).then(function (reason) {
                glViewModel.dataSource = reason.data;
            });
        };

        //重新加载所有数据
        var reloadAnalysisResultData = function () {
            $scope.analysisResult.selectedRow = null;

            $scope.analysisResult.entriesCheck.isLoaded = false;
            $scope.analysisResult.entriesCheck.dataSource = [];

            $scope.analysisResult.indexAnalysis.isLoaded = false;
            $scope.analysisResult.indexAnalysis.dataSource = [];

            var checkRst = $scope.isModelBackFill ? checkModelBackFillRequestAccessible() : checkRequestAccessible();
            if (!checkRst)
                return;

            if ($scope.isModelBackFill)
                $scope.modelType === 1 ? loadModelBackFillIndexAnalysisData() : loadModelBackFillEntriesCheckData();
            else
                $scope.modelType === 1 ? loadIndexAnalysisData() : loadEntriesCheckData();
        };

        var calcResizableHeightLimit = function () {
            //计算 dataGrid 能调整的高度
            var viewModel = $scope.analysisResult[($scope.modelType & 1) === 1 ? "indexAnalysis" : "entriesCheck"];
            if ((!viewModel.dataSource) || viewModel.dataSource.length < 1) {
                $scope.analysisResult.height = $scope.element.height();
                $scope.analysisResult.selectedRow = null;
                return;
            }

            var gvMinHeight = 34 + (viewModel.dataSource.length >= 3 ? 3 : viewModel.dataSource.length) * 32;
            var gvMaxHeight = 34 + (viewModel.dataSource.length >= 10 ? 10 : viewModel.dataSource.length) * 32;

            //计算 dxResizable 能调整的高度
            var minHeight = $scope.element.height() - 5 - gvMaxHeight;
            var maxHeight = $scope.element.height() - 5 - gvMinHeight;

            var resizableInstance = $scope.dxResizableOption.dxResizableInstance;
            var opHeight = resizableInstance.option("height");
            var opMaxHeight = resizableInstance.option("maxHeight");
            var opMinHeight = resizableInstance.option("minHeight");
            if (maxHeight !== opMaxHeight)
                resizableInstance.option("maxHeight", maxHeight);

            if (minHeight !== opMinHeight)
                resizableInstance.option("minHeight", minHeight);

            var height = opHeight;
            if (opHeight < minHeight)
                height = minHeight;
            if (opHeight > maxHeight)
                height = maxHeight;
            if (height !== opHeight)
                resizableInstance.option("height", height);
        };

        $scope.$watch("modelType", function (newValue, oldValue) {
            var selectedRows = [];
            var viewModel = $scope.analysisResult;

            if (newValue === 1) {
                if (!viewModel.indexAnalysis.isLoaded) {
                    $scope.isModelBackFill ? loadModelBackFillIndexAnalysisData() : loadIndexAnalysisData();
                }
                else if (!!viewModel.indexAnalysis.dataGridInstance) {
                    selectedRows = viewModel.indexAnalysis.dataGridInstance.getSelectedRowsData();
                }
            }
            else {
                if (!viewModel.entriesCheck.isLoaded) {
                    $scope.isModelBackFill ? loadModelBackFillEntriesCheckData() : loadEntriesCheckData();
                }
                else if (!!viewModel.entriesCheck.dataGridInstance) {
                    selectedRows = viewModel.entriesCheck.dataGridInstance.getSelectedRowsData();
                }
            }

            $scope.analysisResult.selectedRow = selectedRows.length > 0 ? selectedRows[0] : null;
        });

        $scope.$watch("selectedRow", function (newValue, oldValue) {
            calcResizableHeightLimit();
        });

        $scope.$on("EditModelWriteBack", function (event, data) {
            var viewModel = $scope.analysisResult.entriesCheck;
            viewModel.dataGridInstance.option("editing.allowUpdating", true);
            viewModel.dataGridInstance.columnOption("writeBackData", "visible", true);
        });

        $scope.$on("CancelEditModelWriteBack", function (event, data) {
            var viewModel = $scope.analysisResult.entriesCheck;
            var hasWriteBackData = _.any(viewModel.dataSource, function (e) {
                return !!e.originalWriteBackData;
            });

            for (var i = 0; i < viewModel.dataSource.length; i++) {
                viewModel.dataSource[i].writeBackData = viewModel.dataSource[i].originalWriteBackData;
            }

            viewModel.dataGridInstance.option("editing.allowEditing", false);
            viewModel.dataGridInstance.columnOption("writeBackData", "visible", hasWriteBackData);
        });

        $scope.$on("CheckModelWriteBackHasChanged", function (event, data) {
            var viewModel = $scope.analysisResult.entriesCheck;
            viewModel.dataGridInstance.saveEditData();

            if (!$scope.modelDataSourceId)
                $scope.modelDataSourceId = PWC.newGuid();

            var eventData = {cellDataId: $scope.cellDataId, dataSourceId: $scope.modelDataSourceId};
            eventData.haveChanged = _.any(viewModel.dataSource, function (e) {
                return e.originalWriteBackData !== e.writeBackData;
            });

            var originalWriteBackData = _.filter(viewModel.dataSource, function (e) {
                return !!e.originalWriteBackData;
            });
            eventData.originalWriteBackData = [];
            _.each(originalWriteBackData, function (e) {
                eventData.originalWriteBackData.push({key: e.id, value: e.originalWriteBackData});
            });

            var currentWriteBackData = _.filter(viewModel.dataSource, function (e) {
                return !!e.writeBackData;
            });
            eventData.currentWriteBackData = [];
            _.each(currentWriteBackData, function (e) {
                eventData.currentWriteBackData.push({key: e.id, value: e.writeBackData});
            });

            $scope.$emit("ModelWriteBackHasChanged", eventData);

            //提交事件后修改 DataGrid 不能修改
            var hasWriteBackData = _.any(viewModel.dataSource, function (e) {
                return !!e.writeBackData;
            });

            viewModel.dataGridInstance.option("editing.allowEditing", false);
            viewModel.dataGridInstance.columnOption("writeBackData", "visible", hasWriteBackData);
        });

        $scope.dxResizableOption = {
            dxResizableInstance: null,
            width: "100%",
            height: 200,
            minHeight: 0,
            maxHeight: 500,
            handles: "top",
            onInitialized: function (e) {
                $scope.dxResizableOption.dxResizableInstance = e.component;
            },
            onResizeStart: function (e) {
                calcResizableHeightLimit();
            },
            onResize: function (e) {
                //计算 dataGrid 能调整的高度
                var height = $scope.element.height() - 5 - e.height;
                $scope.analysisResult.height = height;
            }
        };

        $scope.analysisResult = {
            entriesCheck: {
                isLoaded: false,
                dataGridInstance: null,
                dataSource: [],
                //在 模型回填中需要用到合计汇总信息
                dxDataGridSummary: {
                    totalItems: [
                        {
                            column: 'voucherDoubts',
                            customizeText: function (data) {
                                return $translate.instant('Subtotal');
                            }
                        },
                        {
                            column: 'debitRelevantAmt',
                            displayFormat: "{0}",
                            summaryType: 'sum',
                            valueFormat: {
                                type: "fixedPoint",
                                precision: 2
                            }
                        },
                        {
                            column: 'creditRelevantAmt',
                            displayFormat: "{0}",
                            summaryType: 'sum',
                            valueFormat: {
                                type: "fixedPoint",
                                precision: 2
                            }
                        },
                        {
                            column: 'writeBackData',
                            displayFormat: "{0}",
                            summaryType: 'sum',
                            valueFormat: {
                                type: "fixedPoint",
                                precision: 2
                            }
                        }
                    ]
                },
                writeBackData: null,
                dxDataGridOptions: {
                    bindingOptions: {
                        dataSource: "analysisResult.entriesCheck.dataSource",
                        height: "analysisResult.height"
                    },
                    columns: ENTRIES_CHECK_COLUMNS,
                    onCellPrepared: function (e) {
                        if (e.rowType != "data")
                            return;

                        if (e.column.dataField === "isException") {
                            $(e.cellElement).html(e.value ? "<span><i class='fa fa-exclamation-circle'></i>系统检测异常</span>" : "<span><i class='fa fa-check-circle'></i>系统检测正常</span>");
                        }

                        if (e.column.dataField === "voucherNum") {
                            $(e.cellElement).html("<span class=\"voucher-num\">" + (e.value > 0 && e.data.isFilter == 1 ? e.value : "-") + "</span>");
                        }

                        if (e.column.dataField === "isFilter") {
                            if (e.data.isFilter == 1 && e.data.voucherNum > 0) {
                                var editorBtn = $("<div class=\"filter-btn\" ng-disabled=\"!hasFilterIssuePermission\"><span class=\"fa fa-ellipsis-h\"></span></div>");
                                editorBtn.attr("ng-click", "vouchersAndEntriesModal.openModal($event,1)");
                                $(e.cellElement).html($compile(editorBtn)($scope));
                            } else {
                                $(e.cellElement).html("<span class=\"voucher-num\">-</span>");
                            }
                        }

                        if (e.column.dataField === "voucherDoubts" && e.value > 0) {
                            $(e.cellElement).html("<div class=\"voucher-doubts\"><span>" + e.value + "</span></div>");
                        }
                    },
                    onInitialized: function (e) {
                        $scope.analysisResult.entriesCheck.dataGridInstance = e.component;
                        dxDataGridService.fixContentOverflowWithMaxHeight(e.component);
                    },
                    onSelectionChanged: function (e) {
                        if (e.selectedRowsData.length < 1)
                            return;

                        var data = e.selectedRowsData[0];

                        $scope.analysisResult.selectedRow = data;

                        $scope.analysisDetailResult.modelName = data.name;
                        $scope.analysisDetailResult.modelDesc = data.description;
                    }
                }
            },
            indexAnalysis: {
                isLoaded: false,
                dataGridInstance: null,
                dataSource: [],
                dxDataGridOptions: {
                    bindingOptions: {
                        dataSource: "analysisResult.indexAnalysis.dataSource",
                        height: "analysisResult.height"
                    },
                    columns: INDEX_ANALYSIS_COLUMNS,
                    onCellPrepared: function (e) {
                        if (e.rowType !== "data")
                            return;

                        if (e.column.dataField === "isException") {
                            $(e.cellElement).html(e.value ? "<span><i class='fa fa-exclamation-circle'></i>系统检测异常</span>" : "<span><i class='fa fa-check-circle'></i>系统检测正常</span>");
                        }
                    },
                    onInitialized: function (e) {
                        $scope.analysisResult.indexAnalysis.dataGridInstance = e.component;
                        dxDataGridService.fixContentOverflowWithMaxHeight(e.component);
                        dxDataGridService.registerRowDbClick(e.component);
                    },
                    onRowDbClick: function (e) {
                        if ($scope.hasQueryPermission) {
                            $scope.indexAnalysisGeneralLedger.openModal(e.data);
                        }
                    },
                    onSelectionChanged: function (e) {
                        if (e.selectedRowsData.length < 1)
                            return;

                        var data = e.selectedRowsData[0];
                        $scope.analysisResult.selectedRow = data;

                        $scope.analysisDetailResult.modelName = data.name;
                        $scope.analysisDetailResult.modelDesc = data.description;

                        var maxSqence = _.max(data.indexAnalysisDetailResults, function (element) {
                            return element.sequence
                        });
                        var resultDetailDataList = [];
                        var searchData = data.indexAnalysisDetailResults;
                        var isShowMonthJudge = !PWC.isNullOrEmpty(data.monthExplain);
                        var tempColumns = [];
                        tempColumns.push({
                            dataField: "period",
                            caption: "期间",
                            width: 70,
                            alignment: "center"
                        });

                        for (var i = 1; i <= 13; i++) {
                            var rowObj = {period: i === 13 ? "年度" : i};

                            for (var m = 1; m <= maxSqence.sequence; m++) {
                                var cellData = _.first(_.filter(searchData, function (element) {
                                    return (element.period === i && element.sequence === m);
                                }));
                                if (cellData) {
                                    if (cellData.displayType === 1 || cellData.displayType === 2) {
                                        rowObj["colmun" + m] = PWC.isNullOrEmpty(cellData.indexResult) ? 0 : parseFloat(cellData.indexResult);
                                    } else if (cellData.displayType === 3) {
                                        rowObj["colmun" + m] = cellData.indexResult === "1" ? '是' : '否';
                                    } else {
                                        rowObj["colmun" + m] = cellData.indexResult;
                                    }
                                    //是否添加月度判断
                                    if (isShowMonthJudge === true && cellData.isMainValue === 1) {
                                        if (i !== 13)
                                            rowObj["monthJudge"] = cellData.isMonExp === 1;
                                        else
                                            rowObj["monthJudge"] = cellData.isYearExp === 1;
                                    }

                                    //动态添加列
                                    if (i === 1) {
                                        var colmun = {};
                                        colmun.dataField = "colmun" + m,
                                            colmun.caption = cellData.indexName;
                                        if (cellData.displayType === 1) {
                                            colmun.format = {
                                                type: "fixedPoint",
                                                precision: 2
                                            };
                                        }
                                        if (cellData.displayType === 2) {
                                            colmun.format = {
                                                type: "percent",
                                                precision: 2
                                            };
                                        }
                                        if (cellData.displayType === 3) {
                                            colmun.format = {
                                                type: "bool",
                                                precision: 2
                                            };
                                        }
                                        tempColumns.push(colmun)
                                    }
                                    //设置基础信息
                                    if (i === 13) {
                                        if (cellData.isMainValue === 1) {
                                            resultDetailDataList.mainColmunName = cellData.indexName;
                                            if (cellData.displayType === 1 || cellData.displayType === 2) {
                                                if (cellData.displayType === 1) {
                                                    resultDetailDataList.mainValue = PWC.isNullOrEmpty(cellData.indexResult) ? PWC.round(0, 2) : PWC.round(cellData.indexResult, 2);
                                                } else {
                                                    resultDetailDataList.mainValue = PWC.isNullOrEmpty(cellData.indexResult) ? PWC.round(0, 2) + "%" : PWC.round(cellData.indexResult * 100, 2) + "%";
                                                }

                                            } else {
                                                $scope.indexResultData.mainValue = cellData.indexResult;
                                            }
                                            if (cellData.displayType === 3) {
                                                resultDetailDataList.yearException = cellData.isYearExp === 1;
                                            }
                                        }
                                    }
                                }
                            }

                            resultDetailDataList.push(rowObj);
                        }
                        //是否添加月度判断
                        if (isShowMonthJudge === true) {
                            var colmunJudge = {};
                            colmunJudge.dataField = "monthJudge";
                            colmunJudge.caption = "异常判断";
                            colmunJudge.dataType = "boolean";
                            colmunJudge.alignment = 'left';
                            tempColumns.push(colmunJudge)
                        }

                        $scope.analysisDetailResult.indexAnalysis.dataGridInstance.option("columns", tempColumns);
                        $scope.analysisDetailResult.indexAnalysis.dataSource = resultDetailDataList;
                    }
                }
            },
            height: null,
            selectedRow: null
        };

        $scope.analysisDetailResult = {
            indexAnalysis: {
                dataGridInstance: null,
                dataSource: [],
                dxDataGridOptions: {
                    bindingOptions: {
                        dataSource: "analysisDetailResult.indexAnalysis.dataSource"
                    },
                    onInitialized: function (e) {
                        $scope.analysisDetailResult.indexAnalysis.dataGridInstance = e.component;
                        dxDataGridService.fixContentOverflowWithMaxHeight(e.component);
                    }
                }
            },
            modelName: "",
            modelDesc: ""
        };

        //"分录比对->问题筛选" & "指标分析->总帐->明细账" 两个弹出框共用该模型
        $scope.vouchersAndEntriesModal = {
            title: null,
            subTitle: null,
            exportSupported: false,
            filterIssue: false,
            modelId: null,
            modelType: null,
            periodFrom: null,
            periodTo: null,
            serviceTypeId: null,
            //usage === 1:分录比对->问题筛选,usage === 2:指标分析->总帐->明细账
            openModal: function (event, usage) {
                var model = $scope.vouchersAndEntriesModal;
                model.filterIssue = usage === 1;
                model.exportSupported = usage === 2;

                if (usage === 1) {
                    model.periodFrom = $scope.periodFrom;
                    model.periodTo = $scope.periodTo;

                    var focusedRowData = $(event.originalEvent.currentTarget).closest("tr.dx-row").data("options").data;
                    model.modelId = focusedRowData.modelID;
                    model.modelType = focusedRowData.type;
                    model.serviceTypeId = focusedRowData.serviceTypeID;

                    model.title = "筛选问题";
                    model.subTitle = $translate.instant("EntryComparison") + ":" + focusedRowData.name;
                }
                else {
                    model.periodFrom = $scope.indexAnalysisGeneralLedger.periodFrom;
                    model.periodTo = $scope.indexAnalysisGeneralLedger.periodTo;

                    //TODO:未实现
                    model.modelId = event.data.balanceId;
                    model.modelType = $scope.modelType;
                    model.serviceTypeId = $scope.serviceTypeId;

                    model.title = "指标分析:";
                    model.subTitle = event.data.accountName + "分析/总帐/明细账";
                }

                var modalInstance = $uibModal.open({
                    animation: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    backdrop: "static",
                    templateUrl: "model-analysis-report-vouchers-and-entries-modal.html",
                    scope: $scope,
                    windowClass: "model-analysis-report-vouchers-and-entries-modal"
                });

                modalInstance.closed.then(function () {
                    if (usage === 1)
                        loadEntriesCheckData();
                });

                model.confirm = function ($event) {
                    if (usage === 1)
                        return;

                    var selectedRows = $(".model-analysis-report-vouchers-and-entries-modal [dx-data-grid]").dxDataGrid("instance").getSelectedRowsData();
                    var filterList = _.groupBy(selectedRows, function (item) {
                        return item.period + "_" + item.group + "_" + item.vid;
                    });

                    filterList = $.map(filterList, function (item) {
                        return {period: item[0].period, group: item[0].group, vid: item[0].vid};
                    });

                    var paramQuery = {};
                    paramQuery.modelId = model.modelId;
                    paramQuery.serviceTypeId = model.serviceTypeId;
                    paramQuery.modelType = model.modelType;
                    paramQuery.entriesList = filterList;
                    paramQuery.period = $scope.period;
                    modelConfigurationService.updateEntriesFiter(paramQuery).then(function (response) {
                        if (response.data.result)
                            modalInstance.close(response.data);
                    });
                };

                model.dismiss = function (reason) {
                    modalInstance.dismiss(reason);
                };
            }
        };

        //"指标分析->总帐" 弹出框模型
        $scope.indexAnalysisGeneralLedger = {
            dataSource: [],
            title: null,
            subTitle: null,
            periodFrom: null,
            periodTo: null,
            resultId: null,
            treeListOptions: {
                allowColumnResizing: true,
                bindingOptions: {
                    dataSource: "indexAnalysisGeneralLedger.dataSource"
                },
                columns: INDEX_ANALYSIS_GENERAL_LEDGER_COLUMNS,
                dataStructure: "plain",
                keyExpr: "acctCode",
                parentIdExpr: "parentCode",
                onCellPrepared: function (e) {
                    if (e.rowType === "header" && e.column.dataField === "acctCode") {
                        var icon = $("<div class=\"dx-treelist-icon-container\"><div class=\"dx-treelist-empty-space\"><span></span></div></div>");
                        icon.find(".dx-treelist-empty-space").addClass("dx-treelist-collapsed");
                        icon.find("span").attr("ng-click", "indexAnalysisGeneralLedger.toggleAllExpanded($event)");
                        e.cellElement.prepend($compile(icon)($scope));
                    }
                },
                onInitialized: function (e) {
                    dxDataGridService.registerRowDbClick(e.component);
                },
                onRowDbClick: function (e) {
                    $scope.vouchersAndEntriesModal.openModal(e, 2);
                }
            },
            openModal: function (indexAnalysisResultRow) {
                var modalInstance = $uibModal.open({
                    animation: false,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    backdrop: "static",
                    templateUrl: 'model-analysis-report-index-analysis-general-ledger-modal.html',
                    scope: $scope,
                    windowClass: "model-analysis-report-index-analysis-general-ledger-modal"
                });

                var glViewModel = $scope.indexAnalysisGeneralLedger;
                glViewModel.title = indexAnalysisResultRow.name;
                glViewModel.periodFrom = $scope.periodFrom;
                glViewModel.periodTo = $scope.periodTo;
                glViewModel.resultId = indexAnalysisResultRow.id;

                loadIndexAnalysisGeneralLedgerData();

                var rangePicker = null;
                modalInstance.rendered.then(function () {
                    //初始化期间选择控件
                    var input = $(".model-analysis-report-index-analysis-general-ledger-modal .modal-body .field .period-range input");
                    var monthList = [
                        $translate.instant('Month01'),
                        $translate.instant('Month02'),
                        $translate.instant('Month03'),
                        $translate.instant('Month04'),
                        $translate.instant('Month05'),
                        $translate.instant('Month06'),
                        $translate.instant('Month07'),
                        $translate.instant('Month08'),
                        $translate.instant('Month09'),
                        $translate.instant('Month10'),
                        $translate.instant('Month11'),
                        $translate.instant('Month12')
                    ];

                    input = input.rangePicker({
                        minDate: [1, $scope.projectYear],
                        maxDate: [12, $scope.projectYear],
                        setDate: [
                            [glViewModel.periodFrom, $scope.projectYear],
                            [glViewModel.periodTo, $scope.projectYear]
                        ],
                        months: monthList,
                        ConfirmBtnText: $translate.instant('Confirm'),
                        CancelBtnText: $translate.instant('ButtonCancel')
                    });
                    input.on('datePicker.done', function (e, result) {
                        $scope.indexAnalysisGeneralLedger.periodFrom = result[0][0];
                        $scope.indexAnalysisGeneralLedger.periodTo = result[1][0];
                        loadIndexAnalysisGeneralLedgerData();
                    });

                    rangePicker = $(input).data("_ranegPicker");
                });

                $scope.indexAnalysisGeneralLedger.dismiss = function (reason) {
                    modalInstance.dismiss(reason);
                    rangePicker.destroy();
                };
            }
        };

        (function initialize() {
            var customOption = {loadPanel: {enabled: false}};
            $.extend(true, $scope.analysisResult.entriesCheck.dxDataGridOptions, dxDataGridService.BASIC_GRID_OPTIONS, customOption);
            $.extend(true, $scope.analysisResult.indexAnalysis.dxDataGridOptions, dxDataGridService.BASIC_GRID_OPTIONS, customOption);
            $.extend(true, $scope.analysisDetailResult.indexAnalysis.dxDataGridOptions, dxDataGridService.BASIC_GRID_OPTIONS);
            $.extend(true, $scope.indexAnalysisGeneralLedger.treeListOptions, dxDataGridService.BASIC_GRID_OPTIONS, {keyExpr: "balanceId"});

            if ($scope.isModelBackFill) {
                $scope.analysisResult.entriesCheck.dxDataGridOptions.editing.mode = "cell";
                $scope.analysisResult.entriesCheck.dxDataGridOptions.summary = $scope.analysisResult.entriesCheck.dxDataGridSummary;

                $scope.$watchGroup(["cellDataId", "projectYear", "periodFrom", "periodTo"], function (newValue, oldValue) {
                    reloadAnalysisResultData();
                });
                $scope.$watchCollection("modelIdList", function (e) {
                    reloadAnalysisResultData();
                });
            }
            else {
                $scope.$watchGroup(["categoryId", "industryId", "organizationId", "serviceTypeId", "projectYear", "periodFrom", "periodTo"], function (newValue, oldValue) {
                    reloadAnalysisResultData();
                });
            }
        })();
    }
]);
commonModule.directive('modelAnalysisReport', ['$log', function ($log) {
    'use strict';
    return {
        restrict: 'E',
        templateUrl: '/app/common/controls/model-analysis-report/model-analysis-report.html' + '?_=' + Math.random(),
        replace: true,
        scope: {
            hasQueryPermission: "=",
            hasFilterIssuePermission: "=",
            modelType: "=",
            projectYear: "=",
            periodFrom: "=",
            periodTo: "=",

            //以下三个参数模型回填特有
            isModelBackFill: "=?",
            cellDataId: "=?",
            modelDataSourceId: "=?",
            modelIdList: "=?",

            //以下四个参数模型分析特有
            categoryId: "=?",
            industryId: "=?",
            organizationId: "=?",
            serviceTypeId: "=?"
        },
        controller: 'modelAnalysisReportController',
        link: function ($scope, $element, $attr) {

            $scope.element = $element;

            //由于 dx-resizable 没有 onContentReady 事件,所以在第一次渲染时进行判断并添加 collapse.png
            $scope.$watch("analysisResult.selectedRow", function (newValue, oldValue) {
                var detailElem = $($element).find(".detail[dx-resizable]");
                var handleElem = detailElem.find(".dx-resizable-handle-top");

                if (handleElem.length > 0 && handleElem.has("img").length == 0) {
                    handleElem.html("<img src='../../../../app-resources/images/collapse.png'/>");
                }

                if ((!!newValue) != (!!oldValue)) {
                    $scope.analysisResult.indexAnalysis.dataGridInstance.resize();
                    $scope.analysisResult.entriesCheck.dataGridInstance.resize();
                }
            });
        }
    };
}]);
// Model select tree view, select multiple models with checkboxes
commonModule.directive('modelMultiSelector', ['$log', '$translate',
    function ($log, $translate) {
        'use strict';
        $log.debug('modelMultiSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/model-multi-selector/model-multi-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                modelDataSource: '=*',
                isShow: '=',
                selectedModelIds: '=',
                title: '=',
                selectorOptions: '=?',
                selectorApi: '=?' // In: onSelectorClose, onSelectorConfirm; Out: getGridInstance
            },
            link: function (scope, element) {
                scope.columnDefs = [{
                    visible: false,
                    caption: $translate.instant('ModelCode'),
                    dataField: 'code'
                }, {
                    caption: $translate.instant('ModelName'),                    
                    dataField: 'name'
                }, {
                    caption: $translate.instant('ModelDescription'),
                    width: '20%',
                    dataField: 'description'
                }, {
                    caption: $translate.instant('ModelFeature'),
                    dataField: 'featureName'
                }, {
                    caption: $translate.instant('ModelType'),
                    dataField: 'modelTypeName'
                }, {
                    caption: $translate.instant('ModelOrganization'),
                    dataField: 'organizationName'
                }, {
                    visible: false,
                    dataField: 'id',
                    isIdentity: true
                }, {
                    visible: false,
                    dataField: 'parentID',
                    isParentKey: true
                }];
            }
        };
    }
]);
commonModule.
controller('operateLogController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', 'operationLogService', '$filter', 'loginContext', 'userService',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, operationLogService, $filter, loginContext, userService) {

        var logTypeMap = {
            organization: {
                index: "organization",
                logTitle: "OperateOrganizationLog",
                type: constant.OperateLogType.OperationLogOrganization,
                moduleName: 'Organization'
            },
            user: {
                index: "user",
                logTitle: "OperateUserLog",
                type: constant.OperateLogType.OperationLogUser,
                moduleName: 'User'
            },
            userlist: {
                index: "user",
                logTitle: "OperateUserLog",
                type: constant.OperateLogType.OperationLogUser,
                moduleName: 'User'
            },
            userDetail: {
                index: "user",
                logTitle: "OperateUserLog",
                type: constant.OperateLogType.OperationLogUser,
                moduleName: 'User'
            },
            project: {
                index: "project",
                logTitle: "OperateProjectLog",
                type: constant.OperateLogType.OperationLogProject,
                moduleName: 'Project'
            },
            role: {
                index: "role",
                logTitle: "OperateRoleLog",
                type: constant.OperateLogType.OperationLogRole,
                moduleName: 'Role'
            },
            declarationFormConfiguration: {
                index: "declarationFormConfiguration",
                logTitle: "ReportConfigurationDescLogTitle",
                type: constant.OperateLogType.OperationLogReport,
                moduleName: 'ReportConfiguration'
            },
            subjectCorresponding: {
                index: "subjectCorresponding",
                logTitle: "SubjectCorrespondingLogTitle",
                type: constant.OperateLogType.OperationLogSubjectCorres,
                moduleName: 'BasicDataEnterpriceAccount'
            },
            orangizationStructureManage: {
                index: "orangizationStructureManage",
                logTitle: "OrangizationStructureManageLog",
                type: constant.OperateLogType.OperationLogBasicData,
                moduleName: 'BasicDataOrganizationStructure'
            },
            businessUnit: {
                index: "businessUnit",
                logTitle: "BusinessUnitLog",
                type: constant.OperateLogType.OperationLogBasicData,
                moduleName: 'BasicDataBusinessUnit'
            },
            regionManage: {
                index: "regionManage",
                logTitle: "RegionManageLog",
                type: constant.OperateLogType.OperationLogBasicData,
                moduleName: 'BasicDataArea'
            },
            enterpriseAccountManage: {
                index: "enterpriseAccountManage",
                logTitle: "EnterpriseAccountManageLog",
                type: constant.OperateLogType.OperationLogEnterPrise,
                moduleName: 'BasicDataEnterpriceAccount'
            },
            customerListManage: {
                index: "customerListManage",
                logTitle: "CustomerListManageLog",
                type: constant.OperateLogType.OperationLogBasicData,
                moduleName: 'BasicDataCustomer'
            },
            keyCodeConfiguration: {
                index: "keyValueConfig",
                logTitle: "KeyValueConfigurationLogTitle",
                type: constant.OperateLogType.OperationKeyvalueConfiguration,
                moduleName: 'KeyValueConfig'
            },
            modelconfiguration: {
                index: "modelConfiguration",
                logTitle: "ModelConfigurationLogLogTitle",
                type: constant.OperateLogType.OperationLogModelConfiguration,
                moduleName: 'ModelConfiguration'
            },
            ruleEngineConfiguration: {
                index: "ruleEngineConfig",
                logTitle: "RuleSourceLogTitle",
                type: constant.OperateLogType.OperationRuleEngineConfiguration,
                moduleName: 'RuleEngineConfig'
            },
            workFlowManage: {
                index: "workFlowManage",
                logTitle: "LogTitleWorkflow",
                type: constant.OperateLogType.OperationLogWorkflow,
                moduleName: 'Workflow'
            },
            storeArchitectureView: {
                index: "storeArchitectureView",
                logTitle: "LogTitleStock",
                type: constant.OperateLogType.OperationLogStock,
                moduleName: 'Stock'
            },

        };

        var commonTitle = {
            logType: "OperationContent",
            logOperateObject: "LogOperateObject",
            logOriginalState: "LogOriginalState",
            logUpdateState: "LogUpdateState",
            logOperationDescription: "LogOperationDescription",
            logOperationUser: "LogOperationUser",
            logOperationTime: "LogOperationTime",
            logOperationOID: "LogOperationOID",
            logOperationIP: "LogOperationIP",
            logComments: 'LogComments'
        };

        var actionMap = {
            1: $translate.instant('New'),
            2: $translate.instant('Update'),
            3: $translate.instant('Delete'),
            4: $translate.instant('Copy'),
            5: $translate.instant('AutoMapping'),
            6: $translate.instant('ManualMapping'),
            7: $translate.instant('CancelMapping'),
            8: $translate.instant('AddEnterpriseAccountSet'),
            9: $translate.instant('UpdateEnterpriseAccountSet'),
            10: $translate.instant('AddEnterpriseAccount'),
            11: $translate.instant('UpdateEnterpriseAccount'),
            12: $translate.instant('AddRelevantOrgAction'),
            13: $translate.instant('UpdateRelevantOrg'),
            14: $translate.instant('DeleteRelevantOrg'),
            15: $translate.instant('AddNewUser'),
            16: $translate.instant('DeleteUser'),
            17: $translate.instant('AddNewPermission'),
            18: $translate.instant('DeletePermission')
        };

        var perationModuleMap = {
            1: 'OrganizationStructureDesc',
            2: 'RegionDesc',
            3: 'StandardAccountDesc',
            4: 'WordLibraryDesc',
            5: 'KeyValueDesc',
            6: 'ProjectDesc',
            7: 'ProjectServiceTypeDesc',
            8: 'UserDesc',
            9: 'OrganizationDesc',
            10: 'RoleDesc',
            11: 'UserRoleDesc',
            12: 'EnterpriceAccountDesc',
            13: 'TemplateFormulaDesc',
            14: 'TemplateDesc',
            15: 'TemplateGroupDesc',
            16: 'ReportConfigurationDesc',
            17: 'AreaDesc',
            18: 'CustomerDesc',
            19: 'BusinessUnitDesc'
        };

        //点击任意一页事件
        var load_page = function (pageIndex) {
            getLogs(pageIndex);
        };

        var getLogs = function (pageIndex) {

            // $scope.InitType();
            $scope.curPage = pageIndex;

            $scope.paginInfo = {
                totalCount: $scope.queryResult.pageInfo.totalCount,
                pageIndex: pageIndex,
                pageSize: $scope.queryResult.pageInfo.pageSize
            };

            var model = {};
            model.pageInfo = $scope.paginInfo;
            model.logType = $scope.logObj.type;
            model.searchText = $scope.searchText;
            model.moduleName = $scope.logObj.moduleName;
            model.operationObject = $scope.logObj.operationObject;
            if ($scope.filterOperationObjectList) {
                model.filterOperationObjectList = $scope.filterOperationObjectList;
            }

            operationLogService.getOrgLogList(model).success(function (data) {
                if (data != '') {
                    if (data && data.pageInfo && data.pageInfo.totalCount > 0) {
                        var i = 1 + (pageIndex - 1) * $scope.queryResult.pageInfo.pageSize;
                        data.list.forEach(function (row) {
                            row.id = i;
                            row.createTime = $filter('date')(row.createTime, 'yyyy-MM-dd HH:mm');
                            row.operationObject = $translate.instant(row.operationObject);

                            row.comment = $translate.instant(row.comment);
                            row.operationContent = $translate.instant(row.operationContent);
                            row.action = actionMap[row.action];
                            row.originalState = $translate.instant(row.originalState);
                            row.updateState = $translate.instant(row.updateState);
                            i++;
                        });
                        //$scope.operateLogGridOptions.data = data.list;
                        $scope.operateGridDataSource = data.list;
                        $scope.queryResult = data;
                        computeTotalPage();
                    } else {
                        //$scope.operateLogGridOptions.data = data.list;
                        $scope.operateGridDataSource = data.list;
                        $scope.queryResult = data;
                        computeTotalPage();
                    }
                }
            });
        };

        var computeTotalPage = function () {

            if ($scope.queryResult.pageInfo && $scope.queryResult.pageInfo.totalCount > 0) {

                var totalPage = parseInt($scope.queryResult.pageInfo.totalCount / $scope.queryResult.pageInfo.pageSize);
                totalPage = $scope.queryResult.pageInfo.totalCount % $scope.queryResult.pageInfo.pageSize == 0 ? totalPage : totalPage + 1;

                $scope.queryResult.pageInfo.totalPage = totalPage;

                $scope.creatPage = $(".tcdPageCode").createPage({
                    pageCount: totalPage,
                    current: $scope.curPage,
                    backFn: function (p) {
                        //单击回调方法,p是当前页码
                        getLogs(p);
                    }
                });

                $('.tcdPageCode').css('display', 'inline-block');
            } else {
                $scope.creatPage = $(".tcdPageCode").createPage({
                    pageCount: 0,
                    current: $scope.curPage,
                    backFn: function (p) {
                        //单击回调方法,p是当前页码
                        getLogs(p);
                    }
                });

                $('.tcdPageCode').css('display', 'inline-block');
            }
        };

        var prePage = function () {

            if ($scope.curPage > 1) {
                $scope.curPage--;
            }

            getLogs($scope.curPage);
        };

        var nextPage = function () {
            if ($scope.curPage < $scope.queryResult.pageInfo.totalPage) {
                $scope.curPage++;
            }

            loadSAPDataByPageIndex($scope.curPage);
        };

        var normalDataGridOptions = function () {
            var columnNameMap = $scope.logObj;

            $scope.operateGridDataSource = [];

            //var height = $(window).height();

            //var gridHeight = Math.ceil(height * 0.8);

            $scope.operateLogGridOptions = {
                bindingOptions: {
                    dataSource: 'operateGridDataSource'
                },
                // keyExpr: "ID",
                selection: {
                    mode: "single",
                },
                paging: {
                    enabled: false,
                },
                allowColumnResizing: true,
                columnAutoWidth: true,
                showRowLines: true,
                showColumnLines: true,
                rowAlternationEnabled: true,
                showBorders: true,
                width: '1140px',
                height: 460,
                noDataText: $translate.instant('NoDataText'),
                onContentReady: function (e) {
                    $scope.invoiceGridInstance = e.component;
                },
                onSelectionChanged: function (data) {

                },
                columns: [
                    { dataField: 'id', caption: $translate.instant('LogIndex') },
                    { dataField: 'createTime', caption: $translate.instant(commonTitle.logOperationTime) },
                    { dataField: 'operationObject', caption: $translate.instant(commonTitle.logOperateObject), width: 140 },
                    { dataField: 'action', caption: $translate.instant(commonTitle.logOperationDescription) },
                    { dataField: 'operationContent', caption: $translate.instant(commonTitle.logType) },
                    { dataField: 'originalState', caption: $translate.instant(commonTitle.logOriginalState) }, //税额合计小写
                    { dataField: 'updateState', caption: $translate.instant(commonTitle.logUpdateState) }, //税额
                    { dataField: 'operationUser', caption: $translate.instant(commonTitle.logOperationUser), width: 70 }, //开票日期
                    { dataField: 'comment', caption: $translate.instant(commonTitle.logComments) }, //开票日期
                ]

            };

        };

        $scope.$watch('isShow', function (newValue, oldValue) {
            if (newValue) {
                $scope.searchText = '';

                $scope.queryResult = {
                    list: [],
                    pageInfo: {
                        totalCount: -1,
                        pageIndex: 1,
                        pageSize: 100,
                        totalPage: 0,
                    }
                };

                $scope.InitType();
                load_page(1);
                $('#showOperatePop').modal('show');
            }
        });


        // 获取用户机构权限
        var thisPermission = {

            // 获取用户权限
            getUserOrganzationPermission: function () {

                if ($scope.queryOrganizationCode) {
                    userService.getUserPermission(loginContext.userName).success(function (userPermission) {
                        var orgList = thisPermission.getHasPermissionOrgList($scope.queryOrganizationCode, userPermission);
                        var orgNameList = _.pluck(orgList, 'name');
                        $scope.filterOperationObjectList = orgNameList;

                    });
                } else {

                }

            },

            // filter机构列表
            getHasPermissionOrgList: function (permissionCode, permission) {

                var orgList = [];
                if (permission.isAdmin) {

                    permission.organizationPermissionList.forEach(function (row) {

                        orgList.push({

                            id: row.id,
                            name: row.name
                        });
                    });
                } else {

                    permission.organizationPermissionList.forEach(function (row) {
                        var find = _.find(row.permissionList, function (num) {
                            return num.code.indexOf(permissionCode) > -1;
                        });


                        if (find) {
                            orgList.push({
                                id: row.id,
                                name: row.name
                            });
                        }

                    });
                }

                return orgList;

            }
        };

        $scope.closeModal = function () {
            $scope.isShow = false;
        };

        $scope.InitType = function () {
            var url = $location.absUrl();
            //if ($scope.lastUrl === url) {
            //    return;
            //}

            $scope.lastUrl = url;
            var array = url.substr(url.indexOf('#') + 2).split('/');

            $scope.curRoute = array[array.length - 1];


            // 根据logType映射过来的数据
            var columnNameMap = logTypeMap[$scope.curRoute];

            // 弄个默认的
            if (!columnNameMap) {
                if (array.length > 1) {
                    columnNameMap = logTypeMap[array[array.length - 2]];
                }

                if (!columnNameMap) {
                    columnNameMap = logTypeMap.organization;
                }
            }

            $scope.logObj = columnNameMap;

            $scope.logTitle = $translate.instant(columnNameMap.logTitle);
            $scope.searchText = '';

            $scope.queryResult = {
                list: [],
                pageInfo: {
                    totalCount: -1,
                    pageIndex: 1,
                    pageSize: 100,
                    totalPage: 0,
                }
            }

            $scope.curPage = 1;

            thisPermission.getUserOrganzationPermission();
        };

        (function initialize() {
            $log.debug('operateLogController.ctor()...');
            $scope.InitType();
            normalDataGridOptions();

            $scope.load_page = load_page;

        })();
    }
]);
commonModule.directive('operateLog', ['$log',
    function ($log) {
        'use strict';
        $log.debug('operateLog.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/operate-log/operate-log.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'operateLogController',
            scope:
            {
                isShow: '=',
                searchText: '=?',
                filterOperationObjectList: '=?',
                queryOrganizationCode: '=?',
            }
            //,
            //link: function (scope, element) {
            //    element.find('.selector-input').on('focus', function () {
            //        element.find('.org-tree-container').show();
            //    });
            //    $(document).on('click', function () {
            //        element.find('.org-tree-container').hide();
            //    }).on('click', '.org-tree-wrapper', function (e) {
            //        e.stopPropagation();
            //    });
            //}
        };
    }
]);
commonModule.
controller('OrgAreaIndustryController', ['$scope', 'orgService','$log','uiGridTreeViewConstants', '$timeout', 'areaService', 'uiGridConstants','$translate','$interval','$q',
    function ($scope, orgService, $log, uiGridTreeViewConstants, $timeout, areaService, uiGridConstants, $translate, $interval,$q) {
        'use strict';

        $scope.collapse = function () {
            $scope.gridApi.treeBase.expandAllRows();
        }

        $scope.getGridHeight = function () { 
            return {};
        };

        $scope.getOrgListForDashboard = function (orgId) {

            var deferred = $q.defer();
            var promise = deferred.promise;

            //var orgId = '81a3df63-b87d-4d7f-b3af-54169c13fa15';
            orgService.getOrgListForDashboard(orgId).success(function (data) {

                data.forEach(function (row) {
                    if (row.level != null) {
                        row.$$treeLevel = parseInt(row.level);
                    }
                });

                //往uigrid填充数据并默认展开所有的节点
                $scope.areaORGGridList.data = data;

                $timeout(function () {
                    $scope.gridApi.treeBase.expandAllRows();

                }, 500);

                deferred.resolve(data);
            });

            return deferred.promise;
        };

        var areaORGGridInit = function () {
            $scope.areaORGGridList = {
                enableRowSelection: true,
                enableSelectAll: false,
                rowHeight: 30,
                enableRowHeaderSelection: false,
                modifierKeysToMultiSelect: false,
                enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
                enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,

                enableSorting: true,
                enableColumnMenus: false,
                enableFiltering: false,
                showTreeExpandNoChildren: false,
                enableFullRowSelection: true, //是否点击行任意位置后选中,默认为false
                multiSelect: false, // 是否可以选择多个,默认为true; 
                columnDefs: [{
                    field: 'orgName',
                    name: $translate.instant('OrganizationName'),
                    headerCellClass: '',

                    cellTemplate: '<div ng-class="{true: \'text-align-left\', false: \'text-align-left-padding\'}[!row.entity.isOrganization]"><span title="{{row.entity.orgName}}">{{row.entity.orgName|limitString:16}}</span></div>'
                }, {
                    field: 'areaName',
                    name: $translate.instant('AreaDesc'),
                    headerCellClass: '',

                    cellTemplate: '<div class="text-align-left"><span title="{{row.entity.areaName}}">{{row.entity.areaName|limitString:16}}</span></div>'
                }, {
                    field: 'industryName',
                    name: $translate.instant('PIndustry'),
                    headerCellClass: '',

                    cellTemplate: '<div class="text-align-left"><span>{{row.entity.industryName}}</span></div>'
                }],
                onRegisterApi: function (gridApi) {

                    $scope.gridApi = gridApi;

                    $scope.gridSelectCount = $scope.gridApi.selection.getSelectedRows().length;
                    var onRowsRenderedOff = gridApi.core.on.rowsRendered(null, function () {
                        onRowsRenderedOff(); // run once
                        PWC.triggerRowSelectOnClick('#etsGrid'); // requires '.ui-grid-canvas'
                    });
                    // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                    $interval(function () {
                        $scope.gridApi.core.handleWindowResize();
                    }, 500, 60 * 60 * 8);

                }
            };

        };


        (function initialize() {
            $log.debug('OrgAreaIndustryController.ctor()...');
             
            areaORGGridInit();

        })();
    }
]);
commonModule.directive('orgAreaIndustry', ['$log', '$compile', '$timeout', '$interval',
    function ($log, $compile, $timeout, $interval) {
        'use strict';
        $log.debug('orgChart.ctor()...');

        return {
            restrict: 'AE',
            templateUrl: '/app/common/controls/org-area-industry/org-area-industry.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                orgId: '=',
                isRenderCompleted: '='
            },
            controller: 'OrgAreaIndustryController',
            link: function (scope, element) {
                scope.$watch('orgId', function (newValue, oldValue) {
                    if (newValue !== oldValue) {

                        //refresh ui grid with new data
                        scope.getOrgListForDashboard(newValue).then(function () {
                            scope.isRenderCompleted = true;
                        });
                    }

                    //点击弹出的面板,禁止冒泡事件
                    $("#orgAreaIndustryPopup").on("click", function (e) {
                        e.stopPropagation();
                    });
                     
                })
            }
        };
    }
]);
commonModule.
controller('OrgChartController', ['$scope', 'areaService',
    function ($scope, areaService) {
        'use strict';


    }
]);
commonModule.directive('orgChart', ['$log', '$compile', '$timeout', '$interval',
    function ($log, $compile, $timeout, $interval) {
        'use strict';
        $log.debug('orgChart.ctor()...');

        return {
            restrict: 'A',
            templateUrl: '/app/common/controls/org-chart/org-chart.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                selectedAreaCode: '=',
                selectedAreaName: '=',
                selectedAreaId: '=',
                componentSelectedArea: '=',
                isShowAll: '=',
                loadData: '&',
                onChange: '&onChange'
            },
            controller: 'OrgChartController',
            link: function (scope, element) {
                
                var nameAttr = $compile($('#node-name').html())(scope);
                var titleAttr = $compile($('#node-title').html())(scope);
                var topFirstAttr=$compile($('#topNode').html())(scope);

                var nameTemplate, titleTemplate,topTemplate;

                var myInterval = $interval(function () {
                    nameTemplate = nameAttr.html();
                    titleTemplate = titleAttr.html();
                    topTemplate = topFirstAttr.html();

                    if (nameTemplate !== undefined && titleTemplate !== undefined && topTemplate !== undefined) {

                        $interval.cancel(myInterval);

                        var datascource = {
                            'name': topTemplate,
                            // 'title': 'general manager',
                            'children': [
                              {
                                  'name': nameTemplate,
                                  'title': titleTemplate,
                                  'age': '12'

                              },
                              {
                                  'name': nameTemplate,
                                  'title': titleTemplate,
                                  'children': [
                                    {
                                        'name': nameTemplate,
                                        'title': titleTemplate
                                    },
                                    {
                                        'name': nameTemplate,
                                        'title': titleTemplate,
                                        'children': [
                                          {
                                              'name': nameTemplate,
                                              'title': titleTemplate
                                          },
                                          {
                                              'name': nameTemplate,
                                              'title': titleTemplate
                                          }
                                        ]
                                    }
                                  ]
                              },
                              {
                                  'name': nameTemplate,
                                  'title': titleTemplate
                              },
                              {
                                  'name': nameTemplate,
                                  'title': titleTemplate
                              }
                            ]
                        };

                        $('#subsidiary-chart').orgchart({
                            'data': datascource,
                            'nodeContent': 'title',
                            'pan': true,
                            'zoom': true,
                            "draggable": true
                        });
                    }
                }, 100)
            }
        };
    }
]);
commonModule.
controller('OrgCityAreaUserController', ['$scope', 'orgService', '$log', 'uiGridTreeViewConstants', '$timeout', 'areaService', 'uiGridConstants', '$translate', '$interval', '$q',
    function ($scope, orgService, $log, uiGridTreeViewConstants, $timeout, areaService, uiGridConstants, $translate, $interval,$q) {
        'use strict';

        $scope.collapse = function () {
            $scope.gridApi.treeBase.expandAllRows();
        }

        $scope.getGridHeight = function () { 
            return {};
        };

        $scope.getOrgCityAreaUserCountList = function (orgId) {

            var deferred = $q.defer();
            var promise = deferred.promise;

            //var orgId = '81a3df63-b87d-4d7f-b3af-54169c13fa15';
            orgService.getOrgCityAreaUserCountList(orgId).success(function (data) {
                 
                data.forEach(function (row) {
                    if (row.level != null) {
                        row.$$treeLevel = parseInt(row.level);
                    }
                });

                //往uigrid填充数据并默认展开所有的节点
                $scope.areaORGGridList.data = data;

                $timeout(function () {
                    $scope.gridApi.treeBase.expandAllRows();

                }, 500);

                deferred.resolve(data);
            });

            return deferred.promise;
        };

        var areaORGGridInit = function () {
            $scope.areaORGGridList = {
                enableRowSelection: true,
                enableSelectAll: false,
                rowHeight: 30,
                enableRowHeaderSelection: false,
                modifierKeysToMultiSelect: false,
                enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
                enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,

                enableSorting: true,
                enableColumnMenus: false,
                enableFiltering: false,
                showTreeExpandNoChildren: false,
                enableFullRowSelection: true, //是否点击行任意位置后选中,默认为false
                multiSelect: false, // 是否可以选择多个,默认为true; 
                columnDefs: [{
                    field: 'orgName',
                    name: $translate.instant('OrgShortName'),
                    headerCellClass: '',

                    cellTemplate: '<div ng-class="{true: \'text-align-left\', false: \'text-align-left-padding\'}[!row.entity.isOrganization]"><span title="{{row.entity.orgName}}">{{row.entity.orgName|limitString:16}}</span></div>'
                }, {
                    field: 'orgCity',
                    name: $translate.instant('OrgCity'),
                    headerCellClass: '',

                    cellTemplate: '<div class="text-align-left"><span title="{{row.entity.orgCity}}">{{row.entity.orgCity|limitString:16}}</span></div>'
                }, {
                    field: 'orgArea',
                    name: $translate.instant('OrgArea'),
                    headerCellClass: '',

                    cellTemplate: '<div class="text-align-left"><span>{{row.entity.orgArea}}</span></div>'
                }, {
                    field: 'orgUserCount',
                    name: $translate.instant('OrgUser'),
                    headerCellClass: '',

                    cellTemplate: '<div class="text-align-left"><span>{{row.entity.orgUserCount}}</span></div>'
                }],
                onRegisterApi: function (gridApi) {
                     
                    $scope.gridApi = gridApi;

                    $scope.gridSelectCount = $scope.gridApi.selection.getSelectedRows().length;
                    var onRowsRenderedOff = gridApi.core.on.rowsRendered(null, function () {
                        onRowsRenderedOff(); // run once
                        PWC.triggerRowSelectOnClick('#etsGrid'); // requires '.ui-grid-canvas'
                    });
                    // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                    $interval(function () {
                        $scope.gridApi.core.handleWindowResize();
                    }, 500, 60 * 60 * 8);

                }
            };

        };

        $scope.test = function () {
            $scope.testOrgID = '81a3df63-b87d-4d7f-b3af-54169c13fa15';
            $scope.getOrgCityAreaUserCountList($scope.testOrgID).then(function () {
                
            });
        };


        (function initialize() {
            $log.debug('OrgCityAreaUserController.ctor()...');
             
            areaORGGridInit();

        })();
    }
]);
commonModule.directive('orgCityAreaUser', ['$log', '$compile', '$timeout', '$interval',
    function ($log, $compile, $timeout, $interval) {
        'use strict';
        $log.debug('orgCityAreaUser.ctor()...');

        return {
            restrict: 'AE',
            templateUrl: '/app/common/controls/org-city-area-user/org-city-area-user.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                orgIdCityAreaUser: '=',
                isRenderCompletedCityAreaUser: '='
            },
            controller: 'OrgCityAreaUserController',
            link: function (scope, element) {
                scope.$watch('orgIdCityAreaUser', function (newValue, oldValue) {
                    if (newValue !== oldValue) {

                        var orgId = newValue.substring(0, newValue.indexOf('|'));
                        //refresh ui grid with new data
                        scope.getOrgCityAreaUserCountList(orgId).then(function () {
                            scope.isRenderCompletedCityAreaUser = true;
                        });
                    }

                    //点击弹出的面板,禁止冒泡事件
                    $("#orgCityAreaUserPop").on("click", function (e) {
                        e.stopPropagation();
                    });
                     
                })
            }
        };
    }
]);
commonModule.
controller('OrgAreaIndustryController', ['$scope', 'orgService','$log','uiGridTreeViewConstants', '$timeout', 'areaService', 'uiGridConstants','$translate','$interval','$q',
    function ($scope, orgService, $log, uiGridTreeViewConstants, $timeout, areaService, uiGridConstants, $translate, $interval,$q) {
        'use strict';

        $scope.collapse = function () {
            $scope.gridApi.treeBase.expandAllRows();
        }

        $scope.getGridHeight = function () { 
            return {};
        };

        $scope.getOrgListForDashboard = function (orgId) {

            var deferred = $q.defer();
            var promise = deferred.promise;

            //var orgId = '81a3df63-b87d-4d7f-b3af-54169c13fa15';
            orgService.getOrgListForDashboard(orgId).success(function (data) {

                data.forEach(function (row) {
                    if (row.level != null) {
                        row.$$treeLevel = parseInt(row.level);
                    }
                });

                //往uigrid填充数据并默认展开所有的节点
                $scope.areaORGGridList.data = data;

                $timeout(function () {
                    $scope.gridApi.treeBase.expandAllRows();

                }, 500);

                deferred.resolve(data);
            });

            return deferred.promise;
        };

        var areaORGGridInit = function () {
            $scope.areaORGGridList = {
                enableRowSelection: true,
                enableSelectAll: false,
                rowHeight: 30,
                enableRowHeaderSelection: false,
                modifierKeysToMultiSelect: false,
                enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
                enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,

                enableSorting: true,
                enableColumnMenus: false,
                enableFiltering: false,
                showTreeExpandNoChildren: false,
                enableFullRowSelection: true, //是否点击行任意位置后选中,默认为false
                multiSelect: false, // 是否可以选择多个,默认为true; 
                columnDefs: [{
                    field: 'orgName',
                    name: $translate.instant('OrganizationName'),
                    headerCellClass: '',

                    cellTemplate: '<div ng-class="{true: \'text-align-left\', false: \'text-align-left-padding\'}[!row.entity.isOrganization]"><span title="{{row.entity.orgName}}">{{row.entity.orgName|limitString:16}}</span></div>'
                }, {
                    field: 'areaName',
                    name: $translate.instant('AreaDesc'),
                    headerCellClass: '',

                    cellTemplate: '<div class="text-align-left"><span title="{{row.entity.areaName}}">{{row.entity.areaName|limitString:16}}</span></div>'
                }, {
                    field: 'industryName',
                    name: $translate.instant('PIndustry'),
                    headerCellClass: '',

                    cellTemplate: '<div class="text-align-left"><span>{{row.entity.industryName}}</span></div>'
                }],
                onRegisterApi: function (gridApi) {

                    $scope.gridApi = gridApi;

                    $scope.gridSelectCount = $scope.gridApi.selection.getSelectedRows().length;
                    var onRowsRenderedOff = gridApi.core.on.rowsRendered(null, function () {
                        onRowsRenderedOff(); // run once
                        PWC.triggerRowSelectOnClick('#etsGrid'); // requires '.ui-grid-canvas'
                    });
                    // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                    $interval(function () {
                        $scope.gridApi.core.handleWindowResize();
                    }, 500, 60 * 60 * 8);

                }
            };

        };


        (function initialize() {
            $log.debug('OrgAreaIndustryController.ctor()...');
             
            areaORGGridInit();

        })();
    }
]);
commonModule.directive('orgAreaIndustry', ['$log', '$compile', '$timeout', '$interval',
    function ($log, $compile, $timeout, $interval) {
        'use strict';
        $log.debug('orgChart.ctor()...');

        return {
            restrict: 'AE',
            templateUrl: '/app/common/controls/org-area-industry/org-area-industry.html' + '?_=' + Math.random(),
          
            scope: {
                orgId: '=',
                isRenderCompleted: '='
            },
            controller: 'OrgAreaIndustryController',
            link: function (scope, element) {
                scope.$watch('orgId', function (newValue, oldValue) {
                    if (newValue !== oldValue) {

                        //refresh ui grid with new data
                        scope.getOrgListForDashboard(newValue).then(function () {
                            scope.isRenderCompleted = true;
                        });
                    }

                    //点击弹出的面板,禁止冒泡事件
                    $("#orgAreaIndustryPopup").on("click", function (e) {
                        e.stopPropagation();
                    });
                     
                })
            }
        };
    }
]);
commonModule.
controller('OrgGeneralInfoController', ['$scope', 'orgService', '$log', 'uiGridTreeViewConstants', '$timeout', 'areaService', 'uiGridConstants', '$translate', '$interval', '$q', 'dimensionService',
    function ($scope, orgService, $log, uiGridTreeViewConstants, $timeout, areaService, uiGridConstants, $translate, $interval, $q, dimensionService) {
        'use strict';


        var getDimensionList = function () {
            dimensionService.getDimensionList().success(function (data) {
                if (data) {
                    $scope.customDimensionList = data;

                    $log.debug($scope.customDimensionList);

                    $scope.businessName = dimension.getBusinessUnitName();
                    $scope.areaName = dimension.getAreaName();
                }
            });
        };

        var dimension = {
            getBusinessUnitName: function () {
                var findResult = _.find($scope.customDimensionList, function (item) {
                    return item.id == constant.dimensionID.businessUnitID;
                });
                if (findResult) {
                    return findResult.name;
                }
                else {
                    return '';
                }
            },
            getAreaName: function () {
                var findResult = _.find($scope.customDimensionList, function (item) {
                    return item.id == constant.dimensionID.areaID;
                });
                if (findResult) {
                    return findResult.name;
                }
                else {
                    return '';
                }
            }
        };


        $scope.getGeneralInfo = function (orgId) {

            var deferred = $q.defer();
            var promise = deferred.promise;

            //var orgId = '81a3df63-b87d-4d7f-b3af-54169c13fa15';
            orgService.getGeneralInfo(orgId).success(function (data) {
                if (data) {
                    $scope.info = data;
                    $scope.info.id = orgId;
                    deferred.resolve(data);
                }
                else {
                    deferred.resolve(true);
                }
            });

            return deferred.promise;
        };

        (function initialize() {
            $log.debug('OrgGeneralInfoController.ctor()...');
            getDimensionList();


        })();
    }
]);
commonModule.directive('orgGeneralInfo', ['$log', '$compile', '$timeout', '$interval',
    function ($log, $compile, $timeout, $interval) {
        'use strict';
        $log.debug('orgGeneralInfo.ctor()...');

        return {
            restrict: 'AE',
            templateUrl: '/app/common/controls/org-general-info/org-general-info.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                orgIdGeneralInfo: '=',
                isRenderCompletedGeneralInfo: '='
            },
            controller: 'OrgGeneralInfoController',
            link: function (scope, element) {

                $(".org-general-info").draggable({ containment: "parent", cursor: "cursor" });


                scope.$watch('orgIdGeneralInfo', function (newValue, oldValue) {
                    if (newValue) {
                        //refresh ui grid with new data
                        scope.getGeneralInfo(newValue).then(function (row) {

                            scope.isRenderCompletedGeneralInfo = true;
                        });
                    }
                });

                var orgCityAreaUserPop, orgUserListPop, row, oldOrgId, oldOprType;

                // 显示机构 区域和行业的卡片
                //var showCard = function (pop, row, topOffset, leftOffset) {

                //    pop.css("display", "block").css("top", (function (r) {

                //        if (r.offset().top > window.innerHeight - pop.height())
                //            return r.offset().top - topOffset;
                //        else
                //            return r.offset().top - topOffset;
                //    })(row)).css("left", (function (r) {

                //        if (r.offset().left + r.width() > window.innerWidth - pop.width())
                //            return r.offset().left - leftOffset;
                //        else
                //            return r.offset().left - leftOffset;
                //    })(row)).show();

                //    $(document).one('click', function () {
                //        pop.hide();
                //        orgCityAreaUserPop.hide();
                //        orgUserListPop.hide();
                //    });
                //};

                var showCard = function (pop, row, topOffset, leftOffset,self) {

                    var $popover = pop.show();
                    var pos = $.PositionCalculator({
                        target: this,
                        targetAt: 'top right',
                        item: $popover,
                        itemAt: 'top left',
                        flip: 'both'
                    }).calculate();

                    $popover.css({
                        top: parseInt($popover.css('top')) + pos.moveBy.y + 'px',
                        left: parseInt($popover.css('left')) + pos.moveBy.x + 'px'
                    });

                    $(document).one('click', function () {
                        pop.hide();
                        orgCityAreaUserPop.hide();
                        orgUserListPop.hide();
                    });
                };

                //先判断directive中的uigrid是否渲染完成,如果完成那么就显示card
                scope.$watch('isRenderCompletedCityAreaUser', function (newValue, oldValue) {
                    if (newValue !== undefined && oldValue !== undefined) {
                        showCard(orgCityAreaUserPop, row, 258, 677);
                    }

                });

                scope.$watch('isRenderCompletedUserList', function (newValue, oldValue) {
                    if (newValue !== undefined && oldValue !== undefined) {
                        showCard(orgUserListPop, row, 258, 661);
                    }

                });


                $(".close-card").on("click", function (e) {
                    scope.isRenderCompletedGeneralInfo = false;
                });

                //点击弹出的面板,禁止冒泡事件
                $("#orgGeneralInfoPop").on("click", function (e) {

                    e.stopPropagation();
                });

                //$('.general-tmpl').click(function () {

                //    orgCityAreaUserPop = $("#orgCityAreaUserPop");
                //    orgUserListPop = $('#orgUserListPop');

                //    row = $(this);
                //    var orgId = row.find('#OrgID').text();
                //    var oprType = row.find('#OrgID').attr('data-opr-type');

                //    if (oprType === 'enum.orgCityAreaUserOpr') {

                //        orgUserListPop.hide();

                //        //如果两个值不同,说明点击的是不同的机构,
                //        //需要给orgId赋值触发directive的watch更新uigrid的数据
                //        if (orgId !== oldOrgId || oprType !== oldOprType) {
                //            scope.isRenderCompletedCityAreaUser = false;
                //            scope.orgIdCityAreaUser = orgId + '|' + Math.random();  ////会触发directive的watch操作,从而更新数据
                //        } else {
                //            // 如果点击的是同一个子公司,需要直接显示
                //            //showCard(pop, row);
                //            orgCityAreaUserPop.toggle();

                //            if (orgCityAreaUserPop.is(':visible')) {
                //                //如果当前是可视的那么再绑定一次
                //                $(document).one('click', function () {
                //                    orgCityAreaUserPop.hide();
                //                });
                //            }
                //        }

                //        oldOrgId = orgId;
                //        oldOprType = oprType;

                //    } else if (oprType === 'enum.orgUserList') {

                //        orgCityAreaUserPop.hide();

                //        // 如果两个值不同,说明点击的是不同的机构,
                //        // 需要给orgId赋值触发directive的watch更新uigrid的数据
                //        if (orgId !== oldOrgId || oprType !== oldOprType) {
                //            scope.isRenderCompletedUserList = false;
                //            scope.orgIdUserList = orgId + '|' + Math.random();  ////会触发directive的watch操作,从而更新数据
                //        } else {
                //            // 如果点击的是同一个子公司,需要直接显示
                //            //showCard(pop, row);
                //            orgUserListPop.toggle();

                //            if (orgUserListPop.is(':visible')) {
                //                //如果当前是可视的那么再绑定一次
                //                $(document).one('click', function () {
                //                    orgUserListPop.hide();
                //                });
                //            }
                //        }

                //        oldOrgId = orgId;
                //        oldOprType = oprType;
                //    }
                //});
            }
        };
    }
]);
commonModule.
controller('orgMultiSelectorController', ['$scope', '$timeout','orgService',
    function ($scope,$timeout, orgService) {
        $scope.requiredValidation = function ($event) {
            $timeout(function () {
                if ($scope.selectedNames && $scope.selectedNames.length > 0) return;
                // $($event.target).find('input').css('border-color', 'red');
                $($event.target).css('border-color', 'red');
            }, 1000, false);
           
        };
    }
]);
commonModule.directive('orgMultiSelector', ['$log','orgService',
    function ($log, orgService) {
        'use strict';
        $log.debug('regionSelector.ctor()...');
        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/org-multi-selector/org-multi-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                selectedNoList: '=',
                provinceCityData: '=',
            },
            controller: 'orgMultiSelectorController',
            link: function (scope, element) {
                var provinceMap = {};
                scope.selectedNames = '';
                scope.$watch('provinceCityData', function (newValue, oldValue) {
                    scope.provinceCityData.forEach(function (row) {
                        provinceMap[row.id] = row;
                    });
                    refresh();
                });


                scope.$watch('selectedNoList', function (newValue, oldValue) {
                    if (newValue !== oldValue) {
                        refresh();
                    }
                });

                function refresh() {
                    scope.selectedNames = '';
                    scope.selectedNoList.forEach(function (id) {
                        if (provinceMap[id]) {
                            scope.selectedNames += provinceMap[id].name + ',';
                        }
                    });
                    scope.selectedNames = scope.selectedNames.substring(0, scope.selectedNames.length - 2);
                }

                (function () {
                })();
            }
        };
    }
]);
commonModule.
controller('OrgPermissionFilterController', ['$scope', 'orgService', 'userService', 'loginContext', '$translate',
    function ($scope, orgService, userService, loginContext, $translate) {

        // 本页面常量
        var thisConstant = {
            businessUnitID: 'businessUnitID',
            businessUnitName: 'businessUnitName',

            // 所有事业部
            allBusinessUnits: $translate.instant('AllBusinessUnit'),

            // 所有区域
            allAreas: $translate.instant('AllArea'),

            // 所有机构
            allOrgs: $translate.instant('AllOrganization'),

            // 所有税种
            allTaxs: $translate.instant('AllTax'),
            areaID: 'areaID',
            areaName: 'areaName',
            name: 'name',
            id: 'id',

            // UI事业部ID
            uiBusinessUnitID: 'org_businessUnit',
            // UI区域ID
            uiAreaID: 'org_Area',
            // UI机构ID
            uiOrgID: 'org_OrgTreeList',

            // ui税种
            uiTaxID: 'org_taxTreeList',


        };

        // 缓存的数据
        var thisData = {

            // 所有机构,包括无效,无权限的
            organizationList: [],

            // 有效的事业部列表,包括所有事业部,id,name,parentID, expanded
            businessUnitList: [],

            // 有效的区域列表,包括所有区域,id,name,parentID,expanded
            areaList: [],

            // 有效的机构列表,包括所有机构,id,name,parentID,expanded
            orgList: [],

            selectOrgMap: {},

            // 选中的事业ID部列表
            selectBusinessList: [],

            // 选中区域ID列表
            selectAreaList: [],

            // 选中机构ID列表
            selectOrgList: [],

            // 选中税种列表
            selectTaxList: [],

            // 默认drop down 展示的字符串
            businessUnitText: thisConstant.allBusinessUnits,
            areaText: thisConstant.allAreas,
            orgText: thisConstant.allOrgs,
            taxText: thisConstant.allTaxs,
        };

        // 临时数据,以后可能会从后台读取
        var thisTempData = {
            taxList: [
                { id: '823492374928739847329843', name: '增值税', selected: true }
            ],
        };



        var dataType = {
            isPrefixNumber: function (value) {
                var reg = /^\d+/;
                if (reg.test(value)) {
                    return true;
                } else {
                    return false;
                }
            },
            isPrefixChar: function (value) {
                var reg = /^[a-zA-Z]+/;
                if (reg.test(value)) {
                    return true;
                } else {
                    return false;
                }
            },
            isPrefixNumberOrChar: function (value) {
                if (dataType.isPrefixNumber(value)) {
                    return true;
                }

                if (dataType.isPrefixChar(value)) {
                    return true;
                }

                return false;
            }
        }

        var sortByName = function (data) {
            if (data && data.length > 0) {

                var charList = [];
                var nocharList = [];

                data.forEach(function (row) {
                    if (dataType.isPrefixNumberOrChar(row.name)) {
                        row.nameSort = row.name;

                        if (row.nameSort) {
                            row.nameSort = row.nameSort.toLowerCase();
                        }

                        charList.push(row);

                    } else {
                        nocharList.push(row);
                    }

                });

                charList = _.sortBy(charList, 'nameSort');

                nocharList = nocharList.sort(function compareFunction(param1, param2) {
                    return param1.name.localeCompare(param2.name, 'zh');
                });

                var all = _.union(charList, nocharList);
                return all;
            }

            return data;
        };

        // 本页面数据服务
        var thisUtilService = {

            getMap: function (data, idCol, nameCol, allName) {
                if (data && data.length > 0) {
                    var idList = _.uniq(_.pluck(data, idCol));
                    var list = [];

                    idList.forEach(function (row) {
                        if (row) {
                            var findOne = _.find(thisData.organizationList, function (o) {
                                return o[idCol] === row;
                            });

                            if (findOne && findOne[nameCol]) {
                                list.push({
                                    id: row,
                                    name: findOne[nameCol],
                                    selected: true,
                                });
                            }
                        }
                    });

                    list = sortByName(list);
                    return list;
                } else {
                    return [];
                }
            },
            getIDList: function (data) {
                if (data && data.length > 0) {
                    var list = _.pluck(data, thisConstant.id);

                    return list;
                }

                return [];
            },

            filterDropDownOrgList: function (orgList, selectIDList, idCol) {
                if (!orgList || orgList.length === 0) {
                    return orgList;
                }

                // 什么都没有选
                if (!selectIDList) {
                    return orgList;
                }

                // 按照条件进行过滤
                orgList = _.filter(orgList, function (row) {

                    return selectIDList.indexOf(row[idCol]) > -1;
                });

                return orgList;
            },


            // 过滤无查看权限的机构
            setOrgPermissionList: function (filter) {
                if (!filter && filter.length === 0) {
                    return filter;
                }

                if ($scope.queryPermissionCode) {
                    var permission = thisData.userPermission;
                    if (permission.isAdmin) {
                        filter.forEach(function (row) {
                            // 默认都是有权限的
                            row.isHaveOrganizationPermission = true;
                        });
                        return filter;
                    }

                    filter.forEach(function (row) {
                        row.isHaveOrganizationPermission = window.PWC.isHaveOrganizationPermission(row.id, $scope.queryPermissionCode, permission);
                    });

                    // 返回权限设置情况
                    return filter;
                } else {
                    filter.forEach(function (row) {
                        // 默认都是有权限的
                        row.isHaveOrganizationPermission = true;
                    });
                    return filter;
                }
            },
            filterOrgs: function () {
                if (thisData.organizationList && thisData.organizationList.length > 0) {

                    // 只要启用的和有权限的机构
                    var filter = _.filter(thisData.organizationList, function (row) {
                        return row.isActive && row.isHaveOrganizationPermission;
                    });

                    // var filter = thisData.organizationList;
                    // 过滤事业部
                    if (thisData.businessUnitText !== thisConstant.allBusinessUnits) {

                        // 没有选中所有事业部
                        if (thisData.selectBusinessList && thisData.selectBusinessList.length !== thisData.businessUnitList.length) {

                            filter = thisUtilService.filterDropDownOrgList(filter, thisData.selectBusinessList, thisConstant.businessUnitID);
                        }
                    }

                    // 过滤区域
                    if (thisData.areaText !== thisConstant.allAreas) {

                        // 没有选中所有区域
                        if (thisData.selectAreaList && thisData.selectAreaList.length != thisData.areaList.length) {

                            filter = thisUtilService.filterDropDownOrgList(filter, thisData.selectAreaList, thisConstant.areaID);
                        }
                    }

                    return filter;

                } else {
                    return [];
                }
            },

            // 获取机构drop down的list
            getOrgDropDownList: function () {
                var showList = thisUtilService.filterOrgs();
                showList = angular.copy(showList);
                 showList = sortByName(showList); 
                for (var i = 0; i < showList.length; i++) {
                    var item = showList[i];
                    item.selected = true;
                    if (item.parentID === null) {
                        continue;
                    }

                    var parentNode = _.find(showList, function (num) {
                        return num.id === item.parentID
                    });

                    if (parentNode) {
                        continue;
                    }

                    item.parentID = getParentID(item, thisData.organizationList, showList);
                }

                var idList = _.pluck(showList, 'id');

                $scope.selectedOrganizationList = idList;

                // var topNodeList = _.filter(showList, function(org) {
                //     return idList.indexOf(org.parentID) === -1;
                // });

                // var orgList = [];
                // topNodeList.forEach(function(org) {
                //     var item = {
                //         id: org.id,
                //         name: org.name,
                //     };

                //     // 构造子节点
                //     orgList.push(item);
                //     var tempList = thisUtilService.getSubOrgDropDownList(org, showList);
                //     orgList = _.union(orgList, tempList);
                // });

                // return orgList;

                return showList;
            },

            getSubOrgDropDownList: function (current, showList) {
                var sublist = _.filter(showList, function (row) {
                    return row.parentID === current.id;
                });

                var list = [];
                if (!sublist || sublist.length === 0) {
                    return list;
                }

                sublist.forEach(function (row) {
                    var item = {
                        id: row.id,
                        name: row.name,
                        parentID: current.id,
                        expanded: true,
                    }

                    list.push(item);

                    var tempList = thisUtilService.getSubOrgDropDownList(row, showList);
                    if (tempList && tempList.length > 0) {
                        list = _.union(list, tempList);
                    }

                });

                return list;
            },

            isChangedArray: function (newValue, oldValue) {
                if (!newValue && !oldValue) {
                    return false;
                }

                if (!newValue) {
                    return true;
                }

                if (!oldValue) {
                    return true;
                }

                if (newValue.length !== oldValue.length) {
                    return true;
                }

                // 排序
                newValue = newValue.sort();
                oldValue = oldValue.sort();

                for (var i = 0; i < newValue.length; i++) {
                    if (newValue[i] !== oldValue[i]) {
                        return true;
                    }
                }

                return false;
            }

        };

        // 获取父节点
        var getParentID = function (current, allList, orgDtoList) {
            if (current.parentID === null) {
                return null;
            }

            var findParent = _.find(allList, function (num) {
                return num.id === current.parentID;
            });

            if (!findParent) {

            }

            var parent = _.find(orgDtoList, function (num) {
                return num.id === findParent.id;
            });

            if (parent != null) {
                return parent.id;
            } else {
                return getParentID(findParent, allList, orgDtoList);
            }
        };

        // 主模块
        var mainModule = {
            main: function () {
                mainModule.initParams();
                if ($scope.queryPermissionCode) {
                    userService.getUserPermission(loginContext.userName).success(function (userPermission) {
                        thisData.userPermission = userPermission;
                        mainModule.loadData();
                    });
                } else {
                    mainModule.loadData();
                }
            },

            // 出事化参数
            initParams: function () {

                // 所有事业部
                $scope.selectedBusinessNames = thisConstant.allBusinessUnits;

                // 所有区域
                $scope.selectedareaNames = thisConstant.allAreas;

                // 所有机构
                $scope.selectedOrgNames = thisConstant.allOrgs;

                // 所有税种
                $scope.selectedTaxNames = thisConstant.allTaxs;
            },

            // 加载数据
            loadData: function () {

                orgService.getOrganizationFilterList().success(function (data) {
                    if (data && data.length > 0) {
                        data = thisUtilService.setOrgPermissionList(data);
                        thisData.organizationList = data;
                        thisData.orgList = thisUtilService.getOrgDropDownList();
                        thisData.businessUnitList = thisUtilService.getMap(thisData.orgList, thisConstant.businessUnitID, thisConstant.businessUnitName, thisConstant.allBusinessUnits);
                        thisData.selectBusinessList = thisUtilService.getIDList(thisData.businessUnitList);

                        thisData.areaList = thisUtilService.getMap(thisData.orgList, thisConstant.areaID, thisConstant.areaName, thisConstant.allAreas);
                        thisData.selectAreaList = thisUtilService.getIDList(thisData.areaList);

                        thisData.selectOrgList = thisUtilService.getIDList(thisData.orgList);

                        // 事业部drop down
                        mainModule.drawBusinessUnitDropDownList(thisConstant.uiBusinessUnitID, thisData.businessUnitList);

                        // 区域Drop down
                        mainModule.drawAreaDropDownList(thisConstant.uiAreaID, thisData.areaList);

                        $scope.selectedOrganizationList = thisData.selectOrgList;

                        // 机构dropDown
                        mainModule.drawOrgDropDownList(thisData.orgList);

                        // 绘制税种
                        thisData.selectTaxList = thisUtilService.getIDList(thisTempData.taxList);
                        mainModule.drawTaxDropDownList();
                    }
                });

                // 税种数据使用临时数据
                $scope.taxList = thisTempData.taxList;
            },
            // 事业部DropDownList
            drawBusinessUnitDropDownList: function (uiID, dataArray) {
                var syncTreeViewSelection = function (treeView, value) {
                    if (!value) {
                        treeView.unselectAll();
                        return;
                    }

                    value.forEach(function (key) {
                        treeView.selectItem(key);
                    });

                    var orgList = thisUtilService.getOrgDropDownList();
                    mainModule.drawOrgDropDownList(orgList);
                };


                var getText = function (value) {
                    var text = '';
                    if (value && value.length === dataArray.length) {
                        text = thisConstant.allBusinessUnits;
                    } else {
                        text = '选中' + value.length + '个事业部';
                    }

                    return text;
                };


                $("#" + uiID).dxDropDownBox({
                    // valueExpr: "id",
                    // displayExpr: "name",
                    value: thisConstant.allBusinessUnits,
                    showClearButton: false,
                    // dataSource: dataArray,
                    contentTemplate: function (e) {
                        var value = e.component.option("value"),
                            $treeView = $("<div>").dxTreeView({
                                dataSource: dataArray,
                                dataStructure: "plain",
                                keyExpr: "id",
                                parentIdExpr: "parentID",
                                selectionMode: "multiple",
                                displayExpr: "name",
                                selectByClick: true,
                                // onContentReady: function(args) {
                                //     syncTreeViewSelection(args.component, value);
                                // },
                                itemTemplate: function (itemData, itemIndex, itemElement) {
                                    itemElement.append("<span title='" + itemData.name + "'>" + itemData.name + "</span>");
                                },
                                selectNodesRecursive: true,
                                expandAllEnabled: true,
                                showCheckBoxesMode: "selectAll",
                                selectAllText: thisConstant.allBusinessUnits,
                                onItemSelectionChanged: function (args) {
                                    // console.log('事业部onItemSelectionChanged');
                                    // var value = args.component.getSelectedNodesKeys();
                                    // // e.component.option("value", value);
                                    // var text = '';
                                    // if (value && value.length === dataArray.length) {
                                    //     text = thisConstant.allBusinessUnits;
                                    // } else {
                                    //     text = '选中' + value.length + '个事业部';
                                    // }

                                    // thisData.selectBusinessList = value;
                                    // e.component.option("text", text);
                                    // $('#' + thisConstant.uiBusinessUnitID).dxDropDownBox('repaint');
                                    // thisData.businessUnitText = text;
                                    // syncTreeViewSelection(thisData.buTreeView, value);
                                },
                                onSelectionChanged: function (args) {


                                    var value = args.component.getSelectedNodesKeys();
                                    // e.component.option("value", value);
                                    var text = getText(value);

                                    thisData.selectBusinessList = value;
                                    e.component.option("value", text);
                                    // $('#' + +thisConstant.uiBusinessUnitID).dxDropDownBox('repaint');
                                    $('#' + +thisConstant.uiBusinessUnitID).dxDropDownBox('option', e.component.option());
                                    thisData.businessUnitText = text;
                                    syncTreeViewSelection(thisData.buTreeView, value);
                                }
                            });

                        thisData.buTreeView = $treeView.dxTreeView("instance");
                        thisData.businessUnitText = e.component.option("text");
                        // e.component.on("valueChanged", function(args) {
                        //     if (thisUtilService.isChangedArray(args.previousValue, args.value)) {
                        //         var value = args.value;
                        //         thisData.selectBusinessList = value;
                        //         thisData.businessUnitText = e.component.option("text");
                        //         syncTreeViewSelection(thisData.buTreeView, value);
                        //     }
                        // });

                        return $treeView;
                    }
                });
            },

            // 区域dropdownList
            drawAreaDropDownList: function (uiID, dataArray) {
                var syncTreeViewSelection = function (treeView, value) {
                    // if (!value) {
                    //     treeView.unselectAll();
                    //     return;
                    // }

                    // value.forEach(function(key) {
                    //     treeView.selectItem(key);
                    // });

                    thisData.selectAreaList = value;
                    var orgList = thisUtilService.getOrgDropDownList();
                    mainModule.drawOrgDropDownList(orgList);
                };

                var getText = function (value) {
                    var text = '';
                    if (value && value.length === dataArray.length) {
                        text = thisConstant.allAreas;
                    } else {
                        text = '选中' + value.length + '个区域';
                    }
                    return text;
                };

                $("#" + uiID).dxDropDownBox({
                    // valueExpr: "id",
                    // displayExpr: "name",
                    // placeholder: thisConstant.allAreas,
                    value: thisConstant.allAreas,
                    showClearButton: false,
                    // dataSource: dataArray,
                    contentTemplate: function (e) {
                        var value = e.component.option("value"),
                            $treeView = $("<div>").dxTreeView({
                                dataSource: dataArray,
                                dataStructure: "plain",
                                keyExpr: "id",
                                parentIdExpr: "parentID",
                                selectionMode: "multiple",
                                displayExpr: "name",
                                selectByClick: true,
                                // onContentReady: function(args) {
                                //     syncTreeViewSelection(args.component, value);
                                // },
                                itemTemplate: function (itemData, itemIndex, itemElement) {
                                    itemElement.append("<span title='" + itemData.name + "'>" + itemData.name + "</span>");
                                },
                                selectNodesRecursive: true,
                                expandAllEnabled: true,
                                showCheckBoxesMode: "selectAll",
                                selectAllText: thisConstant.allAreas,
                                onItemSelectionChanged: function (args) {
                                    // var value = args.component.getSelectedNodesKeys();
                                    // var text = '';
                                    // if (value && value.length === dataArray.length) {
                                    //     text = thisConstant.allAreas;
                                    // } else {
                                    //     text = '选中' + value.length + '个区域';
                                    // }

                                    // thisData.selectAreaList = value;
                                    // e.component.option("text", text);
                                    // $('#' + thisConstant.uiAreaID).dxDropDownBox('repaint');
                                    // thisData.areaText = text;
                                    // syncTreeViewSelection(thisData.areaTreeView, value);
                                },
                                onSelectionChanged: function (args) {
                                    var value = args.component.getSelectedNodesKeys();
                                    var text = getText(value);

                                    thisData.selectAreaList = value;
                                    e.component.option("value", text);
                                    // $('#' + thisConstant.uiAreaID).dxDropDownBox('repaint');
                                    thisData.areaText = text;
                                    syncTreeViewSelection(thisData.areaTreeView, value);
                                }
                            });

                        thisData.areaText = e.component.option("text");
                        thisData.areaTreeView = $treeView.dxTreeView("instance");

                        // e.component.on("valueChanged", function(args) {
                        //     if (thisUtilService.isChangedArray(args.previousValue, args.value)) {
                        //         var value = args.value;
                        //         thisData.areaText = args.component.option("text");
                        //         syncTreeViewSelection(thisData.areaTreeView, value);
                        //     }
                        // });

                        return $treeView;
                    }
                });
            },

            // 机构drop down list
            drawOrgDropDownList: function (data) {

                thisData.selectOrgList = _.pluck(data, 'id');

                $scope.onChanged({ model: thisData.selectOrgList });

                var syncTreeViewSelection = function (treeView, value, isReady) {
                    // if (!value) {
                    //     treeView.unselectAll();
                    //     return;
                    // }

                    // value.forEach(function(key) {
                    //     treeView.selectItem(key);
                    // });

                    if (isReady) {
                        $scope.selectedOrganizationList = thisData.selectOrgList;
                        $scope.onChanged({ model: thisData.selectOrgList });
                    } else {
                        $scope.selectedOrganizationList = value;
                        $scope.onChanged({ model: value });
                    }
                };


                var getText = function (value) {
                    var text = '';
                    if (value && value.length === data.length) {
                        text = thisConstant.allOrgs;
                    } else {
                        text = '选中' + value.length + '个机构';
                    }

                    return text;
                };


                thisData.orgDropDownInstantce = $("#" + thisConstant.uiOrgID).dxDropDownBox({
                    // valueExpr: "id",
                    // displayExpr: "name",
                    // placeholder: thisConstant.allOrgs,
                    value: thisConstant.allOrgs,
                    showClearButton: false,
                    // dataSource: data,
                    contentTemplate: function (e) {
                        var value = e.component.option("value"),
                            $treeView = $("<div>").dxTreeView({
                                dataSource: data,
                                dataStructure: "plain",
                                keyExpr: "id",
                                parentIdExpr: "parentID",
                                selectionMode: "multiple",
                                displayExpr: "name",
                                selectByClick: true,
                                noDataText: '',
                                itemTemplate: function (itemData, itemIndex, itemElement) {
                                    itemElement.append("<span title='" + itemData.name + "'>" + itemData.name + "</span>");
                                },
                                onContentReady: function (args) {
                                    // syncTreeViewSelection(args.component, value, true);
                                },
                                selectNodesRecursive: false,
                                expandAllEnabled: true,
                                showCheckBoxesMode: "selectAll",
                                selectAllText: thisConstant.allOrgs,
                                onItemSelectionChanged: function (args) {
                                    // var value = args.component.getSelectedNodesKeys();
                                    // var text = '';
                                    // if (value && value.length === data.length) {
                                    //     text = thisConstant.allOrgs;
                                    // } else {
                                    //     text = '选中' + value.length + '个机构';
                                    // }

                                    // thisData.selectOrgList = value;
                                    // e.component.option("text", text);
                                    // $('#' + thisConstant.uiOrgID).dxDropDownBox('repaint');
                                    // thisData.orgText = text;
                                    // syncTreeViewSelection(thisData.orgTreeView, value, false);
                                },
                                onSelectionChanged: function (args) {
                                    var value = args.component.getSelectedNodesKeys();
                                    var text = getText(value);
                                    thisData.selectOrgList = value;
                                    e.component.option("value", text);
                                    // $('#' + thisConstant.uiOrgID).dxDropDownBox('repaint');
                                    thisData.orgText = text;
                                    syncTreeViewSelection(thisData.orgTreeView, value, false);
                                }
                            });

                        thisData.orgTreeView = $treeView.dxTreeView("instance");
                        thisData.orgText = e.component.option("text");
                        // e.component.on("valueChanged", function(args) {
                        //     if (thisUtilService.isChangedArray(args.previousValue, args.value)) {
                        //         var value = args.value;

                        //         syncTreeViewSelection(thisData.orgTreeView, value, false);
                        //     }
                        // });

                        return $treeView;
                    }
                });
            },
            // 税种
            drawTaxDropDownList: function () {
                var syncTreeViewSelection = function (treeView, value, isReady) {
                    if (!value) {
                        treeView.unselectAll();
                        return;
                    }

                    value.forEach(function (key) {
                        treeView.selectItem(key);
                    });
                };

                var getText = function (value) {
                    var text = '';
                    if (value && value.length === thisTempData.taxList.length) {
                        text = thisConstant.allTaxs;
                    } else {
                        text = '选中' + value.length + '个税种';
                    }

                    return text;
                };

                $("#" + thisConstant.uiTaxID).dxDropDownBox({
                    value: thisConstant.allTaxs,
                    showClearButton: false,
                    dataSource: thisTempData.taxList,
                    contentTemplate: function (e) {
                        var value = e.component.option("value"),
                            $treeView = $("<div>").dxTreeView({
                                dataSource: e.component.option("dataSource"),
                                dataStructure: "plain",
                                keyExpr: "id",
                                parentIdExpr: "parentID",
                                selectionMode: "multiple",
                                displayExpr: "name",
                                selectByClick: true,
                                expandAllEnabled: true,
                                // showCheckBoxesMode: 'selectAll', 
                                // onContentReady: function(args) {
                                //     syncTreeViewSelection(args.component, value);
                                // },
                                selectNodesRecursive: true,
                                showCheckBoxesMode: "selectAll",
                                selectAllText: thisConstant.allTaxs,
                                onSelectionChanged: function (args) {
                                    var value = args.component.getSelectedNodesKeys();
                                    var text = getText(value);
                                    e.component.option("value", text);
                                }
                            });

                        thisData.taxTreeView = $treeView.dxTreeView("instance");
                        thisData.taxText = e.component.option("text");
 

                        return $treeView;
                    }
                });
            },

        };

        (function () {

            mainModule.main();
        })();

    }
]);
commonModule.directive('orgPermissionFilter', ['$log',
    function ($log) {
        'use strict';
        $log.debug('orgPermissionFilter.ctor()...');
        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/org-permission-filter/org-permission-filter.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                queryPermissionCode:'=?',
                selectedOrganizationList:'=?',
                onChanged: '&'
            },
            controller: 'OrgPermissionFilterController',
            link: function (scope, element) {

                // in dialog

            }
        };
    }
]);

commonModule.
controller('OrgSearchSelectorController', ['$scope', 'orgService', 'userService', 'loginContext', '$translate', '$timeout',
    function ($scope, orgService, userService, loginContext, $translate, $timeout) {

        // 本页面常量
        var thisConstant = {
            allOrgs: $translate.instant('PleaseSelect'),
            name: 'name',
            id: 'id',
        };

        // 缓存的数据
        var thisData = {

            // 所有机构,包括无效,无权限的
            organizationList: [],

            // 有效的机构列表,包括所有机构,id,name,parentID,expanded
            orgList: [],

            selectOrgMap: {},

            // 选中机构ID列表
            selectOrgList: [],

            orgText: thisConstant.allOrgs,

            selectOrg: null,

            // 查询机构字符串
            searchText: null
        };

        // 本页面数据服务
        var thisUtilService = {

            getMap: function (data, idCol, nameCol, allName) {
                if (data && data.length > 0) {
                    var idList = _.uniq(_.pluck(data, idCol));
                    var list = [];

                    idList.forEach(function (row) {
                        if (row) {
                            var findOne = _.find(thisData.organizationList, function (o) {
                                return o[idCol] === row;
                            });

                            if (findOne[nameCol]) {
                                list.push({
                                    id: row,
                                    name: findOne[nameCol]
                                });
                            }
                        }
                    });

                    return list;
                } else {
                    return [];
                }
            },

            getIDList: function (data) {
                if (data && data.length > 0) {
                    var list = _.pluck(data, thisConstant.id);

                    return list;
                }

                return [];
            },

            filterDropDownOrgList: function (orgList, selectIDList, idCol) {
                if (!orgList || orgList.length === 0) {
                    return orgList;
                }

                // 什么都没有选
                if (!selectIDList) {
                    return orgList;
                }

                // 按照条件进行过滤
                orgList = _.filter(orgList, function (row) {

                    return selectIDList.indexOf(row[idCol]) > -1;
                });

                return orgList;
            },

            // 过滤无查看权限的机构
            setOrgPermissionList: function (filter) {
                if (!filter && filter.length === 0) {
                    return filter;
                }

                if ($scope.queryPermissionCode || $scope.editPermissionCode) {
                    var permission = thisData.userPermission;
                    if (permission.isAdmin) {
                        filter.forEach(function (row) {
                            // 默认都是有权限的
                            row.isHaveOrganizationPermission = true;

                            // editPermissionCode
                            row.isHaveEditPermission = true;
                        });
                        return filter;
                    }

                    filter.forEach(function (row) {
                        if ($scope.queryPermissionCode) {
                            row.isHaveOrganizationPermission = window.PWC.isHaveOrganizationPermission(row.id, $scope.queryPermissionCode, permission);
                        }

                        if ($scope.editPermissionCode) {
                            row.isHaveEditPermission = window.PWC.isHaveOrganizationPermission(row.id, $scope.editPermissionCode, permission);
                        }
                    });

                    // 返回权限设置情况
                    return filter;
                } else {
                    filter.forEach(function (row) {
                        // 默认都是有权限的
                        row.isHaveOrganizationPermission = true;
                    });
                    return filter;
                }
            },

            filterOrgs: function () {
                if (thisData.organizationList && thisData.organizationList.length > 0) {

                    // 只要启用的和有权限的机构,或者当前选中的机构
                    var filter = _.filter(thisData.organizationList, function (row) {
                        return (row.isActive || row.id === $scope.editOrgId) && row.isHaveOrganizationPermission;
                    });

                    // 过滤value 相似的字段
                    if (thisData.searchText) {
                        thisData.searchText = thisData.searchText.toLowerCase();
                        filter = _.filter(filter, function (row) {
                            if (row.name) {
                                var a = row.name.toLowerCase();
                                if (a.indexOf(thisData.searchText) > -1) {
                                    return true;
                                }
                            }

                            return false;
                        });
                    }

                    return filter;

                } else {
                    return [];
                }
            },

            // 获取机构drop down的list
            getOrgDropDownList: function () {
                var showList = thisUtilService.filterOrgs();
                showList = angular.copy(showList);
                for (var i = 0; i < showList.length; i++) {
                    var item = showList[i];
                    if (item.parentID === null) {
                        continue;
                    }

                    var parentNode = _.find(showList, function (num) {
                        return num.id === item.parentID
                    });

                    if (parentNode) {
                        continue;
                    }

                    item.parentID = getParentID(item, thisData.organizationList, showList);
                }

                var idList = _.pluck(showList, 'id');

                $scope.selectedOrganizationList = idList;

                // var topNodeList = _.filter(showList, function(org) {
                //     return idList.indexOf(org.parentID) === -1;
                // });

                // var orgList = [];
                // topNodeList.forEach(function(org) {
                //     var item = {
                //         id: org.id,
                //         name: org.name,
                //     };

                //     // 构造子节点
                //     orgList.push(item);
                //     var tempList = thisUtilService.getSubOrgDropDownList(org, showList);
                //     orgList = _.union(orgList, tempList);
                // });

                // return orgList;

                return showList;
            },

            getSubOrgDropDownList: function (current, showList) {
                var sublist = _.filter(showList, function (row) {
                    return row.parentID === current.id;
                });

                var list = [];
                if (!sublist || sublist.length === 0) {
                    return list;
                }

                sublist.forEach(function (row) {
                    var item = {
                        id: row.id,
                        name: row.name,
                        parentID: current.id,
                        expanded: true,
                    }

                    list.push(item);

                    var tempList = thisUtilService.getSubOrgDropDownList(row, showList);
                    if (tempList && tempList.length > 0) {
                        list = _.union(list, tempList);
                    }

                });

                return list;
            },

            // 数组是否发生变化
            isChangedArray: function (newValue, oldValue) {
                if (!newValue && !oldValue) {
                    return false;
                }

                if (!newValue) {
                    return true;
                }

                if (!oldValue) {
                    return true;
                }

                if (newValue.length !== oldValue.length) {
                    return true;
                }

                // 排序
                newValue = newValue.sort();
                oldValue = oldValue.sort();

                for (var i = 0; i < newValue.length; i++) {
                    if (newValue[i] !== oldValue[i]) {
                        return true;
                    }
                }

                return false;
            },

            // 异步选择机构
            synSelectOrg: function (values) {
                if (values && values.length === 1) {
                    var orgid = values[0];
                    if ($scope.selectedOrgId !== orgid) {
                        var selectModel = _.find(thisData.orgList, function (row) {
                            return row.id === orgid;
                        });


                        if (selectModel) {

                            $timeout(function () {
                                $scope.selectedOrgId = selectModel.id;
                                $scope.selectedOrgName = selectModel.name;
                                $scope.selectedOrgModel = selectModel;
                            }, 50);

                            // $scope.selectionChanged();
                            // console.log('选中的为:' + JSON.stringify(selectModel));
                        }
                    }
                }
            }

        };

        // 获取父节点
        var getParentID = function (current, allList, orgDtoList) {
            if (current.parentID === null) {
                return null;
            }

            var findParent = _.find(allList, function (num) {
                return num.id === current.parentID;
            });

            var parent = _.find(orgDtoList, function (num) {
                return num.id === findParent.id;
            });

            if (parent != null) {
                return parent.id;
            } else {
                return getParentID(findParent, allList, orgDtoList);
            }
        };

        // 主模块
        var mainModule = {
            main: function () {
                mainModule.initParams();
                if ($scope.queryPermissionCode) {
                    userService.getUserPermission(loginContext.userName).success(function (userPermission) {
                        thisData.userPermission = userPermission;
                        mainModule.loadData();
                    });
                } else {
                    mainModule.loadData();
                }
            },

            // 出事化参数
            initParams: function () {

                // 所有机构
                $scope.selectedOrgNames = thisConstant.allOrgs;

                // 搜素框ID
                $scope.searchTextBox = window.PWC.newGuid();

                // drop down 的ID
                $scope.orgTreeDropDownID = window.PWC.newGuid();

                // 机构树ID
                $scope.orgTreeID = window.PWC.newGuid();

                // 机构树的Div
                thisData.orgTreeDiv = '<div id="' + $scope.orgTreeID + '">';
                thisData.searchBoxDiv = '<div id="' + $scope.searchTextBox + '">';




            },

            // 加载数据
            loadData: function () {

                orgService.getOrganizationFilterList().success(function (data) {
                    if (data && data.length > 0) {
                        data = thisUtilService.setOrgPermissionList(data);
                        thisData.organizationList = data;

                        thisData.orgList = thisUtilService.getOrgDropDownList();
                        if ($scope.selectedOrgId && $scope.selectedOrgId.length > 0) {
                            thisData.selectOrgList = [];
                            thisData.selectOrgList.push($scope.selectedOrgId);

                            thisData.orgText = $scope.selectedOrgName;
                        } else {
                            if ($scope.isFirstDefault) {
                                thisData.selectOrgList = [];

                                if (thisData.orgList && thisData.orgList.length > 0) {


                                    thisData.selectOrgList.push(thisData.orgList[0].id);

                                    thisData.orgText = thisData.orgList[0].name;
                                }
                            }
                        }

                        $scope.selectedOrganizationList = thisData.selectOrgList;

                        // 机构dropDown
                        mainModule.drawOrgDropDownList(thisData.orgList);


                    }
                });
            },
            drawOrgDropDownList: function (data) {

                // thisData.selectOrgList = _.pluck(data, 'id');

                // 异步处理选中状态
                var syncTreeViewSelection = function (treeView, value, isReady) {
                    if (!value && isReady && treeView) {

                        treeView.unselectAll();
                        return;
                    }

                    if (treeView && isReady) {
                        value.forEach(function (key) {
                            treeView.selectItem(key);
                        });
                    }


                    if (isReady) {
                        $scope.selectedOrganizationList = thisData.selectOrgList;
                    } else {
                        $scope.selectedOrganizationList = value;
                    }

                    thisUtilService.synSelectOrg(value);
                };

                // 初始化orgTreeView
                var renderOrgTreeView = function (e, data, value) {
                    $treeView = $(thisData.orgTreeDiv).dxTreeView({
                        dataSource: data,
                        dataStructure: "plain",
                        keyExpr: "id",
                        parentIdExpr: "parentID",
                        selectionMode: "single",
                        displayExpr: "name",
                        selectByClick: true,
                        noDataText: '',
                        value: thisData.selectOrgList,
                        height: '300px',
                        itemTemplate: function (itemData, itemIndex, itemElement) {
                            itemElement.append("<span title='" + itemData.name + "'>" + itemData.name + "</span>");
                        },
                        onContentReady: function (args) {
                            var value = args.component.option("value");
                            syncTreeViewSelection(args.component, value, true);
                        },
                        selectNodesRecursive: false,
                        expandAllEnabled: true,
                        showCheckBoxesMode: "none",
                        selectAllText: thisConstant.allOrgs,
                        onItemSelectionChanged: function (args) {
                            var value = args.component.getSelectedNodesKeys();
                            e.component.option("value", value);
                            // syncTreeViewSelection(args.component, value, false);


                        },
                        onSelectionChanged: function (args) {

                            // 没什么卵用
                            // var value = args.component.getSelectedNodesKeys();
                            // e.component.option("value", value);
                        }
                    });

                    thisData.orgTreeView = $treeView.dxTreeView("instance");
                    // thisData.orgDxTreeView = $treeView;
                    return $treeView;
                };

                // 搜索框发生变化时
                var searchTextChange = function (value) {
                    if (thisData.searchText === value) {
                        return;
                    }
                    thisData.searchText = value;
                    var orgList = thisUtilService.getOrgDropDownList();
                    var o = $('#' + $scope.orgTreeID).dxTreeView('option');
                    o.dataSource = orgList;
                    o.value = '';
                    $('#' + $scope.orgTreeID).dxTreeView('option', o);
                };

                var treeViewDiv = $('#' + $scope.orgTreeDropDownID);

                thisData.orgDropDownInstantce = treeViewDiv.dxDropDownBox({
                    value: thisData.selectOrgList[0],
                    valueExpr: "id",
                    displayExpr: "name",
                    // placeholder: thisConstant.allOrgs,
                    text: thisData.orgText,
                    showClearButton: false,
                    dataSource: data,
                    onContentReady: function (args) {
                        var value = args.component.option("value");
                        syncTreeViewSelection(thisData.orgTreeView, thisData.selectOrgList, false);
                    },
                    contentTemplate: function (e) {
                        thisData.DropDownEvent = e;
                        var value = e.component.option("value");
                        var $treeView = renderOrgTreeView(e, data, value);

                        e.component.on("valueChanged", function (args) {
                            if (thisUtilService.isChangedArray(args.previousValue, args.value)) {
                                var value = args.value;

                                syncTreeViewSelection(thisData.orgTreeView, value, false);
                                // $scope.selectionChanged();
                                $('#' + $scope.orgTreeDropDownID).dxDropDownBox('close');
                            }
                        });

                        var textBox = $(thisData.searchBoxDiv).dxTextBox({
                            placeholder: "搜索",
                            mode: "search",
                            onValueChanged: function (args) {
                                var value = args.value;
                                searchTextChange(value);
                            },
                            onKeyUp: function (args) {
                                var value = $(args.element).dxTextBox('option').text;
                                searchTextChange(value);
                            }
                        });

                        var wrapper = $("<div>").append(textBox).append('<br/>').append($treeView);

                        return wrapper;
                    }
                });

                // if ($scope.isFirstDefault) {
                //     syncTreeViewSelection(thisData.orgTreeView, thisData.orgList, false);
                // }
            }

        };

        (function () {

            mainModule.main();
        })();

    }
]);
commonModule.directive('orgSearchSelector', ['$log',
    function($log) {
        'use strict';
        $log.debug('orgSearchSelector.ctor()...');
        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/org-search-selector/org-search-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                selectedOrgName: '=',
                selectedOrgId: '=',
                selectedOrgModel: '=?',
                queryPermissionCode: '=?',
                isFirstDefault:'=?',
                editPermissionCode: '=?',
                editOrgId:'=?'

            },
            controller: 'OrgSearchSelectorController',
            link: function(scope, element) {
 
            }
        };
    }
]);
commonModule.
controller('orgSelectorModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', '$filter', 'SweetAlert', 'orgService', 'userService','$rootScope',
function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, $filter, SweetAlert, orgService, userService,$rootScope) {
        $scope.gridInstance = null;
        var modalSelector = '#addOrgModal';
        var showWarning = function (resultMsg) {
            var errMsg = $translate.instant(resultMsg);
            SweetAlert.warning(errMsg);
        };

        var showSuccessMsg = function (resultMsg) {
            var errMsg = $translate.instant(resultMsg);
            SweetAlert.success(errMsg);
        };

        $(".addOrgModal").on("hidden.bs.modal", function () {
        });

        $scope.$watch("operation", function (newValue, oldValue) {
            if (newValue && newValue.type === 'open') {
                $scope.selectedOrgList = [];
                $scope.selectedKeyItems = angular.copy($scope.selectedOrgs);
                getOrgList();
                $(modalSelector).modal("show");
                isOpened = true;
            }
        });

        //$scope.$on("openOrgSelectorModel", function (event,data) {
        //    $scope.selectedOrgList = [];
        //    //copy = data;
        //    data = [];
        //    $scope.selectedKeyItems = angular.copy(data);;
        //    getOrgList();
        //    $(modalSelector).modal("show");
        //});

        $scope.Save = function ()
        {
            $scope.selectedOrgs = $scope.selectedKeyItems;
            $rootScope.$broadcast('orgsChanged', $scope.selectedKeyItems);

            $(modalSelector).modal("hide");
        };

        var setSelectItems=function(selectedKeyItems)
        {
            //设置选中
            $timeout(function () {
                $scope.gridInstance.clearSelection();
                if (selectedKeyItems && selectedKeyItems.length > 0) {
                    $scope.gridInstance.selectRows(selectedKeyItems, true);
                }
            }, 100); 
        };

        var getOrgList = function () {
            if (!$scope.DataGridSource) {
                orgService.getOrgListLevel().success(function (data) {
                    if (data) {
                        $scope.DataGridSource = data;
                        setSelectItems($scope.selectedKeyItems);
                    }
                });
            }
            else {
                setSelectItems($scope.selectedKeyItems);
            }
        };

        var loadDatagrid = function () {
            $scope.orgDataGridOptions = {
                bindingOptions: {
                    dataSource: 'DataGridSource'
                }, 
                columns: [
                        {
                            dataField: "name",
                            caption: $translate.instant('OrganizationName'),
                            width:200
                        },
                        {
                            dataField: "businessUnitName",
                            caption: $translate.instant('BusinessUnit')
                        },
                        {
                            dataField: "areaName",
                            caption: $translate.instant('AreaTitleName'),
                            width:100
                        },
                        {
                            dataField: "industryName",
                            caption: $translate.instant('PIndustry')
                        }
                ],

                loadPanel: {
                    enabled: true
                },
                scrolling: {
                    mode: "virtual"
                },
                keyExpr: "id",
                parentIdExpr: "parentID",
                selection: {
                    mode: "multiple",
                    showCheckBoxesMode: "always",
                    allowSelectAll: false
                },
                allowColumnResizing: true,
                columnAutoWidth: true,
                showRowLines: true,
                showColumnLines: true,
                autoExpandAll: true,
             
                rowAlternationEnabled: true,  //单双行颜色
                noDataText: $translate.instant('NoDataText'),
                showBorders: true,
                //sorting: {
                //    mode: "none"
                //},
                searchPanel: {
                    placeholder: $translate.instant('Search'),
                    width:518,
                    visible: true
                },
                onInitialized: function (e) {
                    $scope.gridInstance = e.component;
                },
                onSelectionChanged: function (e) {
                    //只有orgID List
                    $scope.selectedKeyItems = e.selectedRowKeys;;
                },
                onRowPrepared: function (e) {
                    //if (e && e.data) {
                    //    if ($scope.originalList.indexOf(e.data.id) > -1)
                    //    {
                    //        e.rowElement.addClass("dx-state-disabled");
                    //    }
                    //}
                },
                onContentReady: function (e, container)
                {
                }
            };

        };

        (function initialize() {
            $log.debug('addExistOrganizationModalController.ctor()...');
        
            loadDatagrid();
           // showModal();
        })();
    }
]);

commonModule.directive('orgSelectorModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('orgSelectorModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/org-selector-modal/org-selector-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'orgSelectorModalController',
            scope:
            {
                selectedOrgs: '=',
                operation:'='
            } ,
            link: function (scope, element) {
            }
        };
    }
]);
commonModule.controller('orgSelectorController', ['$scope', 'orgService', '$translate', 'userService', 'loginContext',
function ($scope, orgService, $translate, userService, loginContext) {

    var NoOptions = {
        'id': constant.organization.parentIdNull,
        'name': $translate.instant('OrgSelectNoOption')
    };
    var selectorg = $translate.instant('SelectOrg');
    $scope.pleaseSelect =  $translate.instant('PleaseSelect') ;
    $scope.init = function () {

        //设置每一项的默认最大长度
        $scope.itemMaxLength = angular.isDefined($scope.itemMaxLength) ? $scope.itemMaxLength : constant.organization.defaultMaxLength;

        $scope.isRequire = angular.isDefined($scope.itemMaxLength) ? $scope.isRequire : true;

        $scope.isAdminUser = false;
        var useType = $scope.isShowAll ? 1 : 0;
        orgService.getOrgList(useType).success(function (data) {
            if (data && data.length > 0) {
                if ($scope.selectNoOption) {
                    data.splice(0, 0, NoOptions);
                }

                if (!$scope.queryOrganizationCode && !$scope.editOrganizationCode) {

                    // 设置机构树和默认值
                    setDataAndFirstDefault(data);

                    setSelectOrg();
                } else {
                    getUserOrganzationPermission(data);
                }
            }
        });
    };


    $scope.selectedOrg = null;

    $scope.getSelectedOrgDisplayText = function () {
        if ($scope.selectedOrgId != null) {
            return $scope.selectedOrgName;
        } else {
            return '';
        }
    };

    $scope.selectOrg = function (org) {
        $scope.selectedOrgName = org.name;
        $scope.selectedOrgId = org.id;
        $scope.componentSelectedOrg = org;

        $('.dropdown').removeClass('open');

        $("#selectedOrgName").val(org.name);
        if ($("#selectedOrgName").val() != null && $("#selectedOrgName").val() != selectorg && $("#selectedOrgName").val() != '') {
            $("#selectedOrgName-error").hide();
        } else {
            $("#selectedOrgName-error").show();
        }
    };

    $scope.loadParentData = function () {
        $scope.loadData();
    };

    $scope.getNumber = function (num) {
        if (!num) {
            num = 0;
        }

        return new Array(num);
    }

    var findOrg = function (orgid, data) {
        if (data && data.length > 0) {
            var target = _.find(data, function (num) {
                return num.id === orgid
            });

            if (target) {
                return target;
            }

            for (var i = 0; i < data.length - 1; i++) {
                var row = data[i];
                target = findOrg(orgid, row.subOrgs);
                if (target) {
                    return target;
                }
            }
        }

        return null;
    };

    var setSelectOrg = function () {
        if ($scope.selectedOrgId && !$scope.selectedOrgName) {
            var target = findOrg($scope.selectedOrgId, $scope.orgList);
            if (target) {
                $scope.selectOrg(target);
            }
        }
    };

    $scope.$watch('selectedOrgId', function (newValue, oldValue) {
        if (newValue !== oldValue) {

            if ($scope.componentSelectedOrg) {
                if ($scope.isAdminUser) {
                    $scope.componentSelectedOrg.isHaveQueryPermission = true;
                    $scope.componentSelectedOrg.isHaveEditPermission = true;
                }
            }

            $scope.loadParentData();
        }

        // 强制重新取数据
        if ($scope.componentSelectedOrg && $scope.componentSelectedOrg.forceRefresh) {
            $scope.init();
        }
    });

    // 获取所有机构列表
    var getAllOrganizationList = function (orgList) {
        var showIDList = [];
        orgList.forEach(function (row) {
            showIDList.push(row);
            if (row.subOrgs && row.subOrgs.length > 0) {
                var tempIDList = getAllOrganizationList(row.subOrgs);
                if (tempIDList && tempIDList.length > 0) {
                    showIDList = _.union(showIDList, tempIDList);
                }
            }
        });

        return showIDList;
    };

    // 设置机构权限
    var setOrgPermission = function (orgList, userPermission) {

        orgList.forEach(function (row) {
            row.isHaveQueryPermission = window.PWC.isHaveOrganizationPermission(row.id, $scope.queryOrganizationCode, userPermission);
            row.isHaveEditPermission = window.PWC.isHaveOrganizationPermission(row.id, $scope.editOrganizationCode, userPermission);
        });

        return orgList;
    };

    // 获取父节点
    var getParentID = function (current, allList, orgDtoList) {
        if (current.parentID === null) {
            return null;
        }

        var findParent = _.find(allList, function (num) {
            return num.id === current.parentID;
        });

        var parent = _.find(orgDtoList, function (num) {
            return num.id === findParent.id;
        });

        if (parent != null) {
            return parent.id;
        } else {
            return getParentID(findParent, allList, orgDtoList);
        }
    };

    // tree 数据
    var buildOrgTree = function (or, orgList) {

        var orgItem = or;
        var selfDimensionIndex = 1;

        var sublist = _.filter(orgList, function (org) {
            return org.parentID === or.id;
        });

        var children = [];

        if (sublist != null && sublist.length > 0) {
            sublist.forEach(function (org) {
                var temp = buildOrgTree(org);
                children.push(temp);
            });
        }

        orgItem.subOrgs = children;

        return orgItem;
    };


    // 设置第一个机构为默认选择机构
    var setDataAndFirstDefault = function (orgTreeList) {
        $scope.orgList = orgTreeList;
        if ($scope.isFirstDefault) {
            if (orgTreeList && orgTreeList.length > 0) {
                $scope.selectedOrgId = orgTreeList[0].id;
                $scope.selectedOrgName = orgTreeList[0].name;
                $scope.componentSelectedOrg = orgTreeList[0];
            } else {
                $scope.selectedOrgId = null;
                $scope.selectedOrgName = null;
                $scope.componentSelectedOrg = {};
            }
        }
    };

    // 获取设置权限后的机构树
    var getUserOrganzationTreeList = function (orgTreeList, userPermission) {

        if (userPermission.isAdmin) {
            $scope.isAdminUser = true;

            // 默认选中第一条数据
            setDataAndFirstDefault(orgTreeList);

        } else {

            // 转换成机构列表
            var allOrgList = getAllOrganizationList(orgTreeList);

            // 设置机构权限
            var setOrgPermissionList = setOrgPermission(allOrgList, userPermission);

            // 获取有查看或者编辑权限的机构
            var showList = _.filter(setOrgPermissionList, function (row) {
                return row.isHaveQueryPermission || row.isHaveEditPermission;
            });

            // 重新设置上级节点
            for (var i = 0; i < showList.length; i++) {
                var item = showList[i];
                if (item.parentID === null) {
                    continue;
                }

                var parentNode = _.find(showList, function (num) {
                    return num.id === item.parentID
                });

                if (parentNode) {
                    continue;
                }

                item.parentID = getParentID(item, setOrgPermissionList, showList);
            }

            // 构造树形结构
            // 获取所有根节点的机构
            var idList = _.pluck(showList, 'id');
            var topNodeList = _.filter(showList, function (org) {
                return idList.indexOf(org.parentID) === -1;
            });

            // 构造树形列表
            var orglist = [];
            topNodeList.forEach(function (org) {
                var temp = buildOrgTree(org, showList);
                orglist.push(temp);
            });

            // 设置机构树和默认值
            setDataAndFirstDefault(orglist);
        }

    };

    // 获取用户机构权限
    var getUserOrganzationPermission = function (orgData) {
        userService.getUserPermission(loginContext.userName).success(function (userPermission) {
            getUserOrganzationTreeList(orgData, userPermission);
            setSelectOrg();
        });
    };

    $scope.init();

    $scope.isOpen = false;
    $scope.closeDropdown = function ($event) {
        var elem = $event.originalEvent.srcElement;
        if ($(elem).hasClass("fa")) {
            $scope.isOpen = true;
            $event.preventDefault();
            $event.stopPropagation();
        }
    }
}
]);
commonModule.directive('orgSelector', [
    '$log', function ($log) {
        'use strict';

        $log.debug('orgSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/org-selector/org-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                selectedOrgCode: '=',
                selectedOrgName: '=',
                selectedOrgId: '=',
                componentSelectedOrg: '=',
                isShowAll: '=',
                selectNoOption: '=',
                loadData: '&',
                itemMaxLength: '=?',
                isRequire: '=?',
                queryOrganizationCode: '=?',
                editOrganizationCode: '=?',
                isFirstDefault: '=?',
            },
            controller: 'orgSelectorController',
            link: function (scope, element) {
            }
        };
    }
]);
commonModule.
controller('OrgUserListController', ['$scope', 'orgService', '$log', 'uiGridTreeViewConstants', '$timeout', 'areaService', 'uiGridConstants', '$translate', '$interval', '$q',
    function ($scope, orgService, $log, uiGridTreeViewConstants, $timeout, areaService, uiGridConstants, $translate, $interval, $q) {
        'use strict';

        $scope.collapse = function () {
            $scope.gridApi.treeBase.expandAllRows();
        }

        $scope.getGridHeight = function () {
            return {};
        };

        $scope.getOrgUserList = function (orgId) {

            var deferred = $q.defer();
            var promise = deferred.promise;

            //var orgId = '81a3df63-b87d-4d7f-b3af-54169c13fa15';
            orgService.getOrgUserList(orgId).success(function (data) {
                 
                data.forEach(function (row) {
                    if (row.isUserType != null && row.isUserType!==undefined && row.isUserType===true) {
                        row.$$treeLevel = 0;
                    } else {
                        row.$$treeLevel = 1;
                    }
                });

                //往uigrid填充数据并默认展开所有的节点
                $scope.areaORGGridList.data = data;

                $timeout(function () {
                    $scope.gridApi.treeBase.expandAllRows();

                }, 500);

                deferred.resolve(data);
            });

            return deferred.promise;
        };

        var areaORGGridInit = function () {
            $scope.areaORGGridList = {
                enableRowSelection: true,
                enableSelectAll: false,
                rowHeight: 30,
                enableRowHeaderSelection: false,
                modifierKeysToMultiSelect: false,
                enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
                enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,

                enableSorting: true,
                enableColumnMenus: false,
                enableFiltering: false,
                showTreeExpandNoChildren: false,
                enableFullRowSelection: true, //是否点击行任意位置后选中,默认为false
                multiSelect: false, // 是否可以选择多个,默认为true; 
                columnDefs: [{
                    field: 'orgUser',
                    name: $translate.instant('OrgUser'),
                    headerCellClass: '',
                    width: '60%',
                    cellTemplate: '<div ng-class="{true: \'text-bold\', false: \'xxx\'}[row.entity.isUserType]"><span title="{{row.entity.orgUser}}">{{row.entity.orgUser|limitString:16}}</span></div>'
                }, {
                    field: 'orgUserAction',
                    name: $translate.instant('OrgUserAction'),
                    headerCellClass: '',
                    width: '40%',
                    //cellTemplate: '<div ng-class="{true: \'text-align-left\', false: \'xxx\'}[row.entity.isUserType]"><span title=""><i class="fa fa-pencil-square-o" aria-hidden="true"></i>&nbsp; <i class="fa fa-trash" aria-hidden="true"></i></span></div>'
                    cellTemplate:''
                }],
                onRegisterApi: function (gridApi) {

                    $scope.gridApi = gridApi;

                    $scope.gridSelectCount = $scope.gridApi.selection.getSelectedRows().length;
                    var onRowsRenderedOff = gridApi.core.on.rowsRendered(null, function () {
                        onRowsRenderedOff(); // run once
                        PWC.triggerRowSelectOnClick('#etsGrid'); // requires '.ui-grid-canvas'
                    });
                    // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                    $interval(function () {
                        $scope.gridApi.core.handleWindowResize();
                    }, 500, 60 * 60 * 8);

                }
            };

        };

        $scope.test = function () {
            $scope.testOrgID = '81a3df63-b87d-4d7f-b3af-54169c13fa15';
            $scope.getOrgUserList($scope.testOrgID).then(function () {

            });
        };


        (function initialize() {
            $log.debug('OrgUserListController.ctor()...');

            areaORGGridInit();

        })();
    }
]);
commonModule.directive('orgUserList', ['$log', '$compile', '$timeout', '$interval',
    function ($log, $compile, $timeout, $interval) {
        'use strict';
        $log.debug('orgUserList.ctor()...');

        return {
            restrict: 'AE',
            templateUrl: '/app/common/controls/org-user-list/org-user-list.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                orgIdUserList: '=',
                isRenderCompletedUserList: '='
            },
            controller: 'OrgUserListController',
            link: function (scope, element) {
                scope.$watch('orgIdUserList', function (newValue, oldValue) {
                    if (newValue !== oldValue) {

                        var orgId = newValue.substring(0, newValue.indexOf('|'));
                        //refresh ui grid with new data
                        scope.getOrgUserList(orgId).then(function () {
                            scope.isRenderCompletedUserList = true;
                        });
                    }

                    //点击弹出的面板,禁止冒泡事件
                    $("#orgUserListPop").on("click", function (e) {
                        e.stopPropagation();
                    });
                     
                })
            }
        };
    }
]);
commonModule.controller('outputInvoiceCancelController', ['$scope', '$log', '$uibModal', '$document', 'modalAdapterService',
    function ($scope, $log, $uibModal,$document, modalAdapterService) {
       
    }
]);
commonModule.directive('outputInvoiceCancel', ['$log', '$uibModal', '$document', 'modalAdapterService',
    function ($log, $uibModal, $document, modalAdapterService) {
        'use strict';
        $log.debug('orgUserList.ctor()...');
        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/output-invoice-cancel-modal/output-invoice-cancel-modal.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                parentElement:'@',
                cancelTitle: '=',
                callBack:'&',

            },
            controller: 'outputInvoiceCancelController',
            link: function ($scope, $element, attrs) {
                // ensure id attribute exists
                if (!attrs.id) {
                    console.error('modal must have an id');
                    return;
                }
                console.log($scope.cancelTitle);
                $scope.cancelDialog = {
                    confirm: function () {
                        if (_.isFunction($scope.callBack)) {
                            $scope.callBack();
                        }
                    },
                    //id: 'cancelGDModal.html',
                    id: attrs.id,
                    parentID:$scope.parentElement,
                    modalInstance: null,
                    open: function () {
                        var parentElem = $scope.parentElement ?
                                    angular.element($document[0].querySelector('.' + $scope.parentElement)) : undefined;
                        $scope.cancelDialog.modalInstance = $uibModal.open({
                            animation: false,
                            //backdrop: false,
                            ariaLabelledBy: 'modal-title',
                            ariaDescribedBy: 'modal-body',
                            templateUrl: 'cancelGDModal.html',
                            //windowClass: 'GD-Vechicle-detail',
                            scope: $scope,
                            appendTo: parentElem
                        });

                    },
                    cancel: function () {
                        $scope.cancelDialog.modalInstance.dismiss('cancel');
                       // $scope.cancelDialog.modalInstance = null;
                    }

                };
                modalAdapterService.add($scope.cancelDialog);
                // remove self from modal service when directive is destroyed
                $scope.$on('$destroy', function () {
                    modalAdapterService.remove(attrs.id, $scope.cancelDialog.parentID);
                    $element.remove();
                });
            }
        };
    }]);


commonModule.
controller('permissionSelectorController', ['$scope', 'menuService', 'permissionService', '$translate',
    function ($scope, menuService, permissionService, $translate) {

        $scope.serviceType = constant.serviceType.VAT;
        $scope.selectedItemData = [];

        $scope.$watch('selectedPermissionNames', function (newValue, oldValue) {
            //先全部清空
            $scope.widgetInstance.unselectAll();
            $scope.selectedItemData = [];
        });

        var addSelectedItemData = function (node) {

            $scope.selectedItemData.push(node.itemData);

            if (node.children && node.children.length > 0) {
                node.children.forEach(function (item) {
                    $scope.selectedItemData.push(item.itemData);
                    addSelectedItemData(item);
                });
            }
        };

        var removeSelectedItemData = function (node) {

             $scope.selectedItemData = _.without($scope.selectedItemData, _.find($scope.selectedItemData, function (item) {
                            return item.id === node.key
                        }));

            if (node.children && node.children.length > 0) {
                node.children.forEach(function (item) {
                      $scope.selectedItemData = _.without($scope.selectedItemData, _.find($scope.selectedItemData, function (sub) {
                          return sub.id === item.key
                        }));
                    removeSelectedItemData(item);
                });
            }
        };

        $scope.searchOptions = {
            bindingOptions: {
                value: "searchValue"
            },
            placeholder: $translate.instant('Search'),
            width: '92%',
            mode: "search",
            valueChangeEvent: "keyup"
        };

        //初始化dx-tree-view结构
        var loadAllPermissionTree = function () {
            $scope.allPermissionTreeViewOptions = {
                bindingOptions: {
                    dataSource: 'allPermissionTreeViewData',
                    searchValue: 'searchValue',
                    expandAllEnabled: 'expandAll'
                },
                dataStructure: "plain",
                selection: {
                    mode: "multiple"
                },
                loadPanel: {
                    enabled: true
                },
                scrolling: {
                    mode: "virtual"
                },
                keyExpr: "id",
                showRowLines: true,
                showColumnLines: true,
                rowAlternationEnabled: true,
                showBorders: true,
                selectAllText: $translate.instant('SelectAll'),
                scrollDirection: 'vertical',  //Accepted Values: 'vertical' | 'horizontal' | 'both'
                selectNodesRecursive: true,  //级联选择
                showCheckBoxesMode: 'normal',  //Accepted Values: 'none' | 'normal' | 'selectAll'
                onInitialized: function (e) {
                    $scope.widgetInstance = e.component;
                    // $scope.widgetInstance.selectItem($scope.itemElement.id);
                },
                onItemSelectionChanged: function (e) {
                    var node = e.node;
                    var relyOnCodesStr = node.itemData.relyOnCodes;

                    //如果是选中的状态,将其添加的选中的列表中,否则移除
                    if (node.selected) {
                        addSelectedItemData(node);
                    } else {
                        removeSelectedItemData(node);
                    }

                    if (relyOnCodesStr !== null && relyOnCodesStr !== undefined) {
                        var relyOnCodesArray = relyOnCodesStr.split(',');
                        if (relyOnCodesArray && relyOnCodesArray.length > 0) {

                            //提取出统一层级的属性为数组
                            var relyOnCodeList = _.map(node.parent.children, function (item) {
                                return {
                                    'key': item.key,
                                    'code': item.itemData.relyOnCodes,
                                    'selected': item.itemData.selected
                                };
                            });

                            node.parent.children.forEach(function (child) {

                                if (!node.selected) {
                                    var filtered = _.filter(relyOnCodeList, function (item) {
                                        return item.code == child.itemData.code && item.selected !== node.selected;
                                    });

                                    if (filtered && filtered.length >= 0) return;
                                }

                                //https://www.devexpress.com/Support/Center/Question/Details/T499903/treeview-selectitem-method-not-working
                                if (relyOnCodesArray.indexOf(child.itemData.code) >= 0) {
                                    if (node.selected) {
                                        $scope.widgetInstance.selectItem(child.key);
                                    }
                                    else {
                                        $scope.widgetInstance.unselectItem(child.key);
                                    }
                                }
                            });
                        }
                    } else {

                        if (node.selected) {
                            //返回选中的keys
                            $scope.selectedPermissionCodes = $scope.widgetInstance.getSelectedNodesKeys();
                            return;
                        }
                            //比如手动取消查看的权限,那么此时修改等权限也应该做相应的改动
                            var codeList = _.map(node.parent.children, function (item) {
                                return {
                                    'key': item.key,
                                    'selected': item.selected,
                                    'relyOnCodes': item.itemData.relyOnCodes
                            };
                        });

                        var filtered = _.filter(codeList, function (item) {
                            return item.relyOnCodes !== null && item.relyOnCodes.indexOf(node.itemData.code) >= 0 && item.selected == true;
                        });

                            //unchecked 
                            _.each(filtered, function (item) {
                                $scope.widgetInstance.unselectItem(item.key);
                        });
                    }
                    
                    //返回选中的keys
                    $scope.selectedPermissionCodes = $scope.widgetInstance.getSelectedNodesKeys();
                }
            };
        };

        ///初始化权限列表
        var initPermission = function () {
            permissionService.getAllPermissions($scope.serviceType).success(function (data) {
                $scope.allPermissionTreeViewData = data;

                //先全部清空
                $scope.widgetInstance.unselectAll();
            });
        };

        //获取选中的名字并且在textbox显示
        $scope.getSelectedOrgDisplayText = function () {
            var selectedRoleNameList = _.pluck($scope.selectedItemData, 'text');
            var unique = _.uniq(selectedRoleNameList);
            return unique.join(',');
        };

        (function () {

            loadAllPermissionTree();
            initPermission();
        })();

    }
]);

commonModule.directive('permissionSelector', ['$log',
    function ($log) {
        'use strict';
        $log.debug('permissionSelector.ctor()...');
        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/permission-selector/permission-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                selectedPermissionCodes: '=',
                selectedPermissionNames: '='
            },
            controller: 'permissionSelectorController',
            link: function (scope, element) {

                // in dialog
                element.find('.selector-input').on('click', function () {
                    element.find('.menu-tree-container').show();
                });

                $(document).on('click', function () {
                    element.find('.menu-tree-container').hide();
                }).on('click', '.permission-selector-wrapper', function (e) {
                    e.stopPropagation();
                });
            }
        };
    }
]);
commonModule.controller('previewAccountVoucherController', ['$scope', '$log', '$translate', '$timeout', 'apiInterceptor', 'Upload', 'dataImportService', 'SweetAlert', '$q', 'uiGridConstants', 'projectService', 'uiGridGroupingConstants', 'vatImportService', 'i18nService', 'browserService', '$interval', '$uibModal', 'vatPreviewService', '$http', 'region', 'citSessionService', '$state', '$compile',
    function ($scope, $log, $translate, $timeout, apiInterceptor, Upload, dataImportService, SweetAlert, $q, uiGridConstants, projectService, uiGridGroupingConstants, vatImportService, i18nService, browserService, $interval, $uibModal, vatPreviewService, $http, region, citSessionService, $state, $compile) {
        'use strict';

        // Subject Code Popup
        $scope.getCIT = "CIT";
        $scope.serviceType = $scope.project.serviceTypeID;

        $scope.popTheParentCode = function (e) {
            $scope.isShowParentCodePop = true;
            $(e.originalEvent.srcElement).parents(".dx-texteditor:first").dxAutocomplete("instance").option("opened", false);
        }

        $scope.confirmCodes = function (confirmedRecords) {

            var codes = "";
            $scope.queryParams.inputs.accountCode = "";
            confirmedRecords.forEach(function (item) {
                codes = codes + " " + item.subjectCode + " ";
            });

            //$scope.filterData.accountCode = codes;
            $scope.queryParams.inputs.accountCode = codes;
        }

        $scope.cancelCodes = function () {
            
        }
        // Subject Code Popup

        var projectYear = $scope.project.year;
        var startMonth = 1;
        var endMonth = 12;
        //VAT
        if ($scope.serviceType === '2') {
            var startMonth = $scope.month;
            var endMonth = $scope.month;
        }

        var minDate = new Date("2010-01-01");
        var maxDate = new Date("2030-12-31");

        var defaultPeriodDate = {
            from: new Date(projectYear, startMonth-1, 1),
            to: new Date(new Date(projectYear, endMonth, 1) - 10000)
        };

        var pageCanLeave = false;
        $scope.$on("$stateChangeStart", function (event, toState, toParams, fromState, fromParams, options) {
            //根据 Michelle YT Yao 的要求取消跳转提示拦截,但是以下代码保留,可能以后会需要拦截
            //将 pageCanLeave 设为 true 表示可以直接跳转
            pageCanLeave = true;

            if (!pageCanLeave) {
                event.preventDefault();

                var msgboxOptions = {
                    title: $translate.instant('WarningTitle'),
                    text: $translate.instant('AccountVoucher_AlertMsg_Leave'),
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonColor: "#e0301e",
                    confirmButtonText: $translate.instant('ConfirmYes'),
                    cancelButtonText: $translate.instant('ConfirmNo'),
                    closeOnConfirm: true,
                    closeOnCancel: true
                };

                SweetAlert.swal(msgboxOptions, function (isConfirm) {
                    if (isConfirm) {
                        pageCanLeave = true;
                        $state.go(toState, toParams, options);
                    };
                });
            }
            return false;
        });

        $scope.filterMode = {
            //普通查询
            normal: true,
            //高级查询
            advanced: false,
            //自定义查询
            custom: false,
            //借/贷方关联科目查询
            debitCrebitAccountCode: false
        }

        $scope.openAccountCodeModal = function () {
            $uibModal.open({
                animation: true,
                ariaLabelledBy: 'modal-title',
                ariaDescribedBy: 'modal-body',
                templateUrl: 'account-code.html',
                controller: 'vatPreviewAccountVoucherAccountCodeCtrl',
                controllerAs: '$accountCodeCtrl',
                size: "520px",
                scope: $scope
            });
        }

        var closeAccountVoucherFilterDialog = function (e) {
            var dialogs = $("div.filter-dialog[id^='filterMode-']:visible");
            //不存在查询窗体事可以离开当前界面
            if (dialogs.length < 1) {
                return;
            }

            if (!(e && e.originalEvent && e.originalEvent.srcElement))
                return;

            var srcElement = e.originalEvent.srcElement;
            /*
             * 不关闭 filterDialog 的情形
             *  1.触发点击事件的控件在 filterDialog 内部时
             *  2.在打开 filterDialog 的菜单中时
             *  3.存在显示的 modal 时
             *  4.点击会计期间控件时
             *  5.点击自动补全控件内容时
             */
            for (var i = 0; i < dialogs.length; i++) {
                if (dialogs[i].contains(srcElement))
                    return;
            }

            if ($("#mainPreviewDiv .filter-menu")[0].contains(srcElement))
                return;

            if ($(".sweet-alert:visible").length > 0 || $(".modal-open").length > 0)
                return;

            var rp = dialogs.find('#period-picker').data("_ranegPicker");
            if (rp && rp.tether && rp.tether.element && rp.tether.element.contains(srcElement)) {
                return;
            }

            //点击的是自动补全控件时不关闭
            if ($(srcElement).parents("md-virtual-repeat-container:first").length > 0)
                return;

            dialogs.hide();
            $(".vat-preview-account-voucher#mainPreviewDiv").off("click", closeAccountVoucherFilterDialog);
        }

        $scope.showFilterDialog = function ($evn, selector) {
            var target = $evn.delegateTarget;
            var fDialog = $(selector);
            if (fDialog.length < 1)
                return;

            var dialogs = $("div.filter-dialog[id^='filterMode-']");
            $.each(dialogs, function (i, n) {
                if (n == fDialog[0])
                    return;

                $(n).hide();
            });

            fDialog.css({ "top": ((target.offsetHeight + target.offsetTop) + "px"), "left": (target.offsetLeft + "px") });
            fDialog.show();
            $(".vat-preview-account-voucher#mainPreviewDiv").on("click", closeAccountVoucherFilterDialog);
            $scope.UpdateDisableStatusManual("accountCode", $scope.queryParams.selectors.accountCode.selected);
            $scope.UpdateDisableStatusManual("accountName", $scope.queryParams.selectors.accountName.selected);

            //初始化month-picker ,以下代码被屏蔽:界面暂时不再使用 rangePicker ,切换到 dx 的 dateBox 控件
            //var rp = fDialog.find('#period-picker').data("_ranegPicker");
            //if (!rp) {
            //    var monthList = [
            //        $translate.instant('Month01'),
            //        $translate.instant('Month02'),
            //        $translate.instant('Month03'),
            //        $translate.instant('Month04'),
            //        $translate.instant('Month05'),
            //        $translate.instant('Month06'),
            //        $translate.instant('Month07'),
            //        $translate.instant('Month08'),
            //        $translate.instant('Month09'),
            //        $translate.instant('Month10'),
            //        $translate.instant('Month11'),
            //        $translate.instant('Month12')
            //    ];
            //    fDialog.find('#period-picker').rangePicker({
            //        minDate: [1, citSessionService.project.year],
            //        maxDate: [12, citSessionService.project.year],
            //        setDate: [
            //            [citSessionService.month, citSessionService.project.year],
            //            [citSessionService.month, citSessionService.project.year]
            //        ],
            //        months: monthList,
            //        ConfirmBtnText: $translate.instant('Confirm'),
            //        CancelBtnText: $translate.instant('ButtonCancel')
            //    })
            //        .on('datePicker.done', function (e, result) {
            //            //开始月份
            //            var startMonth = result[0][0];
            //            //结束月份
            //            var endMonth = result[1][0];

            //            $scope.queryParams.inputs.period.from = startMonth;
            //            $scope.queryParams.inputs.period.to = endMonth;
            //        })
            //        .data("_ranegPicker")
            //        .applyDate();
            //}

            if ($scope.accountCodes.length < 1) {
                vatPreviewService.getEnterpriseAccount().success(function (data) {
                    $scope.accountCodes = data;

                    for (var i = 0; i < data.length; i++) {
                        $scope.autocompleteDataSource.store().insert(data[i]);
                    }
                    $scope.autocompleteDataSource.load();
                });
            }
        }
        
        $scope.autocompleteDataSource = new DevExpress.data.DataSource([]);
        $scope.autocompleteAccountCodeSearchMode = "startswith";
        $scope.autocompleteAccountCodePlaceholder = $translate.instant("AccountVoucher_Placeholder_Text");
        $scope.autocompleteAccountNameSearchMode = "startswith";
        $scope.autocompleteAccountNamePlaceholder = $translate.instant("AccountVoucher_Placeholder_Text");

        $scope.UpdateDisableStatusManual = function (type, item) {
            if (!(type && item))
                return;

            //var searchModes = ["contains", "startswith"];
            var input = $("#filterMode-normal div[ng-class*='" + type + "'] input");
            if (item.id && !$scope.isFromReMapping) {
                input.removeAttr("disabled");
                var searchMode = (item.id == "1" || item.id == "2") ? "startswith" : "contains";
                if (type.toLowerCase() === "accountCode".toLowerCase()) {
                    $scope.autocompleteAccountCodeSearchMode = searchMode;
                }
                else {
                    $scope.autocompleteAccountNameSearchMode = searchMode;
                }
            } else {
                input.attr("disabled", "disabled");
            }
        }

        $scope.getVoucherDataFromDatabase = function (mainRelation, allJe, period, vID, group, queryCondition) {
            var deferred = $q.defer();
            vatPreviewService.getVoucherByConditon(mainRelation, allJe, period, vID, group, queryCondition).success(function (dataList) {
                deferred.resolve(dataList);

            }).error(function () {
                deferred.reject();
            });
            return deferred.promise;
        };
       
        var voucherDataLoad = function (pageIndex) {
            $log.debug("vat-preview-accountVoucher-ctrl: voucherDataLoad");
            $scope.curVoucherItemPage = pageIndex;
            $scope.queryParams.pagingInfo.pageIndex = pageIndex;
            $log.debug($scope.queryParams);
            if ($scope.queryParams.isEntryShow) {                             
                vatPreviewService.voucherSelectAdvancedByEntry($scope.queryParams.mainRelation, $scope.queryParams.allJe, $scope.queryParams.pagingInfo, $scope.queryParams.listQueryCondition).success(function (listData) {
                    listData.data.debitSum = PWC.round(listData.data.debitSum, 2);
                    listData.data.creditSum = PWC.round(listData.data.creditSum, 2);
                    listData.data.voucherList.forEach(function (v) {
                        v.debit = PWC.round(v.debit, 2);
                        v.credit = PWC.round(v.credit, 2);
                    });
                    $scope.voucherDataList = listData.data.voucherList;
                    //var dataGrid = $('#gridContainer').dxDataGrid('instance');
                    //dataGrid.refresh();
                    initDataGrid();              
                    vatPreviewService.getSelectWhereString($scope.queryParams.mainRelation, $scope.queryParams.allJe, $scope.queryParams.listQueryCondition).success(function (queryString) {
                        showVoucherCount(listData.data.itemIDCount, listData.data.vidCount, listData.data.debitSum, listData.data.creditSum, queryString);                    
                    });                 
                });
                computeVoucherItemPage(false);
            }
            else {
                vatPreviewService.voucherSelectAdvancedByVoucher($scope.queryParams.mainRelation, $scope.queryParams.allJe, $scope.queryParams.pagingInfo, $scope.queryParams.listQueryCondition).success(function (listData) {
                    listData.data.debitSum = PWC.round(listData.data.debitSum, 2);
                    listData.data.creditSum = PWC.round(listData.data.creditSum, 2);
                    listData.data.voucherMainList.forEach(function (v) {
                        v.debitSum = PWC.round(v.debitSum, 2);
                        v.creditSum = PWC.round(v.creditSum, 2);
                    });
                    $scope.voucherDataList = listData.data.voucherMainList;
                    //var dataGrid = $('#gridContainer').dxDataGrid('instance');
                    //dataGrid.refresh();
                    initDataGrid();                   
                    vatPreviewService.getSelectWhereString($scope.queryParams.mainRelation, $scope.queryParams.allJe, $scope.queryParams.listQueryCondition).success(function (queryString) {
                        showVoucherCount(listData.data.itemIDCount, listData.data.vidCount, listData.data.debitSum, listData.data.creditSum, queryString);
                    });

                });
                computeVoucherItemPage(false);
            }

            
            
        };

        //显示凭证相关信息(分录数、凭证数、借贷方总金额、查询条件)
        var showVoucherCount = function (itemIDCount, vIDCount, debitSum, creditSum, queryString) {
            $scope.vIDCount = vIDCount;
            $scope.itemIDCount = itemIDCount;
            $scope.debitSum = debitSum;
            $scope.creditSum = creditSum;
            $scope.queryString = queryString;
        };

        //计算页数,创建分页栏
        var computeVoucherItemPage = function (fristLoad) {

            if (!fristLoad) {
                vatPreviewService.voucherSelectAdvancedCount($scope.queryParams.mainRelation, $scope.queryParams.isEntryShow, $scope.queryParams.allJe, $scope.queryParams.listQueryCondition).success(function (data) {
                    if (data && !data.result) {
                        SweetAlert.warning($translate.instant(data.resultMsg));
                        return false;
                    }
                    $scope.queryParams.pagingInfo.totalCount = data.data;

                    if ($scope.queryParams.pagingInfo && $scope.queryParams.pagingInfo.totalCount > 0) {

                        var totalPage = parseInt($scope.queryParams.pagingInfo.totalCount / $scope.queryParams.pagingInfo.pageSize);
                        totalPage = $scope.queryParams.pagingInfo.totalCount % $scope.queryParams.pagingInfo.pageSize == 0 ? totalPage : totalPage + 1;

                        var createPage = $("#totalVoucherPage").createPage({
                            pageCount: totalPage,
                            current: $scope.curVoucherItemPage,
                            backFn: function (p) {
                                //单击回调方法,p是当前页码
                                voucherDataLoad(p);
                            }
                        });

                        $('#totalVoucherPage').css('display', 'inline-block');
                    } else {
                        var createPage = $("#totalVoucherPage").createPage({
                            pageCount: 0,
                            current: $scope.curVoucherItemPage,
                            backFn: function (p) {
                                //单击回调方法,p是当前页码
                                voucherDataLoad(p);
                            }
                        });

                        $('#totalVoucherPage').css('display', 'inline-block');
                    }
                });
            }
            else {
                var createPage = $("#totalVoucherPage").createPage({
                    pageCount: 0,
                    current: $scope.curVoucherItemPage,
                    backFn: function (p) {
                        //单击回调方法,p是当前页码
                        voucherDataLoad(p);
                    }
                });

                $('#totalVoucherPage').css('display', 'inline-block');
            }
            return true;
        };

        $scope.queryParams = {
            //查询模板
            listQueryCondition: [],
            //分页信息
            pagingInfo: { "totalCount": 0, "pageIndex": 1, "pageSize": 100 },
            andOr: 'AND',
            //主条件
            mainRelation: '8',
            //是否显示所有凭证
            allJe: false,
            //是否为分录显示
            isEntryShow: true,
            //二级子查询-期间
            period: '',
            //二级子查询-凭证编号
            vID: '',
            //二级子查询-凭证类型
            group: null
        };

        $scope.queryConditionTemp = {
            conditionName: null,
            searchKeyWord: 0,
            searchValue: null
        };

        var copyArray = function (data) {
            var ret = [];
            data.forEach(function (row) {
                ret.push(row);
            });

            return ret;
        };

        //按凭证显示
        var voucherShow = function () {
            if ($scope.queryParams.isEntryShow) {
                $scope.queryParams.isEntryShow = false;
                if ($scope.queryParams.listQueryCondition && $scope.queryParams.listQueryCondition.length > 0) {
                    $scope.curVoucherItemPage = 1;
                    computeVoucherItemPage(false);
                    voucherDataLoad($scope.curVoucherItemPage);
                }
                else {
                    initDataGrid();
                }

            }
        };

        //按分录显示
        var entryShow = function () {
            if (!$scope.queryParams.isEntryShow) {
                $scope.queryParams.isEntryShow = true;
                if ($scope.queryParams.listQueryCondition && $scope.queryParams.listQueryCondition.length > 0) {
                    $scope.curVoucherItemPage = 1;
                    computeVoucherItemPage(false);
                    voucherDataLoad($scope.curVoucherItemPage);
                }
                else {
                    initDataGrid();
                }
            }
        };

        //查询确定
        var selectVoucher = function () {
            $log.debug("start to selectVoucher");
            $scope.queryParams.listQueryCondition = [];
            //条件间主关系
            if ($scope.queryParams.andOr == "AND") {
                $scope.queryParams.mainRelation = '8';
            } else {
                $scope.queryParams.mainRelation = '7';
            }
            //是否显示所有凭证
            //$scope.queryParams.allJe = $scope.filterParams.isAllJe;
            //是否按分录显示
            //$scope.queryParams.isEntryShow = $scope.filterParams.isEntryShow;
            //$scope.queryParams.pagingInfo = $scope.pagingInfo;

            var selectors = $scope.queryParams.selectors;
            var inputs = $scope.queryParams.inputs;

            //企业科目代码
            if (selectors.accountCode.selected.id) {
                //期望使用该字段参与查询,却不给定查询关键字时,给出提示
                if (!inputs.accountCode) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_AccountCodeEmpty'));
                    return;
                }

                var accountCodeMto = {};
                accountCodeMto.conditionName = $translate.instant('AccountVoucher_AccountCode');
                accountCodeMto.searchKeyWord = selectors.accountCode.selected.id;
                accountCodeMto.searchValue = inputs.accountCode;
                $scope.queryParams.listQueryCondition.push(accountCodeMto);
            }
            //企业科目名称
            if (selectors.accountName.selected.id) {
                if (!inputs.accountName) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_AccountNameEmpty'));
                    return;
                }

                var accountNameMto = {};
                accountNameMto.conditionName = $translate.instant('AccountVoucher_AccountName');
                accountNameMto.searchKeyWord = selectors.accountName.selected.id;
                accountNameMto.searchValue = inputs.accountName;
                $scope.queryParams.listQueryCondition.push(accountNameMto);
            }
            //会计期间
            if (inputs.period.from || inputs.period.to) {
                var from = inputs.period.from;
                var to = inputs.period.to;
                
                if (to && from && to < from) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_PeriodEndMonthTooBig'));
                    return;
                }

                var periodMto = {};
                periodMto.conditionName = $translate.instant('AccountVoucher_Period');
                periodMto.searchKeyWord = 14;
                periodMto.searchValue = (from ? from.getMonth() + 1 : "null") + " " + (to ? to.getMonth() + 1 : "null");
                $scope.queryParams.listQueryCondition.push(periodMto);
            }
            //凭证类型
            if (selectors.group.selected.id) {
                if (!inputs.group) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_GroupEmpty'));
                    return;
                }

                var groupMto = {};
                groupMto.conditionName = $translate.instant('AccountVoucher_Group');
                groupMto.searchKeyWord = selectors.group.selected.id;
                groupMto.searchValue = inputs.group;
                $scope.queryParams.listQueryCondition.push(groupMto);
            }
            //凭证编号
            if (selectors.groupNum.selected.id) {
                if (!inputs.groupNum) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_GroupNumEmpty'));
                    return;
                }

                var groupNumMto = {};
                groupNumMto.conditionName = $translate.instant('AccountVoucher_GroupNum');
                groupNumMto.searchKeyWord = selectors.groupNum.selected.id;
                groupNumMto.searchValue = inputs.groupNum;
                $scope.queryParams.listQueryCondition.push(groupNumMto);
            }
            //凭证摘要
            if (selectors.summary.selected.id) {
                if (!inputs.summary) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_SummaryEmpty'));
                    return;
                }

                if (inputs.summary.toString().length < 3) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_SummaryTooShort'));
                    return;
                }

                var summaryMto = {};
                summaryMto.conditionName = $translate.instant('AccountVoucher_Summary');
                summaryMto.searchKeyWord = selectors.summary.selected.id;
                summaryMto.searchValue = inputs.summary;
                $scope.queryParams.listQueryCondition.push(summaryMto);
            }
            //往来核算代码
            //if (selectors.customerCode.selected.id) {
            //    if (!inputs.customerCode) {
            //        SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_CustomerCodeEmpty'));
            //        return;
            //    }

            //        var customerCodeMto = {};
            //        customerCodeMto.conditionName = $translate.instant('AccountVoucher_CustomerCode');
            //        customerCodeMto.searchKeyWord = selectors.customerCode.selected.id;
            //        customerCodeMto.searchValue = inputs.customerCode;
            //        $scope.queryParams.listQueryCondition.push(customerCodeMto);
            //}
            //往来核算名称
            //if (selectors.customerName.selected.id) {
            //    if (!inputs.customerName) {
            //        SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_CustomerNameEmpty'));
            //        return;
            //    }

            //        var customerNameMto = {};
            //        customerNameMto.conditionName =$translate.instant('AccountVoucher_CustomerName')";
            //        customerNameMto.searchKeyWord = selectors.customerName.selected.id;
            //        customerNameMto.searchValue = inputs.customerName;
            //        $scope.queryParams.listQueryCondition.push(customerNameMto);
            //}
            //凭证日期
            if (inputs.date.from || inputs.date.to) {
                var from = inputs.date.from;
                var to = inputs.date.to;

                if ((from && (from > maxDate || from < minDate)) || (to && (to > maxDate || to < minDate))) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_DateInvalid'));
                    return;
                }

                if (to && from && to < from) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_DateEndDateTooBig'));
                    return;
                }

                var dateMto = {};
                dateMto.conditionName = $translate.instant('AccountVoucher_Date');
                dateMto.searchKeyWord = 14;
                dateMto.searchValue = (from ? moment(from).format("YYYY-MM-DD") : "null") + " " + (to ? moment(to).format("YYYY-MM-DD") : "null");

                $scope.queryParams.listQueryCondition.push(dateMto);
            }
            //借方金额
            if (inputs.debit.from || inputs.debit.to) {
                var from = inputs.debit.from;
                var to = inputs.debit.to;
                from = from == null ? "" : from;
                to = to == null ? "" : to;
                if ((from && isNaN(from)) || (to && isNaN(to))) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_DebitInvalid'));
                    return;
                }

                if (to && from && Number(to) < Number(from)) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_DebitEndAmountTooBig'));
                    return;
                }

                if (!from) {
                    from = "null";
                }
                if (!to) {
                    to = "null";
                }

                var debitMto = {};
                debitMto.conditionName = $translate.instant('AccountVoucher_Debit');
                debitMto.searchKeyWord = 14;
                debitMto.searchValue = from + " " + to;
                $scope.queryParams.listQueryCondition.push(debitMto);
            }
            //贷方金额
            if (inputs.credit.from || inputs.credit.to) {
                var from = inputs.credit.from;
                var to = inputs.credit.to;
                from = from == null ? "" : from;
                to = to == null ? "" : to;
                if ((from && isNaN(from)) || (to && isNaN(to))) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_CreditInvalid'));
                    return;
                }

                if (to && from && Number(to) < Number(from)) {
                    SweetAlert.warning($translate.instant('AccountVoucher_FVMsg_CreditEndAmountTooBig'));
                    return;
                }
                if (!from) {
                    from = "null";
                }
                if (!to) {
                    to = "null";
                }
                var creditMto = {};
                creditMto.conditionName = $translate.instant('AccountVoucher_Credit');
                creditMto.searchKeyWord = 14;
                creditMto.searchValue = from + " " + to;
                $scope.queryParams.listQueryCondition.push(creditMto);
            }           
            setRemapSearchConditions();
            if ($scope.queryParams.listQueryCondition.length == 0) {
                SweetAlert.warning($translate.instant("NotInputTheQueryConditions"));
                return;
            }
            $scope.curVoucherItemPage = 1;
            if (computeVoucherItemPage(false)) {
                $log.debug("start to voucherDataLoad");
                voucherDataLoad($scope.curVoucherItemPage);
                $("div.filter-dialog[id^='filterMode-']:visible").hide();             
            }
        };

        //查询重置
        var resetSelectCondition = function () {
            var obj = { id: "" };

            $scope.queryParams.andOr = "AND";
            $scope.queryParams.allJe = false;
            $scope.queryParams.selectors.accountCode.selected = obj;
            $scope.queryParams.selectors.accountName.selected = obj;
            $scope.queryParams.selectors.period.selected = obj;
            $scope.queryParams.selectors.group.selected = obj;
            $scope.queryParams.selectors.groupNum.selected = obj;
            $scope.queryParams.selectors.summary.selected = obj;

            $scope.queryParams.inputs = {
                accountCode: null,
                accountName: null,
                period: {
                    from: new Date(projectYear, startMonth - 1, 1),
                    to: new Date(projectYear, endMonth - 1, 1)
                },
                group: null,
                groupNum: null,
                summary: null,
                date: {
                    from: new Date(defaultPeriodDate.from),
                    to: new Date(defaultPeriodDate.to)
                },
                debit: {
                    from: null,
                    to: null
                },
                credit: {
                    from: null,
                    to: null
                }
            };

            //以下代码被屏蔽:界面暂时不再使用 rangePicker ,切换到 dx 的 dateBox 控件
            //var dialog = $("div.filter-dialog[id^='filterMode-']");
            //var rq = dialog.find("#period-picker").data("_ranegPicker");
            //if (!_.isNull(rq) && !_.isUndefined(rq)) {
            //    rq.result[0][0] = citSessionService.month;
            //    rq.result[0][1] = citSessionService.project.year;
            //    rq.result[1][0] = citSessionService.month;
            //    rq.result[1][1] = citSessionService.project.year;
            //    rq.update(rq.result);
            //}

        }
        //导出
        var exportToExcel = function () {
            var dataGrid = $('#gridContainer').dxDataGrid('instance');
            setExportFileName();
            var exportValues = dataGrid.option("export");
            exportValues.fileName = $scope.exportToExcelFileName;
            dataGrid.option("export", exportValues);
            //dataGrid.fileName="testExport",
            dataGrid.exportToExcel(false);
        };

        // ****************************************************************************************
        //************ EXCEL EXPORT FUNCTION ***************/
        $scope.$on('ngEntryRepeatFinished', function (ngRepeatFinishedEvent) {
            if ($scope.isToPrint) {
                setExportFileName();
                export_table_to_excel('exportEntryTable', $scope.exportToExcelFileName, 'xlsx', '');
            }
            $scope.isToPrint = false;
        });
        
        $scope.$on('ngVoucherRepeatFinished', function (ngRepeatFinishedEvent) {
            if ($scope.isToPrint) {
                setExportFileName();
                export_table_to_excel('exportVoucherTable', $scope.exportToExcelFileName, 'xlsx', '');
            }
            $scope.isToPrint = false;
        });
        //导出全部
        $scope.exportAllToExcel = function () {
            $scope.isToPrint = true;
            $scope.getExportData();
        };
        $scope.getExportData = function () {
            if ($scope.queryParams.listQueryCondition && $scope.queryParams.listQueryCondition.length > 0) {
                if ($scope.queryParams.isEntryShow) {
                    vatPreviewService.voucherSelectAdvancedByEntry($scope.queryParams.mainRelation, $scope.queryParams.allJe, null, $scope.queryParams.listQueryCondition).success(function (listData) {
                        listData.data.voucherList.forEach(function (v) {
                            v.debit = PWC.round(v.debit, 2);
                            v.credit = PWC.round(v.credit, 2);
                        });
                        $scope.exportEntryDataList = listData.data.voucherList;
                    });
                }
                else {
                    vatPreviewService.voucherSelectAdvancedByVoucher($scope.queryParams.mainRelation, $scope.queryParams.allJe, null, $scope.queryParams.listQueryCondition).success(function (listData) {
                        listData.data.voucherMainList.forEach(function (v) {
                            v.debitSum = PWC.round(v.debitSum, 2);
                            v.creditSum = PWC.round(v.creditSum, 2);
                        });
                        $scope.exportVoucherDataList = listData.data.voucherMainList;
                    });
                }
            }
        };

        $scope.toggleAllMasterRows = function ($event) {
            var expand = "dx-datagrid-group-closed";
            var collapse = "dx-datagrid-group-opened";
            if ($($event.target).hasClass(expand)) {
                $scope.gridInstance.expandAll(-1);
                $($event.target).removeClass(expand);
                $($event.target).addClass(collapse);
            } else {
                $scope.gridInstance.collapseAll(-1);
                $($event.target).removeClass(collapse);
                $($event.target).addClass(expand);
            }
        }

        var initDataGrid = function () {
            //分录显示
            $log.debug("start to initDataGrid");
            if ($scope.queryParams.isEntryShow) {
                $("#gridContainer").dxDataGrid({
                    dataSource: $scope.voucherDataList,
                    scrolling: {
                        mode: "virtual"
                    },
                    sorting: {
                        mode: "none"
                    },
                    export: {
                        fileName: $scope.exportToExcelFileName
                    },
                    allowColumnResizing: true,
                    //columnAutoWidth: true,
                    showRowLines: true,
                    showColumnLines: true,
                    rowAlternationEnabled: true, //单双行颜色
                    showBorders: true,
                    noDataText: $translate.instant('AccountVoucher_DataGrid_NoDataText'),
                    columns: [
                        {
                            alignment: "left",
                            dataField: "period",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColPeriod'),
                            sortIndex: 0,
                            sortOrder: 'asc',
                            width: 65
                        },
                        {
                            alignment: "center",
                            dataField: "date",
                            dataType: "date",
                            format: "yyyy-MM-dd",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColDate'),
                            sortIndex: 1,
                            sortOrder: 'asc',
                            width: 95
                        },
                        {
                            dataField: "group",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColGroup'),
                            sortIndex: 2,
                            sortOrder: 'asc',
                            width: 180
                        },
                        {
                            dataField: "vid",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColVID'),
                            sortIndex: 3,
                            sortOrder: 'asc',
                            width: "20%"
                        },
                        {
                            dataField: "summary",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColSummary'),
                            width: "30%"
                        },
                        //{
                        //    dataField: "customerCodeAndNameShow",
                        //    caption: $translate.instant('AccountVoucher_DataGrid_ColCustomerCodeAndNameShow'),
                        //    //width: 170
                        //},
                        {
                            dataField: "acctCodeAndNameShow",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColAcctCodeAndNameShow'),
                            width: "20%"
                        },
                        {
                            dataField: "stdCodeAndNameShow",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColStdCodeAndNameShow'),
                            width: "30%"
                        },
                        {
                            dataField: "debit",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColDebit'),
                            alignment: "right",
                            width: 120
                        },
                        {
                            dataField: "credit",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColCredit'),
                            alignment: "right",
                            width: 120
                        }
                    ],
                    masterDetail: {
                        enabled: false
                    },
                    onContentReady: function () {
                        $log.debug("onContentReady entry");
                        $scope.setVoucherSelected();
                    },
                    onInitialized: function (e) {
                        $scope.gridInstance = e.component;
                    }
                });
            } else {

                $("#gridContainer").dxDataGrid({
                    dataSource: $scope.voucherDataList,
                    scrolling: {
                        mode: "virtual"
                    },
                    sorting: {
                        mode: "none"
                    },
                    export: {
                        fileName: $scope.exportToExcelFileName,
                    },
                    allowColumnResizing: true,
                    showRowLines: true,
                    showColumnLines: true,
                    noDataText: $translate.instant('AccountVoucher_DataGrid_NoDataText'),
                    columns: [
                        {
                            dataField: "period",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColPeriod'),
                            sortIndex: 0,
                            sortOrder: 'asc',
                            width: 130
                        },
                        {
                            alignment: "center",
                            dataField: "date",
                            dataType: "date",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColDate'),
                            format: "yyyy-MM-dd",
                            sortIndex: 1,
                            sortOrder: 'asc',
                            width: 100
                        },
                        {
                            dataField: "group",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColGroup'),
                            sortIndex: 2,
                            sortOrder: 'asc',
                            width: "50%"
                        },
                        {
                            dataField: "vid",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColVID'),
                            sortIndex: 3,
                            sortOrder: 'asc',
                            width: "50%"
                        },
                        {
                            dataField: "debitSum",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColDebitSum'),
                            alignment: "right",
                            width: 170
                        },
                        {
                            dataField: "creditSum",
                            caption: $translate.instant('AccountVoucher_DataGrid_ColCreditSum'),
                            alignment: "right",
                            width: 170
                        }
                    ],
                    masterDetail: {
                        enabled: true,
                        template: function (container, options) {
                            var currentVoucherData = options.data;
                            $scope.queryParams.period = currentVoucherData.period;
                            $scope.queryParams.vID = currentVoucherData.vid;
                            $scope.queryParams.group = currentVoucherData.group;
                            container.addClass("internal-grid-container");
                            $("<div>")
                                .addClass("internal-grid")
                                .dxDataGrid({
                                    columnAutoWidth: true,
                                    loadPanel: {
                                        enabled: false
                                    },
                                    showBorders: true,
                                    sorting: {
                                        mode: "none"
                                    },
                                    columns: [
                                        {
                                            dataField: "summary",
                                            caption: $translate.instant('AccountVoucher_DataGrid_ColSummary'),
                                            width: "50%"
                                        },
                                        //{
                                        //    dataField: "customerCodeAndNameShow",
                                        //    caption: $translate.instant('AccountVoucher_DataGrid_ColCustomerCodeAndNameShow') ,
                                        //    //width: 170
                                        //},
                                        {
                                            dataField: "acctCodeAndNameShow",
                                            caption: $translate.instant('AccountVoucher_DataGrid_ColAcctCodeAndNameShow'),
                                            sortIndex: 1,
                                            sortOrder: 'asc',
                                            width: "25%"
                                        },
                                        {
                                            dataField: "stdCodeAndNameShow",
                                            caption: $translate.instant('AccountVoucher_DataGrid_ColStdCodeAndNameShow'),
                                            sortIndex: 0,
                                            sortOrder: 'asc',
                                            width: "25%"
                                        },
                                        {
                                            dataField: "debit",
                                            caption: $translate.instant('AccountVoucher_DataGrid_ColDebit'),
                                            alignment: "right",
                                            width: 170
                                        },
                                        {
                                            dataField: "credit",
                                            caption: $translate.instant('AccountVoucher_DataGrid_ColCredit'),
                                            alignment: "right",
                                            width: 170
                                        }
                                    ],
                                    dataSource: {
                                        store: new DevExpress.data.CustomStore({
                                            load: function (loadOptions) {
                                                return $scope.getVoucherDataFromDatabase($scope.queryParams.mainRelation, $scope.queryParams.allJe, currentVoucherData.period, currentVoucherData.vid, currentVoucherData.group, $scope.queryParams.listQueryCondition).then(function (data) {
                                                    data.data.forEach(function (v) {
                                                        v.debit = PWC.round(v.debit, 2);
                                                        v.credit = PWC.round(v.credit, 2);
                                                    });
                                                    return { data: data.data, totalCount: data.data.length };
                                                }, function () {
                                                    return $q.reject($translate.instant("DataLoadingError"));
                                                });
                                            }
                                        })
                                    }
                                }).appendTo(container);
                        }
                    },
                    onCellPrepared: function(e) {
                        if (e.rowType === "header" && $(e.cellElement).hasClass("dx-command-expand")) {
                            var btn = $("<div class='dx-datagrid-group-closed'></div>");
                            btn.attr("ng-click", "toggleAllMasterRows($event)");
                            e.cellElement.empty();
                            e.cellElement.append($compile(btn) ($scope));
                        }
                    },
                    onContentReady: function() {
                        $log.debug("onContentReady voucher");
                        $scope.setVoucherSelected();
                    },
                    onInitialized: function(e) {
                        $scope.gridInstance = e.component;
                    }
                });
            }
        };

        var setExportFileName = function () {
            var myDate = new Date();
            var now = myDate.formatDateTime('yyyy-MM-dd') + " " + myDate.formatDateTime('HH') + myDate.formatDateTime('mm') + myDate.formatDateTime('ss');
            $scope.exportToExcelFileName = $translate.instant('Voucher_Export_result')+" " + now ;
        };
        $scope.queryParams.selectors =
        {
            accountCode: {
                itemArray: [
                    { id: "", name: $translate.instant('AccountVoucher_SelectorEmpty') },
                    { id: "1", name: $translate.instant('AccountVoucher_Selector_1') },
                    { id: "2", name: $translate.instant('AccountVoucher_Selector_2') }
                ],
                selected: { id: "" }
            },
            accountName: {
                itemArray: [
                    { id: "", name: $translate.instant('AccountVoucher_SelectorEmpty') },
                    { id: "1", name: $translate.instant('AccountVoucher_Selector_1') },
                    { id: "3", name: $translate.instant('AccountVoucher_Selector_3') },
                    { id: "4", name: $translate.instant('AccountVoucher_Selector_4') },
                    { id: "2", name: $translate.instant('AccountVoucher_Selector_2') }
                ],
                selected: { id: "" }
            },
            period: {
                itemArray: [
                    { id: "", name: $translate.instant('AccountVoucher_SelectorEmpty') },
                    { id: "1", name: $translate.instant('AccountVoucher_Selector_1') },
                    { id: "10", name: $translate.instant('AccountVoucher_Selector_10') },
                    { id: "11", name: $translate.instant('AccountVoucher_Selector_11') },
                    { id: "12", name: $translate.instant('AccountVoucher_Selector_12') },
                    { id: "13", name: $translate.instant('AccountVoucher_Selector_13') }
                ],
                selected: { id: "" }
            },
            group: {
                itemArray: [
                    { id: "", name: $translate.instant('AccountVoucher_SelectorEmpty') },
                    { id: "1", name: $translate.instant('AccountVoucher_Selector_1') },
                    { id: "3", name: $translate.instant('AccountVoucher_Selector_3') },
                    { id: "4", name: $translate.instant('AccountVoucher_Selector_4') },
                    { id: "2", name: $translate.instant('AccountVoucher_Selector_2') }
                ],
                selected: { id: "" }
            },
            groupNum: {
                itemArray: [
                    { id: "", name: $translate.instant('AccountVoucher_SelectorEmpty') },
                    { id: "1", name: $translate.instant('AccountVoucher_Selector_1') },
                    { id: "2", name: $translate.instant('AccountVoucher_Selector_2') }
                ],
                selected: { id: "" }
            },
            summary: {
                itemArray: [
                    { id: "", name: $translate.instant('AccountVoucher_SelectorEmpty') },
                    { id: "1", name: $translate.instant('AccountVoucher_Selector_1') },
                    { id: "3", name: $translate.instant('AccountVoucher_Selector_3') },
                    { id: "4", name: $translate.instant('AccountVoucher_Selector_4') },
                    { id: "2", name: $translate.instant('AccountVoucher_Selector_2') }
                ],
                selected: { id: "" }
            },
            date: {
                itemArray: [
                    { id: "", name: $translate.instant('AccountVoucher_SelectorEmpty') },
                    { id: "9", name: $translate.instant('AccountVoucher_Selector_9') },
                    { id: "10", name: $translate.instant('AccountVoucher_Selector_10') },
                    { id: "11", name: $translate.instant('AccountVoucher_Selector_11') },
                    { id: "12", name: $translate.instant('AccountVoucher_Selector_12') },
                    { id: "13", name: $translate.instant('AccountVoucher_Selector_13') }
                ],
                selected: { id: "" }
            },
            debit: {
                itemArray: [
                    { id: "", name: $translate.instant('AccountVoucher_SelectorEmpty') },
                    { id: "9", name: $translate.instant('AccountVoucher_Selector_9') },
                    { id: "10", name: $translate.instant('AccountVoucher_Selector_10') },
                    { id: "11", name: $translate.instant('AccountVoucher_Selector_11') },
                    { id: "12", name: $translate.instant('AccountVoucher_Selector_12') },
                    { id: "13", name: $translate.instant('AccountVoucher_Selector_13') }
                ],
                selected: { id: "" }
            },
            credit: {
                itemArray: [
                    { id: "", name: $translate.instant('AccountVoucher_SelectorEmpty') },
                    { id: "9", name: $translate.instant('AccountVoucher_Selector_9') },
                    { id: "10", name: $translate.instant('AccountVoucher_Selector_10') },
                    { id: "11", name: $translate.instant('AccountVoucher_Selector_11') },
                    { id: "12", name: $translate.instant('AccountVoucher_Selector_12') },
                    { id: "13", name: $translate.instant('AccountVoucher_Selector_13') }
                ],
                selected: { id: "" }
            }
        };

        $scope.queryParams.inputs = {
            accountCode: null,
            accountName: null,
            period: {
                from: null,
                to: null
            },
            group: null,
            groupNum: null,
            summary: null,
            date: {
                from: null,
                to: null
            },
            debit: {
                from: null,
                to: null
            },
            credit: {
                from: null,
                to: null
            }
        };

        $scope.accountCodes = [];

        $scope.dxControlsOptions = {
            queryPeriodFrom: {
                ControlOption: {
                    acceptCustomValue: false,
                    displayFormat: "yyyy年MM月",
                    max: new Date(projectYear, 11, 31),
                    min: new Date(projectYear, 0, 1),
                    maxZoomLevel: "year",
                    minZoomLevel: "year",
                    placeholder: $translate.instant('AccountVoucher_Placeholder_Period'),
                    showClearButton: true,
                    bindingOptions: {
                        value: "queryParams.inputs.period.from"
                    }
                },
                validatorOption: {
                    validationRules: [],
                    onInitialized: function (e) {
                        $scope.dxControlsOptions.queryPeriodFrom.validatorInstance = e.component;
                    }
                },
                validatorInstance: null
            },
            queryPeriodTo: {
                ControlOption: {
                    acceptCustomValue: false,
                    displayFormat: "yyyy年MM月",
                    max: new Date(projectYear, 11, 31),
                    min: new Date(projectYear, 0, 1),
                    maxZoomLevel: "year",
                    minZoomLevel: "year",
                    placeholder: $translate.instant('AccountVoucher_Placeholder_Period'),
                    showClearButton: true,
                    bindingOptions: {
                        value: "queryParams.inputs.period.to"
                    }
                },
                validatorOption: {
                    validationRules: [],
                    onInitialized: function (e) {
                        $scope.dxControlsOptions.queryPeriodTo.validatorInstance = e.component;
                    }
                },
                validatorInstance: null
            },
            queryDateFrom: {
                ControlOption: {
                    acceptCustomValue: false,
                    displayFormat: "yyyy-MM-dd",
                    maxZoomLevel: "month",
                    minZoomLevel: "year",
                    placeholder: $translate.instant('AccountVoucher_Placeholder_Date'),
                    showClearButton: true,
                    bindingOptions: {
                        value: "queryParams.inputs.date.from"
                    }
                },
                validatorOption: {
                    validationRules: [],
                    onInitialized: function (e) {
                        $scope.dxControlsOptions.queryDateFrom.validatorInstance = e.component;
                    }
                },
                validatorInstance: null
            },
            queryDateTo: {
                ControlOption: {
                    acceptCustomValue: false,
                    displayFormat: "yyyy-MM-dd",
                    maxZoomLevel: "month",
                    minZoomLevel: "year",
                    placeholder: $translate.instant('AccountVoucher_Placeholder_Date'),
                    showClearButton: true,
                    bindingOptions: {
                        value: "queryParams.inputs.date.to"
                    }
                },
                validatorOption: {
                    validationRules: [],
                    onInitialized: function (e) {
                        $scope.dxControlsOptions.queryDateTo.validatorInstance = e.component;
                    }
                },
                validatorInstance: null
            },
            queryAccountCode: {
                dataSource: $scope.autocompleteDataSource,
                minSearchLength: 1,
                maxItemCount: 7,
                searchTimeout: 50,
                maxlength: 12,
                placeholder: $scope.autocompleteAccountCodePlaceholder,
                valueExpr: 'acctCode',
                searchExpr: 'acctCode',
                focusStateEnabled: true,
                itemTemplate: 'autocompleteAcctCodeItemTemplate',
                bindingOptions: {
                    disabled: "!queryParams.selectors.accountCode.selected.id",
                    searchMode: 'autocompleteAccountCodeSearchMode',
                    value: 'queryParams.inputs.accountCode'
                },
                onInitialized: function (e) {

                    var initialBtn = function () {
                        if (e.element.find(".dx-texteditor-buttons-container").length < 1)
                            return false;

                        if (e.element.find(".display-flex.dx-dropdowneditor-icon").length > 0)
                            return true;

                        var btnStr = '<div class="dx-dropdowneditor-button dx-button-normal dx-widget" ng-click="popTheParentCode($event)" role="button">' +
                            '<div class="dx-button-content">' +
                            '<div class="dx-dropdowneditor-icon display-flex justify-content-center align-items-center">' +
                            '<i class="fa fa-columns"></i>' +
                            '</div></div></div>';

                        var button = $(btnStr);
                        var container = e.element.find(".dx-texteditor-buttons-container");
                        container.empty();
                        container.append($compile(button)($scope));
                        e.element.find(".dx-texteditor-input").css("padding-right", "34px");
                        return true;
                    }

                    var tryInitialBtn = function () {
                        if (initialBtn())
                            return;

                        var rst = $timeout(initialBtn, 100);
                        rst.then(function (data) {
                            if (!data)
                                tryInitialBtn();

                        });
                    }
                    tryInitialBtn();
                }
            },
            queryAccountName: {
                dataSource: $scope.autocompleteDataSource,
                minSearchLength: 1,
                maxItemCount: 7,
                searchTimeout: 50,
                maxlength: 12,
                placeholder: $scope.autocompleteAccountNamePlaceholder,
                valueExpr: 'name',
                searchExpr: 'name',
                focusStateEnabled: true,
                itemTemplate: 'autocompleteAccountNameItemTemplate',
                bindingOptions: {
                    disabled: "!queryParams.selectors.accountName.selected.id",
                    searchMode: 'autocompleteAccountNameSearchMode',
                    value: 'queryParams.inputs.accountName'
                }
            }
        };

        //凭证重对应编辑时, 勾选已重对应的凭证
        var setVoucherSelected = function () {
            $log.debug("setVoucherSelected");
            if ($scope.isFromReMapping && !_.isUndefined($scope.selectedVouchers) && !_.isNull($scope.selectedVouchers)
                && !_.isUndefined($scope.voucherDataList) && !_.isNull($scope.voucherDataList)
                && $scope.selectedVouchers.length > 0 && $scope.voucherDataList.length > 0) {
                $log.debug("star to setVoucherSelected");
                var voucherIndexArray = [];
                $scope.selectedVouchers.forEach(function (item, index) {
                    $scope.voucherDataList.forEach(function (vdItem, vdIndex) {
                        if (_.isEqual(item.voucherID, vdItem.voucherID)) {
                            $log.debug(vdIndex);
                            voucherIndexArray.push(vdIndex);

                        }
                    });
                });
                $log.debug(voucherIndexArray);
                $('#gridContainer').dxDataGrid('instance').selectRowsByIndexes(voucherIndexArray);
            }
        }

        //从科目对应调用时,初始化整个页面
        function InitPageFromReMapping(fromReMapping) {
            $log.debug("start InitPageFromReMapping");        
            if (fromReMapping) { 
                //初始化页面样式
                $("#mainPreviewDiv").addClass('vat-preview-account-voucher-accountmapping');
                $("#filterMode-normal").css({ "left": 10 + "px" });
                                                      
                //初始化grid
                $("#gridContainer").dxDataGrid({                  
                    selection: {
                        mode: 'multiple',
                        allowSelectAll: false,
                        selectAllMode: 'allPages',
                        showCheckBoxesMode: 'always'
                    },
                    onSelectionChanged: function (selectedItems) {
                        $scope.selectedVouchers = selectedItems.selectedRowsData;
                        VoucherReMapping($scope.selectedVouchers);
                    }
                });
            }
        }


        function VoucherReMapping(selectedVouchers) {
            $log.debug("start VoucherReMapping");
            $log.debug(selectedVouchers);
        }


        //科目重对应时设置默认的查询条件
        function setRemapSearchConditions() {
            if ($scope.isFromReMapping && $scope.isEdit) {
                $log.debug("start to setRemapSearchConditions");
                $scope.resetSelectCondition();
                $scope.queryParams.listQueryCondition = [];
                var acctMto = {};
                //科目代码
                acctMto.conditionName = $translate.instant('AccountVoucher_AccountCode');
                acctMto.searchKeyWord = "1";
                acctMto.searchValue = $scope.enterpriseCode;
                $scope.queryParams.listQueryCondition.push(acctMto);

                //会计期间
                var periodMto = {};
                periodMto.conditionName = $translate.instant('AccountVoucher_Period');
                periodMto.searchKeyWord = 14;
                periodMto.searchValue = startMonth + " " + endMonth; //eg: "5 5" 
                $scope.queryParams.listQueryCondition.push(periodMto);

                //其它查询条件
                $scope.queryParams.pagingInfo = { pageIndex: 1, pageSize: 100, totalCount: 87 };
                $scope.queryParams.andOr = "AND",
                $scope.queryParams.mainRelation = '8';
                $scope.queryParams.allJe = false;
                $scope.queryParams.isEntryShow = true;
                $scope.queryParams.period = "";
                $scope.queryParams.vID = "";
                $scope.queryParams.group = null;

                $log.debug($scope.queryParams);
            }
        }

        //开始
        (function initialize() {
            $scope.curVoucherItemPage = 1;
            $scope.selectVoucher = selectVoucher;
            $scope.resetSelectCondition = resetSelectCondition;
            $scope.voucherShow = voucherShow;
            $scope.entryShow = entryShow;
            $scope.selectedVouchers;
            $scope.enterpriseCode;
            $scope.setVoucherSelected = setVoucherSelected;
            $scope.isEdit;
            $scope.exportToExcel = exportToExcel;
            showVoucherCount("0", "0", "0", "0", null);
            computeVoucherItemPage(true);
            $timeout(function () {
                initDataGrid();
                InitPageFromReMapping($scope.isFromReMapping);
            }, 100);

            $scope.resetSelectCondition();
            $scope.selectVoucher();
            // Reposition Header when the window is resized
            //$(window).on('resize', function () {
            //    SetUiGridHeader();
            //});
        })();
    }
]);

//树形控件弹出模态框
commonModule.controller('vatPreviewAccountVoucherAccountCodeCtrl', ["$scope", "$translate", "$uibModalInstance", "ivhTreeviewBfs", function ($scope, $translate, $uibModalInstance, ivhTreeviewBfs) {
    var $ctrl = this;

    var initControls = function () {

        var itemSource = angular.copy($scope.$parent.accountCodes);
        var dic = {};

        var debit = $translate.instant('AccountVoucher_Direction_Debit'), credit = $translate.instant('AccountVoucher_Direction_Credit');
        for (var ix = 0; ix < itemSource.length; ix++) {
            var item = itemSource[ix];
            dic[item.acctCode] = {
                id: item.acctCode,
                code: item.acctCode,
                name: item.name,
                selected: false,
                parentNode: null,
                parentCode: item.parentCode,
                direction: item.direction == 1 ? debit : credit,
                children: [],
                data: item
            };
        }

        //查找每个节点是否存在父节点,并维护父节点与本节点的关系
        for (var key in dic) {
            if (dic.hasOwnProperty(key)) {
                var item = dic[key];
                var pCode = item.parentCode || "undefined";
                var p = dic[pCode];
                if (!p)
                    continue;

                if (pCode == "undefined")
                    throw "parentCode is undefined,please check the data in database";

                item.parentNode = p;
                p.children.push(item);
            }
        }

        //node 是已经转化的数据结构
        var trans = function (node) {
            for (var ix = 0; ix < node.children.length; ix++) {
                var cn = node.children[ix];
                cn.parentNode = node;
                trans(cn);
            }
        }

        //对于树节点的根节点(没有父节点信息的节点)的所有子节点数据格式进行转换,并缓存到所有根节点 srcData 中
        var srcData = [];
        for (var key in dic) {
            if (dic.hasOwnProperty(key)) {
                var item = dic[key];
                if (!item || item.parentNode)
                    continue;

                trans(item);
                srcData.push(item);
            }
        }

        //会计科目分类
        var groupData = [
            {
                id: "1",
                code: "资产",
                name: "",
                selected: false,
                direction: "",
                data: null,
                children: []
            }, {
                id: "2",
                code: "负债",
                name: "",
                selected: false,
                direction: "",
                data: null,
                children: []
            }, {
                id: "3",
                code: "共同",
                name: "",
                selected: false,
                direction: "",
                data: null,
                children: []
            }, {
                id: "4",
                code: "权益",
                name: "",
                selected: false,
                direction: "",
                data: null,
                children: []
            }, {
                id: "5",
                code: "成本",
                name: "",
                selected: false,
                direction: "",
                data: null,
                children: []
            }, {
                id: "6",
                code: "损益",
                name: "",
                selected: false,
                direction: "",
                data: null,
                children: []
            }
        ];

        //其他未知类型
        var other = {
            id: "0",
            code: "其他",
            name: "",
            selected: false,
            direction: "",
            data: null,
            children: []
        };

        //将会计科目进行分类
        for (var ix = 0; ix < srcData.length; ix++) {
            item = srcData[ix];
            var p = _.find(groupData, function (n) {
                return Number(n.id) === Number(item.data.acctProp);
            });

            if (p) {
                item.parentNode = p;
                item.parentCode = p.id;
                p.children.push(item);
            } else {
                other.children.push(item);
            }
        }

        if (other.children.length > 0) {
            groupData.push(other);
        }


        $ctrl.treeSrcData = groupData;

        $ctrl.treeViewOps = {
            idAttribute: 'id',
            labelAttribute: 'code',
            childrenAttribute: 'children',
            selectedAttribute: 'selected',
            useCheckboxes: true,
            expandToDepth: 0,
            validate: true,
            defaultSelectedState: false,
            twistieExpandedTpl: '<span class="fa fa-caret-right"></span>',
            twistieCollapsedTpl: '<span class="fa fa-caret-right"></span>',
            twistieLeafTpl: ' ',
            nodeTpl: [
                '<div class="ivh-treeview-node-content" title="{{trvw.label(node)}}">',
                '<div>',
                '<div>',
                '<span ivh-treeview-toggle>',
                '<span class="ivh-treeview-twistie-wrapper" ivh-treeview-twistie></span>',
                '</span>',
                '<span class="ivh-treeview-checkbox-wrapper" ng-if="trvw.useCheckboxes()" ivh-treeview-checkbox></span>',
                '<span class="ivh-treeview-node-label" ivh-treeview-label-select>{{trvw.label(node)}}</span>',
                '</div>',
                '<span class="accountName">{{node.name}}</span>',
                '<span class="debitOrCredit">{{node.direction}}</span>',
                '</div>',
                '<div ivh-treeview-children></div>',
                '</div>'
            ].join('\n')
        };

    }

    $ctrl.ok = function () {

        var selects = [];
        ivhTreeviewBfs($ctrl.treeSrcData, $ctrl.treeViewOps, function (node) {
            if (node.selected && node.id && node.id.toString().length > 1)
                selects.push(node.id);

            return true;
        });

        selects = selects.join(' ');
        $scope.$parent.queryParams.inputs.accountCode = selects;
        $uibModalInstance.close();
    };

    $ctrl.cancel = function () {
        $uibModalInstance.dismiss('cancel');
    };

    initControls();
}]);
commonModule.directive('previewAccountVoucher', ['$log', 'browserService', '$translate',
    function ($log, browserService, $translate) {
        $log.debug('previewAccountVoucher.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/preview-account-voucher/preview-account-voucher.html' + '?_=' + Math.random(),
            scope: {
                isFromReMapping: '@',
                reMappId: '@',
                isEdit: '@',
                enterpriseCode: '=?',
                selectedVouchers: "=?",
                project: '=?',
                month:'=?',
            },
            controller: 'previewAccountVoucherController',
            link: function ($scope, element) {
                // ************************************************************************************************
                // Perform Data filter
                $scope.doDataFilter = function (removeData) {

                    $scope.filterData.periodFrom = $scope.monthFrom.selected.id;
                    $scope.filterData.periodTo = $scope.monthTo.selected.id;

                    if ($scope.filterData.periodFrom > $scope.filterData.periodTo) {
                        $scope.filterData.periodTo = $scope.filterData.periodFrom;
                    }

                    if (removeData !== "") {

                        $scope.openFilterPopup();

                        var textBoxNames = removeData.split("|");

                        for (var i = 0; i < textBoxNames.length; i++)
                            $("#" + textBoxNames[i]).val("");
  
                    }

                    $scope.filterData = {
                        periodFrom: $scope.filterData.periodFrom,
                        periodTo: $scope.filterData.periodTo,
                        accountCode: $("#accountCode").val().trim(),
                        accountName: $("#accountName").val().trim(),
                        debitOpeningBalanceFrom: $("#debitOpeningBalanceFrom").val().trim(),
                        debitOpeningBalanceTo: $("#debitOpeningBalanceTo").val().trim(),
                        creditOpeningBalanceFrom: $("#creditOpeningBalanceFrom").val().trim(),
                        creditOpeningBalanceTo: $("#creditOpeningBalanceTo").val().trim(),
                        accumulatedDebitAmountFrom: $("#accumulatedDebitAmountFrom").val().trim(),
                        accumulatedDebitAmountTo: $("#accumulatedDebitAmountTo").val().trim(),
                        accumulatedCreditAmountFrom: $("#accumulatedCreditAmountFrom").val().trim(),
                        accumulatedCreditAmountTo: $("#accumulatedCreditAmountTo").val().trim(),
                        debitClosingBalanceFrom: $("#debitClosingBalanceFrom").val().trim(),
                        debitClosingBalanceTo: $("#debitClosingBalanceTo").val().trim(),
                        creditClosingBalanceFrom: $("#creditClosingBalanceFrom").val().trim(),
                        creditClosingBalanceTo: $("#creditClosingBalanceTo").val().trim()
                    };

                    //********************************************************************************
                    // add to Criteria List for display on top of the grid:
                    var crits = $scope.filterData;

                    $scope.criteriaList = [];

                    var crit = [];
                    if (crits.accountCode !== "null" && crits.accountCode.length > 0) {
                        crit = new Object;
                        crit.name = $translate.instant('AccountCode');
                        crit.valueFrom = crits.accountCode;
                        crit.propertyName = "accountCode";

                        $scope.criteriaList.push(crit);
                    }

                    if (crits.accountName !== "null" && crits.accountName.length > 0) {
                        crit = new Object;
                        crit.name = $translate.instant('AccountName');
                        crit.valueFrom = crits.accountName;
                        crit.propertyName = "accountName";

                        $scope.criteriaList.push(crit);
                    }

                    if (crits.debitOpeningBalanceFrom !== "null" && crits.debitOpeningBalanceFrom.length > 0 || crits.debitOpeningBalanceTo !== "null" && crits.debitOpeningBalanceTo.length) {
                        crit = new Object;
                        crit.name = $translate.instant('DebitOpeningBalance');
                        crit.valueFrom = crits.debitOpeningBalanceFrom;
                        crit.valueTo = crits.debitOpeningBalanceTo;
                        crit.propertyName = "debitOpeningBalanceFrom|debitOpeningBalanceTo";

                        $scope.criteriaList.push(crit);
                    }

                    if (crits.creditOpeningBalanceFrom !== "null" && crits.creditOpeningBalanceFrom.length > 0 || crits.creditOpeningBalanceTo !== "null" && crits.creditOpeningBalanceTo.length) {
                        crit = new Object;
                        crit.name = $translate.instant('CreditOpeningBalance');
                        crit.valueFrom = crits.creditOpeningBalanceFrom;
                        crit.valueTo = crits.creditOpeningBalanceTo;
                        crit.propertyName = "creditOpeningBalanceFrom|creditOpeningBalanceTo";

                        $scope.criteriaList.push(crit);
                    }

                    if (crits.accumulatedDebitAmountFrom !== "null" && crits.accumulatedDebitAmountFrom.length > 0 || crits.accumulatedDebitAmountTo !== "null" && crits.accumulatedDebitAmountTo.length) {
                        crit = new Object;
                        crit.name = $translate.instant('AccumulatedDebitAmount');
                        crit.valueFrom = crits.accumulatedDebitAmountFrom;
                        crit.valueTo = crits.accumulatedDebitAmountTo;
                        crit.propertyName = "accumulatedDebitAmountFrom|accumulatedDebitAmountTo";

                        $scope.criteriaList.push(crit);
                    }

                    if (crits.accumulatedCreditAmountFrom !== "null" && crits.accumulatedCreditAmountFrom.length > 0 || crits.accumulatedCreditAmountTo !== "null" && crits.accumulatedCreditAmountTo.length) {
                        crit = new Object;
                        crit.name = $translate.instant('AccumulatedCreditAmount');
                        crit.valueFrom = crits.accumulatedCreditAmountFrom;
                        crit.valueTo = crits.accumulatedCreditAmountTo;
                        crit.propertyName = "accumulatedCreditAmountFrom|accumulatedCreditAmountTo";

                        $scope.criteriaList.push(crit);
                    }

                    if (crits.debitClosingBalanceFrom !== "null" && crits.debitClosingBalanceFrom.length > 0 || crits.debitClosingBalanceTo !== "null" && crits.debitClosingBalanceTo.length) {
                        crit = new Object;
                        crit.name = $translate.instant('DebitClosingBalance');
                        crit.valueFrom = crits.debitClosingBalanceFrom;
                        crit.valueTo = crits.debitClosingBalanceTo;
                        crit.propertyName = "debitClosingBalanceFrom|debitClosingBalanceTo";

                        $scope.criteriaList.push(crit);
                    }

                    if (crits.creditClosingBalanceFrom !== "null" && crits.creditClosingBalanceFrom.length > 0 || crits.creditClosingBalanceTo !== "null" && crits.creditClosingBalanceTo.length) {
                        crit = new Object;
                        crit.name = $translate.instant('CreditClosingBalance');
                        crit.valueFrom = crits.creditClosingBalanceFrom;
                        crit.valueTo = crits.creditClosingBalanceTo;
                        crit.propertyName = "creditClosingBalanceFrom|creditClosingBalanceTo";

                        $scope.criteriaList.push(crit);
                    }
                    // add to Criteria List for display on top of the grid:
                    //********************************************************************************



                    var criteria = JSON.stringify($scope.filterData);
                    if (browserService.isIE() || browserService.isEdge())
                        criteria = encodeURIComponent(criteria);

                    $scope.getDataFromDatabase($scope.currentCategory, $scope.filterData.periodFrom, $scope.filterData.periodTo, criteria);
                    $('.justPopMeOver').popover("hide");
                };
                // Perform Data filter
                // ************************************************************************************************

                $scope.openFilterPopup = function () {

                    $("#accountCode").val($scope.filterData.accountCode);
                    $("#accountName").val($scope.filterData.accountName);
                    $("#debitOpeningBalanceFrom").val($scope.filterData.debitOpeningBalanceFrom);
                    $("#debitOpeningBalanceTo").val($scope.filterData.debitOpeningBalanceTo);
                    $("#creditOpeningBalanceFrom").val($scope.filterData.creditOpeningBalanceFrom);
                    $("#creditOpeningBalanceTo").val($scope.filterData.creditOpeningBalanceTo);
                    $("#accumulatedDebitAmountFrom").val($scope.filterData.accumulatedDebitAmountFrom);
                    $("#accumulatedDebitAmountTo").val($scope.filterData.accumulatedDebitAmountTo);
                    $("#accumulatedCreditAmountFrom").val($scope.filterData.accumulatedCreditAmountFrom);
                    $("#accumulatedCreditAmountTo").val($scope.filterData.accumulatedCreditAmountTo);
                    $("#debitClosingBalanceFrom").val($scope.filterData.debitClosingBalanceFrom);
                    $("#debitClosingBalanceTo").val($scope.filterData.debitClosingBalanceTo);
                    $("#creditClosingBalanceFrom").val($scope.filterData.creditClosingBalanceFrom);
                    $("#creditClosingBalanceTo").val($scope.filterData.creditClosingBalanceTo);


                };
         
                $scope.isFromReMapping = false;
                
                $scope.$watch("enterpriseCode", function (newValue, oldValue) {
                    //选择不同COA时,初始化搜索条件  
                    if ($scope.isFromReMapping) {
                        $log.debug("start vat-preview-accountVoucher.js watching  enterpriseCode");
                        //设置科目代码
                        $("#coaAutoComplete").dxAutocomplete("instance").option("value", newValue);
                        if (!_.isUndefined(newValue) && !_.isUndefined(oldValue)) {
                            if (!_.isEqual(newValue, oldValue)) {                              
                                $scope.voucherDataList = [];
                                $('#gridContainer').dxDataGrid('instance').option("dataSource", $scope.voucherDataList); //切换不同的COA时,查询界面重置为空
                                $scope.queryString = ''; //查询条件汇总
                                $scope.vIDCount = 0;//凭证数
                                $scope.itemIDCount = 0;//分路数
                                $scope.debitSum = 0;//借方金额
                                $scope.creditSum = 0;//贷方金额
                            }
                        }
                    }                                        
                });

      
                $scope.$watch("isEdit", function (newValue, oldValue) {
                    $log.debug("start vat-preview-accountVoucher.js watching  isEdit");
                    $log.debug($scope.enterpriseCode);
                    $log.debug($scope.selectedVouchers);
                    $log.debug($scope.isEdit);

                    if ($scope.isFromReMapping) {
                        $("#coaAutoComplete").dxAutocomplete("instance").option("value", $scope.enterpriseCode);
                        $scope.voucherDataList = [];
                        $('#gridContainer').dxDataGrid('instance').option("dataSource", $scope.voucherDataList); //切换不同的COA时,查询界面重置为空
                        $scope.queryString = ''; //查询条件汇总
                        $scope.vIDCount = 0;//凭证数
                        $scope.itemIDCount = 0;//分路数
                        $scope.debitSum = 0;//借方金额
                        $scope.creditSum = 0;//贷方金额

                        //当凭证重对应点击编辑按钮时,调用查询
                        if (!_.isNull($scope.selectedVouchers) && $scope.isEdit === "true") {
                            $log.debug("start vat-preview-accountVoucher.js watching  selectVoucher ");
                            $scope.selectVoucher(); 
                        }

                    }
                });

             
            }
        };
    }
]);


commonModule.directive('convertToNumber', function () {
    return {
        require: 'ngModel',
        link: function (scope, element, attrs, ngModel) {
            ngModel.$parsers.push(function (val) {
                return val != null ? parseInt(val, 10) : null;
            });
            ngModel.$formatters.push(function (val) {
                return val != null ? '' + val : null;
            });
        }
    };
});



commonModule.controller('previewTrialBalanceController', ['$scope', '$log', '$translate', '$timeout', 'apiInterceptor', 'Upload', 'dataImportService', 'SweetAlert', '$q', 'uiGridConstants', 'projectService', 'uiGridGroupingConstants', 'vatImportService', 'i18nService', 'browserService', '$interval', 'region', 'citSessionService', 'enums',
    function ($scope, $log, $translate, $timeout, apiInterceptor, Upload, dataImportService, SweetAlert, $q, uiGridConstants, projectService, uiGridGroupingConstants, vatImportService, i18nService, browserService, $interval, region, citSessionService, enums) {
        'use strict';

        $scope.serviceType = $scope.project.serviceTypeID;       
        $scope.startDate = new Date($scope.project.year, 0, 1);
        $scope.endDate = new Date($scope.project.year, 11, 31);
        $scope.dateFormat = $translate.instant('dateFormat4YearMonthDay');
        $scope.isReadOnly = false; 
      
        var minDate = [1, $scope.project.year];
        var maxDate = [12, $scope.project.year];
        var setDate = [
              [$scope.month, $scope.project.year],
              [$scope.month, $scope.project.year]];
       
        $scope.treeData = null;
        $scope.stupidData = null;
        $scope.isShowParentCodePop = false;
        $scope.isToClearSelection = false;

        $scope.isRunningTheFirstTime = true;
        $scope.isToPrint = false;
        $scope.switchedToCIT = false; 

        //Date range picker:
        // **********************************************************************
        $scope.filterDataCriteria = "";
        $scope.filterData = {
            periodFrom: $scope.month,
            periodTo: $scope.month,
            accountCode: null,
            accountName: null,
            debitOpeningBalanceFrom: null,
            debitOpeningBalanceTo: null,
            creditOpeningBalanceFrom: null,
            creditOpeningBalanceTo: null,
            accumulatedDebitAmountFrom: null,
            accumulatedDebitAmountTo: null,
            accumulatedCreditAmountFrom: null,
            accumulatedCreditAmountTo: null,
            debitClosingBalanceFrom: null,
            debitClosingBalanceTo: null,
            creditClosingBalanceFrom: null,
            creditClosingBalanceTo: null,
            hideAllZeroRecords: false
        };

        //CIT
        if ($scope.serviceType === '6') {
            $scope.isReadOnly = true;
            setDate = [[1, $scope.project.year], [12, $scope.project.year]];
            $scope.filterData.periodFrom = 1;
            $scope.filterData.periodTo = 12;
        }

        $scope.criteriaList = [];

        // current CATEGORY:

        $scope.categoryList = [{ id: 'CIT', name: $translate.instant('CITProject') }, {
            id: 'STD', name: $translate.instant('STANDARDProject')
        }];
        $scope.currentCategory = {
        };
        $scope.currentCategory.selected = {
            id: 'CIT', name: $translate.instant('CITProject')
        };


        $scope.monthList = [$translate.instant('Month01'),
                            $translate.instant('Month02'),
                            $translate.instant('Month03'),
                            $translate.instant('Month04'),
                            $translate.instant('Month05'),
                            $translate.instant('Month06'),
                            $translate.instant('Month07'),
                            $translate.instant('Month08'),
                            $translate.instant('Month09'),
                            $translate.instant('Month10'),
                            $translate.instant('Month11'),
                            $translate.instant('Month12')
        ];

        $scope.subtotals = {
            TitleName: '',
            BegDebitBal: '0.00',
            BegCreditBal: '0.00',
            EndDebitBal: '0.00',
            EndCreditBal: '0.00',
            YearDebitBal: '0.00',
            YearCreditBal: '0.00'
        }; 


        $scope.confirmCodes = function (confirmedRecords) {

            var codes = "";
            $scope.filterData.accountCode = "";
            confirmedRecords.forEach(function (item) {
                codes = codes + " " + item.subjectCode + " ";
            });

            $scope.filterData.accountCode = codes;
            $timeout(function () {
                $("#filterButton").click();
            }, 500);
        }

        $scope.cancelCodes = function () {
            $timeout(function () {
                $("#filterButton").click();
            }, 500);
        }
         
        //************ EXCEL EXPORT FUNCTION ***************/
        $scope.$on('ngRepeatFinished', function (ngRepeatFinishedEvent) {
            if ($scope.isToPrint)
                export_table_to_excel('exportTable', 'GL', 'xlsx', '');
            $scope.isToPrint = false;
        });

        $scope.doExport = function (fileName, type, fn) {
            $scope.isToPrint = true;
            $scope.getDataFromDatabase($scope.currentCategory.selected.id, $scope.filterData.periodFrom, $scope.filterData.periodTo, $scope.filterDataCriteria, true);

        }

        // function to get data from Backend
        $scope.getDataFromDatabase = function (category, from, to, criteria, isExportOnly) {
            vatImportService.getBalanceDataForDisplay(category, from, to, criteria).success(function (trialBalance) {
                $scope.treeData = JSON.parse(trialBalance);
                writeoutNode($scope.treeData.List, 0, newTree);

                //check to see if user switch to STD subject:
                if ($scope.switchedToCIT && ($scope.treeData === null || $scope.treeData.length <= 0)) {
                    var selectedDisplaySubjectName = $translate.instant('SwitchToSTANDARDProject');
                    // give a  notice:
                    swal({ title: "", text: selectedDisplaySubjectName, type: "warning", confirmButtonText: "确定" });
                    $scope.switchedToCIT = false;
                }

                if (isExportOnly !== null && isExportOnly) {
                    $scope.exportDataList = newTree;

                }
                else {
                    $scope.gridOptions.data = newTree;

                    //populate standard parents code:
                    if ($scope.isRunningTheFirstTime) {

                        var formedNewTree;
                        var formedNewTrees = [];
                        var debit = $translate.instant('AccountVoucher_Direction_Debit'), credit = $translate.instant('AccountVoucher_Direction_Credit');

                        newTree.forEach(function (item) {
                            formedNewTree = new Object();
                            formedNewTree.$$treeLevel = item.$$treeLevel;
                            formedNewTree.subjectCode = item.accountCode;
                            formedNewTree.subjectName = item.accountName;
                            formedNewTree.acctProp = item.acctProp;
                            formedNewTree.direction = item.direction === "1" ? debit : credit;

                            formedNewTrees.push(formedNewTree);
                        });
                        $scope.stupidData = formedNewTrees;

                        $scope.isRunningTheFirstTime = false;
                    }


                    newTree = [];

                    $scope.subtotals = $scope.treeData.SubTotals;
                    $('.filter-button').popover("hide");
                    setTimeout(function () {
                        SetUiGridHeader();
                    }, 900);
                }
                $scope.isToClearSelection = false;
            });
        };
         
        // Write UI GRID TREE NOTES:
        var newTree = [];
        var id = "0";
        var writeoutNode = function (childArray, currentLevel, dataArray) {
            childArray.forEach(function (childNode) {
                if (childNode.children.length > 0) {
                    childNode.$$treeLevel = currentLevel;
                    id = childNode.accountCode;
                }
                else {
                    childNode.$$treeLevel = currentLevel;
                }
                dataArray.push(childNode);
                writeoutNode(childNode.children, currentLevel + 1, dataArray);
            });
        }; 
        //************************EXCEL EXPORT FUNCTION **********************************
        
        $scope.initGridOption = function () {
            
            $scope.gridOptions = {
                rowHeight: 50,
                showGridFooter: false,
                showColumnFooter: true,
                selectionRowHeaderWidth: 50,
                enableFullRowSelection: false,
                enableRowSelection: false,
                enableSorting: false,
                enableFiltering: false,
                enableColumnMenus: false,
                enableRowHeaderSelection: false,
                enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
                showTreeExpandNoChildren: false,
                enableGridMenu: false,
                enableSelectAll: false,
                //exporterLinkLabel: 'get it here',
                //exporterCsvFilename: 'GL.csv',
                exporterOlderExcelCompatibility: true,
                virtualizationThreshold: 50,
                exporterHeaderFilter: function (displayName) {
                    var headerName = "";

                    if (displayName === $translate.instant('Debitor'))
                        headerName = $translate.instant('DebitOpeningBalance');

                    else if (displayName === $translate.instant('Creditor'))
                        headerName = $translate.instant('CreditOpeningBalance');

                    else if (displayName === $translate.instant('Debitor') + ' ')
                        headerName = $translate.instant('AccumulatedDebitAmount');

                    else if (displayName === $translate.instant('Creditor') + ' ')
                        headerName = $translate.instant('AccumulatedCreditAmount');

                    else if (displayName === $translate.instant('Debitor') + '  ')
                        headerName = $translate.instant('DebitClosingBalance');

                    else if (displayName === $translate.instant('Creditor') + '  ')
                        headerName = $translate.instant('CreditClosingBalance');

                    else
                        headerName = displayName;

                    return headerName;
                },
                exporterHeaderFilterUseName: true,
                exportCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
                onRegisterApi: function (gridApi) {
                    //$scope.gridApi = gridApi;

                    $scope.gridApiTotal = gridApi;
                    //$timeout(function () {
                    //    $scope.gridApiTotal.core.handleWindowResize();
                    //});

                    var counterx = 1;
                    $interval(function () {
                        if (counterx === 1) {
                            $scope.gridApiTotal.core.handleWindowResize();
                            counterx++;
                        }
                    }, 500, 60 * 60 * 8);
                },

                columnDefs: [
                {
                    field: 'accountCode', name: $translate.instant('AccountCode'), headerCellClass: 'dataColumn1',
                    cellTemplate:
                    '<div ng-if="row.entity.$$treeLevel==0" class=""><span>{{row.entity.accountCode}}<span></div>' +
                              '<div ng-if="row.entity.$$treeLevel==1" class="text-align-left-padding"><span>&nbsp;&nbsp;{{row.entity.accountCode}}<span></div>' +
                              '<div ng-if="row.entity.$$treeLevel==2" class="text-align-left-padding"><span>&nbsp;&nbsp;&nbsp;&nbsp;{{row.entity.accountCode}}<span></div>' +
                '<div ng-if="row.entity.$$treeLevel==3" class="text-align-left-padding"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{row.entity.accountCode}}<span></div>' +
        '<div ng-if="row.entity.$$treeLevel==4" class="text-align-left-padding"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{row.entity.accountCode}}<span></div>'
                },
                {
                    field: 'accountName', width: 200, name: $translate.instant('AccountName'), headerCellClass: 'dataColumn2',

                    cellTemplate: '<div class=""><span>{{row.entity.accountName}}<span></div>'

                , footerCellTemplate: '<div class=" alignRight margin-right5 margin-top5" >{{grid.appScope.subtotals.TitleName}}: </div>'
                },

                {
                    field: 'debitOpeningBalance', name: $translate.instant('Debitor'), headerCellClass: 'alignCenter dataColumn3',

                    cellTemplate: '<div class="alignRight margin-right5"><span>{{row.entity.debitOpeningBalance}}</span></div>'
                , footerCellTemplate: '<div class=" alignRight margin-right5 margin-top5" >{{grid.appScope.subtotals.BegDebitBal}}</div>'
                },

                {
                    field: 'creditOpeningBalance', name: $translate.instant('Creditor'), headerCellClass: 'alignCenter dataColumn4',

                    cellTemplate: '<div class=" alignRight margin-right5"><span>{{row.entity.creditOpeningBalance}}</span></div>'
                , footerCellTemplate: '<div class=" alignRight margin-right5 margin-top5" >{{grid.appScope.subtotals.BegCreditBal}}</div>'

                },

                {
                    field: 'accumulatedDebitAmount', name: $translate.instant('Debitor') + ' ', headerCellClass: 'alignCenter dataColumn5',

                    cellTemplate: '<div class=" alignRight margin-right5"><span>{{row.entity.accumulatedDebitAmount}}</span></div>'
                , footerCellTemplate: '<div class=" alignRight margin-right5 margin-top5" >{{grid.appScope.subtotals.DebitBal}}</div>'

                },

                {
                    field: 'accumulatedCreditAmount', name: $translate.instant('Creditor') + ' ', headerCellClass: 'alignCenter dataColumn6',

                    cellTemplate: '<div class=" alignRight margin-right5"><span>{{row.entity.accumulatedCreditAmount}}</span></div>'
                , footerCellTemplate: '<div class=" alignRight margin-right5 margin-top5" >{{grid.appScope.subtotals.CreditBal}}</div>'

                },

                {
                    field: 'debitClosingBalance', name: $translate.instant('Debitor') + '  ', headerCellClass: 'alignCenter dataColumn7',
                    cellTemplate: '<div class=" alignRight margin-right5"><span>{{row.entity.debitClosingBalance}}</span></div>'
                , footerCellTemplate: '<div class="alignRight margin-right5 margin-top5" >{{grid.appScope.subtotals.EndDebitBal}}</div>'

                },

                {
                    field: 'creditClosingBalance', name: $translate.instant('Creditor') + '  ', headerCellClass: 'alignCenter dataColumn8',
                    cellTemplate: '<div class=" alignRight margin-right5"><span>{{row.entity.creditClosingBalance}}</span></div>'
                , footerCellTemplate: '<div class="alignRight margin-right5 margin-top5" >{{grid.appScope.subtotals.EndCreditBal}}</div>'
                }
                ]
            };

            // Get initial Data from Backend to fill the UI grid Tree:
            $scope.getDataFromDatabase($scope.currentCategory.selected.id, $scope.filterData.periodFrom, $scope.filterData.periodTo, "");

        };
         
        $scope.doDataFilterReset = function () {
            var from = $scope.filterData.periodFrom;
            var to = $scope.filterData.periodTo;

            $scope.filterData = {
                periodFrom: from,
                periodTo: to,
                accountCode: null,
                accountName: null,
                debitOpeningBalanceFrom: null,
                debitOpeningBalanceTo: null,
                creditOpeningBalanceFrom: null,
                creditOpeningBalanceTo: null,
                accumulatedDebitAmountFrom: null,
                accumulatedDebitAmountTo: null,
                accumulatedCreditAmountFrom: null,
                accumulatedCreditAmountTo: null,
                debitClosingBalanceFrom: null,
                debitClosingBalanceTo: null,
                creditClosingBalanceFrom: null,
                creditClosingBalanceTo: null,
                hideAllZeroRecords: false
            };

            // $scope.criteriaList = [];

            //$scope.getDataFromDatabase($scope.currentCategory.selected.id, from, to, "");
            $scope.isToClearSelection = true;
        }

        $scope.doDataFilter = function (removeData) {

            if ($scope.filterData.periodFrom > $scope.filterData.periodTo) {
                $scope.filterData.periodTo = $scope.filterData.periodFrom;
            }

            // Filter validations:
            if (!PWC.isNullOrEmpty($scope.filterData.debitOpeningBalanceFrom) && !PWC.isNullOrEmpty($scope.filterData.debitOpeningBalanceTo) &&
                $scope.filterData.debitOpeningBalanceFrom > $scope.filterData.debitOpeningBalanceTo) {
                swal({ title: "", text: $translate.instant('AmountWarningSearch'), type: "warning", confirmButtonText: "确定" },
                    function (isConfirm) {
                        if (isConfirm) {
                            $("#filterButton").click();
                        }

                    });
            }

            else if (!PWC.isNullOrEmpty($scope.filterData.creditOpeningBalanceFrom) && !PWC.isNullOrEmpty($scope.filterData.creditOpeningBalanceTo) &&
                $scope.filterData.creditOpeningBalanceFrom > $scope.filterData.creditOpeningBalanceTo) {

                swal({ title: "", text: $translate.instant('AmountWarningSearch'), type: "warning", confirmButtonText: $translate.instant('Confirm') },
                    function (isConfirm) {
                        if (isConfirm) {
                            $("#filterButton").click();
                        }

                    });
            }

            else if (!PWC.isNullOrEmpty($scope.filterData.accumulatedDebitAmountFrom) && !PWC.isNullOrEmpty($scope.filterData.accumulatedDebitAmountTo) &&
            $scope.filterData.accumulatedDebitAmountFrom > $scope.filterData.accumulatedDebitAmountTo) {

                swal({ title: "", text: $translate.instant('AmountWarningSearch'), type: "warning", confirmButtonText: $translate.instant('Confirm') },
                     function (isConfirm) {
                         if (isConfirm) {
                             $("#filterButton").click();
                         }

                     });
            }



            else if (!PWC.isNullOrEmpty($scope.filterData.accumulatedCreditAmountFrom) && !PWC.isNullOrEmpty($scope.filterData.accumulatedCreditAmountTo) &&
        $scope.filterData.accumulatedCreditAmountFrom > $scope.filterData.accumulatedCreditAmountTo) {

                swal({ title: "", text: $translate.instant('AmountWarningSearch'), type: "warning", confirmButtonText: $translate.instant('Confirm') },
                     function (isConfirm) {
                         if (isConfirm) {
                             $("#filterButton").click();
                         }

                     });
            }

            else if (!PWC.isNullOrEmpty($scope.filterData.debitClosingBalanceFrom) && !PWC.isNullOrEmpty($scope.filterData.debitClosingBalanceTo) &&
        $scope.filterData.debitClosingBalanceFrom > $scope.filterData.debitClosingBalanceTo) {

                swal({ title: "", text: $translate.instant('AmountWarningSearch'), type: "warning", confirmButtonText: $translate.instant('Confirm') },
                     function (isConfirm) {
                         if (isConfirm) {
                             $("#filterButton").click();
                         }

                     });
            }


            else if (!PWC.isNullOrEmpty($scope.filterData.creditClosingBalanceFrom) && !PWC.isNullOrEmpty($scope.filterData.creditClosingBalanceTo) &&
   $scope.filterData.creditClosingBalanceFrom > $scope.filterData.creditClosingBalanceTo) {

                swal({ title: "", text: $translate.instant('AmountWarningSearch'), type: "warning", confirmButtonText: $translate.instant('Confirm') },
                     function (isConfirm) {
                         if (isConfirm) {
                             $("#filterButton").click();
                         }

                     });
            } 

            else {
                //设置需要去掉的查询条件的值为空
                if (!PWC.isNullOrEmpty(removeData)) {
                    var removeItem = removeData.split("|");
                    removeItem.forEach(function (v) {
                        $scope.filterData[v] = null;
                    });
                }


                //********************************************************************************
                // add to Criteria List for display on top of the grid:
                var crits = $scope.filterData;

                $scope.criteriaList = [];

                var crit = [];
                if (!PWC.isNullOrEmpty(crits.accountCode)) {
                    crit = new Object;
                    crit.name = $translate.instant('AccountCode');
                    crit.valueFrom = crits.accountCode;
                    crit.propertyName = "accountCode";

                    $scope.criteriaList.push(crit);
                }

                if (!PWC.isNullOrEmpty(crits.accountName)) {
                    crit = new Object;
                    crit.name = $translate.instant('AccountName');
                    crit.valueFrom = crits.accountName;
                    crit.propertyName = "accountName";

                    $scope.criteriaList.push(crit);
                }

                if (!PWC.isNullOrEmpty(crits.debitOpeningBalanceFrom) || !PWC.isNullOrEmpty(crits.debitOpeningBalanceTo)) {
                    crit = new Object;
                    crit.name = $translate.instant('DebitOpeningBalance');
                    crit.valueFrom = crits.debitOpeningBalanceFrom;
                    crit.valueTo = crits.debitOpeningBalanceTo;
                    crit.propertyName = "debitOpeningBalanceFrom|debitOpeningBalanceTo";

                    $scope.criteriaList.push(crit);
                }

                if (!PWC.isNullOrEmpty(crits.creditOpeningBalanceFrom) || !PWC.isNullOrEmpty(crits.creditOpeningBalanceTo)) {
                    crit = new Object;
                    crit.name = $translate.instant('CreditOpeningBalance');
                    crit.valueFrom = crits.creditOpeningBalanceFrom;
                    crit.valueTo = crits.creditOpeningBalanceTo;
                    crit.propertyName = "creditOpeningBalanceFrom|creditOpeningBalanceTo";

                    $scope.criteriaList.push(crit);
                }

                if (!PWC.isNullOrEmpty(crits.accumulatedDebitAmountFrom) || !PWC.isNullOrEmpty(crits.accumulatedDebitAmountTo)) {
                    crit = new Object;
                    crit.name = $translate.instant('AccumulatedDebitAmount');
                    crit.valueFrom = crits.accumulatedDebitAmountFrom;
                    crit.valueTo = crits.accumulatedDebitAmountTo;
                    crit.propertyName = "accumulatedDebitAmountFrom|accumulatedDebitAmountTo";

                    $scope.criteriaList.push(crit);
                }

                if (!PWC.isNullOrEmpty(crits.accumulatedCreditAmountFrom) || !PWC.isNullOrEmpty(crits.accumulatedCreditAmountTo)) {
                    crit = new Object;
                    crit.name = $translate.instant('AccumulatedCreditAmount');
                    crit.valueFrom = crits.accumulatedCreditAmountFrom;
                    crit.valueTo = crits.accumulatedCreditAmountTo;
                    crit.propertyName = "accumulatedCreditAmountFrom|accumulatedCreditAmountTo";

                    $scope.criteriaList.push(crit);
                }

                if (!PWC.isNullOrEmpty(crits.debitClosingBalanceFrom) || !PWC.isNullOrEmpty(crits.debitClosingBalanceTo)) {
                    crit = new Object;
                    crit.name = $translate.instant('DebitClosingBalance');
                    crit.valueFrom = crits.debitClosingBalanceFrom;
                    crit.valueTo = crits.debitClosingBalanceTo;
                    crit.propertyName = "debitClosingBalanceFrom|debitClosingBalanceTo";

                    $scope.criteriaList.push(crit);
                }

                if (!PWC.isNullOrEmpty(crits.creditClosingBalanceFrom) || !PWC.isNullOrEmpty(crits.creditClosingBalanceTo)) {
                    crit = new Object;
                    crit.name = $translate.instant('CreditClosingBalance');
                    crit.valueFrom = crits.creditClosingBalanceFrom;
                    crit.valueTo = crits.creditClosingBalanceTo;
                    crit.propertyName = "creditClosingBalanceFrom|creditClosingBalanceTo";

                    $scope.criteriaList.push(crit);
                }
                // add to Criteria List for display on top of the grid:
                //********************************************************************************
 
                var criteria = JSON.stringify($scope.filterData); 

                $scope.filterDataCriteria = criteria;

                $scope.getDataFromDatabase($scope.currentCategory.selected.id, $scope.filterData.periodFrom, $scope.filterData.periodTo, criteria, false);
            }
        };  

        $scope.popTheParentCode = function () {
            $scope.isShowParentCodePop = true;
            $scope.isToClearSelection = false;

            $('.filter-button').popover("hide");
        }

        $scope.hideAllZeroRecords = function () {
            $scope.filterData.hideAllZeroRecords = $("#ckbHideAllZeroRecords").is(":checked");

            var criteria = JSON.stringify($scope.filterData);
             
            $scope.getDataFromDatabase($scope.currentCategory.selected.id, $scope.filterData.periodFrom, $scope.filterData.periodTo, criteria, false);
        };

        //过滤条件变化
        $scope.doCategoryChange = function () {
            $scope.doDataFilterReset();
            $scope.criteriaList = [];
            $scope.isRunningTheFirstTime = true;
            $scope.filterData.hideAllZeroRecords = false;
            $("#ckbHideAllZeroRecords").prop('checked', false);

            $scope.doDataFilter('');
            var selectedSubjectName = $scope.currentCategory.selected.id; 
            if (selectedSubjectName === "CIT")
                $scope.switchedToCIT = true; 
        };

        // ************************************************************************************************
        // Control how the Header looks:
        function SetUiGridHeader() {
            var column1 = $("#tbDataPreviewGrid .ui-grid-header-cell").first();
            var column2 = $("#tbDataPreviewGrid .dataColumn1");
            var column3 = $("#tbDataPreviewGrid .dataColumn2");
            var column4 = $("#tbDataPreviewGrid .dataColumn3");
            var column5 = $("#tbDataPreviewGrid .dataColumn4");
            var column6 = $("#tbDataPreviewGrid .dataColumn5");
            var column7 = $("#tbDataPreviewGrid .dataColumn6");
            var column8 = $("#tbDataPreviewGrid .dataColumn7");
            var column9 = $("#tbDataPreviewGrid .dataColumn8");



            var col1 = column1.width();
            var col2 = column2.width();
            var col3 = column3.width();
            var col4 = column4.width();
            var col5 = column5.width();
            var col6 = column6.width();
            var col7 = column7.width();
            var col8 = column8.width();
            var col9 = column9.width();

            var marginSize = "-20px";
            var marginSizeForIcon = "-17px";

            if (browserService.isIE() || browserService.isEdge()) {
                $("#UIHeaderCol001").width(col1 - 1);
                $("#UIHeaderCol01").width(col2);
                $("#UIHeaderCol1").width(col3);

                $("#UIHeaderCol2").width(col4 + col5 + 1);
                $("#UIHeaderCol3").width(col6 + col7 + 1);
            }
            else if (browserService.isFirefox()) {
                $("#UIHeaderCol001").width(col1);
                $("#UIHeaderCol01").width(col2);
                $("#UIHeaderCol1").width(col3);

                $("#UIHeaderCol2").width(col4 + col5 + 1);
                $("#UIHeaderCol3").width(col6 + col7 + 1);

                marginSize = "-16px";
                marginSizeForIcon = "-16px";
            }

            else if (browserService.isChrome()) {
                $("#UIHeaderCol001").width(col1 - 1);
                $("#UIHeaderCol01").width(col2);
                $("#UIHeaderCol1").width(col3);

                $("#UIHeaderCol2").width(col4 + col5 + 1);
                $("#UIHeaderCol3").width(col6 + col7 + 1);

                marginSize = "-15px";
                marginSizeForIcon = "-15px";
            }


            var treeExpanderIcon = $("#tbDataPreviewGrid .ui-grid-tree-base-row-header-buttons").first();

            treeExpanderIcon.css("margin-top", marginSizeForIcon);


            var subjectCode = column2.find('span');
            var subjectName = column3.find('span');



            subjectCode.css("margin-top", 0);
            subjectName.css("margin-top", 0);

            setTimeout(function () {
                subjectName.css("position", "absolute");
                subjectName.css("margin-top", marginSize);
                subjectCode.css("position", "absolute");
                subjectCode.css("margin-top", marginSize);

            }, 900);


        };

        //开始
        (function initialize() {
                      
            //初始化month-picker
            $('#input-invoice-period-picker').rangePicker({
                minDate: minDate,
                maxDate: maxDate,
                setDate: setDate,
                months: $scope.monthList,//['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
                ConfirmBtnText: $translate.instant('Confirm'),
                CancelBtnText: $translate.instant('ButtonCancel')
            })
             .on('datePicker.show', function (ev, picker) {
                    $('.filter-button').popover("hide");
                })
             .on('datePicker.done', function (e, result) {
                 //开始月份
                 var startMonth = result[0][0];
                 //结束月份
                 var endMonth = result[1][0];
                 $scope.filterData.periodFrom = startMonth;
                 $scope.filterData.periodTo = endMonth;

                 var criteria = JSON.stringify($scope.filterData);
                  
                 $scope.getDataFromDatabase($scope.currentCategory.selected.id, $scope.filterData.periodFrom, $scope.filterData.periodTo, criteria);


             });

            $scope.initGridOption();

            $scope.$on(enums.vatEvent.layoutChanged, function () {
                $scope.gridApiTotal.core.handleWindowResize();
                SetUiGridHeader();
            }); 

            // Reposition Header when the window is resized
            $(window).on('resize', function () {
                $scope.gridApiTotal.core.handleWindowResize();
                SetUiGridHeader();
            });
        })();
    }
]);
commonModule.directive('previewTrialBalance', ['$log', 'browserService', '$translate',
    function ($log, browserService, $translate) {
        $log.debug('previewTrialBalance.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/preview-trial-balance/preview-trial-balance.html' + '?_=' + Math.random(),
            scope: {
                project: '=?',
                month:'=?',
            },
            controller: 'previewTrialBalanceController',
            link: function ($scope, element) { 
            }
        };
    }
]);




commonModule.controller('refundReasonController', ['$log', '$translate', '$uibModal', '$scope', '$document', 'InvoiceManageService', 'SweetAlert',
    function ($log, $translate, $uibModal, $scope, $document, InvoiceManageService, SweetAlert) {
        'use strict';

        $scope.refundReason = {
            reasonSelectOptions: {
                bindingOptions: {
                    dataSource: 'reasons'
                },
                width: "60%",
                height:"32px",
                onSelectionChanged: function (e) {
                    var selectItem = e.selectedItem;
                    if (selectItem.id === 4) {
                        $scope.refundReason.remarkEntity.value = null;
                        //OtherReason
                        $('#otherReasonRemark').show();
                    } else {
                        $('#otherReasonRemark').hide();
                        $scope.refundReason.remarkEntity.id = selectItem.id;
                        $scope.refundReason.remarkEntity.value = selectItem.value;
                    }
                },
                valueExpr: 'id',
                displayExpr: 'value',
                placeHolder: $translate.instant('ChoosePlaceholder')

            },
            otherReasonOptions: {
                bindingOptions: {
                    value: 'refundReason.remarkEntity.value'
                }
               
            },
            remarkEntity: {
                id: null,
                value: null
            }

        };
        $scope.refundReasonModal = {
            modalInstance: null,
            open: function () {
                var parentSelector = '.refund-reason-modal';
                var parentElem = parentSelector ? angular.element($document[0].querySelector(parentSelector)) : undefined;

                var modalInstance = $uibModal.open({
                    animation: true,
                    ariaLabelledBy: 'modal-title',
                    ariaDescribedBy: 'modal-body',
                    templateUrl: 'refund-reason.html',
                    windowClass: 'reason-modal',
                    scope: $scope,
                    appendTo: parentElem,
                });

                $scope.refundReasonModal.modalInstance = modalInstance;
            },
            close: function () {
                if ($scope.refundReasonModal.modalInstance) {
                    $scope.isShow = false;
                    //发票IDs 退票原因
                    var dto = {
                        invoiceIDs: $scope.invoiceIds,
                        remark: $scope.refundReason.remarkEntity.id + '_' + $scope.refundReason.remarkEntity.value,
                        type: null,
                        userID: null
                    };
                    InvoiceManageService.addRefundRemark(dto).success(function (res) {
                        if (_.isFunction($scope.refreshTable)) {
                            $scope.refreshTable();
                        }                       
                        $scope.refundReasonModal.modalInstance.close();
                    }).error(function () {
                        SweetAlert.error('', $translate.instant('CommonFail'));
                    });
                    

                }
            },
            cancel: function () {
                if ($scope.refundReasonModal.modalInstance) {
                    $scope.isShow = false;
                    $scope.refundReasonModal.modalInstance.dismiss('cancel');
                }
            }
        };

    }
]);
commonModule.directive('refundReason', ['$log',
    function ($log) {
        'use strict';
        $log.debug('refundReason.ctor()...');
        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/refund-reason/refund-reason.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                //display reason list
                reasons: '=',
                //which invoices need to refund
                invoiceIds: '=',
                isShow: '=',
                refreshTable: '&'
            },
            controller: 'refundReasonController',
            link: function ($scope, element) {
                $scope.$watch('isShow', function (newVal, oldValue) {
                    if (newVal !== oldValue && newVal) {
                        $scope.refundReasonModal.open();
                    }
                });
               
            }
        };
    }
]);
commonModule.
controller('regionSelectorController', ['$scope', 'regionService', '$translate', '$timeout',
    function($scope, regionService, $translate, $timeout) {

        var showRegionTree = function() {

            //默认全部不选择
            $scope.gridInstance.unselectAll();

            //如果之前的操作有展开的情况,全部收缩
            var data = $scope.dsCheckBoxTreeView;
            data.forEach(function(item) {
                if (item.expanded) {
                    $scope.gridInstance.collapseItem(item);
                }
            });

            $timeout(InitSelectedNode, 10);

            //展开和隐藏区域选择框
            if ($('.region-tree-wrapper').is(":hidden")) {
                $(".region-tree-wrapper").show();

            } else {
                $(".region-tree-wrapper").hide();
            }

            $(document).one("click", function() {
                $(".region-tree-wrapper").hide();
            });
            event.stopPropagation();
        };

        //当进入编辑状态的时候,前端会传一个选中的城市列表过来,然后根据前端传过来的选中列表去初始化选中的状态
        //所以检测该变量,一旦该变量发生改变
        $scope.$watch('selectedCityList', function(newValue, oldValue) {
            if (newValue) {

                //初始化选中的节点
                $scope.selectedNodeList = [];

                //如果是编辑状态,进入界面前先初始化选中的城市节点
                 $timeout(InitSelectedNode, 10);
                // InitSelectedNode();
            }
        });

        var InitSelectedNode = function() {
            //属于该区域的需要选中
            //selectedCityList选中当前节点之后通过directive传过来的
            $scope.cityNameStr = '';
            if ($scope.selectedCityList != undefined) {
                var citiesOnly = _.filter($scope.selectedCityList, function(item) {
                    return item.level == 2;
                });

                if (citiesOnly && citiesOnly.length > 0)
                {
                    var cityNameList = _.uniq(_.pluck(citiesOnly, 'name'));

                    $scope.cityNameStr = cityNameList.join(',');
                }
                 

                var provincesOnly = _.uniq(_.pluck($scope.selectedCityList, 'parentId'));

                citiesOnly.forEach(function(item) {
                    $scope.gridInstance.selectItem(item.id);
                });

                $scope.selectedNodeList = citiesOnly;



                provincesOnly.forEach(function(item) {
                    // $scope.gridInstance.expandItem(item.id);
                    if (item) {
                        $scope.gridInstance.expandItem(item);
                    }
                });

                // $scope.selectedNodeList = $scope.selectedCityList;
            }
        };

        var getSelectedOrgDisplayText = function() {
            if ($scope.selectedNodeList !== undefined && $scope.selectedNodeList.length > 0) {
                var cityTextList = _.map(_.filter($scope.selectedNodeList, function(node) {
                    return node.level == 2;
                }), function(item) {
                    return item.name;
                });
                return cityTextList.join(',');
            } else {
                return '';
            }
        };

        //加载省市数据
        var loadProvinceAndCity = function() {
            regionService.getProvinceAndCityTreeList().success(function(data) {
                $scope.dsCheckBoxTreeView = data;
            });
        };

        $scope.searchOptions = {
            bindingOptions: {
                value: "searchValue"
            },
            placeholder: $translate.instant('Search'),
            width: 240,
            mode: "search",
            valueChangeEvent: "keyup"
        };

        var dataSource = new DevExpress.data.DataSource({
            load: function(loadOptions) {
                var d = new $.Deferred();

                regionService.getProvinceAndCityTreeList().success(function(data) {
                    $scope.dsCheckBoxTreeView = data;
                    d.resolve(data);
                });

                // regionService.getSettingRegionTree().success(function(data) {
                //     initParam();
                //     setAreaRegionTreeColor(data);
                //     //$scope.areaRegionTreeData = data;

                //     $timeout(function() {

                //         if ($scope.selectedBranch) {
                //             $scope.gridInstance.selectItem($scope.selectedBranch.key);
                //         } else {
                //             $scope.gridInstance.selectItem(data[0].id);
                //         }
                //     }, 20);

                //     d.resolve(data);

                // });

                return d.promise();
            }
        });


        //加载区域选择树形结构
        var loadRegionCheckboxTreeViewSettings = function() {

            $scope.regionCheckboxTreeViewOptions = {

                 bindingOptions: {
                     dataSource: 'dsCheckBoxTreeView',
                     searchValue: 'searchValue'
                 },
                //dataSource: dataSource,
                selection: {
                    mode: "multiple"
                },

                loadPanel: {
                    enabled: true
                },
                scrolling: {
                    mode: "virtual"
                },
                keyExpr: "id",
                showRowLines: true,
                showColumnLines: true,
                expandAllEnabled: true,
                rowAlternationEnabled: true,
                expandedRowKeys: [1],
                showBorders: true,
                noDataText: $translate.instant('NoDataText'),
                selectAllText: $translate.instant('SelectAll'),
                displayExpr: 'text', //显示的属性名称,默认为text
                itemsExpr: 'items', //子层的数组名称,默认为items
                //scrollDirection:'vertical',  //Accepted Values: 'vertical' | 'horizontal' | 'both'
                selectNodesRecursive: true, //级联选择
                showCheckBoxesMode: 'normal', //Accepted Values: 'none' | 'normal' | 'selectAll' 
                onInitialized: function(e) {
                    $scope.gridInstance = e.component;
                },
                onItemSelectionChanged: function(e) {
                    if (e.node.selected) {
                        //如果选中的是叶子节点 
                        if (e.node.children.length == 0) {
                            var selectedNode = {
                                id: e.node.key,
                                parentId: e.node.parent == undefined ? null : e.node.parent.key,
                                name: e.node.text,
                                level: 2
                            };

                            //检查是否重复,只添加不存在的
                            if (!checkNodeExistence($scope.selectedNodeList, selectedNode)) {
                                $scope.selectedNodeList.push(selectedNode);
                            }
                        } else {
                            //选中的是父级节点,需要包含所有的子节点
                            e.node.children.forEach(function(item) {

                                var selectedNode = {
                                    id: item.key,
                                    parentId: item.parent.key,
                                    name: item.text,
                                    level: 2
                                };

                                //检查是否重复,只添加不存在的
                                if (!checkNodeExistence($scope.selectedNodeList, selectedNode)) {
                                    $scope.selectedNodeList.push(selectedNode);
                                }
                            });
                        }
                    } else {
                        //如果只是取消叶子节点
                        if (e.node.children.length == 0) {
                            var selectedNodeList = $scope.selectedNodeList;
                            var findUncheckedOne = _.find(selectedNodeList, function(item) {
                                return item.id === e.node.key && item.name == e.node.text;
                            });
                            $scope.selectedNodeList = _.without(selectedNodeList, findUncheckedOne);
                        } else {
                            //如果取消父级节点 
                            var selectedNodeList = $scope.selectedNodeList;

                            var idList = _.map(e.node.children, function(item) {
                                return item.key;
                            });

                            var findUncheckedList = _.filter(selectedNodeList, function(item) {
                                return idList.indexOf(item.id) >= 0;
                            });

                            $scope.selectedNodeList = _.difference(selectedNodeList, findUncheckedList);
                        }
                    }
                },
                //点击行,选中
                onItemClick: function(e) {
                    var data = e.itemData;
                },
                onContentReady: function(object, container) {
                    //object.element.find('.dx-checkbox-checked').addClass('dx-state-disabled');
                }
            };
        };

        var checkNodeExistence = function(allSelectedNodeList, node) {
            var filteredItem = _.find(allSelectedNodeList, function(item) {
                return item.id == node.id && item.name == node.name;
            });
            if (filteredItem) {
                return true;
            }
            return false;
        };

        (function() {
            $(".region-tree-wrapper").on("click", function(e) {
                e.stopPropagation();
            });
            $scope.isfirstShow = true;
            $scope.checkedRegionsNameSet = {};

            $scope.cityNameStr = '';

            //加载dev Treeview的配置
            loadRegionCheckboxTreeViewSettings();

            //加载省市数据
             loadProvinceAndCity();

            $scope.showRegionTree = showRegionTree;
            $scope.getSelectedOrgDisplayText = getSelectedOrgDisplayText;

        })();
    }
]);

commonModule.directive('regionSelector', ['$log',
    function ($log) {
        'use strict';
        $log.debug('regionSelector.ctor()...');
        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/region-selector/region-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                selectedNodeList: '=',
                selectedCityList: '=',
                isEdit: '='
            },
            controller: 'regionSelectorController',
            link: function (scope, element) {

            }
        };
    }
]);
commonModule.
controller('roleMultiSelectorController', ['$scope', 'roleService',
    function ($scope, roleService) {
        roleService.getRoleTreeList().success(function (data) {
            $scope.roleList = data;
        });

        $scope.toggleRoleSpan = function(role){
            if (!role.data.roleCategoryID){
                return;
            }
            if (role.isChecked){
                role.isChecked = false;
            } else {
                role.isChecked = true;
            }
            $scope.toggleRoleSub(role);
        };

        $scope.toggleRoleSub = function (role) {
            //根据当前的SelectedRoleIds判断是新增还是修改,
            //如果为空,则表示是新增操作,需要将checkedRolesSet和checkedRolesNameSet设置为空
             
            if (!$scope.selectedRoleIds) {
                $scope.checkedRolesSet = {};
                $scope.checkedRolesNameSet = {};
            }
            if (role.isChecked) {
                $scope.checkedRolesSet[role.data.id] = role;
                $scope.checkedRolesNameSet[role.data.id] = role.label;
            }
            else {
                delete $scope.checkedRolesSet[role.data.id];
                delete $scope.checkedRolesNameSet[role.data.id];
            }

            $scope.selectedRoleIds = _.keys($scope.checkedRolesSet);
            $scope.selectedRoleNames = _.values($scope.checkedRolesNameSet);

            if (!role.subRoles) {
                return;
            }
            role.subRoles.forEach(function (d) {
                d.isChecked = role.isChecked;
                if (role.isChecked) {
                    $scope.checkedRolesSet[d.data.id] = d;
                    $scope.checkedRolesNameSet[d.data.id] = d.label;
                }
                else {
                    delete $scope.checkedRolesSet[d.data.id];
                    delete $scope.checkedRolesNameSet[d.data.id];
                }
            });

            $scope.selectedRoleIds = _.keys($scope.checkedRolesSet);
            $scope.selectedRoleNames = _.values($scope.checkedRolesNameSet);
        };


        $scope.getSelectedRoleDisplayText = function () {
            if ($scope.selectedRoleNames && $scope.selectedRoleNames.length > 0) {

                for (var i = 0; i < $scope.selectedRoleIds.length; i++) {
                    $scope.checkedRolesSet[$scope.selectedRoleIds[i]] = { 'id': $scope.selectedRoleIds[i], 'name': $scope.selectedRoleNames[i] };
                    $scope.checkedRolesNameSet[$scope.selectedRoleIds[i]] = $scope.selectedRoleNames[i];
                }

                return $scope.selectedRoleNames;
            }
            else {
                return '';
            }
        };

        var clearAllChecked = function () {
            $scope.roleList.forEach(function (m) {
                m.children.forEach(function (n) {
                    n.isChecked = false;
                });
            });
        }

        $scope.initialCheckedNode = function () {
            if ($scope.selectedRoleIds !== '') {
                clearAllChecked();
                $scope.roleList.forEach(function (m) {
                    m.children.forEach(function (n) {
                        if ($.inArray(n.data.id, $scope.selectedRoleIds) > -1) {
                            n.isChecked = true;
                        }
                    });
                });
            }
            else {
                clearAllChecked();
            }
        };


        (function () {
            //role property

            if (!angular.isDefined($scope.itemMaxLength)){
                $scope.itemMaxLength = 40;
            }

            $scope.roleList = [];
            $scope.checkedRolesSet = {};
            $scope.checkedRolesNameSet = {};

            $scope.selectedRoleIds = [];
            $scope.selectedRoleNames = [];

        })();
    }
]);
commonModule.directive('roleMultiSelector', ['$log',
    function ($log) {
        'use strict';
        $log.debug('roleMultiSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/role-multi-selector/role-multi-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                selectedRoleIds: '=',
                selectedRoleNames: '=',
                itemMaxLength:'=?'
            },
            controller: 'roleMultiSelectorController',
            link: function (scope, element) {
                element.find('.selector-input').on('focus', function () {
                    scope.initialCheckedNode();
                    scope.$digest();
                    element.find('.role-tree-container').show();
                });

                $(document).on('click', function () {
                    element.find('.role-tree-container').hide();
                }).on('click', '.role-multi-selector-container', function (e) {
                    e.stopPropagation();
                });
            }
        };
    }
]);
commonModule.controller('standardAccountGridFilterModalController', ['$scope', '$log', '$translate', '$timeout', 'apiInterceptor', 'Upload'
    , 'dataImportService', 'SweetAlert', '$q', 'uiGridConstants', 'projectService', 'uiGridGroupingConstants'
    , 'vatImportService', 'i18nService', 'browserService', '$interval', 'region', 'vatSessionService'
    , 'vatReductionService', '$uibModal',
    function ($scope, $log, $translate, $timeout, apiInterceptor, Upload
        , dataImportService, SweetAlert, $q, uiGridConstants, projectService, uiGridGroupingConstants
        , vatImportService, i18nService, browserService, $interval, region, vatSessionService
        , vatReductionService, $uibModal) {
        'use strict';
        $log.debug("standardAccountGridFilterModalController  start.....");
                 
        //开始
        (function initialize() {          
 
        })();
    }
]);
commonModule.directive('standardAccountGridFilterModal', ['$log','$translate','$uibModal',
    function ($log, $translate,$uibModal) {
        'use strict';
        $log.debug('standardAccountGridFilterModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/standard-account-grid-filter-modal/standard-account-grid-filter-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'standardAccountGridFilterModalController',
            scope:
            {            
                isShowStdFilter: "=",
                stdAccountList: "=?",
                selectedStdCode: "=?"
            },
            link: function ($scope, element) {
                var selectedStdItem;
                $scope.closeModal = function () {
                    $scope.isShowStdFilter = false;
                    $('#stdAccountFilterModel').modal('hide');
                }

                $scope.selectStdCode = function () {
                    if (!_.isUndefined(selectedStdItem)) {
                        $scope.selectedStdCode = selectedStdItem[0].code;
                    }

                    $scope.closeModal();
                }

                $scope.showStdGridFilter = function () {
                    $scope.stdAccountList = _.sortBy($scope.stdAccountList, 'code');
                    $scope.treeListOptions = {
                        dataSource: $scope.stdAccountList,
                        keyExpr: "code",
                        parentIdExpr: "parentCode",
                        columns: [
                            {
                                dataField: "code",
                                caption: $translate.instant('StdSubjectCodeCol'),
                            },
                            {
                                dataField: "fullName",
                                caption: $translate.instant('StdSubjectNameCol'),
                            },
                            {
                                dataField: "directionDesc",
                                caption: $translate.instant('SubjectDirectionCol'),
                            },
                            {
                                dataField: "parentCode",
                                caption: $translate.instant('ParentCode'),
                            },
                            {
                                dataField: "hasChildren",
                                caption: $translate.instant('DoesHasChildren'),
                                visible:false
                            }
                        ],
                        scrolling: {
                            mode: "virtual"
                        },
                        sorting: {
                            mode: 'single'
                        },
                        filterRow: {
                            visible: true,
                            applyFilter: "auto",
                            showOperationChooser: false //filterRow是否出现放大镜的筛选条件
                        },
                        searchPanel: {
                            placeholder: $translate.instant('Search'),
                            visible: true,
                            width: 200
                        },
                        selection: {
                            allowSelectAll: false,
                            mode: "single"
                        },
                        allowColumnResizing: true,
                        columnAutoWidth: true,
                        showRowLines: true,
                        showColumnLines: true,
                        rowAlternationEnabled: true, //单双行颜色
                        showBorders: true,
                        expandedRowKeys: [1],
                        //onInitialized: function (e) {
                        //    $scope.treeViewInstance = e.component;
                        //},
                        onSelectionChanged: function (e) {                       
                            selectedStdItem = e.component.getSelectedRowsData();                                                                     
                        }
                    };

                    $('#stdAccountFilterModel').modal('show');
                }


                $scope.$watch("isShowStdFilter", function (newValue, oldValue) {
                    $log.debug("standard-account-grid-filter-modal.js   isShow watching:");
                    $log.debug("newValue:" + newValue + " oldValue:" + oldValue);
                    $log.debug($scope.stdAccountList);
                    if (newValue) {
                        $scope.showStdGridFilter();
                    }
                });


            }
        };
    }
]);
commonModule.controller('taxReportAnalyzeReportController', ['$scope', '$translate', 'SweetAlert', 'enums', 'modelConfigurationService', '$compile',
    function ($scope, $translate, SweetAlert, enums, modelConfigurationService, $compile) {

        $scope.modelType = 2;
        $scope.editModalWriteBackData = false;

        //焦点单元格发生变化和显示类型发生变化时,若当前正在编辑"模型回填"则直接取消,编辑
        $scope.$watch("modelType", "cellDataId", function (newValue, oldValue) {
            if ($scope.editModalWriteBackData)
                $scope.fireCancelEditModelWriteBack();
        });

        //数据源列表发生变化时,获取当前单元格的模型回填数据源 Id,并绑定到 model-analysis-report 中,用于提交回填更改时需要 dataSourceId 的要求
        $scope.$watchCollection("modelDataSourceItems", function (newValue, oldValue) {
            $scope.dataSource = _.find(newValue, function (e) {
                return e.type === enums.formulaDataSourceType.ModelDatasource;
            });
        });

        $scope.fireEditModelWriteBack = function () {
            $scope.editModalWriteBackData = true;
            $scope.$broadcast("EditModelWriteBack");
        };

        $scope.fireCancelEditModelWriteBack = function () {
            $scope.editModalWriteBackData = false;
            $scope.$broadcast("CancelEditModelWriteBack");
        };

        $scope.fireCheckModelWriteBackHasChanged = function () {
            $scope.$broadcast("CheckModelWriteBackHasChanged");
            $scope.editModalWriteBackData = false;
        };
    }
]);
commonModule.directive('taxReportAnalyzeReport', [function () {
    return {
        restrict: 'E',
        templateUrl: '/app/common/controls/tax-report-analyze-report/tax-report-analyze-report.html' + '?_=' + Math.random(),
        replace: true,
        scope: {
            cellDataId: '=',
            modelDataSourceItems: '=',
            modelIdList: '=',
            projectYear: '=',
            period: '='
        },
        controller: 'taxReportAnalyzeReportController',
        link: function ($scope, $element, $attr) {
        }
    }
}]);
commonModule.controller('taxReportCellDetailModalController', ['$log', '$scope', '$q', '$translate', '$uibModal', '$document','$rootScope' ,'SweetAlert', 'enums',
    'vatReportService', 'loginContext', 'vatSessionService', 'stdAccountService', 'vatCommonService', 'formulaService', 'KeyValueConfigService', 'modelConfigurationService', '$timeout', 'cellCommentService', 'modifiedReportCellService',
    function ($log, $scope, $q, $translate, $uibModal, $document, $rootScope, SweetAlert, enums, vatReportService, loginContext,
              vatSessionService, stdAccountService, vatCommonService, formulaService, KeyValueConfigService, modelConfigurationService, $timeout, cellCommentService, modifiedReportCellService) {

        var activeClass = 'active';
        $scope.currentUserName = loginContext.userName;
        $scope.tabType = 1;
        $scope.isWriteBackUpdate = false;
        $scope.projectYear = vatSessionService.year;
        $scope.projectPeriod= vatSessionService.month;

        //关闭数据源弹出框
        var hidePanel = function () {
            $scope.selectedDataSourceTabIndex = 1;

            $scope.tabType = 1;
            $('#taxReportCellDetailModal').hide('normal');
            $('#taxReportCellDetailModal #cellDetailConent').show();
            $scope.detail.items = [];
            //隐藏凭证范围弹出框
            $scope.closePropover();
        };

        $scope.$watch('detail.config.cellID', function () {
            if ($scope.detail.config != null) {
                cellCommentService.getCellComments($scope.detail.config.cellID).success(function (op) {
                    if (op.result === true) {
                        $scope.remarks = op.data;
                    }
                });
            }
        });

/******************单元格值修改*********************************/
        //打开修改单元格值弹出框
        $scope.openModifyCellDataDialog = function () {
            var parentElem = angular.element($document[0].querySelector('#modifyCellDataContainer'));
            var modalInstance = $uibModal.open({
                ariaLabelledBy: 'modal-title',
                ariaDescribedBy: 'modal-body',
                templateUrl: 'modifyCellData.html',
                controller: modifyCellDataController,
                windowClass: 'modification-table',
                appendTo: parentElem,
                scope: $scope
            });
        };


        var modifyCellDataController = function ($scope) {
            $scope.modifyReportCellModel = {};
            $scope.modifyReportCellModel.originalValue = $scope.$parent.detail.cellInfo.modifiedReportCell ? $scope.$parent.detail.cellInfo.modifiedReportCell.originalValue : $scope.$parent.detail.cellInfo.value;
            $scope.modifyReportCellModel.col = $scope.$parent.detail.config.columnIndex;
            $scope.modifyReportCellModel.row = $scope.$parent.detail.config.rowIndex;
            $scope.modifyReportCellModel.reportId = $scope.$parent.detail.reportId;

            $scope.saveModification = function () {
                modifiedReportCellService.update($scope.modifyReportCellModel).success(function (ret) {
                    $scope.$parent.detail.cellInfo.modifiedReportCell = ret.data;
                    $scope.$parent.detail.cellInfo.value = $scope.modifyReportCellModel.value;
                    $scope.$parent.detail.cellInfo.money = $scope.modifyReportCellModel.value;
                    $rootScope.$broadcast('cellValueModified',
                        {
                            modifiedReportCell: ret.data
                        });
                    $scope.$dismiss({ $value: 'cancel' });
                });
            };

            $scope.hide = function () {
                $scope.$dismiss({ $value: 'cancel' });
            };
        };

        $scope.resetReportCell = function () {
            modifiedReportCellService.reset($scope.detail.cellInfo.modifiedReportCell.id).success(function () {
                $scope.detail.cellInfo.money = $scope.detail.cellInfo.modifiedReportCell.originalValue;
                $scope.detail.cellInfo.modifiedReportCell = null;
                $rootScope.$broadcast('cellValueReset',
                       {
                           row: $scope.detail.rowIndex,
                           col: $scope.detail.columnIndex,
                       });
            });
        };

        modifyCellDataController.$inject = ['$scope'];
/******************End of 单元格值修改*********************************/
      
/******************单元格备注*****************************/
        $scope.addCellComment = function (content) {
            var addingComment = {
                userId: loginContext.userId,
                cellDataId: $scope.detail.config.cellID,
                userName: loginContext.userName,
                comment: $scope.addingRemark,
            };
            cellCommentService.addCellComment(addingComment).success(function (op) {
                if (op.result === true) {
                    $scope.remarks.push(addingComment);
                    $scope.addingRemark = '';
                }
            });
        };

        $scope.addRemark = function () {
            var now = new Date();
            $scope.remarks.push({
                cellDataId: $scope.detail.config.cellID,
                userName: loginContext.userName,
                content: $scope.addingRemark,
            });
            $scope.addingRemark = '';
        };

        $scope.deleteComment = function (comment) {
            cellCommentService.deleteCellComment(comment.id).success(function () {
                var index = $scope.remarks.indexOf(comment);
                if (index !== -1) {
                    $scope.remarks.splice(index,1);
                }
            });
        };

        $scope.openReplyBox = function (remark) {
            var now = new Date();
            swal({
                title: $translate.instant('cellCommentReply'),
                type: "input",
                confirmButtonText: $translate.instant('Confirm'),
                cancelButtonText: $translate.instant('Cancel'),
                showCancelButton: true,
                closeOnConfirm: true,
            },function(inputValue){   
                if (inputValue === false) return false;      
                if (inputValue === "") {
                    swal.showInputError($translate.instant('cellCommentReplyEmptyMsg'));
                    return false
                }
                $scope.$apply(function () {
                    var addingComment = {
                        userId: loginContext.userId,
                        cellDataId: $scope.detail.config.cellID,
                        userName: loginContext.userName,
                        replyToUserName:remark.userName,
                        comment: inputValue,
                    };

                    cellCommentService.addCellComment(addingComment).success(function (op) {
                        if (op.result === true) {
                            $scope.remarks.push(addingComment);
                        }
                    });
                });
 
                return true;
            });
        };
/***********************end of 单元格备注**********************/
        //展开|收起数据源弹出框
        var togglePanel = function () {

            if ($('#taxReportCellDetailModal #cellDetailConent').css('display') == 'none') {
                $('#taxReportCellDetailModal').height(700);
            } else {
                $('#taxReportCellDetailModal').height(40);
            }
            $timeout(function () {
                $('#taxReportCellDetailModal #cellDetailConent').toggle('normal');
                $('#taxReportCellDetailModal').height();
                $scope.isExpand = !$scope.isExpand;
            }, 50)
        };

        function doConfirmEventHandler() {
            var r = /^00\d*|^\.\d+|\.$/;
            if ($scope.detail.inputValue && (isNaN($scope.detail.inputValue) || r.test($scope.detail.inputValue))) {
                SweetAlert.warning($translate.instant('CheckInputValueFormat'));
                return;
            }
            if ($scope.detail.inputValue && parseFloat($scope.detail.inputValue).toFixed(2) > 9999999999999) {
                SweetAlert.warning($translate.instant('CheckInputValueLength'));
                return;
            }
            if ($scope.detail.dataType === 5) {
                r = /^(-[1-9]\d*|[1-9]\d*|[0]{1,1})$/;
                if (!r.test($scope.detail.inputValue)) {
                    SweetAlert.warning($translate.instant('CheckIntInputValue'));
                    return;
                }
            }
            if ($scope.detail.inputMemo && $scope.detail.inputMemo.length > 500) {
                SweetAlert.warning($translate.instant('CheckInputMemoLength'));
                return;
            }
            if ($scope.detail.inputMemo && !$scope.detail.inputValue) {
                $scope.detail.inputValue = 0;
            }
            if (!$scope.detail.inputValue) {
                $scope.detail.inputValue = "0";
            }
            $scope.detail.inputValue = $scope.detail.dataType === 5 ?
                parseInt($scope.detail.inputValue) :
                parseFloat($scope.detail.inputValue).toFixed(2);

            $scope.onConfirm();

            var status = vatSessionService.project.projectStatusList[vatSessionService.month];
            //已生成,已提交=>原状态
            if (_.isEqual(vatSessionService.project.projectStatusList[vatSessionService.month], constant.ProjectStatusEnum.Generated) ||
                _.isEqual(vatSessionService.project.projectStatusList[vatSessionService.month], constant.ProjectStatusEnum.ReportSubmitted)) {

                status = vatSessionService.project.projectStatusList[vatSessionService.month];
            }

            //已审核及后续状态=>已生成
            if (vatSessionService.project.projectStatusList[vatSessionService.month] >= constant.ProjectStatusEnum.ReportApproved) {

                status = constant.ProjectStatusEnum.Generated;
            }
            $scope.hidePanel();
            vatCommonService.setProjectStatus(vatSessionService.project.dbName, vatSessionService.month, status, null, null);
        };


        //确定点击事件的处理函数
        var confirmEventHandler = function () {
            if (vatSessionService.project.projectStatusList[vatSessionService.month] >= constant.ProjectStatusEnum.AccountMapSubmitted) {
                swal({
                        title: "warning!",
                        text: $translate.instant('IsConfirmSaveReport').formatObj({status: vatCommonService.getProjectStautsEnumDesc(vatSessionService.project.projectStatusList[vatSessionService.month])}),
                        type: "warning",
                        showCancelButton: true,
                        confirmButtonColor: "#DD6B55",
                        confirmButtonText: $translate.instant('Yes'),
                        cancelButtonText: $translate.instant('No'),
                        closeOnConfirm: true,
                        closeOnCancel: true
                    },
                    function (isConfirm) {
                        if (isConfirm) {
                            doConfirmEventHandler();
                        } else {
                            swal.close();
                        }
                    });
            } else {
                doConfirmEventHandler();
            }
        };

        //切换数据源tab时执行
        var changeTabColor = function (type, typeId, typeName, operationType) {
            $scope.detail.cellType = type;
            $scope.detail.cellTypeId = typeId;
            $scope.selectedTabIndex = type;
            $scope.selectedTabId = typeId;
            $scope.selectedTypeName = typeName;
            $scope.currentOperationType = operationType;
            $($scope.detail.items).each(function (index, element) {
                if (element.type === type && (!typeId || typeId == element.id) &&
                    (element.type !== enums.formulaDataSourceType.OutputInvoice &&
                        element.type !== enums.formulaDataSourceType.Voucher &&
                        element.type !== enums.formulaDataSourceType.Special ||
                        typeName === element.name)) {
                    $scope.detail.dataGridSource = element.dataSource;

                    // TODO: Justify IF
                    //if (element.name === 'MaxConditionDataSource') {
                    //    $scope.dataSourceOptions.summary.totalItems[4].summaryType = 'max';
                    //} else {
                    //    $scope.dataSourceOptions.summary.totalItems[4].summaryType = 'min';
                    //}

                    return;
                }
            });
        };

        // 如果公式数据源为销项发票或凭证,该数据源可能是未开票数据源,
        // 这两类公式数据源可能会同时存在多个tab,判断时要加上Name作为判断条件
        var checkIfSelectedTab = function (tabIndex, item) {
            var rtn = false;
            if (tabIndex === 1) { // 非手工数据源
                rtn = $scope.selectedTabIndex === item.type &&
                    $scope.selectedDataSourceTabIndex === 1 &&
                    $scope.selectedTabId === item.id &&
                    (item.type !== enums.formulaDataSourceType.OutputInvoice &&
                        item.type !== enums.formulaDataSourceType.Voucher &&
                        item.type !== enums.formulaDataSourceType.Special ||
                        $scope.selectedTypeName === item.name);
            } else if (tabIndex === 2) { // 手工数据源
                rtn = $scope.selectedDataSourceTabIndex == 2 ||
                    ($scope.detail.dataSourceCount == 1 && $scope.detail.hasKeyIn);
            }

            return rtn;
        };

        var changeVisibleDataSourceContainer = function (num) {
            $scope.selectedDataSourceTabIndex = num;
        };

        //---------------------------凭证范围-------------------------//start
        $scope.formulaList = [];
        $scope.keyValueList = [];
        $scope.accountDataSource = [];
        $scope.selectedAccount = [];
        $scope.selectedAccountCodes = [];
        $scope.selectedAccountTemp = [];
        //凭证范围grid设置。
        var voucherRangeOptions = {
            paging: {
                enabled: false
            },
            bindingOptions: {
                dataSource: {
                    deep: false,
                    dataPath: 'selectedAccount'
                }
            },
            height: 140,
            columns: [
                {caption: $translate.instant('KjSubjectCodeCol'), dataField: 'code', alignment: 'left'},
                {caption: $translate.instant('KjSubjectNameCol'), dataField: 'name', alignment: 'left'},
                {caption: $translate.instant('SubjectDirectionCol'), dataField: 'directionName', alignment: 'left'},
                {caption: $translate.instant('SubjectTypeCol'), dataField: 'acctPropName', alignment: 'left'},
                {
                    alignment: 'center',
                    width: '60px',
                    caption: $translate.instant('BtnDelete'),
                    cellTemplate: function (container, options) {
                        $('<a/>').addClass('dx-link dx-link-delete')
                            .html('<i class="fa fa-trash" aria-hidden="true"></i>')
                            .on('dxclick', function () {
                                options.component.removeRow(options.rowIndex);
                            })
                            .appendTo(container);
                    }
                }
            ],
            customizeColumns: function (columns) {
                $.each(columns, function (_, element) {
                    //定义表头的模板
                    element.headerCellTemplate = function (header, info) {
                        $('<span>').html(info.column.caption).appendTo(header);
                        $(header).parent().css({'color': '#444', 'background-color': '#fdd', 'font-family': '微软雅黑'})
                            .parent().css('border', '1px #ccc solid');
                    };
                });
            },
            columnAutoWidth: true,
            showBorders: true,
            showRowLines: true,
            showColumnLines: true,
            allowColumnResizing: true,
            hoverStateEnabled: true
        };

        //关闭凭证范围弹出框
        var closePropover = function () {
            $('.tab-add-voucher-area').popover('hide');
            $('.add-voucher-range-propover').hide();
            $scope.selectedAccount = $scope.selectedAccountTemp;
            $scope.selectedAccountCodes = _.pluck($scope.selectedAccount, 'code');
        };

        //打开凭证范围弹出框
        var openAcctPropover = function () {
            $('.add-voucher-range-propover').show();
            $scope.selectedAccount = $scope.selectedAccountTemp;
        }

        //保存新的凭证范围。
        var voucherRangeConfirm = function () {
            var keyValue = '';
            var newStdAccountCodes = _.map($scope.selectedAccount, function (item) {
                return item.code;
            }).join(',');
            keyValue = newStdAccountCodes;
            if ($scope.voucherRange.filterWay == '2') {
                keyValue = $scope.voucherRange.voucherKeyword;
            }
            vatReportService
                .updateCellAccountRangeAndSummary($scope.detail.cellTemplateId, vatSessionService.month, keyValue, $scope.voucherRange.filterWay)
                .success(function () {
                    if ($scope.voucherRange.filterWay == '2') {
                        $scope.selectedAccount = [];
                        $scope.selectedAccountCodes = [];
                    } else {
                        $scope.voucherRange.voucherKeyword = '';
                        $scope.selectedAccountTemp = $scope.selectedAccount;
                    }
                    $scope.closePropover();
                });
        };

        // 刷新选中的过滤凭证科目代码
        var refreshVoucherFilter = function () {
            if (!$scope.selectedAccountCodes) {
                $scope.selectedAccountCodes = [];
            }

            if (!_.isEmpty($scope.selectedAccountCodes)) {
                var selectedData = _.filter($scope.accountDataSource, function (data) {
                    return $scope.selectedAccountCodes.indexOf(data.code) > -1;
                });

                $scope.selectedAccount = selectedData;
            } else {
                $scope.selectedAccount = [];
            }
        };

        // 设置科目代码选择器
        $scope.accountTitle = $translate.instant('AddAccount');
        $scope.accountSelectorOptions = {
            height: 500,
            top: 140,
            width: 730
        };
        $scope.accountSelectorApi = {
            onSelectorConfirm: refreshVoucherFilter
        };
        var showSelectAccountPop = function () {
            $scope.isShowAccounts = true;
        };

        //--------------------------凭证范围-----------------------------//end

        //删除所有凭证|发票筛选
        var removeVoucherFilterTab = function (event) {
            if (event.target.tagName.toLowerCase() === 'span') {
                SweetAlert.swal({
                    title: $translate.instant('ConfirmDelete'),
                    text: '',
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonColor: "#DD6B55",
                    confirmButtonText: $translate.instant('Confirm'),
                    cancelButtonText: $translate.instant('Cancel'),
                    closeOnConfirm: true
                }, function (isConfirm) {
                    if (isConfirm) {
                        //获取当前要删除的筛选类型
                        var currentType = $(event.target).parent().attr('data-type');
                        var currentTypeId = $(event.target).parent().attr('data-type-id');
                        var tempDetailItems = _.filter($scope.detail.items, function (sourceItem) {
                            return sourceItem.type != currentType || sourceItem.id != currentTypeId
                        });

                        var deleteService = currentType == $scope.ModelDatasource ? modelConfigurationService.deleteModelBackFill : vatReportService[vatSessionService.citFlag === "cit" ? "citDeleteCellDatasource" : "deleteCellDatasource"];

                        deleteService(currentTypeId, $scope.detail.config.cellID).success(function (rst) {
                            SweetAlert.swal({
                                title: $translate.instant(rst.result ? "DeleteSuccess" : rst.resultMsg),
                                text: '',
                                type: "warning",
                                confirmButtonColor: "#DD6B55",
                                confirmButtonText: $translate.instant('Confirm'),
                                closeOnConfirm: true
                            });

                            if (rst.result) {
                                if (currentType == $scope.ModelDatasource) {
                                    //通知父层去更新 数据
                                    $scope.$emit("hasModelWriteBackUpdated", { isupdated: true });
                                }
                                else {
                                    if (currentType == $scope.VoucherFilter || currentType == $scope.InvoiceFilter) {
                                        _.each($scope.detail.items, function (item) {
                                            if (item.type == currentType && item.id === currentTypeId) {
                                                item.dataSource = [];
                                            }
                                        });
                                    }

                                    var tabContainer = $(event.target).closest(".tab-container");
                                    $(event.target).closest(".tab").remove();

                                    var firstTab = tabContainer.find(".tab:eq(0)");
                                    if (firstTab.length > 0) {
                                        var tabIndex = firstTab.attr('data-tab-index');
                                        var dataType = firstTab.attr('data-type');
                                        var dataTypeId = firstTab.attr('data-type-id');
                                        var dataTypeName = firstTab.attr('data-type-name');
                                        if (dataType !== undefined) {
                                            $scope.selectedTabIndex = parseInt(dataType);
                                            $scope.selectedTabId = dataTypeId;
                                            $scope.selectedTypeName = dataTypeName;
                                            $scope.detail.cellType = parseInt(dataType);
                                            $scope.detail.cellTypeId = dataTypeId;
                                        }
                                        $scope.selectedDataSourceTabIndex = parseInt(tabIndex);
                                    } else {
                                        $scope.detail.cellType = 0;
                                    }
                                    $scope.detail.dataSourceCount--;
                                    $scope.detail.items = tempDetailItems;
                                }
                            }
                        });
                    }
                });
            }
        };

        //设置数据源表格的合计与表格高度
        function setSummaryColumnAndHeight() {
            $timeout(function () {
                $("#dataSourceGrid .dx-datagrid-total-footer").hide();
                $scope.dataSourceOptions.width = '100%';
                //if ($scope.selectedTabIndex == enums.formulaDataSourceType.Report ||
                //    $scope.selectedTabIndex == enums.formulaDataSourceType.Judgment ||
                //    $scope.selectedTabIndex == enums.formulaDataSourceType.ModelDatasource) {
                //    $("#dataGridFooterSummary").show();
                //    $scope.dataGridHeight = 165;

                //} else if ($scope.selectedTabIndex == enums.formulaDataSourceType.VoucherFilter ||
                //    $scope.selectedTabIndex == enums.formulaDataSourceType.InvoiceFilter) {
                //    $("#dataGridFooterSummary").hide();
                //    $scope.dataGridHeight = 165;
                //} else {
                //    $("#dataGridFooterSummary").hide();
                //    $scope.dataGridHeight = 195;
                //}

                if ($scope.selectedTabIndex != enums.formulaDataSourceType.KeyInSource &&
                    $scope.selectedTabIndex != enums.formulaDataSourceType.RuleSource &&
                    $scope.selectedTabIndex != enums.formulaDataSourceType.Special) {
                    $("#dataGridFooterSummary").show();
                    $scope.dataGridHeight = 165;

                } else {
                    $("#dataGridFooterSummary").hide();
                    $scope.dataGridHeight = 195;
                }
            }, 100);
        }

        var dataGridCommonOptions = {
            bindingOptions: {
                columns: 'dataGridColumns',
                dataSource: 'detail.dataGridSource',
                height: 'dataGridHeight'
            },
            //添加合计(dx的合计行隐藏,用重写合计行替代,fixed bug 10941)
            summary: {
                totalItems: [{
                    column: 'reportColumn',
                    displayFormat: $translate.instant('Conclusion')
                }, {
                    column: 'cellName',
                    customizeText: function (data) {
                        $("#dataSourceGrid .dx-datagrid-total-footer").hide();
                        return $scope.detail.summaryExp;
                    }
                }, /*{
                    column: 'cellValue',
                    summaryType: 'sum',
                    customizeText: function (data) {
                        
                    }
                },*/ {
                    column: 'cellConditionName',
                    customizeText: function (data) {
                        $("#dataSourceGrid .dx-datagrid-total-footer").hide();
                        return $scope.detail.summaryExp;
                    }
                }/*, {
                    column: 'cellConditionValue',
                    customizeText: function (data) {
                        var precition = 2;

                        //如果数值是份数类型,则精度为0,否则为2
                        if ($scope.detail.dataType === 5) {
                            precition = 0;
                        }

                        var evalVal = 0;
                        try {
                            evalVal = eval($scope.detail.summaryValue);
                            if (_.isNaN(evalVal)) {
                                evalVal = Number(evalVal);
                            }
                            else {
                                evalVal = 0;
                            }
                        }
                        catch (ex) {

                        }

                        var val = evalVal.formatAmount(precition);

                        $("#dataGridFooterSummary").html($scope.detail.summaryExp + '&nbsp;&nbsp;&nbsp;&nbsp;' + val);
                        setSummaryColumnAndHeight();
                        return val;
                    }
                }*/]
            },
            paging: {
                enabled: false
            },
            showBorders: true,
            showRowLines: true,
            showColumnLines: true,
            allowColumnResizing: true,
            //columnAutoWidth: true,
            hoverStateEnabled: true
        };

        var getConclusionVal = function () {
            var precition = 2;
            //如果数值是份数类型,则精度为0,否则为2
            if ($scope.detail.dataType === 5) {
                precition = 0;
            }
            var summaryValue = $scope.detail.summaryValue;
            var isShowCellNameSummary = $scope.detail.showFormulaSummary;
            if ((typeof summaryValue) === "string")
                summaryValue = summaryValue.replace("--", "- -").replace("++", "+ +");

            var evalVal = 0;
            var evalTaxVal = 0;
            try {
                evalVal = eval(summaryValue);
                if (!_.isNaN(evalVal)) {
                    evalVal = Number(evalVal);
                }
                else {
                    evalVal = 0;
                }
            }
            catch (ex) {

            }

            if ($scope.selectedTabIndex === enums.formulaDataSourceType.InputInvoice
                || $scope.selectedTabIndex === enums.formulaDataSourceType.InputInvoiceDetail
                || $scope.selectedTabIndex === enums.formulaDataSourceType.OutputInvoice
                || $scope.selectedTabIndex === enums.formulaDataSourceType.InvoiceFilter) {
                evalVal = _.reduce($scope.detail.dataGridSource, function (memo, x) {
                    return memo + x.money;
                }, 0);

                evalTaxVal = _.reduce($scope.detail.dataGridSource, function (memo, x) {
                    return memo + x.taxMoney;
                }, 0);
                $("#dataGridFooterSummary").html($translate.instant('Conclusion')
                    + '&nbsp;&nbsp;&nbsp;&nbsp;' + $translate.instant('Amount') + ':&nbsp;&nbsp;&nbsp;&nbsp;'
                    + evalVal.formatAmount(precition) + '&nbsp;&nbsp;&nbsp;&nbsp;' + $translate.instant('TaxAmount')
                    + ':&nbsp;&nbsp;&nbsp;&nbsp;' + evalTaxVal.formatAmount(precition));
            }
            else if ($scope.selectedTabIndex === enums.formulaDataSourceType.Voucher) {
                evalVal = _.reduce($scope.detail.dataGridSource, function (memo, x) {
                    return memo + x.debit - x.credit;
                }, 0);
                $("#dataGridFooterSummary").html($translate.instant('Conclusion')
                    + '&nbsp;&nbsp;&nbsp;&nbsp;' + evalVal.formatAmount(precition));
            }
            else if ($scope.selectedTabIndex === enums.formulaDataSourceType.VoucherFilter) {
                evalVal = _.reduce($scope.detail.dataGridSource, function (memo, x) {
                    return memo + x.debitAmount - x.creditAmount;
                }, 0);
                $("#dataGridFooterSummary").html($translate.instant('Conclusion')
                    + '&nbsp;&nbsp;&nbsp;&nbsp;' + evalVal.formatAmount(precition));
            }
            //else if ($scope.selectedTabIndex === enums.formulaDataSourceType.BSPL) {
            //    evalVal = _.reduce($scope.detail.dataGridSource, function (memo, x) {
            //        return memo + x.amount;
            //    }, 0);
            //    $("#dataGridFooterSummary").html($translate.instant('Conclusion')
            //        + '&nbsp;&nbsp;&nbsp;&nbsp;' + evalVal.formatAmount(precition));
            //}
            else if ($scope.selectedTabIndex === enums.formulaDataSourceType.ModelDatasource) {
                evalVal = _.reduce($scope.detail.dataGridSource, function (memo, x) {
                    return memo + x.cellValue;
                }, 0);
                $("#dataGridFooterSummary").html($translate.instant('Conclusion')
                    + '&nbsp;&nbsp;&nbsp;&nbsp;' + evalVal.formatAmount(precition));
            }
            else { // For 报表数据源 and BSPL数据源
                var summaryExp = '';
                if (isShowCellNameSummary && !_.isEmpty($scope.detail.summaryExp)
                    && $scope.detail.summaryExp.indexOf('DS[') < 0) { // 在Demo中,去掉结论中的未替换表达式
                    summaryExp = '&nbsp;&nbsp;&nbsp;&nbsp;' + $scope.detail.summaryExp;
                }
                $("#dataGridFooterSummary").html($translate.instant('Conclusion') + summaryExp +
                    '&nbsp;&nbsp;&nbsp;&nbsp;' + evalVal.formatAmount(precition));
            }

            setSummaryColumnAndHeight();
            return evalVal.formatAmount(precition);
        };

        //设置数据源表格的列
        var getDataGridColumns = function () {
            var dataGridColumns;
            switch ($scope.detail.cellType) {
                case enums.formulaDataSourceType.InputInvoice:
                    //进项数据源
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '9%'
                        },
                        {
                            dataField: 'date',
                            caption: $translate.instant('InvoiceRZRQ'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'invoiceCode',
                            caption: $translate.instant('InvoiceFPDM'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'invoiceNumber',
                            caption: $translate.instant('InvoiceFPHM'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'saleId',
                            caption: $translate.instant('InvoiceXFSBH'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'money',
                            caption: $translate.instant('InvoiceJE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2},
                            width: '13%'
                        },
                        {
                            dataField: 'taxMoney',
                            caption: $translate.instant('InvoiceSE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2},
                            width: '13%'
                        },
                        {
                            dataField: 'invoiceType',
                            caption: $translate.instant('InvoiceFPLX'),
                            alignment: 'left',
                            width: '13%'
                        }
                    ];
                    break;
                case enums.formulaDataSourceType.InputInvoiceDetail:
                    //进项明细数据源
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '9%'
                        },
                        {
                            dataField: 'date',
                            caption: $translate.instant('InvoiceKPRQ'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'invoiceCode',
                            caption: $translate.instant('InvoiceFPDM'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'invoiceNumber',
                            caption: $translate.instant('InvoiceFPHM'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'money',
                            caption: $translate.instant('InvoiceJE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2},
                            width: '13%'
                        },
                        {
                            dataField: 'taxRate',
                            caption: $translate.instant('InvoiceSL'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'taxMoney',
                            caption: $translate.instant('InvoiceSE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2},
                            width: '13%'
                        },
                        {
                            dataField: 'cargoName',
                            caption: $translate.instant('InvoiceHWMC'),
                            alignment: 'left',
                            width: '13%'
                        }
                    ];
                    break;
                case enums.formulaDataSourceType.OutputInvoice:
                    //销项发票数据源
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '8%'
                        },
                        {
                            dataField: 'date',
                            caption: $translate.instant('InvoiceKPRQ'),
                            alignment: 'left',
                            width: '11%'
                        },
                        {
                            dataField: 'acquiringEnterprise',
                            caption: $translate.instant('BuyerName'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'invoiceCode',
                            caption: $translate.instant('InvoiceFPDM'),
                            alignment: 'left',
                            width: '11%'
                        },
                        {
                            dataField: 'invoiceNumber',
                            caption: $translate.instant('InvoiceFPHM'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'money',
                            caption: $translate.instant('InvoiceJE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2},
                            width: '11%'
                        },
                        {
                            dataField: 'taxRate',
                            caption: $translate.instant('InvoiceSL'),
                            alignment: 'left',
                            width: '11%'
                        },
                        {
                            dataField: 'taxMoney',
                            caption: $translate.instant('InvoiceSE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2},
                            width: '11%'
                        },
                        {
                            dataField: 'invoiceType',
                            caption: $translate.instant('InvoiceType'),
                            alignment: 'left',
                            width: '11%'
                        }
                    ];
                    break;
                case enums.formulaDataSourceType.Voucher:
                    //凭证数据源
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '10%'
                        },
                        {
                            dataField: 'voucherDate',
                            caption: $translate.instant('VoucherDate'),
                            alignment: 'left',
                            width: '15%'
                        },
                        {
                            dataField: 'acctCode',
                            caption: $translate.instant('EntempriseAccount'),
                            alignment: 'left',
                            width: '15%'
                        },
                        {
                            dataField: 'voucherID',
                            caption: $translate.instant('VoucherCode'),
                            alignment: 'left',
                            width: '15%'
                        },
                        {
                            dataField: 'summary',
                            caption: $translate.instant('VoucherSummary'),
                            alignment: 'left',
                            width: '15%'
                        },
                        {
                            dataField: 'debit',
                            caption: $translate.instant('DebitAmount'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2},
                            width: '15%'
                        },
                        {
                            dataField: 'credit',
                            caption: $translate.instant('CreditAmount'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2},
                            width: '15%'
                        }
                    ];
                    break;
                case enums.formulaDataSourceType.VoucherFilter:
                    //凭证筛选
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '9%'
                        },
                        {
                            dataField: 'date',
                            caption: $translate.instant('VoucherDate'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'enterpriseAccounting',
                            caption: $translate.instant('EntempriseAccount'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'voucherNumber',
                            caption: $translate.instant('VoucherCode'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'voucherSammary',
                            caption: $translate.instant('VoucherSummary'),
                            alignment: 'left',
                            width: '13%'
                        },
                        {
                            dataField: 'debitAmount',
                            caption: $translate.instant('DebitAmount'),
                            alignment: 'right',
                            width: '13%',
                            format: {type: 'fixedPoint', precision: 2}
                        },
                        {
                            dataField: 'creditAmount',
                            caption: $translate.instant('CreditAmount'),
                            alignment: 'right',
                            width: '13%',
                            format: {type: 'fixedPoint', precision: 2}
                        },
                        {
                            dataField: 'operate',
                            caption: $translate.instant('Operate'),
                            alignment: 'center',
                            width: '13%',
                            cellTemplate: function (element, info) {
                                $('<span>').css('cursor', 'pointer').html('<i class="fa fa-trash delete-icon" style="color: red;" role="button" tabindex="0" />').appendTo(element);
                                $(element).click(function () {
                                    SweetAlert.swal({
                                        title: $translate.instant('ConfirmDelete'),
                                        text: '',
                                        type: "warning",
                                        showCancelButton: true,
                                        confirmButtonColor: "#DD6B55",
                                        confirmButtonText: $translate.instant('Confirm'),
                                        cancelButtonText: $translate.instant('Cancel'),
                                        closeOnConfirm: true
                                    }, function (isConfirm) {
                                        if (isConfirm) {
                                            var id = info.data.id;
                                            $scope.detail.items = _.map($scope.detail.items, function (item) {
                                                if (item.type == $scope.detail.cellType && item.id == $scope.selectedTabId) {
                                                    item.dataSource = _.filter(item.dataSource, function (itemData) {
                                                        return itemData.id != id;
                                                    });
                                                    //重新计算datasource的值
                                                    calculateFilterDatasourceAmount(item);
                                                    //更新数据库
                                                    vatReportService.updateDataSourceAmount(item.id, item.amount);
                                                    vatReportService.deleteCellVoucher(id, item.id);
                                                }
                                                return item;
                                            });

                                            $scope.detail.dataGridSource = _.filter($scope.detail.dataGridSource, function (item) {
                                                return item.id != id;
                                            });
                                        }
                                    });
                                });
                            }
                        }
                    ];
                    break;
                case enums.formulaDataSourceType.Report:
                    //报表数据源
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '10%',
                            visible: vatSessionService.citFlag ? false : true
                        },
                        {
                            dataField: 'reportName',
                            caption: $translate.instant('ReportName'),
                            alignment: 'left',
                            width: '16%'
                        },
                        {dataField: 'project', caption: $translate.instant('Project'), alignment: 'left', width: '25%'},
                        {
                            dataField: 'reportColumn',
                            caption: $translate.instant('TaxReportColumn'),
                            alignment: 'left',
                            width: '17%'
                        },
                        {
                            dataField: 'cellName',
                            caption: $translate.instant('CellColumn'),
                            alignment: 'left',
                            width: '16%'
                        },
                        {
                            dataField: 'cellValue',
                            caption: $translate.instant('CellValue'),
                            alignment: 'right',
                            width: '16%',
                            format: {type: 'fixedPoint', precision: $scope.detail.dataType === 5 ? 0 : 2}
                        }
                    ];
                    break;
                case enums.formulaDataSourceType.BSPL:
                    //BSPL数据源
                    dataGridColumns = [
                        { dataField: 'index', caption: $translate.instant('SequenceNo'), alignment: 'center', width: '10%' },
                        { dataField: 'account', caption: $translate.instant('Account'), alignment: 'left', width: '60%' },
                        { dataField: 'amount', caption: $translate.instant('Amount'), alignment: 'right', width: '30%', format: { type: 'fixedPoint', precision: 2 } }
                    ];
                    break;
                case enums.formulaDataSourceType.Judgment:
                    //条件判断数据源
                    dataGridColumns = [
                        {
                            dataField: 'cellIndex',
                            caption: $translate.instant('SequenceNo'),
                            alignment: 'center',
                            width: '10%'
                        },
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '10%'
                        },
                        {
                            dataField: 'reportName',
                            caption: $translate.instant('ReportName'),
                            alignment: 'left',
                            width: '16%'
                        },
                        {dataField: 'project', caption: $translate.instant('Project'), alignment: 'left', width: '16%'},
                        {
                            dataField: 'column',
                            caption: $translate.instant('TaxReportColumn'),
                            alignment: 'left',
                            width: '16%'
                        },
                        {
                            dataField: 'cellConditionName',
                            caption: $translate.instant('CellColumn'),
                            alignment: 'left',
                            width: '16%'
                        },
                        {
                            dataField: 'cellConditionValue',
                            caption: $translate.instant('CellValue'),
                            alignment: 'right',
                            width: '16%',
                            format: {type: 'fixedPoint', precision: 2}
                        }
                    ];
                    break;
                case enums.formulaDataSourceType.InvoiceFilter:
                    //发票筛选
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '10%'
                        },
                        {
                            dataField: 'inputInvoiceDate',
                            caption: $translate.instant('InvoiceRZRQ'),
                            alignment: 'left',
                            visible: $scope.detail.invoiceType === 1,
                            width: '20%'
                        },
                        {
                            dataField: 'outputInvoiceDate',
                            caption: $translate.instant('InvoiceKPRQ'),
                            alignment: 'left',
                            visible: $scope.detail.invoiceType === 2,
                            width: '20%'
                        },
                        {
                            dataField: 'IssueDate',
                            caption: $translate.instant('CustomsIssueDate'),
                            alignment: 'left',
                            visible: $scope.detail.invoiceType === 3,
                            width: '20%'
                        },
                        {
                            dataField: 'invoiceCode',
                            caption: $translate.instant('InvoiceFPDM'),
                            alignment: 'left',
                            visible: $scope.detail.invoiceType != 3,
                            width: '20%'
                        },
                        {
                            dataField: 'invoiceNumber',
                            caption: $translate.instant('InvoiceFPHM'),
                            alignment: 'left',
                            visible: $scope.detail.invoiceType != 3,
                            width: '20%'
                        },
                        {
                            dataField: 'payNum',
                            caption: $translate.instant('CustomsPayNum'),
                            alignment: 'left',
                            visible: $scope.detail.invoiceType === 3,
                            width: '20%'
                        },
                        {
                            dataField: 'amount',
                            caption: $translate.instant('InvoiceJE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2, width: '20%'}
                        },
                        {
                            dataField: 'taxRate',
                            caption: $translate.instant('InvoiceSL'),
                            alignment: 'left',
                            width: '20%'
                        },
                        {
                            dataField: 'taxAmount',
                            caption: $translate.instant('InvoiceSE'),
                            alignment: 'right',
                            width: '20%',
                            format: {type: 'fixedPoint', precision: 2},
                            visible: $scope.detail.invoiceType != 3
                        },
                        {
                            dataField: 'productionName',
                            caption: $translate.instant('InvoiceHWMC'),
                            alignment: 'left',
                            width: '20%',
                            visible: $scope.detail.invoiceType === 1
                        },
                        {
                            dataField: 'buyerName',
                            caption: $translate.instant('BuyerName'),
                            alignment: 'left',
                            width: '20%',
                            visible: $scope.detail.invoiceType === 2
                        },
                        {
                            dataField: 'invoiceType',
                            caption: $translate.instant('InvoiceType'),
                            alignment: 'left',
                            width: '20%',
                            visible: $scope.detail.invoiceType === 2
                        },
                        {
                            dataField: 'auditResult',
                            caption: $translate.instant('CustomsAuditResult'),
                            alignment: 'left',
                            width: '20%',
                            visible: $scope.detail.invoiceType === 3
                        },
                        {
                            dataField: 'operate',
                            caption: $translate.instant('Operate'),
                            alignment: 'center',
                            width: '20%',
                            cellTemplate: function (element, info) {
                                $('<span>').css('cursor', 'pointer').html('<i class="fa fa-trash delete-icon" style="color: red;" role="button" tabindex="0" />').appendTo(element);
                                $(element).click(function () {
                                    SweetAlert.swal({
                                        title: $translate.instant('ConfirmDelete'),
                                        text: '',
                                        type: "warning",
                                        showCancelButton: true,
                                        confirmButtonColor: "#DD6B55",
                                        confirmButtonText: $translate.instant('Confirm'),
                                        cancelButtonText: $translate.instant('Cancel'),
                                        closeOnConfirm: true
                                    }, function (isConfirm) {
                                        if (isConfirm) {
                                            var id = info.data.id;

                                            $scope.detail.items = _.map($scope.detail.items, function (item) {
                                                if (item.type == $scope.detail.cellType && item.id == $scope.selectedTabId) {
                                                    item.dataSource = _.filter(item.dataSource, function (itemData) {
                                                        return itemData.id != id;
                                                    });
                                                    calculateFilterDatasourceAmount(item);
                                                    vatReportService.updateDataSourceAmount(item.id, item.amount);
                                                    vatReportService.deleteCellInvoice(id, item.id);
                                                }
                                                return item;
                                            });
                                            $scope.detail.dataGridSource = _.filter($scope.detail.dataGridSource, function (item) {
                                                return item.id != id;
                                            });
                                        }
                                    });
                                });
                            }
                        }
                    ];
                    break;
                case enums.formulaDataSourceType.ModelDatasource:
                    dataGridColumns = [
                        { dataField: 'index', caption: $translate.instant('ModelPeriod'), alignment: 'center', width: '20%' },
                        { dataField: 'reportColumn', caption: $translate.instant('ModelName'), alignment: 'left', width: '40%' },
                        {
                            dataField: 'cellValue',
                            caption: $translate.instant('FillBack'),
                            alignment: 'left',
                            width: '40%',
                            format: {type: 'fixedPoint', precision: $scope.detail.dataType === 5 ? 0 : 2}
                        },
                    ];
                    break;
                case enums.formulaDataSourceType.Special:
                    dataGridColumns = [
                        {dataField: 'money', caption: 'Amount', alignment: 'center', width: '100%'},
                    ];
                    break;
            }
            return dataGridColumns;
        };

        //设置数据源表格的列
        var getAllDataGridColumns = function () {
            var dataGridColumns;
            switch ($scope.detail.allCellType) {
                case enums.cellDataSourceType.InputInvoice:
                    //进项明细数据源
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '80px'
                        },
                        {
                            dataField: 'invoiceDate',
                            caption: $translate.instant('InvoiceKPRQ'),
                            alignment: 'left',
                            dataType: "date",
                            customizeText: function (cellInfo) {
                                if (cellInfo && cellInfo.value) {
                                    return new Date(cellInfo.value).dateTimeToString('yyyyMMdd');
                                }
                                return "";
                            }
                        },
                        {dataField: 'invoiceCode', caption: $translate.instant('InvoiceFPDM'), alignment: 'left'},
                        {dataField: 'invoiceNumber', caption: $translate.instant('InvoiceFPHM'), alignment: 'left'},
                        {
                            dataField: 'taxAmount',
                            caption: $translate.instant('InvoiceJE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2}
                        },
                        {dataField: 'rate', caption: $translate.instant('InvoiceSL'), alignment: 'left'},
                        {
                            dataField: 'taxAmount',
                            caption: $translate.instant('InvoiceSE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2}
                        },
                        {dataField: 'productionName', caption: $translate.instant('InvoiceHWMC'), alignment: 'left'}
                    ];
                    break;
                case enums.cellDataSourceType.OutputInvoice:
                    //销项发票数据源
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '80px'
                        },
                        {dataField: 'invoiceCode', caption: $translate.instant('InvoiceFPDM'), alignment: 'left'},
                        {dataField: 'invoiceNumber', caption: $translate.instant('InvoiceFPHM'), alignment: 'left'},

                        {dataField: 'buyerName', caption: $translate.instant('BuyerName'), alignment: 'left'},
                        {
                            dataField: 'invoiceDate',
                            caption: $translate.instant('InvoiceKPRQ'),
                            alignment: 'left',
                            customizeText: function (cellInfo) {
                                if (cellInfo && cellInfo.value) {
                                    return new Date(cellInfo.value).dateTimeToString('yyyyMMdd');
                                }
                                return "";
                            }
                        },
                        {dataField: 'taxRate', caption: $translate.instant('InvoiceSL'), alignment: 'left'},
                        {
                            dataField: 'amount',
                            caption: $translate.instant('InvoiceJE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2}
                        },

                        {
                            dataField: 'taxAmount',
                            caption: $translate.instant('InvoiceSE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2}
                        },
                        {dataField: 'invoiceType', caption: $translate.instant('InvoiceType'), alignment: 'left'}
                    ];
                    break;
                case enums.cellDataSourceType.CustomInvoice:
                    //海关稽核
                    dataGridColumns = [
                        {
                            dataField: 'periodId',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '80px'
                        },
                        {
                            dataField: 'issueDate',
                            caption: $translate.instant('CustomsIssueDate'),
                            alignment: 'left',
                            customizeText: function (cellInfo) {
                                if (cellInfo && cellInfo.value) {
                                    return new Date(cellInfo.value).dateTimeToString('yyyyMMdd');
                                }
                                return "";
                            }
                        },
                        {dataField: 'payNum', caption: $translate.instant('CustomsPayNum'), alignment: 'left'},
                        {
                            dataField: 'invoiceTaxAmount',
                            caption: $translate.instant('InvoiceSE'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2}
                        },
                        {
                            dataField: 'invoiceAmount',
                            caption: $translate.instant('Amount'),
                            alignment: 'left',
                            format: {type: 'fixedPoint', precision: 2}
                        },
                        {dataField: 'auditResult', caption: $translate.instant('CustomsAuditResult'), alignment: 'left'}
                    ];
                    break;
                case enums.cellDataSourceType.Voucher:
                    //凭证选择
                    dataGridColumns = [
                        {
                            dataField: 'period',
                            caption: $translate.instant('InvoiceQJ'),
                            alignment: 'center',
                            width: '80px'
                        },
                        {dataField: 'date', caption: $translate.instant('VoucherDate'), alignment: 'left'},
                        {
                            dataField: 'accountSubject',
                            caption: $translate.instant('EntempriseAccount'),
                            alignment: 'left'
                        },
                        {dataField: 'voucherCode', caption: $translate.instant('VoucherCode'), alignment: 'left'},
                        {dataField: 'voucherSummary', caption: $translate.instant('VoucherSummary'), alignment: 'left'},
                        {
                            dataField: 'debitAmount',
                            caption: $translate.instant('DebitAmount'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2}
                        },
                        {
                            dataField: 'creditAmount',
                            caption: $translate.instant('CreditAmount'),
                            alignment: 'right',
                            format: {type: 'fixedPoint', precision: 2}
                        }
                    ];
                    break;
            }
            return dataGridColumns;
        };

        //添加数据源(发票|凭证)数据过滤
        var allDataFilter = function (config, data) {
            var dataGridColumns;
            switch ($scope.detail.allCellType) {
                case enums.cellDataSourceType.Voucher:
                    data = _.map(data, function (item) {
                        item.date = item.date ? (new Date(item.date)).dateTimeToString('yyyyMMdd') : ""
                        return item;
                    });
                    return data.filter(function (x) {
                        if ($scope.voucherRange.voucherKeyword) {

                            return x.voucherSummary && x.voucherSummary.indexOf($scope.voucherRange.voucherKeyword) > -1;
                        } else {
                            return _.contains(config.accountCodes, x.accountSubject)
                        }
                    });
                case enums.cellDataSourceType.InputInvoice:
                    return data.filter(function (x) {
                        return (config.taxRate == "99" ||
                            _.contains(config.taxRate.map(function (r) {
                                return percentToPoint(r)
                            }), x.rate)) &&
                            _.contains(config.invoiceCategory, x.invoiceType);
                    });
                case enums.cellDataSourceType.OutputInvoice:
                    data = data.filter(function (x) {
                        return (_.contains(config.taxRate.map(function (r) {
                                return percentToPoint(r)
                            }), x.taxRate) || config.taxRate == "99") &&
                            _.contains(config.invoiceCategory, x.invoiceType);
                    });
                    data = _.map(data, function (item) {
                        item.invoiceType = getOutputInvoiceTypeName(item.invoiceType);
                        return item;
                    });
                    return data;
                case enums.cellDataSourceType.CustomInvoice:
                    return data;

            }
        };

        //添加数据源
        var addDataSource = function () {
            var parentElem = angular.element($document[0].querySelector('#addSourceContainer'));
            var modalInstance = $uibModal.open({
                ariaLabelledBy: 'modal-title',
                ariaDescribedBy: 'modal-body',
                templateUrl: 'addDataSourceModal.html',
                controller: addDataSourceController,
                windowClass: 'data-table',
                appendTo: parentElem,
                scope: $scope
            });
        };

        //添加发票|凭证
        var addInvoiceAndVoucher = function (type) {
            $scope.addDataSourceType = type;
            $scope.selectedInvoice = [];
            $scope.addInvoiceClick = true;
            _.each($scope.detail.dataGridSource, function (item) {
                $scope.selectedInvoice.push(item.id)
            });
            addDataSource();
        }

        //计算凭证的数值
        function calculateVoucherValue(voucher) {
            return voucher.direction * ((voucher.debitAmount ? voucher.debitAmount : 0) - (voucher.creditAmount ? voucher.creditAmount : 0));
        }

        var addDataSourceController = function ($scope) {
            var config = $scope.$parent.detail.config;
            //default value
            if (config.hasVoucher && !config.hasInvoice) {
                config.voucherClass = activeClass;
            } else if (!config.hasVoucher && config.hasInvoice) {
                config.invoiceClass = activeClass;
            }

            config.addClass = activeClass;
            config.contentStatus = 'dataSourceTitle';
            config.dataSourceName = '';

            //如果是以添加发票|添加凭证的形式打开弹框
            if ($scope.$parent.addInvoiceClick) {
                config.contentStatus = 'dataSourceDetail';

                var dataSourceType = 0;
                if (config.hasVoucher) {
                    dataSourceType = enums.cellDataSourceType.Voucher;
                } else if (config.hasInvoice) {
                    if (config.invoiceType === 1) {
                        dataSourceType = enums.cellDataSourceType.InputInvoice;
                    } else if (config.invoiceType === 2) {
                        dataSourceType = enums.cellDataSourceType.OutputInvoice;
                    } else if (config.invoiceType === 3) {
                        dataSourceType = enums.cellDataSourceType.CustomInvoice;
                    }
                }
                config.dataSourceType = dataSourceType;

                config.dataSourceID = $scope.$parent.selectedTabId;
                config.dataSourceName = $scope.$parent.selectedTypeName;
                showAllItems(config);
                //以添加凭证或添加发票打开,则运算方法取当前选中tab的运算方法。
                config.OperationType = $scope.$parent.currentOperationType;
                $scope.$parent.addInvoiceClick = false;
            }

            $scope.config = config;
            $scope.choiceGroupButton = choiceGroupButton;
            $scope.confirmAddDataSource = function (config) {
                if (config.contentStatus === 'dataSourceTitle') {
                    saveDataSource(config);
                    config.contentStatus === 'dataSourceDetail'
                } else {
                    //添加数据源
                    var invoiceList = $scope.$parent.selectedAddDatasourceItems;
                    var tabValue = 0;
                    if (invoiceList && invoiceList.length > 0) {
                        $(invoiceList).each(function (index, item) {
                            if (config.hasVoucher) {
                                item.type = enums.formulaDataSourceType.VoucherFilter;
                            } else {
                                item.type = enums.formulaDataSourceType.InvoiceFilter;
                            }
                        });
                        $scope.$parent.detail.items = _.map($scope.$parent.detail.items, function (item) {
                            if (item.id === config.dataSourceID && item.name === config.dataSourceName) {
                                item.dataSource = [];
                            }
                            return item;
                        });
                        _.each(invoiceList, function (invoice) {

                            var model = {};
                            if (config.hasVoucher) {
                                tabValue += calculateVoucherValue(invoice);
                                model = translateInvoiceFilterDataSource(invoice, invoice.type, config.OperationType);
                            } else {
                                if (config.invoiceAmountType == enums.invoiceAmountType.amount) {
                                    tabValue += invoice.amount;
                                } else if (config.invoiceAmountType == enums.invoiceAmountType.taxAmount) {
                                    tabValue += invoice.taxAmount;
                                } else if (config.invoiceAmountType == enums.invoiceAmountType.quntity) {
                                    tabValue += 1;
                                }

                                model = translateInvoiceFilterDataSource(invoice, config.invoiceType, config.OperationType);
                            }

                            var filterItems = _.where($scope.$parent.detail.items, {
                                id: config.dataSourceID,
                                name: config.dataSourceName
                            });
                            if (filterItems && filterItems.length > 0) {
                                $scope.$parent.detail.items = _.map($scope.$parent.detail.items, function (item) {
                                    if (item.id === config.dataSourceID && item.name === config.dataSourceName && item.type === invoice.type) {
                                        item.dataSource.push(model);
                                    }
                                    return item;
                                });
                            } else {
                                $scope.$parent.detail.cellType = invoice.type;
                                $scope.$parent.detail.cellTypeId = config.dataSourceID;
                                $scope.$parent.selectedDataSourceTabIndex = 1;
                                $scope.$parent.detail.dataSourceCount++;
                                $scope.$parent.detail.items.push({
                                    type: invoice.type,
                                    name: config.dataSourceName,
                                    id: config.dataSourceID,
                                    operationType: config.OperationType,
                                    amount: 0,
                                    dataSource: [model]
                                });
                            }
                        });

                    }

                    var dataSource = {
                        id: config.dataSourceID,
                        items: $scope.selectedItems,
                        projectID: vatSessionService.project.id,
                        amount: tabValue,
                        serviceTypeID: vatSessionService.project.serviceTypeID,
                        DataSourceType: config.dataSourceType
                    };
                    vatReportService.addDataSourceItems(dataSource).success(function () {
                        SweetAlert.warning($translate.instant('AddSuccess'));
                        $scope.$dismiss({$value: 'cancel'});
                    });
                }
            };
            $scope.hideAddDataSourcePanel = function () {
                $scope.$dismiss({$value: 'cancel'});
            };
        };

        addDataSourceController.$inject = ['$scope'];

        var saveDataSource = function (config) {
            var dataSourceType = 0;
            if (config.hasVoucher) {
                dataSourceType = enums.cellDataSourceType.Voucher;
            } else if (config.hasInvoice) {
                if (config.invoiceType === 1) {
                    dataSourceType = enums.cellDataSourceType.InputInvoice;
                } else if (config.invoiceType === 2) {
                    dataSourceType = enums.cellDataSourceType.OutputInvoice;
                } else if (config.invoiceType === 3) {
                    dataSourceType = enums.cellDataSourceType.CustomInvoice;
                }
            }
            config.dataSourceType = dataSourceType;
            var newDataSource = {
                Name: config.dataSourceName,
                DataSourceType: dataSourceType,
                CellDataID: config.cellID,
                Creator: loginContext.userId,
                Updater: loginContext.userId,
                OperationType: config.addClass === activeClass ? 1 : 2
            };
            config.OperationType = config.addClass === activeClass ? 1 : 2;
            vatReportService.addDataSource(newDataSource).success(function (result) {
                if (result && result.result) {
                    config.dataSourceID = result.data;
                    showAllItems(config);
                }
            });
        };

        //根据销项发票类型获取销项发票类型名称
        var getOutputInvoiceTypeName = function (invoiceType) {
            for (var item in enums.outputInvoiceType) {
                if (enums.outputInvoiceType[item] == invoiceType) {
                    return $translate.instant(item);
                }
            }
            return invoiceType;
        }

        //解析发票筛选|凭证筛选数据
        var translateInvoiceFilterDataSource = function (sourceData, type, operationType) {
            var obj = new Object();
            switch (type) {
                case 1:
                    obj.id = sourceData.id;
                    obj.period = sourceData.period;
                    obj.inputInvoiceDate = sourceData.invoiceDate ? (new Date(sourceData.invoiceDate)).dateTimeToString('yyyyMMdd') : "";
                    obj.invoiceCode = sourceData.invoiceCode;
                    obj.invoiceNumber = sourceData.invoiceNumber;
                    obj.amount = sourceData.amount;
                    obj.taxRate = sourceData.rate * 100 + '%';
                    obj.taxAmount = sourceData.taxAmount;
                    obj.productionName = sourceData.productionName;
                    obj.operationType = operationType;
                    break;
                case 2:
                    obj.id = sourceData.id;
                    obj.period = sourceData.period;
                    obj.outputInvoiceDate = sourceData.invoiceDate ? sourceData.invoiceDate.substring(0, 10) : '';
                    obj.buyerName = sourceData.buyerName;
                    obj.invoiceCode = sourceData.invoiceCode;
                    obj.invoiceNumber = sourceData.invoiceNumber;
                    obj.amount = sourceData.amount;
                    obj.taxRate = sourceData.taxRate * 100 + '%';
                    obj.taxAmount = sourceData.taxAmount;
                    obj.invoiceType = getOutputInvoiceTypeName(sourceData.invoiceType);
                    obj.operationType = operationType;
                    break;
                case 3:
                    obj.id = sourceData.customsId;
                    obj.period = sourceData.periodId;
                    obj.IssueDate = sourceData.IssueDate;
                    obj.amount = sourceData.InvoiceAmount;
                    obj.taxRate = sourceData.InvoiceTaxAmount;
                    obj.payNum = sourceData.payNum;
                    obj.auditResult = sourceData.auditResult;
                    obj.operationType = operationType;
                    break;
                //凭证筛选
                case enums.formulaDataSourceType.VoucherFilter:
                    obj.id = sourceData.id;
                    obj.period = sourceData.period;
                    obj.date = sourceData.date ? (new Date(sourceData.date)).dateTimeToString('yyyyMMdd') : "";
                    obj.enterpriseAccounting = sourceData.accountSubject;
                    obj.voucherNumber = sourceData.voucherCode;
                    obj.voucherSammary = sourceData.voucherSummary;
                    obj.debitAmount = sourceData.debitAmount;
                    obj.creditAmount = sourceData.creditAmount;
                    obj.operationType = operationType;
                    obj.direction = sourceData.direction;
                    break;
            }
            return obj;
        }

        var allItemsDataSourceOptions = {
            bindingOptions: {
                columns: 'allItemDataGridColumns',
                dataSource: 'detail.allItemsDataGridSource',
                height: 'allItemDataGridHeight',
                selectedRowKeys: 'selectedInvoice'
            },
            loadPanel: {
                enabled: false
            },
            scrolling: {
                mode: "standard"
            },
            searchPanel: {
                visible: false
            },
            selection: {
                mode: "multiple",
                allowSelectAll: false
            },
            sorting: {
                mode: 'single'
            },
            filterRow: {
                visible: true
            },
            onSelectionChanged: function (selectedItems) {
                $scope.selectedItems = $.map(selectedItems.selectedRowsData, function (data) {
                    $scope.selectedAddDatasourceItems = selectedItems.selectedRowsData;
                    return data.id;
                });

                $log.debug($scope.selectedItems);
            },
            allowColumnResizing: true,
            hoverStateEnabled: true,
            showBorders: true,
            showRowLines: true,
            showColumnLines: true,
        };

        var showAllItems = function (config) {
            config.contentStatus = 'allItems';
            var project = vatSessionService.project;
            vatReportService.getAllDataItems(config.dataSourceType).success(function (result) {
                if (result && result.length > 0) {
                    $scope.detail.allCellType = config.dataSourceType;
                    $scope.detail.allItemsDataGridSource = {
                        store: {
                            data: allDataFilter(config, result),
                            type: 'array',
                            key: 'id'
                        }
                    };
                }
            });
        };

        var choiceGroupButton = function (config, selectCode, unSelectCode) {
            config[selectCode] = activeClass;
            config[unSelectCode] = '';
        };

        var percentToPoint = function (percent) {
            var str = percent.replace("%", "");
            str = str / 100;
            return str;
        };

        var getFormulaList = function () {
            $q.all([
                formulaService.getAll(),
                formulaService.getAllParam(),
                formulaService.getAllParamMapping()
            ]).then(function (result) {
                if (!_.isEmpty(result[0]) && !_.isEmpty(result[0].data) && !_.isEmpty(result[0].data.data)) {
                    var formulaList = _.map(result[0].data.data, function (config) {
                        return {
                            id: config.id,
                            code: config.formulaName,
                            name: config.chineseName,
                            description: config.description,
                            englishName: config.englishName,
                            requiredParamNum: config.requiredParamNum
                        }
                    });

                    if (!_.isEmpty(result[1]) && !_.isEmpty(result[1].data) && !_.isEmpty(result[1].data.data) &&
                        !_.isEmpty(result[2]) && !_.isEmpty(result[2].data) && !_.isEmpty(result[2].data.data)) {
                        var groupedParamList = _.groupBy(result[2].data.data, 'formulaID');
                        var paramList = result[1].data.data;
                        _.each(groupedParamList, function (val, key) {
                            var formula = _.findWhere(formulaList, {id: key});
                            if (formula) {
                                formula.params = _.chain(val)
                                    .map(function (p) {
                                        return {id: p.formulaParamID, index: p.paramIndex};
                                    })
                                    .sortBy(function (p) {
                                        return p.index;
                                    }).value();
                                _.each(formula.params, function (p, idx) {
                                    var param = _.findWhere(paramList, {id: p.id});
                                    _.extend(p, param);
                                });
                            }
                        });
                    }

                    $scope.formulaList = formulaList;
                }
            });
        };

        //计算每个datasource的值
        function calculateFilterDatasourceAmount(filterDatasource, isDirectionCal) {
            isDirectionCal = isDirectionCal || false;
            var datasourceAmountValue = 0;
            if (filterDatasource.type == enums.formulaDataSourceType.VoucherFilter) {
                _.each(filterDatasource.dataSource, function (voucher) {
                    if (!isDirectionCal || filterDatasource.operationType == 1) { //加法
                        datasourceAmountValue += calculateVoucherValue(voucher);
                    } else if (filterDatasource.operationType == 2) { //减法
                        datasourceAmountValue -= calculateVoucherValue(voucher);
                    }
                });
                filterDatasource.amount = datasourceAmountValue;

            } else if (filterDatasource.type == enums.formulaDataSourceType.InvoiceFilter) {
                _.each(filterDatasource.dataSource, function (invoice) {
                    if (!isDirectionCal || filterDatasource.operationType == 1) { //加法
                        if ($scope.detail.config.invoiceAmountType == enums.invoiceAmountType.amount) {
                            datasourceAmountValue += invoice.amount;
                        } else if ($scope.detail.config.invoiceAmountType == enums.invoiceAmountType.taxAmount) {
                            datasourceAmountValue += invoice.taxAmount;
                        } else if ($scope.detail.config.invoiceAmountType == enums.invoiceAmountType.quntity) {
                            datasourceAmountValue += 1;
                        }
                    } else if (filterDatasource.operationType == 2) { //减法
                        if ($scope.detail.config.invoiceAmountType == enums.invoiceAmountType.amount) {
                            datasourceAmountValue -= invoice.amount;
                        } else if ($scope.detail.config.invoiceAmountType == enums.invoiceAmountType.taxAmount) {
                            datasourceAmountValue -= invoice.taxAmount;
                        } else if ($scope.detail.config.invoiceAmountType == enums.invoiceAmountType.quntity) {
                            datasourceAmountValue -= 1;
                        }
                    }
                });
                filterDatasource.amount = datasourceAmountValue;
            }

            return datasourceAmountValue;
        }

        $scope.$watch('detail.dataGridSource', function (newVal, oldValue) {
            $timeout(function () {
                $scope.selectedTabIndex = $scope.detail.cellType;
                $scope.selectedTabId = $scope.detail.cellTypeId;

                $($scope.detail.items).each(function (index, element) {
                    if (element.type === $scope.detail.cellType && element.id === $scope.selectedTabId &&
                        (element.type !== enums.formulaDataSourceType.OutputInvoice &&
                            element.type !== enums.formulaDataSourceType.Voucher &&
                            element.type !== enums.formulaDataSourceType.Special ||
                            _.isEmpty($scope.selectedTypeName) || $scope.selectedTypeName === element.name)) {
                        $scope.detail.dataGridSource = element.dataSource;
                        $scope.selectedTypeName = element.name;

                        //if (element.name === 'MaxConditionDataSource') {
                        //    $scope.dataSourceOptions.summary.totalItems[4].summaryType = 'max';
                        //} else {
                        //    $scope.dataSourceOptions.summary.totalItems[4].summaryType = 'min';
                        //}

                        return;
                    }
                });
                $scope.dataGridColumns = getDataGridColumns();
                getConclusionVal();

            }, 500);
        });

        //当数据源数量变化是,重新排序数据源
        $scope.$watch('detail.items.length', function (newVal, oldValue) {
            if (newVal) {
                $scope.detail.items = _.sortBy($scope.detail.items, function (item) {
                    if (item.type === enums.formulaDataSourceType.ModelDatasource ||
                        item.type === enums.formulaDataSourceType.InvoiceFilter ||
                        item.type === enums.formulaDataSourceType.VoucherFilter) {
                        return new Date(item.createTime).dateTimeToString('yyyyMMddHHmmss');
                    } else {
                        return new Date().dateTimeToString('yyyyMMddHHmmss');
                    }
                });

                var firstItem = _.first($scope.detail.items);
                $scope.detail.cellType = firstItem.type;
                $scope.detail.cellTypeId = firstItem.id;
                $scope.selectedTabIndex = $scope.detail.cellType;
                $scope.selectedTabId = $scope.detail.cellTypeId;
                $scope.selectedTypeName = firstItem.name;
            }
        });

        $scope.$watch('detail.items', function(newVal, oldValue) {
            $timeout(function() {
                $scope.selectedTabIndex = $scope.detail.cellType;
                $scope.selectedTabId = $scope.detail.cellTypeId;
                $scope.selectedTypeName = null;

                var cellAmountValue = 0;
                $($scope.detail.items).each(function (index, element) {

                    if (!$scope.selectedTabId) {
                        $scope.selectedTabIndex = element.type;
                        $scope.selectedTabId = element.id;
                    }

                    if (element.type === $scope.detail.cellType && element.id === $scope.selectedTabId &&
                        (element.type !== enums.formulaDataSourceType.OutputInvoice &&
                            element.type !== enums.formulaDataSourceType.Voucher &&
                            element.type !== enums.formulaDataSourceType.Special ||
                            _.isEmpty($scope.selectedTypeName) || $scope.selectedTypeName === element.name)) {
                        $scope.detail.dataGridSource = element.dataSource;
                        $scope.selectedTypeName = element.name;
                        $scope.currentOperationType = element.operationType
                        //if (element.name === 'MaxConditionDataSource') {
                        //    $scope.dataSourceOptions.summary.totalItems[4].summaryType = 'max';
                        //} else {
                        //    $scope.dataSourceOptions.summary.totalItems[4].summaryType = 'min';
                        //}
                    }
                    cellAmountValue += calculateFilterDatasourceAmount(element, true);
                });

                if ($scope.detail && $scope.detail.cellInfo && ($scope.detail.config.hasInvoice || $scope.detail.config.hasVoucher)) {
                    //数值 = 单元格的除凭证和发票外的数值 + 凭证和发票的数值
                    $scope.detail.cellInfo.money = $scope.detail.cellSubValue + cellAmountValue;
                    if ($scope.detail.config.invoiceAmountType == enums.invoiceAmountType.quntity) {
                        $scope.detail.cellInfo.money = $scope.detail.cellInfo.money.formatAmount(0);
                    } else {
                        $scope.detail.cellInfo.money = $scope.detail.cellInfo.money.formatAmount(2);
                    }
                }

                $scope.dataGridColumns = getDataGridColumns();
                getConclusionVal();

                $scope.isWriteBackUpdate = true;

            }, 500);
        });

        $scope.$watchGroup(['detail.rowIndex', 'detail.columnIndex'], function () {
            //获取凭证筛选范围
            if ($scope.detail.reportTemplateId) {
                vatReportService.getCellAccountRange($scope.detail.reportTemplateId, vatSessionService.month, $scope.detail.rowIndex, $scope.detail.columnIndex).success(function (result) {
                    if (result && result.data && result.data.length > 0) {
                        $scope.selectedAccount = result.data;
                        $scope.selectedAccountTemp = result.data;
                        $scope.selectedAccountCodes = _.pluck($scope.selectedAccount, 'code');
                    } else {
                        $scope.selectedAccount = [];
                        $scope.selectedAccountTemp = [];
                        $scope.selectedAccountCodes = [];
                    }
                });
                vatReportService.getCellTemplateConfig($scope.detail.reportTemplateId, vatSessionService.month, $scope.detail.rowIndex, $scope.detail.columnIndex).success(function (result) {
                    if (result && result.data) {
                        if (result.data.voucherKeyword) {
                            $scope.voucherRange.filterWay = '2';
                            $scope.voucherRange.voucherKeyword = result.data.voucherKeyword;
                        } else {
                            $scope.voucherRange.filterWay = '1';
                        }
                    } else {
                        $scope.voucherRange.filterWay = '1';
                    }
                });
            }

            //获取标准科目用于设置凭证筛选范围。
            vatReportService.getStdAccountByIndustryID(vatSessionService.project.industryID)
                .success(function (data) {
                    _.each(data, function (account) {
                        account.directionName = $translate.instant(enums.standardAccountDirection[account.direction]);
                        account.acctPropName = $translate.instant(enums.standardAccountAcctProp[account.acctProp]);
                        account.AcctPropName = $translate.instant(enums.standardAccountAcctProp[account.acctProp]);
                        account.code = account.acctCode;
                    });

                    if (data && data.length > 0) {
                        $scope.accountDataSource = data;
                    }
                });
        });

        $scope.$watch('detail.allItemsDataGridSource', function (newVal, oldValue) {
            if (newVal !== oldValue) {
                $scope.allItemDataGridColumns = getAllDataGridColumns();
                $scope.allItemDataGridHeight = $scope.detail.allItemsDataGridSource && $scope.detail.allItemsDataGridSource.store.data.length > 4 ? '535px' : 'auto';
                $scope.allItemDataGridHeight = '535px';
            }
        });

        // 特别奇怪监控不了 uib-btn-radio 的值,加上 uib-uncheckable="tabType" 就可以了
        $scope.$watch('tabType', function (newVal, oldValue) {
            if (newVal !== oldValue) {
                if (newVal === 1 && $scope.detail && $scope.isWriteBackUpdate) {
                    $scope.detail.dataGridSource = angular.copy($scope.detail.dataGridSource);
                    $scope.isWriteBackUpdate = false;
                }
            }
        });

        (function () {
            $scope.hidePanel = hidePanel;
            $scope.isExpand = true;
            $scope.togglePanel = togglePanel;
            $scope.changeTabColor = changeTabColor;
            $scope.changeVisibleDataSourceContainer = changeVisibleDataSourceContainer;
            $scope.confirmEventHandler = confirmEventHandler;
            $scope.addDataSource = addDataSource;
            $scope.selectedDataSourceTabIndex = 1;
            $scope.voucherFilter = enums.formulaDataSourceType.VoucherFilter;
            $scope.InvoiceFilter = enums.formulaDataSourceType.InvoiceFilter;
            $scope.ModelDatasource = enums.formulaDataSourceType.ModelDatasource;
            $scope.closePropover = closePropover;
            $scope.openAcctPropover = openAcctPropover;
            $scope.voucherRangeOptions = voucherRangeOptions;
            $scope.showSelectAccountPop = showSelectAccountPop;
            $scope.voucherRangeConfirm = voucherRangeConfirm;
            $scope.removeVoucherFilterTab = removeVoucherFilterTab;
            $scope.addInvoiceAndVoucher = addInvoiceAndVoucher;
            $scope.checkIfSelectedTab = checkIfSelectedTab;
            $scope.numToExcelChar = PWC.numToExcelChar;
            $scope.voucherRange = {
                voucherKeyword: '',
                filterWay: 1
            };

            $scope.dataSourceOptions = dataGridCommonOptions;
            $scope.allItemsDataSourceOptions = allItemsDataSourceOptions;
            switch ($scope.detail.cellType) {
                case 5:
                    //定义表头样式
                    $scope.dataSourceOptions.customizeColumns = function (columns) {
                        $.each(columns, function (_, element) {
                            //定义表头的模板
                            element.headerCellTemplate = function (header, info) {
                                $('<span>').html(info.column.caption).appendTo(header);
                                $(header).parent().css({
                                    'color': 'white',
                                    'background-color': '#d00',
                                    'font-family': '微软雅黑'
                                })
                            };
                        });
                    }
                    break;
                case 6:
                    $scope.dataSourceOptions.customizeColumns = function (columns) {
                        $.each(columns, function (_, element) {
                            element.headerCellTemplate = function (header, info) {
                                $('<span>').html(info.column.caption).appendTo(header);
                                $(header).parent().css({
                                    'color': 'white',
                                    'background-color': '#d00',
                                    'font-family': '微软雅黑'
                                })
                            };
                        });
                    }
                    break;
            }

            getFormulaList();

            KeyValueConfigService.getAll().success(function (data) {
                $scope.keyValueList = _.map(data, function (config) {
                    return {
                        code: '@' + config.keyCode,
                        name: config.name,
                        description: config.description
                    }
                });
            });
        })();
    }
]);
commonModule.directive('taxReportCellDetailModal', ['$log',
function ($log) {
    return {
        restrict: 'E',
        templateUrl: '/app/common/controls/tax-report-cell-detail-modal/tax-report-cell-detail-modal.html' + '?_=' + Math.random(),
        scope: {
            detail: '=',
            onConfirm: '&'
        },
        controller: 'taxReportCellDetailModalController',
        link: function ($scope, $element, $attr) {
            
            $("#taxReportCellDetailModal").resizable({
                minHeight: 700,
                maxHeight: 700,
                minWidth: 650
            });
                        
            $($element).draggable({
                scroll: true,
                cancel: '#dataSourceGrid,.hand-input-container,.add-voucher-range-propover,.add-invoice,.tab-type,.dx-texteditor-input,input,.btn,#remark-input-textarea,.tax-report-analyze-report'
            });
        }
    }
}]);
// Common multiple select tree view, select multiple items with checkboxes
commonModule.directive('treeMultiSelector', ['$log', '$timeout', '$interval', '$translate',
    function($log, $timeout, $interval, $translate) {
        'use strict';
        $log.debug('treeMultiSelector.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/tree-multi-selector/tree-multi-selector.html' + '?_=' + Math.random(),
            replace: true,
            scope: {
                columnDefs: '=',
                treeDataSource: '=*',
                isShow: '=',
                selectedItems: '=',
                title: '=?',
                parentCheckable: '=?',
                isSingleMode: '=?',
                selectorOptions: '=?',
                selectorApi: '=?' // In: onSelectorClose, onSelectorConfirm; Out: getGridInstance
            },
            link: function(scope, element, attrs) {
                $log.debug('treeMultiSelector.link()...');

                var treeList = undefined;

                // Handle id of the element to make sure it is unique.
                // treeListSelector is used to add the style tag to work-around
                // DX grid height issue
                if (_.isEmpty(attrs['id'])) {
                    var randomStr = Math.random().toString().replace(/\./g, '');
                    element.attr('id', 'tree-list' + randomStr);
                    scope.treeListSelector = '#tree-list' + randomStr;
                } else {
                    scope.treeListSelector = '#' + attrs['id'];
                }

                scope.showParentCheckbox = scope.parentCheckable ? '' : 'display: none;';

                // Register api functions in internalApi
                // If selectorApi passed is not undefined, we will use it as internalApi
                scope.internalApi = scope.selectorApi || {};
                scope.internalApi.getGridInstance = function() {
                    return element.find('.tree-multi-selector-grid').dxTreeList('instance');
                };

                // Work-around for DX grid height issue.
                element.find('.modal').on('shown.bs.modal', function() {
                    scope.internalApi.getGridInstance().refresh();
                });


                var getsubNodesRecursive = function(key) {
                    var keyList = [];

                    var subList = _.filter(scope.treeDataSource, function(row) {
                        return row[scope.parentKey] === key
                    });


                    if (subList && subList.length > 0) {

                        subList.forEach(function(row) {

                            var temp = getsubNodesRecursive(row[scope.idField]);
                            keyList.push(row[scope.idField]);

                            if (temp && temp.length > 0) {
                                keyList = _.union(keyList, temp);
                            }
                        });
                    }

                    return keyList;
                };


                var getParentRecursive = function(key) {

                    var parentList = [];
                    var node = _.find(scope.treeDataSource, function(row) {

                        return row[scope.idField] === key;
                    });

                    if (node && node[scope.parentKey]) {
                        parentList.push(node[scope.parentKey]);

                        var temp = getParentRecursive(node[scope.parentKey]);

                        if (temp && temp.length > 0) {
                            parentList = parentList.concat(temp);
                        }
                    }

                    return parentList;
                };


                var getchildren = function(selectKeyList) {

                    var keyList = [];
                    if (selectKeyList && selectKeyList.length > 0) {

                        selectKeyList.forEach(function(key) {
                            keyList.push(key);
                            var temp = getsubNodesRecursive(key);
                            if (temp && temp.length > 0) {
                                keyList = _.union(keyList, temp);
                            }
                        });

                    }

                    return keyList;
                };

                var getParentList = function(keys) {
                    if (keys && keys.length > 0) {
                        // 子节点全部选中,父节点选中
                        // 子节点未选中,父节点不选中

                        var selectNodeList = _.filter(scope.treeDataSource, function(row) {
                            return keys.indexOf(row[scope.idField]) > -1;
                        });

                        var parentKeyList = _.uniq(_.pluck(selectNodeList, scope.parentKey));

                        parentKeyList = _.filter(parentKeyList, function(row) {
                            if (row && row !== '') {
                                return true;
                            } else {
                                return false;
                            }
                        });

                        // 没有被选中的Key
                        parentKeyList = _.difference(parentKeyList, keys);


                        var parentSelectedKeyList = [];

                        var parentUncheckList = [];
                        parentKeyList.forEach(function(row) {
                            var subList = getsubNodesRecursive(row);

                            var noCheck = _.difference(subList, keys);

                            if (!noCheck || noCheck.length === 0) {
                                parentSelectedKeyList.push(row);
                            }

                            if (noCheck && noCheck.length === subList.length) {
                                parentUncheckList.push(row);
                            }

                        });

                        keys = _.union(keys, parentSelectedKeyList);
                        keys = _.difference(keys, parentUncheckList);

                        return keys;

                    }

                    return keys;

                };


                var getCheckParentList = function(key, selectKeyList) {
                    var parentCodeList = getParentRecursive(key);
                    
                    var checkParentList = [];

                    if (parentCodeList && parentCodeList.length > 0) {

                        var uncheckParentCodeList =  _.difference(parentCodeList, selectKeyList);
                        for (var i = 0; i < uncheckParentCodeList.length; i++) {

                            var row = uncheckParentCodeList[i];
                            var subList = getsubNodesRecursive(row);

                            if (subList && subList.length > 0) {
                                var noCheck = _.difference(subList, selectKeyList);

                                if (!noCheck || noCheck.length === 0) {
                                     selectKeyList.push(row);
                                     checkParentList.push(row);
                                } else{
                                    break;
                                }

                            }
                        }

                    }

                    return checkParentList;
                };

                var isAutoSetting = false;

                var gridOptions = function() {
                    return {
                        dataSource: scope.treeDataSource,
                        keyExpr: scope.idField,
                        parentIdExpr: scope.parentKey,
                        height: scope.selectorOptions.gridHeight,
                        columns: scope.columnDefs,
                        loadPanel: {
                            enabled: false
                        },
                        scrolling: {
                            mode: "virtual"
                        },
                        searchPanel: {
                            visible: true
                        },
                        selection: {
                            mode: scope.isSingleMode ? "single" : "multiple",
                            allowSelectAll: false
                        },
                        sorting: {
                            mode: 'single'
                        },
                        filterRow: {
                            visible: false
                        },
                        //cacheEnabled: true,
                        allowColumnResizing: true,
                        columnAutoWidth: true,
                        showRowLines: true,
                        showColumnLines: true,
                        rowAlternationEnabled: true, //单双行颜色
                        showBorders: true,
                        expandedRowKeys: [1],
                        onSelectionChanged: function(item) {

                            var selectKeyList = item.selectedRowKeys;

                            if (item.selectedRowKeys && item.selectedRowKeys.length ===0){
                                isAutoSetting = false;
                            }

                            if (!isAutoSetting) {

                                if (scope.selectorOptions.selectNodesRecursive) {

                                    var unCheckList = [];
                                    var checkList = selectKeyList;
                                    var checkOnlyList = [];
                                    if (item.currentDeselectedRowKeys && item.currentDeselectedRowKeys.length > 0) {
                                        // uncheck children
                                        unCheckList = getchildren(item.currentDeselectedRowKeys);

                                        // uncheck parent
                                        var parentList = getParentRecursive(item.currentDeselectedRowKeys[0]);
                                        unCheckList = _.union(unCheckList, parentList);
                                        var pureUnCheckList = _.filter(unCheckList, function(row){
                                            return selectKeyList.indexOf(row) > -1;
                                        });

                                        checkOnlyList = _.difference(checkList, unCheckList);

                                        if (pureUnCheckList && pureUnCheckList.length > 0) {
                                            isAutoSetting = true;
                                            item.component.deselectRows(pureUnCheckList);
                                        }

                                    } else {

                                        // check
                                        var checkChildren = getchildren(item.currentSelectedRowKeys);

                                        checkList = _.union(checkList, checkChildren);

                                        // check parent
                                        var checkParentList = getCheckParentList(item.currentSelectedRowKeys[0],checkList);

                                        checkList = _.union(checkList, checkParentList);
                                        checkOnlyList = checkList;

                                        var auoCheckList = _.difference(checkOnlyList, selectKeyList);

                                        if (auoCheckList && auoCheckList.length > 0) {
                                            isAutoSetting = true;
                                            item.component.selectRows(checkOnlyList, false);
                                        }
                                    }

                                    selectKeyList = checkOnlyList;
                                }
                            } else {
                                isAutoSetting = false;
                            }

                            scope.tmpSelectedItems = selectKeyList;
                        }
                    };
                };

                // Try to get identity column field from columnDefs
                var getIdField = function(columnDefs) {
                    if (_.isEmpty(columnDefs)) {
                        return null;
                    }

                    var idColumn = _.findWhere(columnDefs, { isIdentity: true });
                    if (_.isEmpty(idColumn)) {
                        idColumn = columnDefs[0];
                    }

                    return idColumn.dataField;
                }

                // Try to get parent key column field from columnDefs
                var getParentKey = function(columnDefs) {
                    if (_.isEmpty(columnDefs)) {
                        return null;
                    }

                    var keyColumn = _.findWhere(columnDefs, { isParentKey: true });
                    if (_.isEmpty(keyColumn)) {
                        keyColumn = columnDefs[0];
                    }

                    return keyColumn.dataField;
                };

                var loadColumnDefs = function(columnDefs) {
                    scope.idField = getIdField(columnDefs);
                    if (_.isEmpty(scope.idField)) {
                        throw new Error('Identity field must be defined!');
                    }

                    scope.parentKey = getParentKey(columnDefs);
                    if (_.isEmpty(scope.parentKey)) {
                        throw new Error('Parent key field must be defined!');
                    }

                    if (scope.idField === scope.parentKey) {
                        throw new Error('Parent key field should not be the same as identity field!');
                    }
                };

                var loadData = function(data) {
                    var idList = _.pluck(data, scope.idField);
                    _.each(data, function(d) {
                        if (!_.contains(idList, d[scope.parentKey])) {
                            d[scope.parentKey] = null;
                        }
                    });
                };

                var initSelections = function() {
                    scope.tmpSelectedItems = angular.copy(scope.selectedItems);
                    scope.internalApi.getGridInstance().selectRows(scope.tmpSelectedItems || []);
                };

                // Adjust the selector options
                var adjustOptions = function() {

                    // Adjust the CSS styles of the selector, currently only support width, height, top and left.
                    scope.selectorOptions = _.extend({
                        // Default options
                        height: 400,
                        width: 730
                    }, scope.selectorOptions);
                    if (_.isNumber(scope.selectorOptions.height)) {
                        scope.selectorOptions.gridHeight = scope.selectorOptions.height > 90 ?
                            (scope.selectorOptions.height - 90) : 1;
                    }

                    scope.cssOptions = _.pick(scope.selectorOptions, 'width', 'height', 'top', 'left');
                };

                scope.$watchCollection('treeDataSource', function(newValue, oldValue) {
                    var internalDataSource = angular.copy(newValue);
                    loadData(internalDataSource);
                    loadColumnDefs(scope.columnDefs);
                    if (treeList) {
                        treeList.option({
                            keyExpr: scope.idField,
                            parentIdExpr: scope.parentKey,
                            columns: scope.columnDefs,
                            dataSource: internalDataSource
                        });
                    } else {
                        element.find('.tree-multi-selector-grid').dxTreeList(gridOptions());
                        treeList = element.find('.tree-multi-selector-grid').dxTreeList('instance');
                        treeList.option('columns', scope.columnDefs);
                    }

                    // Use $timeout to make sure hash of the data generated before initSelections
                    $timeout(initSelections, 10);
                });

                scope.$watch('isShow', function(newValue, oldValue) {
                    if (newValue) {
                        var internalDataSource = angular.copy(scope.treeDataSource);
                        loadData(internalDataSource);
                        loadColumnDefs(scope.columnDefs);
                        if (treeList) {
                            treeList.option({
                                keyExpr: scope.idField,
                                parentIdExpr: scope.parentKey,
                                columns: scope.columnDefs,
                                dataSource: internalDataSource
                            });
                        } else {
                            element.find('.tree-multi-selector-grid').dxTreeList(gridOptions());
                            treeList = element.find('.tree-multi-selector-grid').dxTreeList('instance');
                            treeList.option('columns', scope.columnDefs);
                        }
                        element.find('.modal').modal('show');

                        // Use $timeout to make sure hash of the data generated before initSelections
                        $timeout(initSelections, 10);
                    } else {
                        element.find('.modal').modal('hide');
                    }
                });

                scope.selectorClose = function() {
                    if (scope.internalApi && _.isFunction(scope.internalApi.onSelectorClose)) {
                        scope.internalApi.onSelectorClose();
                    }

                    scope.isShow = false;
                };

                scope.selectorConfirm = function() {
                    // Copy selected items to selectedItems
                    scope.selectedItems.length = 0;
                    for (var i = 0; i < scope.tmpSelectedItems.length; i++) {
                        scope.selectedItems.push(scope.tmpSelectedItems[i]);
                    }

                    if (scope.internalApi && _.isFunction(scope.internalApi.onSelectorConfirm)) {
                        scope.internalApi.onSelectorConfirm();
                    }

                    scope.isShow = false;
                };

                adjustOptions();
                if (!scope.treeDataSource) {
                    scope.treeDataSource = [];
                }
            }
        };
    }
]);
commonModule.controller('uploaderContoller', ['$scope', '$log', '$translate', '$timeout', 'apiInterceptor', 'Upload',
    function ($scope, $log, $translate, $timeout, apiInterceptor, Upload) {

    	'use strict';

    	$log.debug('uploaderContoller.ctor()...');
    	var uploadUrl = apiInterceptor.webApiHostUrl + '/FileUpload/NewFile';
    	$scope.chunkSize = 100000;
    	$scope.success = false;

    	var resumable = true;
    	var allFilesCount = 0;
    	var successCount = 0;
    	var updateProgressToZero = function () {
    	    $scope.percentNumber = '0%';
    	    $scope.showLoading = false;
    	};
    	var uploadSuccess = function (resp) {
    	    successCount++;

    	    if (successCount === allFilesCount) {
    	        $scope.tempFileName = resp.data;
    	        changeSheet(0);
    	        $scope.showLoading = false;
    	    }
    	};


    	var updateProgress = function (evt) {
    	    $scope.showLoading = true;
    	    var progressPercentage = parseInt(100.0 * evt.loaded / evt.total);
    	    $scope.percentNumber = progressPercentage + '%';
    	};
    	var uploadfile = function (files) {
    		if (files && files.length) {
    			allFilesCount = files.length;
    			successCount = 0;
    			var uploadSuccessCallBack = function () {
    				updateProgressToZero();
    			}
    			for (var i = 0; i < files.length; i++) {
    				var file = files[i];

    				if (!file.$error) {
    					var tempFileName = PWC.newGuid() + '.dat';
    					updateProgressToZero();
    					Upload.upload({
    						url: uploadUrl,
    						data: {
    							cancel: false,
    							filename: file.name,
    							tempFileName: tempFileName,
    							FileTypeID: $scope.fileType,
    							ProjectID: $scope.projectID,
    							Remark: $scope.remark,
    							file: file
    						},
    						resumeChunkSize: resumable ? $scope.chunkSize : null,
    						headers: {
    							'Access-Control-Allow-Origin': '*',
    							Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken
    						}
    					}).then(uploadSuccess, uploadSuccessCallBack, updateProgress);
    				}
    			}
    		}
    	};

    	var changeloadingTitle = function (title) {
    		$scope.loadingTitle = $translate.instant(title);
    	};

    	

    	var doUploadFile = function () {

    		$scope.pageStatus = pageStatusEnum.Mapping;
    		changeloadingTitle('fileUploading');

    		uploadfile($scope.fileNameWrapper);
    	};

    	var updateFileName = function (newValue) {
    		$scope.fileName = '';
    		_.each(newValue, function (item) {
    			$scope.fileName = item.name;
    		});
    	};

    	$scope.$watch('fileNameWrapper', function (newValue, oldValue) {
    		if (newValue !== oldValue) {
    			updateFileName(newValue);
    			doUploadFile();
    		}
    	});
    }
]);
commonModule.directive('uploader', ['$log', function ($log) {
    'use strict';
    $log.debug('uploader constructor...');
    return {
        restrict: "E",
        templateUrl: '/app/common/controls/uploader/uploader.html' + '?_=' + Math.random(),
        controller: 'uploaderController',
        replace: true
    };
}]);
commonModule.
controller('userBusinessUnitModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', '$filter', 'SweetAlert', 'dimensionService', 'userService', 'roleService','$q',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, $filter, SweetAlert, dimensionService, userService, roleService, $q) {

        var modalSelector="#userBuModal";

        var roleCardSelector = '#assign-user-box';

        var showWarning = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.warning(errMsg);
        };

        var showSuccessMsg = function (resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.success(errMsg);
        };

        var showModal = function () {

            getSpecialUserRoleList().then(function () {
                $(modalSelector).modal("show");;
            });

            //getSpecialUserRoleList();
            //$(modalSelector).modal("show");
        };

        $scope.$watch('operateType', function (newValue, oldValue) {
            if (newValue) {
                if (newValue == constant.Operation.Add) {
                }
                else if (newValue == constant.Operation.Edit) {
                    showModal();
                }
            }
        });


        //如果添加了用户,则写入该维度下的库
        $scope.$watch('addUserIsUpdate', function (newValue, oldValue) {
            if (newValue) {
                if ($scope.selectedUserList && $scope.selectedUserList.length > 0)
                {
                    //console.log(JSON.stringify($scope.selectedUserList));
                    addUserToDimensionValue($scope.selectedUserList);
                }
            }
        });

        //为当前维度添加用户
        var addUserToDimensionValue = function (selectedUserArray) {

            var selectedArr = [];

            if (selectedUserArray && selectedUserArray.length > 0) {
                for (var i = 0; i < selectedUserArray.length; i++) {
                    //用户的角色列表
                    //var roleList = selectedUserArray[i].roleInfoList;

                    //去掉在当前维度下存在的用户,当前用户的权限可能已经改动过
                    var isUserExist = _.find($scope.userUIGridOptions.data, function (num) {
                        return num.userID == selectedUserArray[i].userID;
                    });

                    if (isUserExist) {
                        continue;
                    }
                    selectedArr.push(selectedUserArray);
                    uiGridAction.addRow(selectedUserArray[i]);
                }
            }

            if (selectedArr.length == 0) {
                showWarning('UserExists');
            }
        };


        $(modalSelector).on("hidden.bs.modal", function () {
            $scope.operateType = null;
        });

        //添加用户,弹框,call指令 add-exist-user-modal
        $scope.addUser = function () {
            var selectedKeyItem = [];
            $scope.userUIGridOptions.data.forEach(function (row) {
                selectedKeyItem.push(row.userID);
            });
            $scope.addUserOperateType = constant.Operation.Add;
            $scope.addUserIsUpdate = false;
            $scope.selectedKeyItems = selectedKeyItem;
        };

        var dataHasChanged = function () {
            $scope.operateType = null;
            $scope.isUpdate = true;
        };

        $scope.save = function ()
        {
            //比较新旧数据的变化更新数据库
            var oldData = $scope.oldUIGridData;
            var newData = uiGridAction.populateDataObject($scope.userUIGridOptions.data);

            if (angular.equals(oldData, newData)) {
                //nothing to do
              //  alert('same data');

            } else {
               // alert('something changed');
                var deleteList = [];
                var addList = [];
                var updateList = [];
                //旧数据在新数据中没有找到,则放到addList
                newData.forEach(function (row) {

                    var findResult = _.find(oldData, function (item) {
                        return item.userID == row.userID;
                    });
                    //旧数据没有找到,说明是新加的数据
                    if (!findResult) {
                        addList.push(row);

                        //添加的用户,改变了默认值,则添加到update list
                        if (!row.isAccessible || !row.hasOriginalRole || row.extraRoleList.length > 0) {
                            updateList.push(row);
                        }
                    }
                    else {
                        //如果旧数据找到了,查看是否相等,,不等的话,放到update list
                        if (!angular.equals(row, findResult)) {
                            updateList.push(row);
                        }
                    }

                });
                //新数据在旧数据中没有找到,则放到deleteList
                oldData.forEach(function (row) {

                    var findResult = _.find(newData, function (item) {
                        return item.userID == row.userID;
                    });
                    //新数据没有找到,说明是删除的数据
                    if (!findResult) {
                        deleteList.push(row);
                    }
                });

                //console.log('addList: ' + JSON.stringify(addList));
                //console.log('updateList: ' + JSON.stringify(updateList));
                //console.log('deleteList: ' + JSON.stringify(deleteList));
                service.addList(addList).then(function () {
                    service.updateList(updateList).then(function () {
                        service.deleteList(deleteList).then(function () {
                            showSuccessMsg("SaveSuccess");
                            dataHasChanged();
                        });
                    });
                });
            }
         
            $(modalSelector).modal("hide");
        };

        //数据库更新
        var service =  {
            addList: function (rowList) {
                var deferred = $q.defer();
                var selectedArr = [];
                rowList.forEach(function (row) {
                    var selectedObject = {
                        id: PWC.newGuid(),
                        dimensionValueID: $scope.dimensionValueId,
                        dimensionID: $scope.dimensionId,
                        userID: row.userID,
                        IsAccessible: true, //添加用户,默认可访问
                        hasOriginalRole: true,//添加用户,默认继承原始角色
                    };
                    selectedArr.push(selectedObject);
                });

                if (selectedArr.length > 0) {
                    //添加用户
                    userService.updateUserRoleForDimension(selectedArr).success(function (data) {
                        if (data) {
                            deferred.resolve(data);
                        }
                    });
                }
                else {
                    deferred.resolve(true);
                }
                return deferred.promise;
            },
            updateList: function (rowList) {
                var deferred = $q.defer();

                var selectedArr = [];
                rowList.forEach(function (row) {
                    //如果有附加角色
                    if (row.extraRoleList && row.extraRoleList.length > 0) {
                        row.extraRoleList.forEach(function (item) {
                            var selectedObject = {
                                dimensionValueID: $scope.dimensionValueId,
                                dimensionID: $scope.dimensionId,
                                userID: $scope.currentUserID,
                                roleID: item.id,
                                isAdd: true,
                                IsAccessible: row.isAccessible,
                                hasOriginalRole: row.hasOriginalRole || false
                            };

                            selectedArr.push(selectedObject);
                        });
                    }
                    else {
                        //如果没有附加角色
                        var selectedObject = {
                            dimensionValueID: $scope.dimensionValueId,
                            dimensionID: $scope.dimensionId,
                            userID: $scope.currentUserID,
                           // roleID: item.id,
                            isAdd: false,
                            IsAccessible: row.isAccessible,
                            hasOriginalRole: row.hasOriginalRole || false
                        };

                        selectedArr.push(selectedObject);
                    }
                });

                if (selectedArr.length > 0) {
                    //edit row
                    userService.updateUserRoleDimension(selectedArr).success(function (data) {
                        if (data) {
                            deferred.resolve(data);
                        }
                    });
                }
                else {
                    deferred.resolve(true);
                }

                return deferred.promise;
            },
            deleteList: function (rowList) {
                var deferred = $q.defer();
                var selectedArr = [];
                rowList.forEach(function (row) {
                    var selectedObject = {
                        dimensionValueID: $scope.dimensionValueId,
                        dimensionID: $scope.dimensionId,
                        userID: row.userID
                    }
                    selectedArr.push(selectedObject);
                });
                if (selectedArr.length > 0) {
                    //删除用户橘色
                    userService.deleteUserRoleDimension(selectedArr).success(function (data) {
                        if (data) {
                            deferred.resolve(data);
                        }
                    });
                }
                else {
                    deferred.resolve(true);
                }

                return deferred.promise;

            }
        };

        $scope.closeModal = function () {
            $scope.operateType = null;
        };
        //用户角色框隐藏
        $scope.closeSetRoleCard = function ()
        {
            hideRoleInfoCard();
        };


        //所有角色,全选和全不选的时候
        $scope.AllRoleChecked = function () {
            angular.forEach($scope.roleList, function (item) {
                item.isChecked = $scope.roleEntity.isAllRoleChecked;
            });
        };
        $scope.rowItemClick = function () {
            var hasCheckAll = true;
            var roleList = $scope.roleList;
            for (var i = 0; i < roleList.length; i++) {
                if (!roleList[i].isChecked) {
                    hasCheckAll = false;
                    break;
                }
            }
            $scope.roleEntity.isAllRoleChecked = hasCheckAll;

        };

        //显示角色卡片的时候,原始角色绑定,并绑定是否选中
        //var getOrignalUserRole = function (userID) {
        //    //getUserRoleListByUserID
        //    userService.getUserRoleListByUserID(userID).success(function (data) {
        //        if (data) {

        //            var subRoleList = data && data.roleInfoList || [];
        //            $scope.originalUserRoleList = subRoleList;
        //            //console.log(JSON.stringify("rolelist:" + JSON.stringify(data.RoleInfoList)));
        //        }
                

        //    });
        //};

        //所有角色列表
        var getRoleByService = function (row) {
            roleService.getRoleListByRoleTypeId(constant.serviceType.VAT).success(function (roleData) {
                if (roleData) {
                    $scope.roleList = roleData;
                }
            });
        };
        //显示角色卡片的时候,获取所有当前用户的角色列表,如果在所有角色列表中有存在,则选中
        var setRoleByService = function (row) {

            //当前用户行
            var selectedUserRole = _.find($scope.useRoleList, function (item) {
                return item.userID == row.userID;
            });
            //当前用户行的角色列表
            var roleInfoList = selectedUserRole && selectedUserRole.extraRoleList;
         
            var hasAllCheck = true;
            // if (selectedUserRole && roleInfoList && roleInfoList.length > 0) {
            $scope.roleList.forEach(function (roleItem) {

                //只有是附加维度上的角色才显示在所有角色列表
                var selectedRole = _.find(roleInfoList, function (item) {
                    return item.id == roleItem.id;
                });

                if (selectedRole) {
                    roleItem.isChecked = true;
                }
                else {
                    roleItem.isChecked = false;
                    hasAllCheck = false;
                }
            });

            $scope.roleEntity.isAllRoleChecked = hasAllCheck;
            $scope.roleEntity.isHeritable = row.hasOriginalRole;
            $scope.roleEntity.isAccessible = row.isAccessible;

        };
        

        //为事业部的值(其他维度的值)编辑用户角色
        $scope.setRoleToDimensionValue = function () {
            var selectedArr = [];
            var hasOneItem = false;
            $scope.roleList.forEach(function (item) {

                if (item.isChecked) {
                    hasOneItem = true;
                    //var selectedObject = {
                    //    //id: PWC.newGuid(),
                    //    //dimensionValueID: $scope.dimensionValueId,
                    //    //dimensionID: $scope.dimensionId,
                    //    //userID: $scope.currentUserID,
                    //    roleID: item.id
                    //    //IsAccessible: $scope.roleEntity.isAccessible,
                    //    //hasOriginalRole: $scope.roleEntity.isHeritable || false
                    //};

                    selectedArr.push(item);
               
                }
            });
            
            if (!hasOneItem && $scope.roleEntity.isAccessible && !$scope.roleEntity.isHeritable)
            {
                showWarning("SelectAtLeastOneRole");
                return false;
            };

            uiGridAction.updateRow(selectedArr);
            //userService.updateUserRoleDimension(selectedArr).success(function (data) {
            //    if (data)
            //    {
            //        showSuccessMsg("SaveSuccess");
            //        //刷新角色列表
            //        getUserRoleList();
            //        $scope.hasDataChanged = true;
            //        hideRoleInfoCard();
            //    }
            //});
            hideRoleInfoCard();
        }

        var confirmWarningWindow = function (title, text) {
            var deferred = $q.defer();
            SweetAlert.swal({
                title: title,
                text: text,
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                allowOutsideClick: false,
                confirmButtonText: $translate.instant('Confirm'),
                cancelButtonText: $translate.instant('Cancel'),
                closeOnConfirm: true,
                closeOnCancel: true
            },
              function (isConfirm) {
                  deferred.resolve(isConfirm);
              });

            return deferred.promise;
        };

        //删除用户角色
        $scope.deleteUserRole = function (row)
        {
            //var selectedObject = {
            //    dimensionValueID: $scope.dimensionValueId,
            //    dimensionID: $scope.dimensionId,
            //    userID: row.userID

            //};

            var confirmToDelete = $translate.instant('ConfirmToDelete');

            confirmWarningWindow(confirmToDelete, '').then(function (data) {
                if (data) {

                    //userService.deleteUserRoleDimension(selectedObject).success(function () {
                    //    showSuccessMsg("OrganizationStructureDeleteSuccess");
                    //    //刷新角色列表
                    //    getUserRoleList();
                    //});
                    uiGridAction.deleteRow(row.userID);
                }
            });      
        };
        //ui grid上面的增加删除修改
        var uiGridAction = {
            deleteRow: function (userID) {
                var tempData = $scope.userUIGridOptions.data;
                for (var i = 0; i < tempData.length; i++) {
                    if (tempData[i].userID == userID) {
                        tempData.splice(i, 1);
                        break;
                    }
                }
                $scope.userUIGridOptions.data = tempData;
            },
            addRow: function (row) {
                var tempData = $scope.userUIGridOptions.data;

                var hasSpecialRole = false;
                var specialRole = _.find($scope.specialUserRoleList, function (item) {
                    return item.userID == row.userID;
                });
               //默认为原始角色,设置角色来源于原始角色
                row.roleInfoList.forEach(function (item) {
                    item.roleSource == constant.roleSource.OriginalLevel;
                });

                if (specialRole) {
                    hasSpecialRole = true;
                }
                var selectedObject = {
                    id: PWC.newGuid(),
                    dimensionValueID: $scope.dimensionValueId,
                    dimensionID: $scope.dimensionId,
                    userID: row.userID,
                    userName:row.userName,
                    isAccessible: true,
                    hasOriginalRole: true,
                    extraRoleList: [],
                    roleInfoStr: row.roleInfoStr,
                    roleInfoList:  row.roleInfoList,
                    hasSpecialRole: hasSpecialRole
                };
                tempData.push(selectedObject);
                $scope.userUIGridOptions.data = tempData;
            },
            updateRow: function (extraRoleList) {

                var allShowList = angular.copy(extraRoleList);
                var tempData = $scope.userUIGridOptions.data;
                //追加原始角色
                if ($scope.roleEntity.isHeritable) {
                    $scope.originalUserRoleList.forEach(function (row) {
                        var newRow = {
                            id: row.id,
                            roleSource: constant.roleSource.OriginalLevel,
                            name: row.name
                        }
                        allShowList.push(newRow);
                    });
                }
                //附加角色
                extraRoleList.forEach(function (row) {
                    row.roleSource = constant.roleSource.DimensionLevel;
                    var newRow = {
                        id: row.id,
                        roleSource: constant.roleSource.DimensionLevel,
                        name: row.name
                    }
                    allShowList.push(newRow);
                });

                var uniqRoleList = _.uniq(allShowList, function (item) { return item.id });

                for (var i = 0; i < tempData.length; i++) {
                    var row = tempData[i];
                    if (row.userID == $scope.currentUserID) {
                        row.isAccessible = $scope.roleEntity.isAccessible;
                        row.hasOriginalRole = $scope.roleEntity.isHeritable || false;
                        row.extraRoleList = extraRoleList;
                        if (row.isAccessible) {
                            if (uniqRoleList && uniqRoleList.length > 0) {
                                row.roleInfoStr = _.map(uniqRoleList, function (x) { return x.name; }).join(constant.comma);
                            }
                            else {
                                row.roleInfoStr = $translate.instant('NoRole');
                            }
                        }
                        else {
                            row.roleInfoStr = $translate.instant('NonAccessible');
                        }

                        break;
                    }
                }
                $scope.userUIGridOptions.data = tempData;

            },//构造对象,用来比较对象是否相等
            populateDataObject: function (uiGridData) {
                var arraryList = [];

                if (uiGridData) {
                    uiGridData.forEach(function (row) {
                        var newObject = {};
                        newObject.userID = row.userID;
                        newObject.userName = row.userName;
                        newObject.isAccessible = row.isAccessible;
                        newObject.hasOriginalRole = row.hasOriginalRole;
                        newObject.extraRoleList = row.extraRoleList;
                        arraryList.push(newObject);
                    });
                }
                return arraryList;

            }
        };


        //点击显示当前用户的角色卡片
        $scope.showRoleInfoCard = function (row) {

            $scope.roleEntity = {};
            $scope.currentUserID = row.entity.userID;

            var roleCard = $(roleCardSelector);
            var rowId = $('#' + row.entity.userID);
            //原始角色
            var originalRole = _.filter(row.entity.roleInfoList, function (item) {
                return item.roleSource == constant.roleSource.OriginalLevel;
            });
            $scope.originalUserRoleList = originalRole;

            setRoleByService(row.entity);

            showOrgCard(roleCard, rowId, -60, -270);
            stopPropagation();
        };

        var stopPropagation = function (event) {
            event = event || window.event;
            if (event.stopPropagation) {
                event.stopPropagation();
            } else {
                event.cancelBubble = true;
            }
        }

        // 显示机构角色卡片
        var showOrgCard = function (popCard, row, topOffset, leftOffset) {

            popCard.css("display", "block");

            var top = row.offset().top + topOffset;
            if (top + popCard.height() > window.innerHeight) {
                top = window.innerHeight - popCard.height() - 20;
            }

            popCard.css('top', top + 'px');

            var left = row.offset().left + leftOffset;
            if (left + popCard.width() > window.innerWidth) {
                left = row.offset().left - popCard.width() - 30;
            }

            popCard.css('left', left + 'px');

            popCard.show();

            $(document).one('click', function () {
                hideRoleInfoCard();
            });
        };

        var hideRoleInfoCard = function ()
        {
            $(roleCardSelector).hide();
        };


        //初始化也的ui grid
        var initUIGrid = function ()
        {
            userUIGridInit();
            priUIGridInit();
        };


        //用户角色数据初始化
        var getUserRoleList = function () {
            var deferred = $q.defer();
            userService.getUserRoleByDimensionValueID($scope.dimensionId, $scope.dimensionValueId).success(function (data) {
                if (data) {

                   // console.log(JSON.stringify(data));

                    data.forEach(function (row) {
                        //这儿包括了原始角色和附加角色,不管有没有可继承
                        var roleInfoList = angular.copy(row.roleInfoList);
                        if (!row.hasOriginalRole) {
                            roleInfoList= _.filter(row.roleInfoList, function (item) {
                                return item.roleSource == constant.roleSource.DimensionLevel;
                            });
                        }

                        var uniqRoleList = _.uniq(roleInfoList, function (item) { return item.id });

                        //附加角色
                        row.extraRoleList = _.filter(row.roleInfoList, function (item) {
                            return item.roleSource == constant.roleSource.DimensionLevel;
                        });

                        if (row.isAccessible) {
                            if (uniqRoleList && uniqRoleList.length > 0) {
                                row.roleInfoStr = _.map(uniqRoleList, function (x) { return x.name; }).join(constant.comma);
                            }
                            else {
                                row.roleInfoStr = $translate.instant('NoRole');
                            }
                        }
                        else {
                            row.roleInfoStr = $translate.instant('NonAccessible');
                        }
                        var specialRole = _.find($scope.specialUserRoleList, function (item) {
                            return item.userID == row.userID;
                        });
                        if (specialRole) {
                            row['hasSpecialRole'] = true;
                        }
                        else {
                            row['hasSpecialRole'] = false;
                        }
                    });
                    $scope.useRoleList = data;
                    $scope.userUIGridOptions.data = data;
                    $scope.oldUIGridData = uiGridAction.populateDataObject(data);
                    deferred.resolve();
                }
            });
            return deferred.promise;
        };
        //机构特殊权限初始化
        var getSpecialUserRoleList = function () {
            var parentDimensionID = $scope.dimensionId;
            var dimensionValueID = $scope.dimensionValueId ;
            var deferred = $q.defer();

            userService.getSpecialUserRoleByDimensionValueID(parentDimensionID, dimensionValueID).success(function (data) {
                if (data) {

                    data.forEach(function (row) {

                        var uniqRoleList = _.uniq(row.roleInfoList, function (item) { return item.id });

                        if (row.isAccessible) {
                            if (uniqRoleList && uniqRoleList.length > 0) {
                                row.roleInfoStr = _.map(uniqRoleList, function (x) { return x.name; }).join(constant.comma);
                            }
                            else {
                                row.roleInfoStr = $translate.instant('NoRole');
                            }
                        }
                        else {
                            row.roleInfoStr = $translate.instant('NonAccessible');
                        }

                        row.isHighLight = false;
                    });
                    $scope.specialUserRoleList = data;
                    $scope.priUIGridOptions.data = data;
                    //初始化角色列表
                    getUserRoleList().then(function () {
                        deferred.resolve();
                    });

                }
            });

            return deferred.promise;
        };
        
        //reset hightlight to false.
        var setDefaultTheme = function () {
            if ($scope.priUIGridOptions.data && $scope.priUIGridOptions.data.length > 0) {
                $scope.priUIGridOptions.data.forEach(function (row) {
                    row.isHighLight = false;
                });
            }
        };

        //选中高亮特殊角色
        $scope.chooseRelavantRow = function (row) {
            setDefaultTheme();

            if (row.hasSpecialRole == true) {
                var matchList = _.filter($scope.priUIGridOptions.data, function (num) {
                    return num.userID == row.userID;
                });

                if (matchList && matchList.length > 0) {
                    matchList.forEach(function (row2) {
                        row2.isHighLight = !row2.isHighLight;
                    });
                }
            }
        };

        var userUIGridInit = function () {

            $scope.columns = [
                  {
                      field: 'userName',
                      name: $translate.instant('UserDesc'),
                      width: '25%',
                      cellTemplate: '<div  class="text-align-left-padding" ><span title="{{row.entity.userName }}">{{row.entity.userName | limitString:20}}</span></div>'
                  }
            ];

            if ($scope.hasEditPermission) {

                var column = {
                    field: 'role',
                    name: $translate.instant('Role'),
                    width: '40%',
                    cellTemplate: '<div class="text-align-left-padding"  id="{{row.entity.userID}}"  aria-hidden="true" ng-click="grid.appScope.showRoleInfoCard(row)"><span title="{{row.entity.roleInfoStr}}">{{row.entity.roleInfoStr | limitString:24}}</span><i class="fa fa-caret-down icon-right" ></i></div>'

                };

                $scope.columns.push(column);

                column = {
                    field: 'isAccess',
                    name: $translate.instant('SpecialAccess'),
                    width: '20%',
                    cellTemplate: '<div class="text-align-left-padding" style="margin-left:22px" ng-show="row.entity.hasSpecialRole==true" > <span><i class="fa fa-check" aria-hidden="true" ></i> </span></div>'
                };


                $scope.columns.push(column);

                column = {
                    field: 'Delete',
                    name: $translate.instant('Delete'),
                    headerCellClass: 'text-align-left',
                    cellTemplate: '<div class="text-align-left-padding" style="margin-left:5px"> \
                                         <a class="operate-btn" href="javascript:void(0)">\
                                            <i class="material-icons highlight-tag" ng-click="grid.appScope.deleteUserRole(row.entity)">&#xE872;</i></a></div>',
                    width: '15%',

                };

                $scope.columns.push(column);
            }
            else {

                var column = {
                    field: 'role',
                    name: $translate.instant('Role'),
                    width: '55%',
                    cellTemplate: '<div class="text-align-left-padding"  id="{{row.entity.userID}}"  aria-hidden="true"><span title="{{row.entity.roleInfoStr}}">{{row.entity.roleInfoStr | limitString:40}}</span></div>'

                };

                $scope.columns.push(column);

                column = {
                    field: 'isAccess',
                    name: $translate.instant('SpecialAccess'),
                    width: '20%',
                    cellTemplate: '<div class="text-align-left-padding" style="margin-left:22px" ng-show="row.entity.hasSpecialRole==true" > <span><i class="fa fa-check" aria-hidden="true" ></i> </span></div>'
                };


                $scope.columns.push(column);
            }


            $scope.userUIGridOptions = {
                data: [],
                enableRowSelection: true,
                enableSelectAll: false,
                rowHeight: 30,
                enableRowHeaderSelection: false,
                modifierKeysToMultiSelect: false,
                enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
                enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,
                renderContainers: undefined,
                enableSorting: true,
                enableColumnMenus: false,
                enableColumnResizing: false,
                enableFiltering: false,
                enableFullRowSelection: true, //是否点击行任意位置后选中,默认为false
                multiSelect: false, // 是否可以选择多个,默认为true; 

                columnDefs: $scope.columns,

                onRegisterApi: function (gridApi) {

                    $scope.userGridApi = gridApi;

                    $scope.gridSelectCount = $scope.userGridApi.selection.getSelectedRows().length;

                    //如果有特殊权限,就高亮特殊角色的那行
                    gridApi.selection.on.rowSelectionChanged($scope, function (row) {
                        $scope.chooseRelavantRow(row.entity);
                    });

                    // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                    $interval(function () {
                        $scope.userGridApi.core.handleWindowResize();
                    }, 500, 60 * 60 * 8);

                }
            };
        };
            //特殊权限UI grid初始化
        var priUIGridInit = function () {
            $scope.priUIGridOptions = {
                    data:[],
                    enableRowSelection: true,
                    enableSelectAll: false,
                    rowHeight: 30,
                    enableRowHeaderSelection: false,
                    modifierKeysToMultiSelect: false,
                    enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
                    enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,
                    renderContainers: undefined,
                    enableSorting: true,
                    enableColumnResizing: false,
                    enableColumnMenus: false,
                    enableFiltering: false,
                    enableFullRowSelection: true, //是否点击行任意位置后选中,默认为false
                    multiSelect: false, // 是否可以选择多个,默认为true; 
                    rowTemplate: '<div ng-repeat="(colRenderIndex, col) in colContainer.renderedColumns track by col.colDef.name" class="ui-grid-cell" ng-class="{\'ui-grid-row-header-cell\':col.isRowHeader,\'red-color\':row.entity.isHighLight }"  ui-grid-cell></div>',

                    columnDefs: [
                           {
                               field: 'name',
                               name: $translate.instant('UserDesc'),
                               width: '30%',
                               cellTemplate: '<div  class="text-align-left-padding" title ="{{row.entity.userName}}"><span>{{row.entity.userName}}</span></div>'
                           },
                            {
                                field: 'name',
                                name: $translate.instant('OrganizationName'),
                                width: '30%',
                                cellTemplate: '<div  class="text-align-left-padding" title ="{{row.entity.organizationName}}"><span>{{row.entity.organizationName}}</span></div>'

                            },
                             {
                                 field: 'role',
                                 name: $translate.instant('Role'),
                                 width: '40%',
                                 cellTemplate: '<div class="text-align-left-padding" style="margin-right:30px;" ><span title="{{row.entity.roleInfoStr}}">{{row.entity.roleInfoStr}}</span></div>'
                             }
                    ],

                    onRegisterApi: function (gridApi) {

                        $scope.gridApi = gridApi;

                        $scope.gridSelectCount = $scope.gridApi.selection.getSelectedRows().length;

                        // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                        $interval(function () {
                            $scope.gridApi.core.handleWindowResize();
                        }, 500, 60 * 60 * 8);

                    }
                };

        };

        //权限check
        var checkUserPermission = function () {

            var list = [];

            $scope.hasQueryPermission = false;
            $scope.hasEditPermission = false;

            //权限设置的权限
            var tempAcess = constant.adminPermission.infrastructure.accessSetting;
            list.push(tempAcess.queryCode);
            list.push(tempAcess.editCode);

       
            $scope.$root.checkUserPermissionList(list).success(function (data) {

                $scope.hasQueryPermission = data[tempAcess.queryCode];
                $scope.hasEditPermission = data[tempAcess.editCode];

                if ($scope.hasQueryPermission) {
                    initUIGrid();
                }
            });
        };


        ;(function initialize() {
            $log.debug('userBusinessUnitModalController.ctor()...');
           // $scope.dimensionId = 'c61a5bd6-a996-4952-9869-d053995237e5';
            //$scope.dimensionValueId = '0bae00f7-96dc-46c8-b6f5-a427616c5bcf';
            checkUserPermission();
       
            getRoleByService();
           // showModal();
            //$scope.setRoleToDimensionValue = setRoleToDimensionValue;
            
        })();
    }
]);

commonModule.directive('userBusinessUnitModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('userBusinessUnitModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/user-business-unit-modal/user-business-unit-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'userBusinessUnitModalController',
            scope:
            {
                operateType: '=',
                isUpdate: '=?',
                dimensionId: '=?',
                dimensionValueId: '=?',
                dimensionValueName: '=?'
            },
            link: function (scope, element) {
                $(".assign-user-box").draggable({ containment: "parent", cursor: "cursor" });


                $(".assign-user-box").on("click", function (e) {
                    e.stopPropagation();
                });


            }
        };
    }
]);
commonModule.
controller('userOrganizationAccessModalController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', '$filter', 'SweetAlert', 'dimensionService', 'userService', '$q', 'roleService',
    function($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, $filter, SweetAlert, dimensionService, userService, $q, roleService) {

        $scope.gridInstance = null;
        var modalSelector = '#userOrgModal';
        var roleCardSelector = '#assign-role-box';

        var showWarning = function(resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.warning(errMsg);
        };

        var showSuccessMsg = function(resultMsg) {

            var errMsg = $translate.instant(resultMsg);
            SweetAlert.success(errMsg);
        };

        var showModal = function() {
            $scope.userId = $scope.userId || '';
            $scope.organizationId = $scope.organizationId || '';
            resetErrorMsg();
            //绑定原始角色
            getOrignalUserRole($scope.userId);

            //获取所有角色
            getAllRole();

            $scope.hasDataChanged = false;
            $scope.currentNavItem = 'page1';
            hideRoleInfoCard();
            $scope.roleEntity = {};
            loadUserRole();
            $(modalSelector).modal("show");
        };
        $scope.$watch('operateType', function(newValue, oldValue) {
            if (newValue) {

                if (newValue == constant.Operation.Add) {

                } else if (newValue == constant.Operation.Edit) {
                    showModal();
                }
            }
        });


        //点击每一行的三角符号,添加原始和附加用户,显示卡片
        $scope.showRoleCard = function(row) {
            $scope.selectedId = row.entity.id;
            var roleCard = $(roleCardSelector);
            var rowId = $('#' + row.entity.id);
            setRowCardCheck(row);
            showCard(roleCard, rowId, 160, 20);
            stopPropagation();
        };

        //用户角色框隐藏
        $scope.closeSetRoleCard = function() {
            hideRoleInfoCard();
        };

        var stopPropagation = function (event) {
            event = event || window.event;
            if (event.stopPropagation) {
                event.stopPropagation();
            } else {
                event.cancelBubble = true;
            }
        }

        // 显示机构角色卡片
        var showCard = function(popCard, row, topOffset, leftOffset) {

            popCard.css("display", "block");

            var top = row.position().top + topOffset;
            if (top + popCard.height() > window.innerHeight) {
                top = window.innerHeight - popCard.height() - 20;
            }

            popCard.css('top', top + 'px');

            var left = row.position().left + leftOffset;
            if (left + popCard.width() > window.innerWidth) {
                left = row.position().left - popCard.width() - 30;
            }

            popCard.css('left', left + 'px');

            popCard.show();

            $(document).one('click', function () {
                hideRoleInfoCard();
            });
        };
        var hideRoleInfoCard = function() {
            $(roleCardSelector).hide();
        };

        var setRowCardCheck = function(row) {

            //附加机构的角色列表
            var roleInfoList = $scope.extraRoleList;
            var hasAllCheck = true;
            if (roleInfoList && roleInfoList.length > 0) {
                $scope.roleList.forEach(function(roleItem) {
                    //只有是附加维度上的角色才显示在所有角色列表
                    var selectedRole = _.find(roleInfoList, function(item) {
                        return item.id == roleItem.id;
                    });

                    if (selectedRole) {
                        roleItem.isChecked = true;
                    } else {
                        roleItem.isChecked = false;
                        hasAllCheck = false;
                    }
                });
            } else {
                hasAllCheck = false;
            }
            $scope.roleEntity.isAllRoleChecked = hasAllCheck;
        }


        //绑定原始角色
        var getOrignalUserRole = function(userID) {
            //getUserRoleListByUserID
            userService.getUserRoleListByUserID(userID).success(function(data) {
                if (data) {
                    var subRoleList = data && data.roleInfoList || [];
                    $scope.originalUserRoleList = subRoleList;
                }

            });
        };

        //全部选中
        $scope.AllRoleChecked = function() {
            angular.forEach($scope.roleList, function(item) {
                item.isChecked = $scope.roleEntity.isAllRoleChecked;
            });
        };

        //所有的角色列表
        var getAllRole = function() {
            roleService.getRoleListByRoleTypeId(constant.serviceType.VAT).success(function(roleData) {
                if (roleData) {
                    $scope.roleList = roleData;
                    // console.log(JSON.stringify(roleData));
                }
            });
        };

        $(".userOrgModal").on("hidden.bs.modal", function() {
            $scope.operateType = null;
            if ($scope.hasDataChanged) {
                dataHasChanged();
            }
        });

        $scope.closeModal = function() {
            $scope.operateType = null;
        };

        $scope.Save = function() {
            var oldUser = $scope.oldUIGridUser;
            var oldDimension = $scope.oldUIGridDimension;

            var newUser = populateDataObject($scope.userUIGridOptions.data, 1);
            var newDimension = populateDataObject($scope.userUIGridOptions.data, 2);

            if (angular.equals(oldUser, newUser) && angular.equals(oldDimension, newDimension)) {
                //nothing to do
            } else {

                var hasExtraRole = _.filter($scope.userUIGridOptions.data, function(item) {
                    return item.dimensionValueID == constant.userRoleDimensionValueID.extraOrgDimensionValueID;
                });

                var hasOriginalRole = _.filter($scope.userUIGridOptions.data, function(item) {
                    return item.dimensionValueID == constant.userRoleDimensionValueID.originalRoleDimensionValueID;
                });
 
                if (hasExtraRole && hasExtraRole.length >= 2 || hasOriginalRole && hasOriginalRole.length >= 2) {
                    //只能添加一个原始角色和一个附加角色
                    showWarning('OnlyAddOneOriginalRoleAndExtraRole');
                    return false;
                }

                if (hasExtraRole.length > 0 && (!$scope.extraRoleList || $scope.extraRoleList.length == 0)) {
                    //请选择附加角色
                    showWarning('SelectExtraRole');
                    return false;
                }

                //比较用户上的新旧不一致
                if (!angular.equals(oldUser, newUser)) {
                    setRoleToOrganization();
                }
                //比较维度上的的新旧不一致
                if (!angular.equals(oldDimension, newDimension)) {
                    var dimensionDifferList = [];
                    newDimension.forEach(function(newData) {
                        oldDimension.forEach(function(oldData) {
                            if (newData.isHeritable != oldData.isHeritable) {
                                //是否有维度是继承关系不一致
                                dimensionDifferList.push(newData);
                            }

                        });
                    });

                    setDimensionIsHeritable(dimensionDifferList);
                }
              
            }

            $(modalSelector).modal("hide");
        };


        var dataHasChanged = function() {
            $scope.operateType = null;
            $scope.isUpdate = true;
        };

        var confirmWarningWindow = function(title, text) {
            var deferred = $q.defer();
            SweetAlert.swal({
                title: title + ' ?',
                text: text,
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                allowOutsideClick: false,
                confirmButtonText: $translate.instant('Confirm'),
                cancelButtonText: $translate.instant('Cancel'),
                closeOnConfirm: true,
                closeOnCancel: true
            },
                function(isConfirm) {
                    deferred.resolve(isConfirm);
                });

            return deferred.promise;
        };


        //弹出卡片 设置角色,可添加或取消原始角色,可添加和取消额外角色。可设置访问不可访问
        var setRoleToOrganization = function() {
            var selectedArr = [];
            var hasOneItem = false;
            //有附加角色
            if ($scope.extraRoleList && $scope.extraRoleList.length > 0) {

                $scope.extraRoleList.forEach(function(item) {
                    var selectedObject = {
                        id: PWC.newGuid(),
                        userID: $scope.userId,
                        organizationID: $scope.organizationId,
                        roleID: item.id,
                        IsAccessible: $scope.roleEntity.isAccessible,
                        hasOriginalRole: $scope.roleEntity.hasOriginalRole
                    };

                    selectedArr.push(selectedObject);
                });
            }
                //没有附加角色
            else {
                var selectedObject = {
                    id: PWC.newGuid(),
                    userID: $scope.userId,
                    organizationID: $scope.organizationId,
                    IsAccessible: $scope.roleEntity.isAccessible,
                    hasOriginalRole: $scope.roleEntity.hasOriginalRole
                };

                selectedArr.push(selectedObject);
            }

            if (selectedArr != null && selectedArr.length > 0) {
                //showWarning("SelectAtLeastOneRole");
                //return false;
                userService.updateUserRoleOrganization(selectedArr).success(function(data) {
                    if (data) {
                        showSuccessMsg("SaveSuccess");
                        hideRoleInfoCard();
                        //update the update flag
                        dataHasChanged();

                    }
                });
            }
        };
        //维度上的是否继承设置
        var setDimensionIsHeritable = function(data) {

            var selectedArr = [];
            if (data && data.length > 0) {
                data.forEach(function(row) {
                    var selectedObject = {
                        dimensionValueID: row.dimensionValueID,
                        dimensionID: row.dimensionID,
                        userID: $scope.userId,
                        organizationID: $scope.organizationId,
                        isHeritable: row.isHeritable //设置维度在机构上,是否可继承
                    };
                    selectedArr.push(selectedObject);
                });
            }

            //维度上做修改
            if (selectedArr.length > 0) {

                userService.deleteUserOrg(selectedArr).success(function(data) {
                    showSuccessMsg("SaveSuccess");
                    //update the update flag
                    dataHasChanged();
                });

            }
        };

        var showErrorMsg = function (msg) {
            $scope.isShowError = true;
            $scope.errorMsg = msg;
        };

        var resetErrorMsg = function () {
            $scope.isShowError = false;
            $scope.errorMsg = '';
        };

        $scope.resetError = function () {
            resetErrorMsg();
        };

        $scope.setOrgAccessible = function () {
            resetErrorMsg();
            var isAccessible = $scope.roleEntity.isAccessible;
            //设置用户在机构上可访问
            if (isAccessible) {
                //是否有维度上的继承不可访问
                var hasHeritableNonAccess = _.find($scope.userUIGridOptions.data, function(item) {
                    return item.dimensionID != constant.userRoleDimensionValueID.extraOrgDimensionID && !item.isAccessible && item.isHeritable;
                });
                //维度上有继承的不可访问的权限,不能点击
                if (hasHeritableNonAccess && hasHeritableNonAccess != null) {
                    $scope.roleEntity.isAccessible = false;
                    showErrorMsg($translate.instant('DimensionBecomeNonheritable'));
                    //var confirmMsg = $translate.instant('DimensionBecomeNonheritable');
                    //confirmWarningWindow(confirmMsg, '').then(function(result) {
                    //    if (result) {
                    //        var data = $scope.userUIGridOptions.data;
                    //        for (var i = 0; i < $scope.userUIGridOptions.data.length; i++) {
                    //            //如果是不是附加的维度,继承了不可访问,要将可继承改为为不可继承
                    //            if (data[i].dimensionID != constant.userRoleDimensionValueID.extraOrgDimensionID && !data[i].isAccessible && data[i].isHeritable) {
                    //                data[i].isHeritable = false;
                    //            }
                    //        }
                    //        $scope.userUIGridOptions.data = data;
                    //    }
                    //});
                }
                //else //设置用户在机构上不可访问
                //{
                //   //nothing to 
                //}
            }
        }

        //删除或设置维度的继承关系,维度上,设置可继承,还是不可以继承
        //删除,原始角色,或者附加角色
        $scope.rowUpdate = function(row) {

            if (row.isDeleted) {
                var confirmToDelete = $translate.instant('ConfirmToDelete');
                confirmWarningWindow(confirmToDelete, '').then(function (result) {
                    if (result) {
                        var data = $scope.userUIGridOptions.data;
                        for (var i = 0; i < $scope.userUIGridOptions.data.length; i++) {
                            if (data[i].id == row.id) {
                                //删除了原始角色
                                if (data[i].dimensionValueID == constant.userRoleDimensionValueID.originalRoleDimensionValueID) {
                                    $scope.roleEntity.hasOriginalRole = false;
                                }
                                //删除了附加角色
                                if (data[i].dimensionValueID == constant.userRoleDimensionValueID.extraOrgDimensionValueID) {
                                    $scope.extraRoleList = [];
                                }

                                data.splice(i, 1);
                                break;
                            }
                        }
                        $scope.userUIGridOptions.data = data;
                    }
                });

            }
            else {
                resetErrorMsg();
                //维度允许继承点击事件
                if (!row.isAccessible && row.isHeritable && $scope.roleEntity.isAccessible) //维度不可访问的时候,当点击继承的时候,机构上的将变成不可访问
                {
                    var data = $scope.userUIGridOptions.data;
                    for (var i = 0; i < $scope.userUIGridOptions.data.length; i++) {
                        if (data[i].id == row.id) {
                            data[i].isHeritable = false;
                            break;
                        }
                    }

                    $scope.userUIGridOptions.data = data;
                    showErrorMsg($translate.instant('OrganizatoinBecomeNonheritable'));
                    //var confirmToDelete = $translate.instant('OrganizatoinBecomeNonheritable');
                    //confirmWarningWindow(confirmToDelete, '').then(function (result) {
                    //    if (result) {
                    //        $scope.roleEntity.isAccessible = false;
                    //    }
                    //});
                }
            }

        };

        $scope.getGridHeight = function() {
            return $('.user-role').css('height') + 'px';
        };

        var populateDataObject = function(data, enumType) {
            var arraryList = [];

            if (data) {

                var hasOriginalRole = false;
                $scope.roleEntity.hasOriginalRole = false;
                var findResult = _.find(data, function (item) { return item.dimensionValueID == constant.userRoleDimensionValueID.originalRoleDimensionValueID });
                if (findResult) {
                    hasOriginalRole = true;
                    $scope.roleEntity.hasOriginalRole = true;
                }

                data.forEach(function(row) {
                    if (enumType == 1) { //用户上的
                        if (row) {
                            var newObject = {};
                            // if (row.dimensionID == constant.userRoleDimensionValueID.extraOrgDimensionID) {

                            newObject.isAccessible = $scope.roleEntity.isAccessible;
                           //newObject.hasOriginalRole = $scope.roleEntity.hasOriginalRole;
                            newObject.hasOriginalRole = hasOriginalRole;

                            //附加额外的角色
                            if (row.dimensionValueID == constant.userRoleDimensionValueID.extraOrgDimensionValueID) {
                                newObject.extraRoleList = $scope.extraRoleList;
                            }
                            // }
                            arraryList.push(newObject);
                        }
                    } else if (enumType == 2) //维度上的
                    {
                        if (row) {
                            if (row.dimensionID != constant.userRoleDimensionValueID.extraOrgDimensionID) {
                                var newObject = {};
                                newObject.dimensionID = row.dimensionID;
                                newObject.dimensionValueID = row.dimensionValueID;
                                newObject.dimensionName = row.dimensionName;
                                newObject.dimensionValueName = row.dimensionValueName;
                                newObject.isHeritable = row.isHeritable;
                                arraryList.push(newObject);
                            }
                        }
                    }
                });
            };

            return arraryList;
        };

        var loadUserRole = function() {

            var userID = $scope.userId;
            var orgID = $scope.organizationId;

            userService.getUserRoleByOrgIDUserID(userID, orgID).success(function(data) {

                $scope.extraRoleList = [];

                if (data) {
                    $scope.userName = data.userName;
                    $scope.orgName = data.organizationName;

                    //计算出来的,是否可以访问
                    $scope.isAccessible = data.isAccessible;
                    //$scope.hasOriginalRole = data.hasOriginalRole;
                    //该机构是否包含原始角色
                    $scope.roleEntity.hasOriginalRole = data.hasOriginalRole;
                    //该机构是否可访问
                    $scope.roleEntity.isAccessible = data.isAccessible;

                    var dimensionUserList = data.dimensionUserList;
                    if (dimensionUserList && dimensionUserList.length > 0) {
                        dimensionUserList.forEach(function(row) {
                            if (row) {
                                row.id = row.id;
                                row.dimensionID = row.dimensionID;
                                row.dimensionValueID = row.dimensionValueID;
                                row.dimensionName = row.dimensionName;
                                row.dimensionValueName = row.dimensionValueName;

                                row.isHeritable = row.isHeritable;
                                //附加额外的角色
                                if (row.dimensionValueID == constant.userRoleDimensionValueID.extraOrgDimensionValueID) {
                                    $scope.extraRoleList = row.roleList;
                                    row.isExtraRole = true;
                                }

                                //附加的角色(原始和附加),只可以做删除
                                if (row.dimensionID == constant.userRoleDimensionValueID.extraOrgDimensionID) {
                                    row.isHeritableStr = 'Delete';
                                    row.isDeleted = true;
                                    row.extraOptions = extraOptions;
                                    //选中是原始角色还是附加角色
                                    row.extraSelected = _.find(extraOptions, function(item) {
                                        return item.id == row.dimensionValueID });
                                } else {
                                    //维度上的角色,可继承不可继承
                                    row.isHeritableStr = $translate.instant('AllowInherit'); //row.isHeritable == true ? $translate.instant('AllowInherit') : $translate.instant('NoInherit');
                                    row.isDeleted = false;
                                }
                                if (row.isAccessible || row.dimensionID == constant.userRoleDimensionValueID.extraOrgDimensionID) {
                                    var roleNames = _.pluck(row.roleList, 'name');
                                    row.roleNameList = roleNames.join(constant.comma);
                                } else {
                                    //只有在维度上的才出现不可访问,附加角色和原始角色照样显示
                                    row.roleNameList = $translate.instant('NonAccessible'); //不可访问
                                }
                            }
                        });
                    }
                    $scope.userUIGridOptions.data = dimensionUserList;
                    $scope.roleTreeViewData = data.permissionTreeList
                        //构造旧的数据
                    $scope.oldUIGridUser = populateDataObject(dimensionUserList, 1);
                    $scope.oldUIGridDimension = populateDataObject(dimensionUserList, 2);

                    // console.log(JSON.stringify(data));
                }
            });
        };

        var loadRoleTree = function() {
            $scope.roleTreeViewOptions = {
                bindingOptions: {
                    dataSource: 'roleTreeViewData'
                },

                selection: {
                    mode: "single"
                },

                loadPanel: {
                    enabled: true
                },
                scrolling: {
                    mode: "virtual"
                },
                // keyExpr: "id",
                //parentIdExpr: "parentId",
                showRowLines: true,
                showColumnLines: true,
                expandAllEnabled: true,
                rowAlternationEnabled: true,
                expandedRowKeys: [1],
                showBorders: true,
                noDataText: $translate.instant('NoDataText'),
                selectAllText: $translate.instant('SelectAll'),
                selectNodesRecursive: true, //级联选择
                showCheckBoxesMode: 'none', //Accepted Values: 'none' | 'normal' | 'selectAll'
                onItemSelectionChanged: function(obj, element, model, node) {
                    populateSelectedRole(obj.itemData);
                },
                onInitialized: function(e) {
                    $scope.gridInstance = e.component;
                }

            };

        };

        //下拉列表,原始角色和附加角色
        var extraOptions = [{
            id: constant.userRoleDimensionValueID.originalRoleDimensionValueID,
            value: constant.userRoleDimensionValueID.originalRoleDimensionValueName
        }, {
            id: constant.userRoleDimensionValueID.extraOrgDimensionValueID,
            value: constant.userRoleDimensionValueID.extraOrgDimensionValueName
        }];

        //卡片弹框点击确认后,给附加的角色,设置角色
        $scope.setRoleToRow = function() {
            $scope.extraRoleList = [];

            $scope.roleList.forEach(function(item) {
                if (item.isChecked) {
                    var selectedObject = {
                        id: item.id,
                        name: item.name
                    };
                    $scope.extraRoleList.push(selectedObject);
                }
            });

            var data = $scope.userUIGridOptions.data;
            data.forEach(function(item) {
                if (item.id == $scope.selectedId) {
                    item.isExtraRole = true;
                    item.roleList = $scope.extraRoleList;
                    var roleNames = _.pluck($scope.extraRoleList, 'name');
                    item.roleNameList = roleNames.join(constant.comma);
                    item.dimensionValueID = constant.userRoleDimensionValueID.extraOrgDimensionValueID;
                }
            });

            $scope.userUIGridOptions.data = data;

            hideRoleInfoCard();
        };
        //添加附加原始和额外角色 数据行
        $scope.addRow = function() {
            var hasExtraRole = _.filter($scope.userUIGridOptions.data, function(item) {
                return item.dimensionID == constant.userRoleDimensionValueID.extraOrgDimensionID;
            });

            if (hasExtraRole && hasExtraRole.length >= 2) {
                //只能添加一个原始角色和一个附加角色
                showWarning('OnlyAddOneOriginalRoleAndExtraRole');
                return false;
            }
            //判断是否已经有原始角色
            var hasOrignialRole = _.find($scope.userUIGridOptions.data, function (item) {
                return item.dimensionValueID == constant.userRoleDimensionValueID.originalRoleDimensionValueID;
            });

            var defaultDimensionValueID = constant.userRoleDimensionValueID.originalRoleDimensionValueID;
            var defaultSelected = _.find(extraOptions, function (item) { return item.id == constant.userRoleDimensionValueID.originalRoleDimensionValueID; });

            var roleNames = _.pluck($scope.originalUserRoleList, 'name');
            var defaultRoleNameList = roleNames.join(constant.comma);
            var defaultIsExtraRole = false;

            //如果有原始角色,默认添加的是附加角色
            if (hasOrignialRole) {
                defaultSelected = _.find(extraOptions, function (item) { return item.id == constant.userRoleDimensionValueID.extraOrgDimensionValueID; });
                defaultDimensionValueID = constant.userRoleDimensionValueID.extraOrgDimensionValueID;
                defaultRoleNameList = '';
                defaultIsExtraRole = true;
            }

            var newRow = {
                id: PWC.newGuid(),
                dimensionID: constant.userRoleDimensionValueID.extraOrgDimensionID,
                dimensionValueID: defaultDimensionValueID,
                dimensionName: constant.userRoleDimensionValueID.extaDimensionName,
                isDeleted: true, //可删除,说明是附加的角色
                userID: $scope.userId,
                extraOptions: extraOptions,
                extraSelected: defaultSelected,
                roleNameList: defaultRoleNameList,
                isExtraRole: defaultIsExtraRole
            };

            $scope.userUIGridOptions.data.push(newRow);
        };

        //选中原始角色和附加角色切换时
        $scope.extraRowSelectionChanged = function(row) {
            var data = $scope.userUIGridOptions.data;
            if (row.entity.extraSelected.id == constant.userRoleDimensionValueID.originalRoleDimensionValueID) //原始角色
            {
                data.forEach(function(item) {
                    if (item.id == row.entity.id) {
                        item.isExtraRole = false;
                        var roleNames = _.pluck($scope.originalUserRoleList, 'name');
                        item.roleList = $scope.originalUserRoleList;
                        item.roleNameList = roleNames.join(constant.comma);
                        item.dimensionValueID = constant.userRoleDimensionValueID.originalRoleDimensionValueID;
                    }
                });
            } else if (row.entity.extraSelected.id == constant.userRoleDimensionValueID.extraOrgDimensionValueID) //附加角色,才会弹框编辑角色
            {
                data.forEach(function(item) {
                    if (item.id == row.entity.id) {
                        item.isExtraRole = true;
                        var roleNames = _.pluck($scope.extraRoleList, 'name');
                        item.roleList = $scope.extraRoleList;
                        item.roleNameList = roleNames.join(constant.comma);
                        item.dimensionValueID = constant.userRoleDimensionValueID.extraOrgDimensionValueID;
                    }
                });
            }
            $scope.userUIGridOptions.data = data;
            //console.log(JSON.stringify(data));
        };
        var userUIGridInit = function() {
            $scope.userUIGridOptions = {
                data: [],
                enableRowSelection: true,
                enableSelectAll: false,
                rowHeight: 30,
                enableRowHeaderSelection: false,
                modifierKeysToMultiSelect: false,
                enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
                enableVerticalScrollbar: uiGridConstants.scrollbars.enableVerticalScrollbar,
                renderContainers: undefined,
                enableSorting: true,
                enableColumnResizing: false,
                enableColumnMenus: false,
                enableFiltering: false,
                enableFullRowSelection: true, //是否点击行任意位置后选中,默认为false
                multiSelect: false, // 是否可以选择多个,默认为true; 

                columnDefs: [

                    {
                        field: 'dimensionName',
                        name: $translate.instant('RoleDimensionTitle'), //角色维度
                        width: '20%',
                        cellTemplate: '<div  class="text-align-left-padding" ><span>{{row.entity.dimensionName  }}</span></div>'
                    }, {
                        field: 'role',
                        name: $translate.instant('DimensionName'), //维度名称
                        width: '20%',
                        cellTemplate: '<div ng-if="!row.entity.isDeleted" class="text-align-left-padding"  id="{{row.entity.userID}}"  aria-hidden="true" ><span title="{{row.entity.dimensionValueName}}">{{row.entity.dimensionValueName  }}</span></div>\
                                           <div ng-if="row.entity.isDeleted" class="text-align-left-padding"  id="{{row.entity.userID}}"  aria-hidden="true" ><select class="extra-select" ng-options="item.value for item in row.entity.extraOptions" ng-model="row.entity.extraSelected" ng-change="grid.appScope.extraRowSelectionChanged(row)"></select></div>'

                    }, {
                        field: 'Role',
                        name: $translate.instant('Role'), //角色
                        width: '40%',
                        cellTemplate: '<div ng-if="!row.entity.isExtraRole" class="text-align-left-padding"  id="{{row.entity.id}}"  aria-hidden="true" ><span title="{{row.entity.roleNameList}}">{{row.entity.roleNameList | limitString:22 }}</span></div>\
                                       <div ng-if="row.entity.isExtraRole"  class="text-align-left-padding"  id="{{row.entity.id}}"  aria-hidden="true" ng-click="grid.appScope.showRoleCard(row)"><span title="{{row.entity.roleNameList}}">{{row.entity.roleNameList | limitString:22 }}</span><select class="extra-select icon-right" ></select></div>'
                    }, {
                        field: 'Setting',
                        name: $translate.instant('Setting'), //设置
                        cellTemplate: '<div class="text-align-left-padding" ng-click="grid.appScope.rowUpdate(row.entity)"> <span title="{{row.entity.isHeritableStr}}" ng-if="!row.entity.isDeleted"><input type="checkbox" ng-model="row.entity.isHeritable">{{row.entity.isHeritableStr  }}</span>\
                                <span ng-if="row.entity.isDeleted" ><i class="material-icons button-icons icon-delete">delete</i></span></div>',
                        width: '20%',
                    }

                ],

                onRegisterApi: function(gridApi) {

                    $scope.userGridApi = gridApi;

                    $scope.gridSelectCount = $scope.userGridApi.selection.getSelectedRows().length;

                    // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                    $interval(function() {
                        $scope.userGridApi.core.handleWindowResize();
                    }, 500, 60 * 60 * 8);

                }
            };
        };

        (function initialize() {
            $log.debug('addExistUserModalController.ctor()...');

            userUIGridInit();
            loadRoleTree();
            // showModal();
        })();
    }
]);

commonModule.directive('userOrganizationAccessModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('addExistUserModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/user-organization-access-modal/user-organization-access-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'userOrganizationAccessModalController',
            scope:
            {
                operateType: '=',
                isUpdate: '=?',
                userId: '=?',
                organizationId:'=?'

            },
            link: function (scope, element) {

                var rolecardSelector = '.assign-role-box';
                $(rolecardSelector).draggable({ containment: "parent", cursor: "cursor" });
                $(rolecardSelector).on("click", function (e) {
                    e.stopPropagation();
                });


                //element.on('click', ':not(.text-align-left-padding)', function () {
                //    $(rolecardSelector).css('display', 'none');
                //    //stopPropagation();
                //});
            }
        };
    }
]);
commonModule.
controller('vatOperateLogController', ['$scope', '$log', '$translate', 'uiGridConstants', '$location', '$timeout', '$interval', 'vatOperationLogService', '$filter', 'enums',
    function ($scope, $log, $translate, uiGridConstants, $location, $timeout, $interval, vatOperationLogService, $filter, enums) {
        
        var commonTitle = {
            logType: "OperationContent",
            logOperateObject: "LogOperateObject",
            logOriginalState: "LogOriginalState",
            logUpdateState: "LogUpdateState",
            logOperationDescription: "LogOperationDescription",
            logOperationUser: "LogOperationUser",
            logOperationTime: "LogOperationTime",
            logOperationOID: "LogOperationOID",
            logOperationIP: "LogOperationIP",
            logComments: 'LogComments'
        };

        //点击任意一页事件
        var load_page = function(pageIndex) {
            getLogs(pageIndex);
        };

        //获取vat日志记录
        var getLogs = function(pageIndex) {
            $scope.InitPagination();
            $scope.curPage = pageIndex;
            $scope.paginInfo = {
                totalCount: $scope.queryResult.pageInfo.totalCount,
                pageIndex: pageIndex,
                pageSize: $scope.queryResult.pageInfo.pageSize
            };

            var model = {};
            model.pageInfo = $scope.paginInfo;
            model.period = $scope.period;
            model.queryValue = $scope.searchText;
            model.moduleID = $scope.moduleType;
            model.userId = $scope.userId;

            vatOperationLogService.getOperationLogList(model).success(function (data) {
                if (data != '') {
                    if (data && data.pageInfo && data.pageInfo.totalCount > 0) {
                        var i = model.pageInfo.pageSize * (model.pageInfo.pageIndex - 1) + 1;
                        data.list.forEach(function(row) {
                            row.index = i++;
                            row.createTime = $filter('date')(row.createTime, 'yyyy-MM-dd HH:mm');
                            row.operationObject = $translate.instant(row.operationObject);

                            row.comment = $translate.instant(row.comment);
                            row.operationContent = $translate.instant(row.operationContent);
                            //row.action = actionMap[row.action];
                            row.originalState = $translate.instant(row.originalState);
                            row.updateState = $translate.instant(row.updateState);
                           
                        });
                        $scope.operateLogGridOptions.data = data.list;
                        $scope.queryResult = data;
                        computeTotalPage();
                    } else {
                        $scope.operateLogGridOptions.data = data.list;
                        $scope.queryResult = data;
                        computeTotalPage();
                    }
                }
            });
        };

        var computeTotalPage = function() {

            if ($scope.queryResult.pageInfo && $scope.queryResult.pageInfo.totalCount > 0) {

                var totalPage = parseInt($scope.queryResult.pageInfo.totalCount / $scope.queryResult.pageInfo.pageSize);
                totalPage = $scope.queryResult.pageInfo.totalCount % $scope.queryResult.pageInfo.pageSize == 0 ? totalPage : totalPage + 1;

                $scope.queryResult.pageInfo.totalPage = totalPage;
                $scope.creatPage = $(".tcdPageCode").createPage({
                    pageCount: totalPage,
                    current: $scope.curPage,
                    backFn: function(p) {
                        //单击回调方法,p是当前页码
                        getLogs(p);
                    }
                });
                $('.tcdPageCode').css('display', 'inline-block');
            } else {
                $scope.creatPage = $(".tcdPageCode").createPage({
                    pageCount: 0,
                    current: $scope.curPage,
                    backFn: function(p) {
                        //单击回调方法,p是当前页码
                        getLogs(p);
                    }
                });
                $('.tcdPageCode').css('display', 'inline-block');
            }
        };

        var prePage = function() {
            if ($scope.curPage > 1) {
                $scope.curPage--;
            }
            getLogs($scope.curPage);
        };

        var nextPage = function() {
            if ($scope.curPage < $scope.queryResult.pageInfo.totalPage) {
                $scope.curPage++;
            }
            getLogs($scope.curPage); 
        };

        var normalDataGridOptions = function() { 
            $scope.operateLogGridOptions = {
                rowHeight: 45,
                selectionRowHeaderWidth: 45,
                enableFullRowSelection: true,
                enableRowSelection: true,
                enableColumnResizing: true,
                enableSorting: false,
                enableFiltering: false,
                enableColumnMenus: false,
                enableRowHeaderSelection: false,
                multiSelect: false,
                enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
                columnDefs: [{
                        
                        name: $translate.instant('LogIndex'),
                        width: '8%',
                        headerCellClass: 'header-cell-class',
                        cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.index}}">{{row.entity.index}}</span></div>'
                    }, {
                       
                        name: $translate.instant(commonTitle.logOperationTime),
                        width: '14%',
                        headerCellClass: 'header-cell-class',
                        cellTemplate: '<div class="ui-grid-cell-contents"><span>{{row.entity.createTime}}</span></div>'
                    }, {
                       
                        name: $translate.instant(commonTitle.logOperateObject),
                        width: '15%',
                        headerCellClass: 'header-cell-class',
                        cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.operationObject}}">{{row.entity.operationObject}}</span></div>'
                    },
                     {
                         name: $translate.instant(commonTitle.logOperationDescription),
                         width: '8%',
                         headerCellClass: 'header-cell-class',
                         cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.operationTypeName}}">{{row.entity.operationTypeName}}</span></div>'
                     },
                    {
                        name: $translate.instant(commonTitle.logType),
                        width: '13%',
                        headerCellClass: 'header-cell-class',
                        cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.operationContent}}">{{row.entity.operationContent}}</span></div>'
                    },                   
                    {
                        name: $translate.instant(commonTitle.logOriginalState),
                        width: '11%',
                        headerCellClass: 'header-cell-class',
                        cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.originalState}}">{{row.entity.originalState}}</span></div>'
                    }, { 
                        name: $translate.instant(commonTitle.logUpdateState),
                        width: '11%',
                        headerCellClass: 'header-cell-class',
                        cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.updateState}}">{{row.entity.updateState}}</span></div>'
                    },

                    { 
                        name: $translate.instant(commonTitle.logOperationUser),
                        width: '10%',
                        headerCellClass: 'header-cell-class',
                        cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.userName}}">{{row.entity.userName}}</span></div>'
                    }, { 
                        name: $translate.instant(commonTitle.logComments),
                        width: '10%',
                        headerCellClass: 'header-cell-class',
                        cellTemplate: '<div class="ui-grid-cell-contents"><span title="{{row.entity.comment}}">{{row.entity.comment}}</span></div>'
                    }

                ],
                onRegisterApi: function(gridApi) {
                    $scope.gridApi = gridApi;

                    // call resize every 500 ms for 5 s after modal finishes opening - usually only necessary on a bootstrap modal
                    $interval(function() {
                        $scope.gridApi.core.handleWindowResize();
                    }, 500, 60 * 60 * 8);
                }
            };
        };

        $scope.$watch('isShow', function(newValue, oldValue) {
            if (newValue) {
                load_page(1);
                $('#showOperatePop').modal('show');
            }
        });

        $scope.closeModal = function () {
            $scope.isShow = false;
        }; 

        $scope.InitData = function () {
            $scope.logTitle = $translate.instant('Logtitle') + $translate.instant(enums.vatModuleNameDic[$scope.moduleType]);
            $scope.searchText = '';
        }

        $scope.InitPagination = function () {          
            $scope.queryResult = {
                list: [],
                pageInfo: {
                    totalCount: -1,
                    pageIndex: 1,
                    pageSize: 100,
                    totalPage: 0,
                }
            }
            $scope.curPage = 1;
        };

        (function initialize() {
            $log.debug('operateLogController.ctor()...');
            $scope.InitData();
            $scope.InitPagination();
            normalDataGridOptions();

            $scope.load_page = load_page;

        })();
    }
]);

commonModule.directive('vatOperateLog', ['$log',
    function ($log) {
        'use strict';
        $log.debug('vatOperateLog.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/vat-operate-log/vat-operate-log.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'vatOperateLogController',
            scope:
            {
                period: '=',
                moduleType: '=',
                isShow: '=',
                userId: '=?'
            }           
        };
    }
]);
commonModule.controller('vatParentCodeModalController', ['$scope', '$log', '$translate', '$timeout', 'apiInterceptor', 'Upload', 'dataImportService', 'SweetAlert', '$q', 'uiGridConstants', 'projectService', 'uiGridGroupingConstants', 'vatImportService', 'i18nService', 'browserService', '$interval', 'region', 'vatSessionService',
    function ($scope, $log, $translate, $timeout, apiInterceptor, Upload, dataImportService, SweetAlert, $q, uiGridConstants, projectService, uiGridGroupingConstants, vatImportService, i18nService, browserService, $interval, region, vatSessionService) {
        'use strict';

        $scope.subjectNames = [];
        $scope.selectedSubjectCodes = ["", "资产", "负债", "共同", "权益", "成本", "损益", "其他"];

        $scope.$watch('isShow', function (newValue, oldValue) {
            if (newValue) {
                $('#showParentCodePop').modal('show');
            } else {
                $('#showParentCodePop').modal('hide');
            }
        });

        $scope.$watch('isUncheckedAll', function (newValue, oldValue) {
            if (newValue) {
                $scope.gridApi.selection.clearSelectedRows();
                $scope.selectedSubjectCodes = [];
            } 
        });

        $scope.closeModal = function () {
            $scope.isShow = false;
        };

        $scope.cancelModal = function () {

        };

        // $scope.confirmedRecords = [];

        $scope.cancelModal = function () {
            $scope.isShow = false;

            $scope.onCancelSelection();
        };

        $scope.getSelectedCodes = function () {
            $scope.selectedSubjectCodes = [];
            var selectedCodeRecords = $scope.gridApi.selection.getSelectedRows();
            selectedCodeRecords.forEach(function (item) {
                if (item.subjectCode.length > 0)
                    $scope.selectedSubjectCodes.push(item);
            });

            $scope.onConfirmSelection({ confirmedRecords: $scope.selectedSubjectCodes });
            $scope.isShow = false;

        };




        // ************************************************************************************************
        // SETUP UI GRID TREE:
        var treeData;

        // 国际化;
        // i18nService.setCurrentLang("zh-cn");

        $scope.parentCodePopOptions = {
            rowHeight: 40,
            showGridFooter: false,
            showColumnFooter: false,
            selectionRowHeaderWidth: 30,
            enableFullRowSelection: false,
            enableRowSelection: true,
            enableSorting: false,
            enableFiltering: false,
            enableColumnMenus: false,
            enableRowHeaderSelection: true,
            multiSelect: true,
            enableHorizontalScrollbar: uiGridConstants.scrollbars.NEVER,
            showTreeExpandNoChildren: false,
            enableGridMenu: false,
            enableSelectAll: true,
            onRegisterApi: function (gridApi) {
                $scope.gridApi = gridApi;

                $scope.gridApi.selection.on.rowSelectionChanged($scope, function (row) {

                    if (row.treeNode.children.length > 0 && row.isSelected == true) {
                        var childRows = row.treeNode.children;
                        for (var j = 0, length = childRows.length; j < length; j++) {
                            var rowEntity = childRows[j].row.entity;
                            $scope.gridApi.selection.selectRow(rowEntity);
                        }
                    }

                    if (row.treeNode.children.length > 0 && row.isSelected == false) {
                        var childRows = row.treeNode.children;
                        for (var j = 0, length = childRows.length; j < length; j++) {
                            var rowEntity = childRows[j].row.entity;
                            $scope.gridApi.selection.unSelectRow(rowEntity);
                        }
                    }

                });

                //$interval(function () {
                //    $scope.gridApi.core.handleWindowResize();
                //}, 500, 60 * 60 * 8);
            },

            columnDefs: [
            {
                field: 'subjectCode', name: $translate.instant('AccountCode'),
                cellTemplate:
                '<div ng-if="row.entity.$$treeLevel==0" class=""><span>{{row.entity.subjectCode}}<span></div>' +
                          '<div ng-if="row.entity.$$treeLevel==1" class="text-align-left-padding"><span>&nbsp;&nbsp;{{row.entity.subjectCode}}<span></div>' +
                          '<div ng-if="row.entity.$$treeLevel==2" class="text-align-left-padding"><span>&nbsp;&nbsp;&nbsp;&nbsp;{{row.entity.subjectCode}}<span></div>' +
            '<div ng-if="row.entity.$$treeLevel==3" class="text-align-left-padding"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{row.entity.subjectCode}}<span></div>' +
    '<div ng-if="row.entity.$$treeLevel==4" class="text-align-left-padding"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{row.entity.subjectCode}}<span></div>'
            },
            {
                field: 'subjectName', width: 220, name: $translate.instant('AccountName'),

                cellTemplate: '<div class=""><span title={{row.entity.subjectName}}>{{row.entity.subjectName | limitString:25}}<span></div>'

            }
            ,
            {
                field: 'direction', width: 80, name: $translate.instant('SubjectDirectionCol'),

                cellTemplate: '<div class=""><span>{{row.entity.direction}}<span></div>'

            },
            {
                field: 'acctProp', width: 80, name: $translate.instant('SubjectTypeCol'),

                cellTemplate: '<div class=""><span>{{row.entity.acctProp}}<span></div>'

            }

            ]
        };
        // SETUP UI GRID TREE:
        // ************************************************************************************************
        function increaseTreeLevelGroup(group) {
            group.forEach(function (item) {
                // item.parentCode = 'A';
                increaseTreeLevel(item);
            });
        }

        function increaseTreeLevel(item) {
            item.$$treeLevel++;
            if (angular.isArray(item.children) && item.children.length > 0) {
                item.children.forEach(function (chiild) {
                    increaseTreeLevel(chiild);
                });
            }
        }

        $scope.$watch('uBackendData', function (newValue, oldValue) {
            if (newValue === oldValue && typeof (newValue) != "undefined") {
                $scope.getSubjectDataFromDatabase(newValue);
            }
        });

        $scope.$watch('uList', function (newV, oldV) {
            if (newV !== oldV) {

                var subjectNewTree;
                var subjectNewTrees = [];
                newV.forEach(function (item) {
                    subjectNewTree = item;
                    subjectNewTree.acctProp = $scope.selectedSubjectCodes[item.acctProp];
                    subjectNewTrees.push(subjectNewTree);
                });

                $scope.parentCodePopOptions.data = subjectNewTrees;
                /*
                var headerItems=[];
                var headerItem;
                
            

                // add header name to data BEGIN:
                var group_1 = newV.filter(function (o) {
                    return o.acctProp === "1";
                });

                increaseTreeLevelGroup(group_1);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[资产]";
               

                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_1);


                //2:
                var group_2 = newV.filter(function (o) {
                    return o.acctProp === "2";
                });

                increaseTreeLevelGroup(group_2);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[负债]";
                

                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_2);

                //3
                var group_3 = newV.filter(function (o) {
                    return o.acctProp === "3";
                });

                increaseTreeLevelGroup(group_3);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[共同]";
                

                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_3);

                //4
                var group_4 = newV.filter(function (o) {
                    return o.acctProp === "4";
                });

                increaseTreeLevelGroup(group_4);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[权益]";
                

                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_4);

                //5
                var group_5 = newV.filter(function (o) {
                    return o.acctProp === "5";
                });

                increaseTreeLevelGroup(group_5);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[成本]";
               

                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_5);
                //6
                var group_6 = newV.filter(function (o) {
                    return o.acctProp === "6";
                });

                increaseTreeLevelGroup(group_6);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[损益]";
                

                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_6);
                //7
                var group_7 = newV.filter(function (o) {
                    return (o.acctProp !== "1" && o.acctProp !== "2" && o.acctProp !== "3" && o.acctProp !== "4" && o.acctProp !== "5" && o.acctProp !== "6");
                });

                increaseTreeLevelGroup(group_7);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[其他]";
                

                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_7);


                // add header name to data END;
                $scope.parentCodePopOptions.data = headerItems;
                console.log(group_1);
                */
            }
        });



        // ************************************************************************************************
        // ************************************************************************************************
        // ************************************************************************************************
        // function to get data subjectFrom Backend
        $scope.getSubjectDataFromDatabase = function (subjectCategory) {
            //  vatImportService.getBalanceDataForDisplay(subjectCategory, subjectFrom, subjecTo, "").success(function (subjectxData) {
            vatImportService.getParentCodesForDisplay(subjectCategory).success(function (subjectxData) {

                var subjectTreeData = JSON.parse(subjectxData);
                writeoutSubjectNode(subjectTreeData, 0, newTree);

                var subjectNewTree;
                var subjectNewTrees = [];
                var debit = $translate.instant('AccountVoucher_Direction_Debit'), credit = $translate.instant('AccountVoucher_Direction_Credit');

                newTree.forEach(function (item) {
                    subjectNewTree = new Object();
                    subjectNewTree.$$treeLevel = item.$$treeLevel;
                    subjectNewTree.subjectCode = item.accountCode;
                    subjectNewTree.subjectName = item.accountName;
                    subjectNewTree.acctProp = $scope.selectedSubjectCodes[item.acctProp];
                    subjectNewTree.direction = item.direction === "1" ? debit : credit;
                    // subjectNewTree.category=
                    subjectNewTrees.push(subjectNewTree);
                });

                $scope.parentCodePopOptions.data = subjectNewTrees;
                /*
                var headerItems = [];
                var headerItem;

                var newV = subjectNewTrees;
                // add header name to data BEGIN:
                var group_1 = newV.filter(function (o) {
                    return o.acctProp === "1";
                });

                increaseTreeLevelGroup(group_1);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[资产]";


                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_1);


                //2:
                var group_2 = newV.filter(function (o) {
                    return o.acctProp === "2";
                });

                increaseTreeLevelGroup(group_2);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[负债]";


                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_2);

                //3
                var group_3 = newV.filter(function (o) {
                    return o.acctProp === "3";
                });

                increaseTreeLevelGroup(group_3);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[共同]";


                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_3);

                //4
                var group_4 = newV.filter(function (o) {
                    return o.acctProp === "4";
                });

                increaseTreeLevelGroup(group_4);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[权益]";


                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_4);

                //5
                var group_5 = newV.filter(function (o) {
                    return o.acctProp === "5";
                });

                increaseTreeLevelGroup(group_5);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[成本]";


                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_5);
                //6
                var group_6 = newV.filter(function (o) {
                    return o.acctProp === "6";
                });

                increaseTreeLevelGroup(group_6);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[损益]";


                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_6);
                //7
                var group_7 = newV.filter(function (o) {
                    return (o.acctProp !== "1" && o.acctProp !== "2" && o.acctProp !== "3" && o.acctProp !== "4" && o.acctProp !== "5" && o.acctProp !== "6");
                });

                increaseTreeLevelGroup(group_7);
                headerItem = {};

                headerItem.$$treeLevel = 0;
                headerItem.subjectCode = "";
                headerItem.subjectName = "[其他]";


                headerItems.push(headerItem);
                headerItems = headerItems.concat(group_7);
               

                // add header name to data END;
                $scope.parentCodePopOptions.data = headerItems;
                 */
            });
        };
        // function to get data subjectFrom Backend
        // ************************************************************************************************



        // ************************************************************************************************
        // Write UI GRID TREE NOTES:
        var newTree = [];
        var id = "0";
        var writeoutSubjectNode = function (childArray, currentLevel, dataSubjectArray) {
            childArray.forEach(function (childNode) {
                if (childNode.children.length > 0) {
                    childNode.$$treeLevel = currentLevel;
                    id = childNode.accountCode;
                }
                else {
                    childNode.$$treeLevel = currentLevel;
                }
                dataSubjectArray.push(childNode);
                writeoutSubjectNode(childNode.children, currentLevel + 1, dataSubjectArray);
            });
        };
        // Write UI GRID TREE NOTES:
        // ************************************************************************************************
        // ************************************************************************************************
        // ************************************************************************************************
        //开始
        (function initialize() {

        })();
    }
]);
commonModule.directive('vatParentCodeModal', ['$log',
    function ($log) {
        'use strict';
        $log.debug('vatParentCodeModal.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/vat-parent-code-modal/vat-parent-code-modal.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'vatParentCodeModalController',
            scope:
            {
                uList: '=',
                uBackendData: '=',
                onConfirmSelection: '&',
                onCancelSelection: '&',
                isShow: '=',
                isUncheckedAll: '='
            }
        };
    }
]);
commonModule.controller('workflowNodeController', ['$scope', '$log', '$translate', '$timeout', 'apiInterceptor', 'Upload', 'dataImportService', 'SweetAlert', '$q', 'uiGridConstants', 'projectService', 'uiGridGroupingConstants', 'vatImportService', 'i18nService', 'browserService', '$interval', 'region', 'vatSessionService', 'vatCommonService', 'enums','vatWorkflowService',
    function ($scope, $log, $translate, $timeout, apiInterceptor, Upload, dataImportService, SweetAlert, $q, uiGridConstants, projectService, uiGridGroupingConstants, vatImportService, i18nService, browserService, $interval, region, vatSessionService, vatCommonService, enums, vatWorkflowService) {
        'use strict';



        var defaultTaskes = [
            {
                "key": "DataImport",
                "taskes": [{
                    "hasPermission":true,
                    "taskName": "数据预览",
                    "taskUrl": "#/vat/previewData",
                    "taskIsActive": true,
                    "taskIsDone": false,
                    "taskAllowUserToUpdate": true,
                    "orgID": ""


                }]
            }
            , {
                "key": "DataProcess",
                "taskes": [{
                    "hasPermission": true,
                    "taskName": "查看未开票销售",
                    "taskUrl": "#/vat/reductionData/unbilledInvoice",
                    "taskIsActive": true,
                    "taskIsDone": false,
                    "taskAllowUserToUpdate": true,
                    "orgID": ""


                }]
            }

            , {
                "key": "ViewReport",
                "taskes": [
                    {
                    "hasPermission": true,
                    "taskName": "查看财务报表",
                    "taskUrl": "#/vat/generateReport",
                    "taskIsActive": true,
                    "taskIsDone": false,
                    "taskAllowUserToUpdate": true,
                    "orgID": ""


                },
                {
                    "hasPermission": true,
                    "taskName": "查看纳税申报表",
                    "taskUrl": "#/vat/generateReport",
                    "taskIsActive": true,
                    "taskIsDone": false,
                    "taskAllowUserToUpdate": true,
                    "orgID": ""
                }]
            }

             , {
                 "key": "ApproveReport",
                 "taskes": [{
                     "hasPermission": true,
                     "taskName": "查看财务报表",
                     "taskUrl": "#/vat/generateReport",
                     "taskIsActive": true,
                     "taskIsDone": false,
                     "taskAllowUserToUpdate": true,
                     "orgID": ""


                 }
                 , {
                     "hasPermission": true,
                     "taskName": "查看纳税申报表",
                     "taskUrl": "#/vat/generateReport",
                     "taskIsActive": true,
                     "taskIsDone": false,
                     "taskAllowUserToUpdate": true,
                     "orgID": ""


                 }]
             }
              , {
                  "key": "DeclarationComplete",
                  "hasPermission": true,
                  "taskes": [{
                      "taskName": "查看财务报表",
                      "taskUrl": "#/vat/generateReport",
                      "taskIsActive": true,
                      "taskIsDone": false,
                      "taskAllowUserToUpdate": true,
                      "orgID": ""


                  }
                  , {
                      "hasPermission": true,
                      "taskName": "查看纳税申报表",
                      "taskUrl": "#/vat/generateReport",
                      "taskIsActive": true,
                      "taskIsDone": false,
                      "taskAllowUserToUpdate": true,
                      "orgID": ""
                  }]
              }];
        

        $scope.$watch('isShow', function (newValue, oldValue) {
            if (newValue) {
                $('#showParentCodePop').modal('show');
            } else {
                $('#showParentCodePop').modal('hide');
            }
        });

      
        $scope.$watch('uStep', function (newValue, oldValue) {
    
            if (newValue !== undefined) {
                $scope.currentStep = newValue;
            }
        });

        $scope.$watch('uOrg', function (newValue, oldValue) {

            if (newValue !== undefined) {
                $scope.organization = newValue;
            }
        });
        


        var PREV_NODE_STATUS=true;
        $scope.$watch('uList', function (newV, oldV) {
            if (newV !== undefined) {

                var currentOrg = $scope.organization;
                var currentStep=$scope.currentStep

                // Check if all Mandatory taskes are all completed in the Previous Node
                var preViousNodeHasAllMandatoryTaskesCompleted = true;

                if (currentStep > 1) {
                    var previousWorkflow = newV.filter(function (wf) {
                        return wf.orderIndex === (currentStep - 1);
                    });
                    previousWorkflow = previousWorkflow[0];

                    if (previousWorkflow !== undefined && previousWorkflow !== null) {
                        if (previousWorkflow.isDone !== null && previousWorkflow.isDone === true) {
                            preViousNodeHasAllMandatoryTaskesCompleted = true;

                        }
                        else
                        {
                            var isAllCompleted = true;
                            previousWorkflow.workflowTaskList.forEach(function (task) {
                                if (task.isActive && task.isMandatory) {
                                    if (task !== null && task.isDone !== true)
                                        isAllCompleted = false;
                                }
                            });
                            preViousNodeHasAllMandatoryTaskesCompleted = isAllCompleted;
                            PREV_NODE_STATUS = isAllCompleted;
                        }
                    }
                    else
                        preViousNodeHasAllMandatoryTaskesCompleted = PREV_NODE_STATUS;

                }


                //Get the current Step (there are step 1,2,3,4,5)
                var currentWorkflow = newV.filter(function (wf) {
                    return wf.orderIndex === currentStep;
                });

                // Current Node
                var workFlowNodes = [];
                var workflowNode;
                currentWorkflow.forEach(function (thisNode) {
                    workflowNode = new Object();
                    workflowNode.hasPermission = thisNode.hasPermission;
                    workflowNode.nodeName = thisNode.dictionaryValue;
                    workflowNode.nodeIsActive = thisNode.isActive /*||( previousWorkflow!== undefined && !previousWorkflow.isActive) */;
                    workflowNode.nodeIsDone = thisNode.isDone;
                    workflowNode.nodeIsClickable = preViousNodeHasAllMandatoryTaskesCompleted;
                    workflowNode.nodeDoneBy = thisNode.doneBy;
                    workflowNode.nodeDoneOn = (thisNode.doneOn !== null) ? thisNode.doneOn : "";

                    //disable if no taskes:
                    if (thisNode.workflowTaskList.length === 0 || (currentStep > 1 && PREV_NODE_STATUS === false))
                        workflowNode.nodeIsClickable = false;
                
                    // Current Taskes
                    var task;
                    var taskes = [];


                    var defaultTaskesForThisNode = _.find(defaultTaskes, function (defaultTask) { return defaultTask.key === thisNode.dictionaryKey });
                    //*****************************************************************
                    //***************  Add default task for everyone: Add to the Top               
                    if (defaultTaskesForThisNode !== undefined && (defaultTaskesForThisNode.key === "ViewReport" || defaultTaskesForThisNode.key === "ApproveReport" || defaultTaskesForThisNode.key === "DeclarationComplete")) {
                        defaultTaskesForThisNode.taskes.forEach(function (dTask) {
                            task = new Object();
                            task.hasPermission = dTask.hasPermission;
                            task.taskName = dTask.taskName;
                            task.taskUrl = dTask.taskUrl;
                            task.taskIsActive = dTask.taskIsActive;
                            task.taskIsDone = dTask.taskIsDone;
                            task.taskAllowUserToUpdate = dTask.taskAllowUserToUpdate;
                            task.orgID = currentOrg.organizationID;

                            taskes.push(task);
                        });
                    }
                    //***************  Add default task for everyone: Add to the Top
                    //*****************************************************************
                    var noDuplication=true;

                    thisNode.workflowTaskList.forEach(function (item) {
                        task = new Object();
                        task.hasPermission = item.hasPermission;
                        task.taskName = item.dictionaryValue;
                        task.taskUrl = item.vatLink;
                        task.taskIsActive = item.isActive;
                        task.taskIsDone = item.isDone;
                        task.taskAllowUserToUpdate = (item.dictionaryKey === "WFReportApproval") ? false : true; // a label,not button. in step 4 (审核报表)
                        task.reportApprovalStatus = item.reportApprovalStatus;
                        task.reportApprovedNumber = item.reportApprovedNumber;
                        task.orgID = currentOrg.organizationID;
                        task.isMandatory = item.isMandatory;

                        // remove 审核报表 duplications
                        if (item.dictionaryKey !== "WFReportApproval" || (item.dictionaryKey === "WFReportApproval" && noDuplication)) {
                            taskes.push(task);
                            noDuplication = false;
                        }

                    });

                    //*****************************************************************
                    //***************  Add default task for everyone: Add to the Bottom
                  
                    if (defaultTaskesForThisNode !== undefined && (defaultTaskesForThisNode.key === "DataImport" || defaultTaskesForThisNode.key === "DataProcess")) {
                        defaultTaskesForThisNode.taskes.forEach(function (dTask) {
                            task = new Object();
                            task.hasPermission = dTask.hasPermission;
                            task.taskName = dTask.taskName;
                            task.taskUrl = dTask.taskUrl;
                            task.taskIsActive = dTask.taskIsActive;
                            task.taskIsDone = dTask.taskIsDone;


                            task.taskAllowUserToUpdate = dTask.taskAllowUserToUpdate;
                            task.orgID = currentOrg.organizationID;

                            taskes.push(task);
                        });
                    }
                    //***************  Add default task for everyone: Add to the Bottom
                    //*****************************************************************
                    

                    workflowNode.taskes = taskes;
                    workFlowNodes.push(workflowNode);
                });

                $scope.workflowNode = workFlowNodes[0];

            }
        });



        $scope.jumpToPage = function (task) {
            var orgID= task.orgID;
            var url = task.taskUrl;

            if (url !== undefined) {
                var allProjects = vatSessionService.projects;
                var project = _.find(allProjects, function (project) { return (project.organizationID === orgID && project.year === vatSessionService.year && project.serviceTypeID === "2" && vatSessionService.month >= project.startPeriod && vatSessionService.month <= project.endPeriod) });

                if (project.haveCreateProject) {
                    if (_.isUndefined(project.projectStatusList[vatSessionService.month])) { //如果当前期间还没有导入任何数据的话,就添加一条未开始状态的记录
                        projectService.setProjectStatus(project.dbName, vatSessionService.month, constant.ProjectStatusEnum.UnStarted)
                          .success(function (or) {
                              if (or.result) {
                                  //添加完成后,在vatSessionService.project中添加新加入的数据
                                  project.projectStatusList[vatSessionService.month] = constant.ProjectStatusEnum.UnStarted;
                              }
                          });
                    }

                    vatSessionService.project = project;
                    //vatSessionService.reset();

                    if (url === "#_voucherModal") {
                        $scope.onClickVoucher({ isVoucherModalShow: true });
                    }
                    else if (url === "#_completedTaxFiling") {
                        $scope.declarationComplete(enums.vatLogOperationTypeEnum.ApproveReport);
                    }

                    else {
                        setTimeout(function () {
                            window.location.href = url;
                        }, 200);
                        
                    }
                }
                else {
                    projectService.addProject(project).success(function (rsp) {
                        if (rsp && rsp.result) {
                            project.haveCreateProject = true;
                            project.dbName = rsp.resultMsg;
                            vatSessionService.project = project;
                           

                            setTimeout(function () {
                                window.location.href = url;
                            }, 200);
                        }
                    });
                }
            }
        };


        //enums.vatLogOperationTypeEnum.SubmitReport
        //申报完成
        $scope.declarationComplete = function (operationTypeId) {
            if (
                vatSessionService.project.projectStatusList[vatSessionService.month] >= constant.ProjectStatusEnum.Generated &&
                vatSessionService.project.projectStatusList[vatSessionService.month] !== constant.ProjectStatusEnum.ReportRejected) {
                swal({
                    title: "warning!",
                    text: $translate.instant('IsConfirmToCompleteDeclaration'),
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonColor: "#DD6B55",
                    confirmButtonText: $translate.instant('Yes'),
                    cancelButtonText: $translate.instant('No'),
                    closeOnConfirm: true,
                    closeOnCancel: true
                },
                    function (isConfirm) {
                        if (isConfirm) {
                          //  setApproveValue(operationTypeId);

                            projectService.setProjectStatus(vatSessionService.project.dbName, vatSessionService.month, constant.ProjectStatusEnum.Completed)
                                .success(function (r1) { //设置项目状态
                                    if (!r1.result) { return false; }
                                  //  $rootScope.$broadcast('statusChanged', { status: constant.ProjectStatusEnum.Completed });
                                    vatSessionService.project.projectStatusList[vatSessionService.month] = constant.ProjectStatusEnum.Completed;
                                    vatWorkflowService.setProcessLog(constant.ProjectStatusEnum.Completed, vatSessionService.project.dbName, vatSessionService.month, constant.DictionaryDictKey.WFDeclarationComplete, enums.FinishStatusEnum.Finished)
                                        .success(function (r2) { //更新WorkflowTaskLog记录
                                            //if (!r2.result) { return false; }
                                            //vatWorkflowService.addApproveReportLog($scope.approveReportLogDto)
                                            //    .success(function (r3) { //添加WorkflowApproveReportLog记录
                                            //        if (!r3.result) { return false; }
                                            //        vatWorkflowService.getWorkflowDetailByDb(vatSessionService.project.dbName, vatSessionService.month)
                                            //            .success(function (r4) { //获取Workflow详细内容                      
                                            //                if (r4.result) {
                                            //                    vatSessionService.project.workflow = r4.data;
                                            //                    $log.debug("$scope.declarationComplete : workflowData.result");
                                            //                    $log.debug(vatSessionService.project.workflow);
                                            //                    //setCompleteBtShow();
                                            //                }
                                            //            })
                                            //    })
                                        })
                                });
                        } else {
                            swal.close();
                        }
                    });
            } else {

                SweetAlert.warning($translate.instant('CompleteDeclarationStatusCheck'));
            }
        };

        

        //开始
        (function initialize() {

        })();
    }
]);
commonModule.directive('workflowNode', ['$log',
    function ($log) {
        'use strict';
        $log.debug('workflowNode.ctor()...');

        return {
            restrict: 'E',
            templateUrl: '/app/common/controls/workflow-node/workflow-node.html' + '?_=' + Math.random(),
            replace: true,
            controller: 'workflowNodeController',
            scope:
            {
                uStep: '=',
                uOrg:'=',
                uList: '=',
                onClickVoucher: '&',
                //onCancelSelection: '&',
                isShow: '='
            }
        };
    }
]);
commonModule.filter('dateFormat', function () {
    return function (str, format) {
        //_.isEmpty(str) && 
        if (_.isFunction(moment)) {
            return moment(str).format(format);
        }
        return '';
    }

});
commonModule.filter('limitString', function () {
    return function (str, maxLength) {
        //_.isEmpty(str) && 
        if (str != '' && str != undefined && str != null) {
            var apostrophe = '...';
            var twoChar = 'mm';
            var r = /[^\x00-\xff]/g;
            if (str.replace(r, twoChar).length <= maxLength) { return str; }
            var m = Math.floor(maxLength / 2);
            for (var i = m; i < str.length; i++) {
                if (str.substr(0, i).replace(r, twoChar).length >= maxLength) {
                    return str.substr(0, i) + apostrophe;
                }
            }
            return str;
        }
    }

});

commonModule.filter("statusFilter", ["enums", function () {
    'use strict';
    var filterfun = function (status, statusList) {
        var statusText = status, statusDic;
        if (statusList) {
            statusDic = _.findWhere(statusList, { value: status + '' });
        }
        if (statusDic) {
            statusText = statusDic.text;
        }
        return statusText;
    };
    return filterfun;
}]);
commonModule.directive("outsideClick", ['$document', function ($document) {
    return {
        link: function ($scope, $element, $attributes) {
            var scopeExpression = $attributes.outsideClick,
                 ignore = $attributes.ignore
            var onDocumentClick = function (event) {

                var isChild = $element.find(event.target).length > 0 || (ignore ? event.target.id === ignore : false);
                if (!isChild) {
                    $scope.$apply(scopeExpression);
                }
            };

            $document.on("click", onDocumentClick);

            $element.on('$destroy', function () {
                $document.off("click", onDocumentClick);
            });
        }
    }
}]);
//unknown: 0,
//    noCheck: 10,
//checkIn: 20,
//repeatshot: 25,
//examing: 30,
//rpCancel: 40,
//examination: 50,
//draft: 100,
//reject: 105,
//submit: 110,
//firstApprove: 120,
//secondApprove: 130
commonModule.factory('browserService', [function () {
    'use strict';


    function isIE() {
        // Internet Explorer 6-11
        var isIE = /*@cc_on!@*/false || !!document.documentMode;
        return isIE;
    }
    function isEdge() {
        var isIE = /*@cc_on!@*/false || !!document.documentMode;
        // Edge 20+
        var isEdge = !isIE && !!window.StyleMedia;
        return isEdge;
    }
    function isChrome() {
        // Chrome 1+
        var isChrome = !!window.chrome && !!window.chrome.webstore;
        return isChrome;
    }
    function isFirefox() {
        // Firefox 1.0+
        var isFirefox = typeof InstallTrigger !== 'undefined';
        return isFirefox;
    }
    function isOpera() {
        // Opera 8.0+
        var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
        return isOpera;
    }


    return {
        isIE: isIE,
        isEdge: isEdge,
        isChrome: isChrome,
        isFirefox: isFirefox,
        isOpera: isOpera
   
    }
}]);
commonModule.factory('canvasUtil',['$q',function ($q) {
    var dataURLToByteArray = function (dataURL) {
        var BASE64_MARKER = ';base64,';
        if (dataURL.indexOf(BASE64_MARKER) == -1) {
            var parts = dataURL.split(',');
            var contentType = parts[0].split(':')[1];
            var raw = decodeURIComponent(parts[1]);
            return new Blob([raw], { type: contentType });
        }
        var parts = dataURL.split(BASE64_MARKER);
        var contentType = parts[0].split(':')[1];
        var raw = window.atob(parts[1]);
        var rawLength = raw.length;
        var uInt8Array = new Uint8Array(rawLength);
        for (var i = 0; i < rawLength; ++i) {
            uInt8Array[i] = raw.charCodeAt(i);
        }
        //return new Blob([uInt8Array], {type: contentType});
        return uInt8Array;
    };

    var hideElement= function(element)
    {
        var e = document.getElementsByClassName(element);
        for (var i = 0; i < e.length; i++)
        {
            e[i].style.display = 'none';
        }

    };
    var showElement = function (element) {
        var e = document.getElementsByClassName(element);
        for (var i = 0; i < e.length; i++) {
            e[i].style.display = 'block';
        }
    };

    return {
        toBinaryData: function (dom) {
            return dataURLToByteArray(dom.querySelector('canvas').toDataURL());
        },
        saveAsImage: function (name, dom,hiddenElement) {
            hideElement(hiddenElement);
            html2canvas(dom).then(function (canvas) {
                canvas.toBlob(function (blob) {
                    saveAs(blob, name + '.png');
                });
            });
            showElement(hiddenElement);
        },
    };
}]);
// define the constant values
commonModule.constant('constants', {
    guid: {
        empty: '00000000-0000-0000-0000-000000000000'
    },
    tabCeiling: 10,
    pageSize: 20
});
commonModule.factory('dictionaryManager', ['$log', 'configurationService', 'loginContext', '$q', 
    function ($log, configurationService, loginContext, $q) {

        $log.debug('dictionaryManager.ctor()...');

        return {
            getDictionaries: function (dictionaryTag) {
                var deferred = $q.defer();
                configurationService.getDictionaries(loginContext.site).success(function (data) {
                    if (data != null && data.length > 0) {
                        var dictionary = _.findWhere(data, { tag: dictionaryTag });
                        if (dictionary) {
                            deferred.resolve(dictionary.values);
                        }
                    }

                    deferred.reject('Cannot find dictionary value by tag ' + dictionaryTag);
                }).error(function () {
                    deferred.reject('Cannot find dictionary value by tag ' + dictionaryTag);

                });
                return deferred.promise;
            }
        };
    }])
commonModule.factory('dxDataGridService', ['$translate', function ($translate) {
    'use strict';

    var resize = function (instance) {
        var rootElement = instance.element();
        var gridView = instance.getView("gridView");
        var rowsView = instance.getView("rowsView");

        var rowsViewHeight = rowsView.element().height();
        var origRootHeigth = rootElement.height();
        var origGridViewHeigth = gridView.getElementHeight();
        var constHeight = origGridViewHeigth - rowsViewHeight;

        var tableElements = rowsView.getTableElements();
        if (tableElements.find("> tbody > .dx-freespace-row:visible").length > 0 && !instance.option("editing.allowUpdating")) {
            tableElements.find("> tbody > .dx-freespace-row:visible").hide();
        }

        if (instance.getController("data").items().length > 0) {
            rowsViewHeight = 0;
            _.forEach(tableElements, function (item) {
                rowsViewHeight += $(item).height();
            });
        }

        //用于测试观察控件高度变化
        //console.log("TIME: " + moment().format("HH:mm:ss.SSSS") + " TableElements height : " + rowsViewHeight + "px");

        var excpHeight = constHeight + rowsViewHeight;

        rootElement.css("maxHeight", "none");
        rootElement.css("minHeight", "none");
        var $testDiv = $("<div>").height(99999).appendTo(rootElement);
        var maxHeight = rootElement.height();
        $testDiv.remove();

        var fHeight = excpHeight > maxHeight ? maxHeight : excpHeight;
        /* 如果没有设置 overflow-y 为 hidden 则,不调整高度,防止高度过度溢出 */
        if (rootElement.css("overflow-y") === "hidden") {
            rootElement.css("maxHeight", fHeight + "px");
            rootElement.css("minHeight", fHeight + "px");
        }
        if (Math.abs(origRootHeigth - fHeight) < 2 && Math.abs(origGridViewHeigth - fHeight) < 2) {
            return;
        }

        instance.resize();
    };

    //1.在内容发生变化时,重新 resize
    var registerAutoSize = function (instance) {
        var contentReady = instance.option("onContentReady");
        var rowCollapsed = instance.option("onRowCollapsed");
        var rowExpanded = instance.option("onRowExpanded");

        instance.option("onContentReady", function (e) {
            if (contentReady)
                contentReady(e);
            resize(instance);
        });


        instance.option("onRowCollapsed", function (e) {
            if (rowCollapsed)
                rowCollapsed(e);
            resize(instance);
        });

        instance.option("onRowExpanded", function (e) {
            if (rowExpanded)
                rowExpanded(e);
            resize(instance);
        });

        $(window).on("resize", function () {
            instance.repaint();
        });
    };

    //2.列头单元格渲染完成后,如果单元格存在排序箭头则,将箭头设置靠右,文本内容居中
    var repaintHeaderCell = function (dataGridInstance) {

    };

    // 本方法仅为了解决 dxDataGrid 设置了 max-height 没有设置 height 导致的内容溢出问题
    //为 onInitialized   时添加 min-height,使 dxDataGrid 之 _hasHeight 为真,使 rowsView 高度可以通过 dxDataGrid 来计算,避免内容溢出
    //在 onRowPrepared   时取消 rowsView 的 min-height
    //在 onContentReady  时检验数据数量,当数量为 0 时,设置 rowsView min-height = 100px,以此弥补为 dxDataGrid 设置 min-height 时导致的 rowsView 高度为 0 问题
    var fixContentOverflowWithMaxHeight = function (instance) {
        var height = instance.option("height");
        //若有 height 则不再进行高度调整
        if (height && height != "auto")
            return;

        var contentReady = instance.option("onContentReady");
        var onRowPrepared = instance.option("onRowPrepared");

        instance.element().addClass("dx-datagrid-1em-min-height");

        instance.option("onContentReady", function (e) {
            if (e.component.getDataSource().items().length === 0)
                e.component.getView("rowsView").element().addClass("dx-datagrid-empty-rows-view");

            if (!!contentReady)
                contentReady(e);
        });

        instance.option("onRowPrepared", function (e) {
            var element = e.component.getView("rowsView").element();
            if (!!element)
                element.removeClass("dx-datagrid-empty-rows-view");

            if (!!onRowPrepared)
                onRowPrepared(e);
        });
    }

    //通过在 onInitialized 事件中添加 registerRowDbClick 方法注册,且 option 中应配置 onRowDbClick 回调函数
    var dxRowDbClickMock = function (instance) {
        var rowClick = instance.option("onRowClick");

        instance.option("onRowClick", function (e) {
            try {
                if (rowClick)
                    rowClick(e);
            }
            finally {
                var option = e.component.option();
                var preTimeStamp = option.rowClickTimeStamp || 0;
                option.rowClickTimeStamp = e.jQueryEvent.timeStamp;
                if (option.rowClickTimeStamp - preTimeStamp > 300 || !!option.rowDbClickIsProcessing)
                    return;

                option.rowDbClickIsProcessing = true;
                var rowDbClick = option.onRowDbClick;
                try {
                    if (rowDbClick)
                        rowDbClick(e)
                } finally {
                    option.rowDbClickIsProcessing = false;
                }
            }
        });
    };

    var BASIC_GRID_OPTIONS = {
        allowColumnResizing: true,
        editing: {
            allowAdding: false,
            allowDeleting: false,
            allowUpdating: false
        },
        focusStateEnabled: true,
        hoverStateEnabled: true,
        keyExpr: "id",
        loadPanel: {
            enabled: true
        },
        noDataText: $translate.instant('NoDataText'),
        paging: {
            enabled: false
        },
        rowAlternationEnabled: false, //单双行颜色
        scrolling: {
            mode: "infinite"
        },
        selection: {
            allowSelectAll: false,
            mode: "single"
        },
        showBorders: true,
        showColumnLines: true,
        showRowLines: true,
        sorting: {
            mode: "single"
        },
    };

    return {
        registerAutoSize: registerAutoSize,
        registerRepaintHeaderCell: repaintHeaderCell,
        resize: resize,
        fixContentOverflowWithMaxHeight: fixContentOverflowWithMaxHeight,
        registerRowDbClick: dxRowDbClickMock,
        BASIC_GRID_OPTIONS: BASIC_GRID_OPTIONS,
    };
}]);
commonModule.factory('loginContext', ['$log', '$cookies', '$location', '$window', function ($log, $cookies, $location, $window)
{
    $log.debug('loginContext.ctor()...');
    
    var apiTokenObj = $cookies.getObject('AtmsApiToken');
    $cookies.put('logout', '0');

    var redirectToLogOut = function ()
    {
        var status = $cookies.get('logout');
        if (status !== '1') {
            alert("登录已经超时,请重新登录");
            $window.location.href = '/Account/LogOut' + '?_=' + (new Date).valueOf();
            // in order to fix ie 10 not reload issue
            $("a[href='/Account/LogOut?_=" + (new Date).valueOf() + "']").click();
            $cookies.put('logout', '1');
        }
    };

    if (!(apiTokenObj)) {
        $log.error("loginContext: Fail to get api token, please log in first.");

        redirectToLogOut();
        return {};
    }

    var serverUrl = $location.protocol() + '://' + $location.host() + ':' + $location.port();

    return {
        redirectToLogOutFunction: redirectToLogOut,
        apiToken: apiTokenObj.access_token,
        tokenType: apiTokenObj.token_type,
        apiHost: apiTokenObj.api_host,
        vatApiToken: apiTokenObj.vat_access_token,
        vatTokenType: apiTokenObj.vat_token_type,
        vatApiHost: apiTokenObj.vat_api_host,
        tpUrl: apiTokenObj.tp_url,
        pdfService: apiTokenObj.pdf_service,
        clinetAgentVersion: apiTokenObj.client_agent,
        printHtml: apiTokenObj.print_html,
        printService: apiTokenObj.print_service,
        risgcService: apiTokenObj.risgc_service,
        userName: decodeURI(apiTokenObj.user_name),
        localName: decodeURI(apiTokenObj.local_name),
        userId: apiTokenObj.user_id,
        domain: apiTokenObj.domain,
        site: apiTokenObj.site,
        language: apiTokenObj.language,
        serverUrl: serverUrl,
        needChangePassword: apiTokenObj.need_change_password,
        isExternalUser: apiTokenObj.is_external_user,
        projectCustomerName: apiTokenObj.project_customer_name,
        passwordHash: apiTokenObj.password_hash
    };
}])
commonModule.factory('modalAdapterService', [function () {
    var modals = []; // array of modals on the page
    var service = {};

    service.add = Add;
    service.remove = Remove;
    service.open = Open;
    service.close = Close;

    return service;

    function Add(modal) {
        var find = _.findWhere(modals, { id: modal.id, parentID: modal.parent });
        if (find) return;
        // add modal to array of active modals
        modals.push(modal);
    };

    function Remove(id,parent) {
        // remove modal from array of active modals
        var modalToRemove = _.findWhere(modals, { id: id,parentID:parent });
        modals = _.without(modals, modalToRemove);
    };
    function RemoveSpecific(modalToRemove) {
        // remove modal from array of active modals       
        modals = _.without(modals, modalToRemove);
    };
    function Open(id,parent) {
        // open modal specified by id
        var modal = _.findWhere(modals, { id: id,parentID:parent });
        modal.open();
    };

    function Close(id,parent) {
        // close modal specified by id
        var modal = _.findWhere(modals, { id: id ,parentID:parent});       
        modal.cancel();
        
    };
}]);
commonModule.factory('ngGridUtil', [function () {
    'use strict';

    return {
        GridLayoutPlugin: function () {
            var self = this;
            this.grid = null;
            this.scope = null;
            this.init = function (scope, grid, services) {
                self.domUtilityService = services.DomUtilityService;
                self.grid = grid;
                self.scope = scope;
            };

            this.updateGridLayout = function () {
                if (!self.scope.$$phase) {
                    self.scope.$apply(function () {
                        self.domUtilityService.RebuildGrid(self.scope, self.grid);
                    });
                } else {
                    // $digest or $apply already in progress
                    self.domUtilityService.RebuildGrid(self.scope, self.grid);
                }
            };
        },

        FlexRowHeight: function () {
            var self = this;
            self.grid = null;
            self.scope = null;
            self.init = function (scope, grid, services) {
                self.domUtilityService = services.DomUtilityService;
                self.grid = grid;
                self.scope = scope;

                var adjust = function () {
                    setTimeout(function () {
                        var row = $(self.grid.$canvas).find('.ngRow'),
                            offs;
                        row.each(function () {
                            var mh = 0,
                                s = angular.element(this).scope();

                            $(this).find('> div').each(function () {
                                var h = $(this)[0].scrollHeight;
                                if (h > mh)
                                    mh = h

                                $(this).css('height', '100%');
                            });

                            $(this).height(mh)

                            if (offs)
                                $(this).css('top', offs + 'px');

                            offs = $(this).position().top + mh;
                            self.scope.$apply(function () {
                                s.rowHeight = mh;
                            });
                        });
                    }, 1);
                }

                self.adjust = adjust;

                self.scope.$watch(self.grid.config.data, adjust, true);
            }
        }
    }
}]);
commonModule.factory('profileManager', ['$log', 'configurationService', 'loginContext', '$q',
    function ($log, configurationService, loginContext, $q) {

        $log.debug('profileManager.ctor()...');

        var resolve = function (profileName, profiles, deferred) {
            if (profiles != null && profiles.length > 0) {
                var profile = _.findWhere(profiles, { name: profileName });
                if (profile) {
                    deferred.resolve(profile.value);
                    return true;
                }
            }
            return false;
        };


        return {
            getProfileValue: function (profileName) {
                var deferred = $q.defer();
                configurationService.getProfiles(loginContext.userId).success(function (data) {
                    if (resolve(profileName, data.userProiles, deferred))
                        return deferred.promise;
                    if (resolve(profileName, data.roleProiles, deferred))
                        return deferred.promise;
                    if (resolve(profileName, data.siteProiles, deferred))
                        return deferred.promise;
                    if (resolve(profileName, data.systemProiles, deferred))
                        return deferred.promise;
                    deferred.reject("Cannot find profile value!");
                }).error(function () {
                    deferred.reject("Cannot find profile value!");
                });
                return deferred.promise;
            }
        };
    }])
commonModule.factory('risDialog', ["$document", "$compile", "$rootScope", "$controller", "$timeout",
  function ($document, $compile, $rootScope, $controller, $timeout) {
      var defaults = {
          id: null,
          template: null,
          templateUrl: null,
          title: 'Default Title',
          backdrop: true,
          success: { label: 'OK', fn: null, param:null },
          cancel: { label: 'Close', fn: null },
          controller: null, //just like route controller declaration
          backdropClass: "modal-backdrop",
          backdropCancel: true,
          footerTemplate: null,
          modalClass: "modal",
          css: {
              margin: '0 auto',
              'z-index': 1050
          }
      };
      var body = $document.find('body');

      return function Dialog(templateUrl/*optional*/, options, passedInLocals) {

          // Handle arguments if optional template isn't provided.
          if (angular.isObject(templateUrl)) {
              passedInLocals = options;
              options = templateUrl;
          } else {
              options.templateUrl = templateUrl;
          }

          options = angular.extend({}, defaults, options); //options defined in constructor

          var key;
          var idAttr = options.id ? ' id="' + options.id + '" ' : '';
          var defaultFooter = '<button class="btn" ng-click="$modalCancel()">{{$modalCancelLabel}}</button>' +
            '<button class="btn btn-primary" ng-click="$modalSuccess()">{{$modalSuccessLabel}}</button>';
          var footerTemplate = '<div class="modal-footer">' +
            (options.footerTemplate || defaultFooter) +
            '</div>';
          var modalBody = (function () {
              if (options.template) {
                  if (angular.isString(options.template)) {
                      // Simple string template
                      return '<div class="modal-body">' + options.template + '</div>';
                  } else {
                      // jQuery/JQlite wrapped object
                      return '<div class="modal-body">' + options.template.html() + '</div>';
                  }
              } else {
                  // Template url
                  return '<div class="modal-body" ng-include="\'' + options.templateUrl + '\'"></div>'
              }
          })();
          //We don't have the scope we're gonna use yet, so just get a compile function for modal
          var modalEl = angular.element(
                    '<div class="' + options.modalClass + ' fade"' + idAttr + ' style="display: block;">' +
                        '  <div class="modal-dialog">' +
                        '    <div class="modal-content">' +
                        '      <div class="modal-header">' +
                        '        <button type="button" class="close" ng-click="$modalCancel()">&times;</button>' +
                        '        <h2>{{$title}}</h2>' +
                        '      </div>' +
                        modalBody +
                        footerTemplate +
                        '    </div>' +
                        '  </div>' +
                        '</div>');

          for (key in options.css) {
              if (options.css.hasOwnProperty(key)) {
                  modalEl.css(key, options.css[key]);
              }
          }
          var divHTML = "<div ";
          if (options.backdropCancel) {
              divHTML += 'ng-click="$modalCancel()"';
          }
          divHTML += ">";
          var backdropEl = angular.element(divHTML);
          backdropEl.addClass(options.backdropClass);
          backdropEl.addClass('fade in');
          var ctrl, locals,
           scope = options.scope || $rootScope.$new();

          scope.$title = options.title;
          scope.$modalClose = closeFn;
          scope.$modalCancel = function () {
              var callFn = options.cancel.fn || closeFn;
              callFn.call(this);
              scope.$modalClose();
          };
          scope.$modalSuccess = function () {
              var callFn = options.success.fn || closeFn;
              callFn.call(this, options.success.param);
              scope.$modalClose();
          };
          scope.$modalSuccessLabel = options.success.label;
          scope.$modalCancelLabel = options.cancel.label;

          var handleEscPressed = function (event) {
              if (event.keyCode === 27) {
                  scope.$modalCancel();
              }
          };

          var closeFn = function () {
              body.unbind('keydown', handleEscPressed);
              modalEl.remove();
              if (options.backdrop) {
                  backdropEl.remove();
              }
          };

          body.bind('keydown', handleEscPressed);

         
          if (options.controller) {
              locals = angular.extend({ $scope: scope }, passedInLocals);
              ctrl = $controller(options.controller, locals);
              // Yes, ngControllerController is not a typo
              modalEl.contents().data('$ngControllerController', ctrl);
          }

          $compile(modalEl)(scope);
          $compile(backdropEl)(scope);
          body.append(modalEl);
          if (options.backdrop)
              body.append(backdropEl);

          $timeout(function () {
              modalEl.addClass('in');
          }, 200);
      };
  }]);
cacheModule.factory('signalRSvc', ['$log', 'CacheFactory', 'loginContext','cacheService','notify','$translate',
    function ($log, CacheFactory, loginContext, cacheService, notify, $translate) {

    'use strict';
    $log.debug('signalr-cache.run()...');

    return {
        initialize: function () {

            //****************************************************************************************************************
            // refer to https://docs.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-javascript-client
            // The following is for generated proxy,if you want to register multiple event handler
            // for a client method that the server calls, you can't use the generated proxy
            //****************************************************************************************************************
             
            var cacheName = constant.cache.cacheName;
            var hubName = constant.cache.hubName; 
            var cacheUpdateMessage = constant.cache.cacheUpdateMessage;

            var connection = $.hubConnection(loginContext.apiHost);
            var cacheHub = connection.createHubProxy(hubName);
            cacheHub.on('updateSignalrCache', function (data) {
                updateCache(data);
            });

            cacheHub.on('updateUserOnlineCount', function (count) {
                console.info('online user count New:', count);
            });
            
            connection.start().done(function () {
                console.log('Now connected -webapi , connection ID=' + connection.id);
            }).fail(function (error) {
                console.log('Could not connect - webapi', error);
            });

            //用户修改数据之后通过SignalR让在线用户及时更新缓存
            var updateCache = function (data) {
                 
                //data对应服务端的dto对象ClientCacheDto 
                var dataCache = CacheFactory.get(cacheName); 
                var cacheKey = data.CacheKey;
                var cacheTime = data.CacheTime;
                
                console.log('signal update triggerred to remove expired cache...,cacheKey:'+cacheKey);
                
                var keys = dataCache.keys();
                _.each(keys, function (key) {
                    if (key.toLowerCase().indexOf(cacheKey.toLowerCase()) >= 0) {
                        var removeKey = dataCache.remove(key);
                        console.log(key + ' was removed');
                    }
                });
                 
                notify({
                    message: cacheUpdateMessage,
                    position: constant.cache.notify.position,
                    classes: constant.cache.notify.classes
                });
            }
        }
    };
}]);


commonModule.factory('spreadJsTipService', ['$rootScope', '$log', '$uibModal', '$translate',
function ($rootScope, $log, $uibModal, $translate) {
    'use strict';

    var hasInvoiceImg;
    var hasVoucherImg;
    var hasKeyInImg;
    var hasModelImg;
    var hasExceptionImg;
    var hasValidationImg;

    var heightOffset = 150;
    var widthOffset = 250;

    var initialize = function (sheet) {

        sheet.isPaintSuspended(true);

        hasVoucherImg = new Image();
        hasVoucherImg.src = '/app-resources/images/vat/hasVoucher.png';
        hasVoucherImg.onload = function () {
            sheet.repaint();
        }

        hasInvoiceImg = new Image();
        hasInvoiceImg.src = '/app-resources/images/vat/hasInvoice.png';
        hasInvoiceImg.onload = function () {
            sheet.repaint();
        }

        hasKeyInImg = new Image();
        hasKeyInImg.src = '/app-resources/images/vat/hasKeyIn.png';
        hasKeyInImg.onload = function () {
            sheet.repaint();
        }

        hasModelImg = new Image();
        hasModelImg.src = '/app-resources/images/vat/hasModel.png';
        hasModelImg.onload = function () {
            sheet.repaint();
        }

        hasExceptionImg = new Image();
        hasExceptionImg.src = '/app-resources/images/vat/hasException.png';
        hasExceptionImg.onload = function () {
            sheet.repaint();
        }

        hasValidationImg = new Image();
        hasValidationImg.src = '/app-resources/images/vat/hasValidation.png';
        hasValidationImg.onload = function () {
            sheet.repaint();
        }

    };

    var paintSheet = function (sheet) {
        sheet.isPaintSuspended(false);
    };

    var setCellTipString = function (cell, tip) {
        //cell.cellType(new IconCellType(null, null, 0, null, tip));
        cell.cellType(new IconsCellType([], [], tip));
    }

    var setCellTipByCellData = function (cell, cellData) {
        var tips = null;
        //BSPL
        if (cellData && cellData.formulaDescription) {
            tips = cellData.formulaDescription;
        }
        if (cellData && cellData.cellTemplateConfig && !_.isEmpty(cellData.cellTemplateConfig.formulaDescription)) {
            tips = cellData.cellTemplateConfig.formulaDescription;
        }
        
        var icons = [];
        var infos = [];

        var hasException = false;
        var exceptionMsg = '';
        if (cellData.hasModelError) {
            hasException = true;
            exceptionMsg = $translate.instant('ModelException');
        }

        if (!_.isEmpty(cellData.validationErrorList)) {
            hasException = true;
            if (_.isEmpty(exceptionMsg)) {
                exceptionMsg = $translate.instant('ValidationException');
            }
            else {
                exceptionMsg = exceptionMsg + '; ' + $translate.instant('ValidationException');
            }
        }

        if (hasException) {
            cell.value(cell.text() + '   '); // Edmond TODO: Temp move cell value for CIT demo
            icons.push(hasExceptionImg);
            infos.push(exceptionMsg);
        }

        cell.cellType(new IconsCellType(icons, infos, tips));
    }

    var setCellTip = function (cell, config) {
        var tips = null;
        if (config.formulaDescription) {
            tips = config.formulaDescription;
        }
        //if (config.hasVoucher && !config.hasInvoice) {
        //    cell.cellType(new IconCellType(hasVoucherImg, null, 1, [getHoverTip('voucher', config), null], tips)).hAlign(0);
        //}else if (config.hasInvoice && !config.hasVoucher) {
        //    cell.cellType(new IconCellType(hasInvoiceImg, null, 1, [getHoverTip('invoice', config), null], tips)).hAlign(0);
        //}else if (config.hasInvoice && config.hasVoucher) {
        //    cell.cellType(new IconCellType(hasVoucherImg, hasInvoiceImg, 2, [getHoverTip('voucher', config), getHoverTip('invoice', config)], tips)).hAlign(0);
        //} else if (config.formulaDescription) {
        //    cell.cellType(new IconCellType(null, null, 0, null, tips)).hAlign(0);
        //}

        var icons = [];
        var infos = [];
        if (config.validation) {
            icons.push(hasValidationImg);
            infos.push($translate.instant('ReportValidation'));
        }
        if (config.hasModel) {
            icons.push(hasModelImg);
            infos.push($translate.instant('LinkModel'));
        }
        if (config.hasKeyIn) {
            icons.push(hasKeyInImg);
            infos.push($translate.instant('ManualInput'));
        }
        if (config.hasVoucher) {
            icons.push(hasVoucherImg);
            infos.push(getHoverTip('voucher', config));
        }
        if (config.hasInvoice) {
            icons.push(hasInvoiceImg);
            infos.push(getHoverTip('invoice', config));
        }
        
        //--不需要左对齐对齐
        if (tips === null) {
            cell.cellType(new IconsCellType(icons, infos, tips));
        }else{
            cell.cellType(new IconsCellType(icons, infos, tips)).hAlign(0);
        }
    };

    var getHoverTip = function (tipType, config) {
        if (config) {
            if (tipType === 'voucher') {
                return $translate.instant('VoucherTip') + getCodejoinString(config.accountCodes);
            } else if (tipType === 'invoice') {
                return $translate.instant('InvoiceTip') + getInvoiceNameTip(config.invoiceType, config) + getInvoiceAmountName(config.invoiceAmountType);
            }
        }
    };

    var getCodejoinString = function (array) {
        if (array) {
            return array.join(',');
        } else {
            return '';
        }
    };

    var getInvoiceNameTip = function (invoiceType, config) {
        var taxRateStr = _.contains(config.taxRate, constant.selectAllValue) ? '' : ($translate.instant('TaxRate') + getCodejoinString(config.taxRate));
        if (invoiceType === 1) {
            return $translate.instant('Income') + ':' + taxRateStr;
        } else if (invoiceType === 2) {
            return $translate.instant('Output') + ':' + taxRateStr;
        } else if (invoiceType === 3) {
            return $translate.instant('CustomsAudit') + ':';
        } else {
            return '';
        }
    };

    var getInvoiceAmountName = function (invoiceAmountType) {
        if (invoiceAmountType === 1) {
            return $translate.instant('TotalAmount');
        } else if (invoiceAmountType === 2) {
            return $translate.instant('TaxAmount');
        } else if (invoiceAmountType === 3) {
            return $translate.instant('CopyNumber');
        } else {
            return '';
        }
    };

    var IconsCellType = function (icons, infos, formula) {
        if (icons && icons.length > 0) {
            this.Icons = icons;
            this.count = icons.length;
            this.Infos = infos;
            this.Formula = formula;
        } else {
            this.count = 0;
            this.Formula = formula;
        }
    }

    //var IconCellType = function (icon1, icon2, count, infos, formula) {

    //    this.icon1 = icon1;
    //    this.icon2 = icon2;

    //    this.count = count;
    //    this.Infos = infos;

    //    this.Formula = formula;
    //}


    IconsCellType.prototype = new GcSpread.Sheets.TextCellType();
    IconsCellType.prototype.paint = function (ctx, value, x, y, w, h, style, context) {
        GcSpread.Sheets.TextCellType.prototype.paint.call(this, ctx, value, x, y, w, h, style, context);
        for (var i = 1; i <= this.count; i++) {
            //距离当前单元格左侧距离,距离顶部距离 , ICON宽度,ICON高度
            ctx.drawImage(this.Icons[i-1], x + w - (h - 3) * i + (h - 6 - 18) * i, y + 3 + (h / 2 - 3 - 9), 18, 18);

            //if (i == 1 && this.icon1) {
            //    //距离当前单元格左侧距离,距离顶部距离 , ICON宽度,ICON高度
            //    ctx.drawImage(this.icons[i], x + w - (h - 3) * i + (h - 6 - 18) * i, y + 3 + (h / 2 - 3 - 9), 18, 18);
            //}

            //if (i == 2 && this.icon2) {
            //    //第二个图标相对于第一个图标向左偏移一个单位的宽度加间隙
            //    ctx.drawImage(this.icon2, x + w - (h - 3) * i + (h - 6 - 18) * i, y + 3 + (h / 2 - 3 - 9), 18, 18);
            //}
        }
    }
    IconsCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
        var index = x - (cellRect.x + cellRect.width - (cellRect.height - 3) * this.count) > 0 ?
            Math.floor(this.count - (x - (cellRect.x + cellRect.width - (cellRect.height - 3) * this.count)) / (cellRect.height - 3)) :
            -1;

        return {
            x: x,
            y: y,
            row: context.row,
            col: context.col,
            cellStyle: cellStyle,
            cellRect: cellRect,
            sheetArea: context.sheetArea,
            reservedLocationIndex: index
        };
    }
    IconsCellType.prototype.processMouseMove = function (hitinfo) {

        //console.log(hitinfo);
        //if (!this.Formula) {
        //    return;
        //}
        //console.log(hitinfo.reservedLocationIndex);
        var tipInfo = this.Formula;

        if (hitinfo.reservedLocationIndex >= 0) {
            tipInfo = this.Infos[hitinfo.reservedLocationIndex];
            //console.log(this.Infos[hitinfo.reservedLocationIndex]);
        }

        //如果没有Tip信息就不再做tip显示。
        if (!tipInfo) {
            return;
        }

        if (this._toolTipElement) {
            $(this._toolTipElement).text(tipInfo)
            .css("top", hitinfo.y + 15 + heightOffset)
            .css("left", hitinfo.x + 15 + widthOffset);
        }
        else {
            var div = document.createElement("div");
            $(div).css("position", "absolute")
            .css("border", "1px #C0C0C0 solid")
            .css("box-shadow", "1px 2px 5px rgba(0,0,0,0.4)")
            .css("font", "9pt Arial")
            .css("background", "white")
            .css("max-width", "400px")
            .css("word-wrap", "break-word")
            .css("padding", 5);

            this._toolTipElement = div;
            $(this._toolTipElement).css("top", hitinfo.y + 15 + heightOffset)
            .css("left", hitinfo.x + 15 + widthOffset);
            $(this._toolTipElement).hide();
            document.body.insertBefore(this._toolTipElement, null);
            $(this._toolTipElement).show("fast");
        }


    };
    IconsCellType.prototype.processMouseLeave = function (hitinfo) {
        if (this._toolTipElement) {
            document.body.removeChild(this._toolTipElement);
            this._toolTipElement = null;
        }
    };

    return {
        initialize: initialize,
        setCellTip: setCellTip,
        setCellTipString: setCellTipString,
        setCellTipByCellData:setCellTipByCellData,
        paintSheet: paintSheet
    };
}]);
//常用公用方法
commonModule.factory('ackLib', ['$translate', function ($translate) {
    'use strict';

    var ackLib = {};

    //辅助方法
    ackLib.Helper = {
        //翻译,仅此一个入口
        translate: function (value) {
            return $translate.instant(value);
        }
    }

    //验证
    ackLib.validation = {
        //是否为日期验证,如果验证成功,返回true,否则返回false
        isDate: function (value, dateSeparator) {
            try {
                var dateSplit = dateSeparator || constant.date.dateFormatSeparator;
                var arr = value.split(dateSplit);
                var year = parseInt(arr[0]);
                var month = parseInt(arr[1]);
                var day = parseInt(arr[2]);
                var date = new Date(year, month - 1, day);
                if (date.getFullYear() == year && date.getMonth() + 1 == month && date.getDate() == day) {
                    return true;
                } else {
                    return false;
                }
            }
            catch (e) {
                return false;
            }
        },
        isEmpty: function (str) {
            if (!str || str === '') {
                return true;
            }
            else {
                return false;
            }
        }
    };

    //翻译,所有的翻译都放这,到时直接调用,不用每个页面都去做翻译
    ackLib.translation = {};
    //常用翻译
    ackLib.translation.common = {
        Remark: ackLib.Helper.translate('Remark'), //备注
        DownloadTemplateFail: ackLib.Helper.translate('DownloadTemplateFail'), //下载模板失败
        FileUploadSuccess: ackLib.Helper.translate('FileUploadSuccess'), //文件上传成功
        SelectAtLeastOneRecord: ackLib.Helper.translate('SelectAtLeastOneRecord'), //请至少选择一条记录
        OperateSuccess: ackLib.Helper.translate('OperateSuccess'), //操作成功
        UploadSuccess: ackLib.Helper.translate('UploadSuccess'), //上传成功
        PleaseSelectFile: ackLib.Helper.translate('PleaseSelectFile'), //请先选择文件
        NoDataText: ackLib.Helper.translate('NoDataText'), //没有数据
        pleaseSelect: ackLib.Helper.translate('ChoosePlaceholder'), //-请选择-
        pleaseInput: ackLib.Helper.translate('InputPlaceholder'), //-请输入-
        PleaseSelectRecordToDelete: ackLib.Helper.translate('PleaseSelectRecordToDelete'), //请选择需要删除的记录
        FileName: ackLib.Helper.translate('FileNameTitle'), //文件名称
        ErrorMessage: ackLib.Helper.translate('ErrorMessage'), //错误消息
        Confirm: ackLib.Helper.translate('Confirm'), //错误消息
        Cancel: ackLib.Helper.translate('Cancel'), //错误消息
    };

    //发票相关
    ackLib.translation.inputInvoice = {
        AllowRefundInvoiceInfo: ackLib.Helper.translate('AllowRefundInvoiceInfo'), //只有状态为识别成功,识别失败,无法识别,待退票或待匹配的发票才可以做退票操作
        SpecialToInvoiceRecognizeSuccessInfo: ackLib.Helper.translate('SpecialToInvoiceRecognizeSuccessInfo'), //对于发票来源为“发票章错误,待退票”且发票状态为【待退票】的发票,只支持单张退票,不支持与其他发票一起批量退票
        SpecialToInvoicePendingRefundInfo: ackLib.Helper.translate('SpecialToInvoicePendingRefundInfo'), //对于发票来源为“发票章错误,待退票”且发票状态为【识别成功】的发票,支持批量退票,不支持将此类发票与其他发票一起批量退票。
        AllowInvoiceRecognizeWithUpload: ackLib.Helper.translate('AllowInvoiceRecognizeWithUpload'), //只有已上传或者已补录的发票可以做发票识别
        RecognizeInvoiceSuccess: ackLib.Helper.translate('RecognizeInvoiceSuccess'), //发票识别成功
        VerifyInvoiceSuccess: ackLib.Helper.translate('VerifyInvoiceSuccess'), //发票验真成功
        CannotExpireInvoice: ackLib.Helper.translate('CannotExpireInvoice'), //已认证、已失效、已清理、已匹配、已退票的发票不能做失效操作
        ConfirmToExpireInvoice: ackLib.Helper.translate('ConfirmToExpireInvoice'), //确认要把选中的发票进行失效处理吗
    }

    //浏览器检测
    ackLib.Browser = {
        isIE: (function () {
            if (navigator.userAgent.match(/msie/i) || navigator.userAgent.match(/trident/i)) {
                return true;
            }
            return false;
        })(),
    };

    //小数点位数
    var fixedNumber = constant.toFixedNumber;
    //数字的格式化
    ackLib.Number = {
        toFixed: function (num) {
            return num.toFixed(fixedNumber);
        },
    }


    //阻止冒泡
    ackLib.stopPropagation = function (event) {
        event = event || window.event;
        if (event.stopPropagation) {
            event.stopPropagation();
        } else {
            event.cancelBubble = true;
        }
    };

    //动态构造table
    ackLib.populateTable = function (columnList, valueList) {

        var table = '';
        var tableHeader = '<table class="table table-striped table-hover table-bordered" style="max-height:200px; overflow:auto; text-align:left">';
        var tbody = '';
        var th = '';

        columnList.forEach(function (item) {
            th += '<th>' + item + '</th>';
        });
        var thead = '<tr>' + th + '</tr>';

        valueList.forEach(function (row) {
            var tr = '';
            columnList.forEach(function (item) {
                tr += '<td>' + row[item] + '</td>';
            });

            tbody += '<tr>' + tr + '</tr>';
        });

        table = tableHeader + thead + tbody + '</table>';

        // console.log(table);

        return table;
    };


    return ackLib;

}]);


/*文件上传:目前支持单文件上传,支持跨域上传
创建于:2017/09/08
*/
commonModule.factory('ackFileUploader', ['Upload', '$q', 'apiInterceptor', 'ackLib', function (Upload, $q, apiInterceptor, ackLib) {
    'use strict';

    var defaultOptions = {
        chunkSize: '10MB',
        resumable: true,
        token: $('input[name="__RequestVerificationToken"]').val(),
        url: '',
        cancel: false,
        maximumSize: 1024 * 1024 * 10,  //10MB,
        isAppend: true, //默认为追加
    };

    defaultOptions.headers = {
        'Access-Control-Allow-Origin': '*',
        Authorization: apiInterceptor.tokenType + ' ' + apiInterceptor.apiToken,
        __RequestVerificationToken: defaultOptions.token,
        withCredentials: true
    }


    var ackFileUploader = {

        //上传单个文件
        upload: function (myfile, options) {
            var deferred = $q.defer();
            options = $.extend(true, {}, defaultOptions, options);
            var fileName = myfile.name;

            var self = ackFileUploader;

            if (!fileName || fileName.size == 0) {
                deferred.reject("FileIsEmpty");
            }
            if (myfile.size > options.maximumSize) {
                deferred.reject("FileSizeExceedMaximum");
            }
            var optionsData = {
                cancel: options.cancel,
                filename: fileName,
            }

            optionsData = $.extend(true, {}, optionsData, options.data);
            Upload.upload({
                url: options.url,
                data:optionsData,
                file: myfile,
                resumeChunkSize: options.resumable ? options.chunkSize : null,
                headers: options.headers,
                withCredentials: true
            }).then(function (resp) {
                deferred.resolve(resp);
            });
            return deferred.promise;
        },

        //uploadMultiple: function (files, options) {
        //    if (files && files.length > 0) {
        //        for (var i = 0; i < files.length; i++) {
        //            ackFileUploader.upload(files[i], options);
        //        }
        //    }
        //}
    };

    return ackFileUploader;

}]);


//消息弹框
commonModule.factory('ackMessageBox', ['$translate', 'SweetAlert', '$q', 'ackLib', function ($translate, SweetAlert, $q, ackLib) {
    'use strict';
    //只负责弹框,保持独立性
    var messageBox = {
        success: function (title, message) {
            if (arguments.length == 1) { // message is undefined
                SweetAlert.success(title, '');
            }
            else if (arguments.length == 2) { // message is undefined
                SweetAlert.success(title, message);
            }
        },

        warning: function (title, message) {
            if (arguments.length == 1) { // message is undefined
                SweetAlert.warning(title, '');
            }
            else if (arguments.length == 2) { // message is undefined
                SweetAlert.warning(title, message);
            }
        },

        close: function () {
            swal.close();
        },

        //有确认和取消按钮
        confirm: function (title, text, customClass) {
            var deferred = $q.defer();
            SweetAlert.swal({
                title: title,
                text: text,
                html: true,
                type: "warning",
                customClass: customClass || '',
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                allowOutsideClick: false,
                confirmButtonText: ackLib.translation.common.Confirm,
                cancelButtonText: ackLib.translation.common.Cancel,
                closeOnConfirm: true,
                closeOnCancel: true
            },
              function (isConfirm) {
                  deferred.resolve(isConfirm);
              });

            return deferred.promise;
        },

        //没有取消按钮
        info: function (title, text, customClass) {
            var deferred = $q.defer();

            SweetAlert.swal({
                title: title,
                text: text,
                html: true,
                type: "warning",
                customClass: customClass || 'swal-info',
                showCancelButton: false,
                confirmButtonColor: "#DD6B55",
                allowOutsideClick: false,
                confirmButtonText: ackLib.translation.common.Confirm,
                cancelButtonText: ackLib.translation.common.Cancel,
                closeOnConfirm: true,
                closeOnCancel: false
            },
              function (isConfirm) {
                  deferred.resolve(isConfirm);
              });

            return deferred.promise;
        },
    };

    return messageBox;

}]);


//UIModal模态框
commonModule.factory('ackUibModal', ['$translate', 'SweetAlert', '$q', '$uibModal', '$document', function ($translate, SweetAlert, $q, $uibModal, $document) {
    'use strict';


    //模态框
    /*参数currentScope:页面的scope
    templateUrl:定义弹框的模板,
    windowClass:定义弹框的css,
    parentSelector:父框,
    isbackrop:,‘static’, or 'trye'
    resetCallbackFunc: 回调函数
    */
    var createModalInstance = function (currentScope, templateUrl, windowClass, parentSelector, isbackrop, resetCallbackFunc) {
        var thisModalService = new Object();
        isbackrop = isbackrop ? isbackrop : true;

        var parentElem = parentSelector ? angular.element($document[0].querySelector(parentSelector)) : undefined;

        thisModalService.open = function () {
            var modalInstance = $uibModal.open({
                animation: true,
                ariaLabelledBy: 'modal-title',
                ariaDescribedBy: 'modal-body',
                backdrop: isbackrop,  //点击父页面不会自动关闭 
                templateUrl: templateUrl, //script模板
                windowClass: windowClass, //弹框页面的css
                scope: currentScope,
                appendTo: parentElem,
            });

            thisModalService.modalInstance = modalInstance;

            //modal关闭之后接收返回值的函数
            modalInstance.result.then(function (data) {
                //call close的时候调用这里

            }, function () {
                //取消的时候触发这里

            }).finally(function () {
                resetCallbackFunc(); //回调函数
                thisModalService = null;
            });
        };

        thisModalService.close = function (result) {
            if (thisModalService.modalInstance) {
                thisModalService.modalInstance.close(result);
            }
        };

        thisModalService.cancel = function () {
            if (thisModalService.modalInstance) {
                thisModalService.modalInstance.dismiss('cancel');
            }
        }
        return thisModalService;
    };

    return createModalInstance;


}]);

(function ($) {
    "use strict";

    var _super = $.fn.popover;

    var Popover = function (element, options) {
        _super.Constructor.apply(this, arguments);
    };

    Popover.prototype = $.extend({}, _super.Constructor.prototype, {
        constructor: Popover,
        _super: function () {
            var args = $.makeArray(arguments);
            _super.Constructor.prototype[args.shift()].apply(this, args);
        },
        show: function () {
            var that = this;
            var e = $.Event('show.bs.' + this.type);
            var templateUrl = this.$element.attr('data-templateUrl');
            var onShow = function () {
                if (templateUrl) {
                    $.get(templateUrl, function (template) {
                        var tip = $(template);
                        that.options.compliler(tip[0])(that.options.scope);
                        that.options.scope.$apply();
                        that.$tip = tip;
                        that.onTipLoaded(that.$tip);
                    })
                } else {
                    that.onTipLoaded(that.tip());
                }
            }

            e.onShow = onShow;

            if ((this.hasContent() || templateUrl) && this.enabled) {
                this.$element.trigger(e);

                if (e.isDefaultPrevented())
                    return;

                onShow();
            }
        },
        onTipLoaded: function (tip) {
            var that = this;
            var $tip = tip;

            if (this.$element.attr('data-overwrite') !== 'true') {
                this.setContent();
            }

            if (this.options.animation)
                $tip.addClass('fade');

            var placement = typeof this.options.placement === 'function' ?
                this.options.placement.call(this, $tip[0], this.$element[0]) :
                this.options.placement;
            placement = placement.trim();

            var autoToken = /\s?auto?\s?/i;
            var autoPlace = autoToken.test(placement);
            if (autoPlace) {
                placement = placement.replace(autoToken, '') || 'rightTop';
            }

            $tip
              .detach()
              .css({ top: 0, left: 0, display: 'block' })
              .addClass(placement);

            this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element);

            var pos = this.getPosition();
            var actualWidth = $tip[0].offsetWidth;
            var actualHeight = $tip[0].offsetHeight;

            if (autoPlace) {
                var $parent = this.$element.parent();

                var orgPlacement = placement;
                var docScroll = document.documentElement.scrollTop || document.body.scrollTop;
                var parentWidth = this.options.container === 'body' ? window.innerWidth : $parent.outerWidth();
                var parentHeight = this.options.container === 'body' ? window.innerHeight : $parent.outerHeight();
                var parentLeft = this.options.container === 'body' ? 0 : $parent.offset().left;
                var parentTop = this.options.container === 'body' ? 0 : $parent.offset().top;
                parentTop += docScroll;

                var placementOrder = placement.split(' ');

                placement = this.getPlacement({
                    placementOrder: placementOrder,
                    pos: pos,
                    actualWidth: actualWidth,
                    actualHeight: actualHeight,
                    parentWidth: parentWidth,
                    parentHeight: parentHeight,
                    parentTop: parentTop,
                    parentLeft: parentLeft,
                    useOptimizedPlacementAlgorithm: this.options.useOptimizedPlacementAlgorithm
                });

                $tip
                  .removeClass(orgPlacement)
                  .addClass(placement);
            }

            var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight);

            this.applyPlacement(calculatedOffset, placement);
            this.hoverState = null;

            var complete = function () {
                that.$element.trigger('shown.bs.' + that.type, $tip);
            };

            $.support.transition && this.$tip.hasClass('fade') ?
              $tip
                .one($.support.transition.end, complete)
                .emulateTransitionEnd(150) :
              complete();
        },
        getCalculatedOffset: function (placement, pos, actualWidth, actualHeight) {
            return placement === 'bottom' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2 } :
                placement === 'top' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :
                placement === 'left' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
                placement === 'right' ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width } :
                placement === 'topLeft' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - (actualWidth * .25) } :
                placement === 'topRight' ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - (actualWidth * .75) } :
                placement === 'rightTop' ? { top: pos.top + pos.height / 2 - (actualHeight * .25), left: pos.left + pos.width } :
                placement === 'rightBottom' ? { top: pos.top + pos.height / 2 - (actualHeight * .75), left: pos.left + pos.width } :
                placement === 'bottomLeft' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - (actualWidth * .25) } :
                placement === 'bottomRight' ? { top: pos.top + pos.height, left: pos.left + pos.width / 2 - (actualWidth * .75) } :
                placement === 'leftTop' ? { top: pos.top + pos.height / 2 - (actualHeight * .25), left: pos.left - actualWidth } :
                /*placement === 'leftBottom' ?*/ { top: pos.top + pos.height / 2 - (actualHeight * .75), left: pos.left - actualWidth };
        },
        getPlacement: function (placementInfo) {
            placementInfo.placementOrder.splice(placementInfo.placementOrder.length, 0
            , 'rightTop'
            , 'rightBottom'
            , 'leftTop'
            , 'leftBottom'
            , 'bottomLeft'
            , 'bottomRight'
            , 'topLeft'
            , 'topRight');


            var placementOrder = placementInfo.placementOrder;
            var pos = placementInfo.pos;
            var actualWidth = placementInfo.actualWidth;
            var actualHeight = placementInfo.actualHeight;
            var parentTop = placementInfo.parentTop;
            var parentLeft = placementInfo.parentLeft;
            var parentWidth = placementInfo.parentWidth;
            var parentHeight = placementInfo.parentHeight;

            var minOffsetRate = 100;
            var minOffsetRateIndex = -1;
            for (var i = 0; i < placementOrder.length; i++) {
                var placement = placementOrder[i];
                var tl = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight);
                var canDisplay = tl.top >= parentTop && tl.left >= parentLeft && tl.left + actualWidth <= parentLeft + parentWidth && tl.top + actualHeight <= parentTop + parentHeight;

                if (canDisplay) {
                    return placement;
                } else if (placementInfo.useOptimizedPlacementAlgorithm) {
                    // calculate the offset rate (area of popup outside parent area/popup area)
                    var offsetRate = 0;
                    if (tl.left < parentLeft) {
                        offsetRate += (parentLeft - tl.left) / actualWidth;
                    }
                    if (tl.left + actualWidth > parentLeft + parentWidth) {
                        offsetRate += (tl.left + actualWidth - parentLeft - parentWidth) / actualWidth;
                    }
                    if (tl.top < parentTop) {
                        offsetRate += (parentTop - tl.top) / actualHeight;
                    }
                    if (tl.top + actualHeight > parentTop + parentHeight) {
                        offsetRate += (tl.top + actualHeight - parentTop - parentHeight) / actualHeight;
                    }
                    // find the minimal offset rate
                    if (offsetRate < minOffsetRate) {
                        minOffsetRate = offsetRate;
                        minOffsetRateIndex = i;
                    }
                }
            }

            return placementOrder[placementInfo.useOptimizedPlacementAlgorithm ? minOffsetRateIndex : 0];
        },
        getPosition: function ($element) {
            $element = $element || this.$element

            var el = $element[0]
            var isBody = el.tagName === 'BODY'

            var parentDeclare = this.$element.attr('data-placement-target');
            if (parentDeclare) {
                var parents = this.$element.parents(parentDeclare);

                if (parents.length > 0) {
                    el = parents[0];
                }
            }

            if (!el) {
                el = this.$element[0];
            }

            var elRect    = el.getBoundingClientRect()
            if (elRect.width == null) {
                // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093
                elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })
            }
            var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()
            var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }
            var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null

            return $.extend({}, elRect, scroll, outerDims, elOffset)
        }
    });

    $.fn.popover = $.extend(function (option) {
        return this.each(function () {
            var $this = $(this)
              , data = $this.data('bs.popover')
              , options = typeof option === 'object' && option;
            if (!data)
                $this.data('bs.popover', (data = new Popover(this, options)));
            if (typeof option === 'string')
                data[option]();
        });
    }, _super);
})(jQuery);
var constant = {};

constant.guid = {
    empty: '00000000-0000-0000-0000-000000000000'
}

//数据验证起始值范围
constant.startNum = -1000000000000;
constant.endNum = 1000000000000;

constant.organization = {
    parentIdNull: "-1",
    defaultMaxLength: 25,
    EstateIndustryId: 23,
    NonEstateIndustryId: 0,
}

constant.date = {
    maxDate: '9999-11',
    minDate: '1900-01',
    dateFormat: 'yyyy-MM-dd',
    dateFormatUppercase: 'YYYY-MM-DD',
    dateFormatyyyyMMdd: 'yyyy/MM/dd',
    dateFormatyyyyMMddUppper: 'YYYY/MM/DD',
    dateFormatSeparator: '/',
    hourSelection: [0, 12, 24, 48, 72, 96, 120]
}

constant.workflow = {
    codeStartWith: 10000,
}
constant.toFixedNumber4 = 4;
constant.toFixedNumber2 = 2;

constant.priority = {
    low: 1,
    medium: 2,
    high: 3
}

constant.customer = {
    codeMaxLength: 50,
    nameMaxLength: 100,
    errorArray: ['CustomerImportDataFormatError', 'SaveFileError', 'CustomerCodeOutOfLength', 'CustomerNameOutOfLength']
}

constant.payTaxTypeList = [
    { value: 1, name: '一般纳税人' },
    { value: 2, name: '小规模纳税人' }];

constant.citReportTypeList = [
    { value: 1, name: '纳税申报表' },
    { value: 2, name: '季度预缴表' },
    { value: 3, name: '工作底稿' }];

constant.cfReportTypeList = [
    { value: 1, name: '企业所得税预算' },
    { value: 2, name: '增值税预算' },
    { value: 3, name: '消费税预算' },
    { value: 4, name: '增值税&消费税附加税费预算' },
    { value: 5, name: '房产税税预算' },
    { value: 6, name: '城镇土地使用税预算' },
    { value: 7, name: '印花税预算' },
    { value: 8, name: '契税预算' },
    { value: 9, name: '车辆购置税预算' },
    { value: 10, name: '车船税预算' },
    { value: 11, name: '土地增值税预算' },
    { value: 12, name: '个人所得税预算' },
    { value: 13, name: '关税预算' }
];

constant.businessUnit =
{
    BUmaxLength: 21
}

constant.activeStatus = {
    active: 1,
    deactive: 0
}

constant.organizationStructManage = {
    nameMaxLength: 21
}

constant.webapi = {
    prefix: '/api/v1'
}

constant.cache = {
    cacheName: 'webadmin',
    hubName: 'cacheHub',
    storageMode: 'localStorage',
    defaultCacheTime: '00000000',
    cacheUpdateMessage: '系统有更新,为了保证数据准确性,请刷新页面更新系统!', //will move to i18n
    cachePrex: 'atms.webadmin.data.',
    notify: {
        position: 'right',
        classes: 'alert-danger'
    }
}

constant.common = {
    undefined: 'undefined'
}

constant.serviceType = {
    Admin: 1,
    VAT: 2,
    AM: 3,
    FDD: 4,
    Dashboard: 5,
    CIT: 6,
    TCS: 7
}

constant.roleSource = {
    Unknown: 0,
    OrganizationLevel: 1,
    AreaLevel: 2,
    BusinessUnitLevel: 3,
    OriginalLevel: 4,
    DimensionLevel: 5,
}

constant.import = {
    overwrite: '1',
    append: '2'
}

constant.OperateLogType = {
    OperationLogOrganization: 0,
    OperationLogUser: 1,
    OperationLogProject: 2,
    OperationLogBasicData: 3,
    OperationLogReport: 4,

    OperationLogEnterPrise: 5,
    OperationLogSubjectCorres: 6,
    OperationLogRole: 7,
    OperationLogModelConfiguration: 8,
    OperationRuleEngineConfiguration: 9,
    OperationKeyvalueConfiguration: 10,
    OperationLogWorkflow: 11,
    OperationLogStock: 12
}

constant.page = {
    pageSize: 10
}
constant.page.pageSizeArrary = [10, 20, 50, 100, 5];

constant.Action = {
    View: 0,
    New: 1,
    Update: 2,
    Delete: 3,
    Copy: 4,
    AutoMapping: 5,
    ManualMapping: 6,
    CancelMapping: 7,
    Edit: 8
}

constant.OperationModule = {
    BasicDataOrganizationStructure: 1,
    BasicDataRegion: 2,
    BasicDataStandardAccount: 3,
    BasicDataWordLibrary: 4,
    BasicDataKeyValue: 5,
    Project: 6,
    ProjectServiceType: 7,
    User: 8,
    Organization: 9,
    Role: 10,
    UserRole: 11,
    BasicDataEnterpriceAccount: 12,
    TemplateFormula: 13,
    Template: 14,
    TemplateGroup: 15,
    ReportConfiguration: 16,
    BasicDataArea: 17,
    BasicDataCustomer: 18,
    BusinessUnit: 19
};

constant.UIGrid = {
    rowHeight: 40,
    selectionRowHeaderWidth: 40,

    errorRowHeight: 30,
    errorRowHeaderWidth: 30,

    minRowHeight: 25,
    minselectionRowHeaderWidth: 25,

    gapHeight: 6
}


constant.enterpriceAccount = {
    codeEmpty: 'EnterpriseAccountCodeEmpty',
    codeMaxLength: 'EnterpriseAccountCodeMaxLength',
    enterpriseAccountNameEmpty: 'EnterpriseAccountNameEmpty',
    nameMaxLength: 'EnterpriseAccountNameMaxLength',
    directionFormatError: 'DirectionFormatError',
    acctPropFormatError: 'AcctPropFormatError',
    noParentCode: 'NoParentCode',
}

constant.dimensionID = {
    businessUnitID: "c61a5bd6-a996-4952-9869-d053995237e5",
    areaID: "c61a5bd6-a996-4952-9869-d053995237e6",
    //机构层级和子公司不是一个定义,机构层级的ID之后用到会更改
    organizationStructureID: "c61a5bd6-a996-4952-9869-d053995237e7",
    orgSubChildrenID: "c61a5bd6-a996-4952-9869-d053995237e7"
}

// 系统定义的属性ID
constant.attributeID = {
    businessUnitID: 'c61a5bd6-a996-4952-9869-d053995237e5',
    areaID: 'c61a5bd6-a996-4952-9869-d053995237e6',
    organizationStructureID: 'c61a5bd6-a996-4952-9869-d053966537e8',
    userID: 'c61a5bd6-a996-4952-9869-d053996237e8',
    industryID: 'c61a5bd6-a996-4952-9869-d053996537e8',
    orgSubChildrenID: 'c61a5bd6-a996-4952-9869-d053995237e7',
    administrativeAreaID: 'c62a5bd6-a996-4952-9869-d053996537e88'
}

constant.userRoleDimensionValueID = {
    extraOrgDimensionID: 'extraOrgDimensionID',
    extaDimensionName: '附加',
    extraOrgDimensionValueName: '附加角色',
    originalRoleDimensionValueName: '原始角色',
    //附加在维度上的角色
    extraOrgDimensionValueID: 'extraOrgDimensionValueID',
    //附加原始角色
    originalRoleDimensionValueID: 'originalRoleDimensionValueID'
}

constant.dimensionType = {
    Unknown: 0,
    SelfDimension: 1,
    BusinessUnit: 2,
    Area: 3,
    OrganizationStructure: 4,
    User: 5,
    Industry: 6,
    OrgSubChildren: 7
}


constant.attributeType = {
    Unknown: 0,
    SelfDimension: 1,
    BusinessUnit: 2,
    Area: 3,
    OrganizationStructure: 4,
    User: 5,
    Industry: 6,
    OrgSubChildren: 7,
    RegionID: 10
}

// 区域排除的下拉选项
constant.areaExcludeAttributeType = [
    // 未知
    0,
];

constant.excludeAttributeType = [
    0,
    5,
    7
]

constant.level = {
    First: 0
}

constant.espAccountFilter = {
    key_0: '0',
    key_1: '1',
    key_2: '2',
    key_3: '3',
    key_4: '4',
    data: [{ key: '0', value: 'AllMappingStatus' }, { key: '1', value: 'Unmapped' },
                             { key: '2', value: 'Mapped' }, { key: '3', value: 'DirectionDifferent' },
                             { key: '4', value: 'AccountTypeDifferent' }]

}

constant.taxpayerNumberFilter = {
    key_0: '0',
    key_1: '1',
    key_2: '2',
}
constant.taxpayerNumberFilter.dataSource = [
    { key: constant.taxpayerNumberFilter.key_0, value: 'All' },
    { key: constant.taxpayerNumberFilter.key_1, value: 'HasTaxPayerNumber' },
    { key: constant.taxpayerNumberFilter.key_2, value: 'NoTaxPayerNumber' },
];

constant.comma = ',';

constant.DimensionType = {
    Unknown: 0,
    SelfDimension: 1,
    BusinessUnit: 2,
    Area: 3,
    OrganizationStructure: 4,
    User: 5,
    Industry: 6,
    OrgSubChildren: 7,
    Stock: 8
}

constant.Operation = {
    Add: 'add',
    Edit: 'edit',

    // 禁用
    Disable: 'disable',

    // 启用
    Enable: 'enable',

    // 查找添加
    findAdd: 'findAdd',

    // 删除
    Delete: 'delete',

    // 查询
    Query: 'Query',

    // 打开
    Open: 'Open',

    // 关闭
    Close: 'Close'
}

constant.TemplateGroupOperation = {
    // 直接连模板一起添加
    AddDirectly: 'addDirectly',

    // 先加模板组,暂不加模板
    AddGroupFirst: 'addGroupFirst',
    Edit: 'edit',

    // 删除
    Delete: 'delete'
}

constant.selectAllValue = '99';

constant.BasicDataManageMenuID = 'F9A18F3A-7E39-4661-BA00-F149710577C8';

constant.noPermissionClass = "no-permission";

constant.attributeTypeIDColMap = {
    0: '',
    1: '',
    2: 'businessUnitID',
    3: 'areaID',
    4: 'structureID',
    5: '',
    6: 'industryID',
    7: 'structureID',
    10: 'regionID'
};

constant.attributeTypeNameColMap = {
    0: '',
    1: '',
    2: 'businessUnitName',
    3: 'areaName',
    4: 'structureName',
    5: '',
    6: 'industryName',
    7: 'structureName',
    10: 'regionName'
};

// vat权限code
constant.vatPermission = {
    dataImport: {
        dataImportCode: '02.001',
        balanceSheet: {
            queryCode: '02.001.001',
            importCode: '02.001.002'
        },
        journalEntry: {
            queryCode: '02.001.003',
            importCode: '02.001.004'
        },
        erpImport: {
            queryCode: '02.001.005',
            importCode: '02.001.006'
        },
        outputInvoice: {
            queryCode: '02.001.009',
            importCode: '02.001.010'
        },
        inputInvoice: {
            queryCode: '02.001.011',
            importCode: '02.001.012'
        },
        customInvoice: {
            queryCode: '02.001.013',
            importCode: '02.001.014'
        },
        voucherMapping: {
            queryCode: '02.001.015',
            importCode: '02.001.016'
        },
        invoiceMapping: {
            queryCode: '02.001.017',
            importCode: '02.001.018'
        },
        auditAdjust: {
            queryCode: '02.001.007',
            importCode: '02.001.008'
        },
    },
    dataPreview: {
        dataPreviewCode: '02.002',
        balanceSheet: {
            queryCode: '02.002.001'
        },
        accountVoucher: {
            queryCode: '02.002.002'
        },
        customInvoice: {
            queryCode: '02.002.006'
        },
        outputInvoice: {
            queryCode: '02.002.004'
        },
        inputInvoice: {
            queryCode: '02.002.003'
        }
    },
    dataManage: {
        dataManageCode: '02.003',
        accountMappingCode: '02.003.001',
        accountMapping: {
            queryCode: '02.003.001.001',
            importCode: '02.003.001.002'
        },
        goodsMappingCode: '02.003.002',
        goodsMapping: {
            queryCode: '02.003.002.001',
            saveCode: '02.003.002.002'
        },


        caculateDataCode: '02.003.003',
        unbilledInvoiceCode: '02.003.004',
    },
    reportView: {
        reportViewCode: '02.004',
        bsplCode: '02.004.001',
        bspl: {
            bsCode: '02.004.001.001',
            plCode: '02.004.001.002'
        },
        taxReturnCode: '02.004.002',
        taxReturn: {
            queryCode: '02.004.002.001',
            editCode: '02.004.002.002'
        },
    },
    dataAnalysis: {
        dataAnalysisCode: '02.005',
        modelAnalysisCode: '02.005.001',
        modelAnalysis: {
            queryCode: '02.005.001.001',
            filterCode: '02.005.001.005'
        },
        dashboard: {
            dashboardCode: '02.005.002',
            querySummaryDashboardCode: '02.005.002.001',
            singleOrgIndexDashboardCode: '02.005.002.002',
        }
    },

    outputInvoice: {

        importVehicelCase: {
            queryCode: '02.007.001.001',
            holdCaseCode: '02.007.001.002',
            reassignCaseCode: '02.007.001.003',
            triggerSyncCode: '02.007.001.004'
        },
        bdInvoice: {
            queryCode: '02.007.002.001',
            manualPrintBDInvoiceCode: '02.007.002.002',
            autoPrintBDInvoiceCode: '02.007.002.003',
            editVehicleCaseCode: '02.007.002.004',
            cancelAndReprintCode: '02.007.002.005',
            cancelInvoiceCode: '02.007.002.006'
        },
        gdInvoice: {
            queryCode: '02.007.003.001',
            printCode: '02.007.003.002',
            cancelAndReprintCode: '02.007.003.003',
            cancelInvoiceCode: '02.007.003.004',
            RedLetterCode: '02.007.003.005',
            fapiaoQuotaSettingsCode: '02.007.003.006',
            markupRateCode: '02.007.003.007'
        },
        gdShipment: {
            queryCode: '02.007.004.001',
            importCodeCode: '02.007.004.002'
        },
        reconciliationConfig: {
            queryCode: '02.007.005.001',
            addCode: '02.007.005.002',
            editCode: '02.007.005.003',
            deleteCode: '02.007.005.004',
            reSortCode: '02.007.005.005'
        },
        outputReconciliationOverview: {
            queryCode: '02.007.006.001'
        },
        mappingConfig: {
            queryCode: '02.007.007.001',
            editCode: '02.007.007.002',
        },
        taxControlDisk: {
            queryCode: '02.007.008.001',
            editCode: '02.007.008.002',
        }

    }


};

// 权限代码
constant.adminPermission = {
    basicData: {

        // 企业账套
        enterpriseAccountSet: {
            // 查看
            queryCode: '01.001.001',
            // 添加
            addCode: '01.001.002',
            // 维护
            editCode: '01.001.003'
        },

        // 事业部
        businessUnit: {
            queryCode: '01.001.008',
            editCode: '01.001.009'
        },

        // 区域
        areaManage: {
            queryCode: '01.001.010',
            editCode: '01.001.011'
        },
        // 机构层级
        orangizationStructure: {
            queryCode: '01.001.006',
            editCode: '01.001.007'
        },

        // 客户列表
        customerList: {
            queryCode: '01.001.004',
            editCode: '01.001.005'
        },

        // 自定义维度
        selfDimension: {
            queryCode: '01.001.012',
            editCode: '01.001.013'
        }
    },
    infrastructure: {
        //用户管理 
        userManage: {
            queryCode: '01.002.002.001',
            addCode: '01.002.002.002',
            editCode: '01.002.002.003'
        },
        //机构管理
        organizationManage: {
            queryCode: '01.002.001.001',
            addCode: '01.002.001.002',
            editCode: '01.002.001.003',
        },
        //角色管理
        roleManage: {
            queryCode: '01.002.003.001',
            addCode: '01.002.003.002',
            editCode: '01.002.003.003',
        },
        //自定义显示属性管理
        customAttribute: {
            queryCode: '01.002.001.004',
        },
        //维度上的用户权限设置
        accessSetting: {
            queryCode: '01.002.001.005',
            editCode: '01.002.001.006',
        },
        //工作流配置
        workflowManage: {
            queryCode: '01.002.004.001',
            addCode: '01.002.004.002',
            editCode: '01.002.004.003',
        },
    },
    systemConfiguration: {
        //报表配置
        declarationFormConfigurationCode: '01.003.002',
        declarationFormConfiguration: {
            queryCode: '01.003.002.001',
            addCode: '01.003.002.002',
            editCode: '01.003.002.003'
        },
        //分析模型配置
        modelConfiguration: {
            queryCode: '01.003.003.001',
            editCode: '01.003.003.002',
            maintainCustomCode: '01.003.003.003',
            maintainModelTreeCode: '01.003.003.004'
        },
        // 科目对应
        subjectCorresponding: {
            queryCode: '01.003.001.001',
            editCode: '01.003.001.002',
        },
        ruleEnginee: {
            viewRatePayer: '01.004.001.001',
            defaultRatePayerAction: '01.004.001.002',
            specialRatePayerAction: '01.004.001.003',
            //地方税
            LocalTax: '01.004.002',
            //地方税-城市建设
            viewCityBuilding: '01.004.002.001.001',
            defaultCityBuildingAction: '01.004.002.001.002',
            specialCityBuildingAction: '01.004.002.001.003',
            //地方教育
            viewLocalEducation: '01.004.002.002.001',
            defaultLocalEducationAction: '01.004.002.002.002',
            specialLocalEducationAction: '01.004.002.002.003',
            //教育费附加税 

            viewEducationAttach: '01.004.002.003.001',
            defaultEducationAttachAction: '01.004.002.003.002',
            specialEducationAttachAction: '01.004.002.003.003',
            //印花税
            viewStampTax: '01.004.002.004.001',
            defaultStampTaxAction: '01.004.002.004.002',
            specialStampTaxAction: '01.004.002.004.003',
            //水利基金
            viewWaterFund: '01.004.002.005.001',
            defaultWaterFundAction: '01.004.002.005.002',
            specialWaterFundAction: '01.004.002.005.003'
        },
        keyValueConfig: {
            viewKey: '01.003.004.001',
            keyAction: '01.003.004.002'
        }
    }
};

constant.basicDataUrl = {
    orangizationStructureManage: '#/masterData/orangizationStructureManage',
    businessUnit: '#/masterData/businessUnit',
    regionManage: '#/masterData/regionManage',
    enterpriseAccountManage: '#/financialData/enterpriseAccountManage',
    customerListManage: '#/financialData/customerListManage',
};

/************************************************vat constant start*************************************************/
constant.inputInvoice = {
    //发票状态
    statusType: {
        InvoiceHasUpload: { id: 1, value: 'InvoiceHasUpload' },  //上传
        InvoiceHasAddRecord: { id: 2, value: 'InvoiceHasAddRecord' },//补录
        InvoiceUnrecognize: { id: 3, value: 'InvoiceUnrecognize' },  //无法识别
        InvoiceHasRefund: { id: 4, value: 'InvoiceHasRefund' }, //已退票
        InvoiceRecognizeSuccess: { id: 5, value: 'InvoiceRecognizeSuccess' },  //识别成功
        InvoiceVerifyFailure: { id: 6, value: 'InvoiceVerifyFailure' },  //验真失败
        InvoicePendingMatch: { id: 7, value: 'InvoicePendingMatch' },  //待匹配
        InvoiceHasMatch: { id: 8, value: 'InvoiceHasMatch' },
        InvoicePendingVerify: { id: 9, value: 'InvoicePendingVerify' },
        InvoiceHasVerify: { id: 10, value: 'InvoiceHasVerify' },
        InvoiceUnableVerify: { id: 11, value: 'InvoiceUnableVerify' },
        InvoiceManualVerify: { id: 12, value: 'InvoiceManualVerify' },
        InvoiceHasClean: { id: 13, value: 'InvoiceHasClean' },//已清理
        InvoiceHasExpired: { id: 14, value: 'InvoiceHasExpired' },  //已失效
        InvoiceRecognizeFailure: { id: 15, value: 'InvoiceRecognizeFailure' },  //识别失败
    },
    //发票类型,普票或专票
    invoiceType: {
        VatInvoiceSpecialTicket: { id: 1, value: 'VatInvoiceSpecialTicket' },
        VatInvoiceOrdinaryTicket: { id: 2, value: 'VatInvoiceOrdinaryTicket' },
    },
    //发票来源类型,原料采购,非原料集中采购,报销
    invoiceSourceType: {
        InvoiceRawMaterialPurchase: { id: 1, value: 'InvoiceRawMaterialPurchase' },
        InvoiceNonRawMaterialPurchase: { id: 2, value: 'InvoiceNonRawMaterialPurchase' },
        InvoiceClaim: { id: 3, value: 'InvoiceClaim' },
    },
    //发票实体类型,纸票或电子票
    invoiceEntityType: {
        InvoicePaperTicket: { id: 1, value: 'InvoicePaperTicket' },
        InvoiceElectronicTicket: { id: 2, value: 'InvoiceElectronicTicket' },
    },
    //发票上传方式,纸质文档,扫描枪,扫描仪
    invoiceUploadType: {
        InvoiceModePDF: { id: 1, value: 'InvoiceModePDF' },
        InvoiceModeScan: { id: 2, value: 'InvoiceModeScan' },
        InvoiceModeMobileDevice: { id: 3, value: 'InvoiceModeMobileDevice' },  //扫描抢
    },

    //上传文件的时候,上传的状态,成功,失败,和重复
    invoiceUploadStatus: {
        success: { id: 1, value: 'UploadSuccess' },
        failure: { id: 2, value: 'UploadFailure' },
        duplicate: { id: 3, value: 'UploadDuplicate' },
    }
}
constant.inputInvoice.invoiceSourceTypeArray = [constant.inputInvoice.invoiceSourceType.InvoiceRawMaterialPurchase,
    constant.inputInvoice.invoiceSourceType.InvoiceNonRawMaterialPurchase,
    constant.inputInvoice.invoiceSourceType.InvoiceClaim
];


constant.inputInvoiceImportBackEndErrorType = {
    DuplicateInputInvoice: 'DuplicateInputInvoice',
    InputInvoiceAlreadyPassed: 'InputInvoiceAlreadyPassed',
    LessThanDetailsTotal: 'LessThanDetailsTotal',
    NotHaveTotalInvoice: 'NotHaveTotalInvoice'
};

constant.errorLength = 600;

constant.errorMaxLine = 10;

constant.validateLength = {
    StringLength_50: 50,
    StringLength_100: 100,
    StringLength_256: 256,
    StringLength_500: 500,
    StringLength_200: 200
}

constant.effectiveTaxRate = ['17%', '13%', '11%', '6%', '5%', '3%', '1.5%', '0.17', '0.13', '0.11', '0.06', '0.05', '0.03', '0.015'];

constant.outputTaxRate = ['17%', '13%', '11%', '6%', '5%', '3%', '1.5%', '0%', '0.17', '0.13', '0.11', '0.06', '0.05', '0.03', '0.015', '0', '0.00'];

constant.AccountMappingProcessKey = { UnSelected: 'UnSelected', Submit: 'Submit', Undo: 'Undo' }

constant.pagesize = 100;

constant.ErpCheckType = {
    CustomInvoice_DuplicatePayNum: 20
}

constant.ProjectStatusEnum = {
    UnStarted: 10,
    Imported: 20,
    AccountMapSubmitted: 30,
    Generated: 40,
    ReportSubmitted: 50,
    ReportApproved: 60,
    ReportRejected: 70,
    Completed: 100
}

//对应TaxAdmin.Dictionary表中workflow相关的Task的Dickey
constant.DictionaryDictKey = {
    //节点:
    ApproveReport: 'ApproveReport', //报表审核
    DataImport: 'DataImport', //数据导入
    DeclarationComplete: 'DeclarationComplete', //申报完成
    DataProcess: 'DataProcess', //数据处理
    ViewReport: 'ViewReport',//查看报表

    //数据导入Task:
    WFImportErpData: 'WFImportErpData',
    WFImportBalanceTable: 'WFImportBalanceTable',
    WFImportJournalEntry: 'WFImportJournalEntry',
    WFImportOutputInvoice: 'WFImportOutputInvoice',
    WFImportIncomeInvoice: 'WFImportIncomeInvoice',
    WFImportCustomInvoice: 'WFImportCustomInvoice',
    WFImportVoucherMap: 'WFImportVoucherMap',
    WFImportInvoiceMap: 'WFImportInvoiceMap',
    WFImportAuditAdjust: 'WFImportAuditAdjust',

    //数据整理Task
    WFAccountMap: 'WFAccountMap',
    WFCargoNameMatch: 'WFCargoNameMatch', //货物名称匹配
    WFDataProcess: 'WFDataProcess', //数据处理
    WFUnBilledInvoice: 'WFUnBilledInvoice', //未开票销售

    //查看报表Task:
    WFViewFinancialReport: 'WFViewFinancialReport', //查看财务报表
    WFSubmitReport: 'WFSubmitReport', //提交审核

    //报表审核Task:
    WFReportApproval: 'WFReportApproval',//审核报表
    //WFApproveReport: 'WFApproveReport', //报表审核

    //完成申报Task:
    WFDeclarationComplete: 'WFDeclarationComplete', //完成申报
    WFUploadCertificate: 'WFUploadCertificate',//上传凭证
}

//task一旦启用,必须为选中Mandatory
constant.DictionaryDictKey.WFMandatoryTask = [constant.DictionaryDictKey.WFSubmitReport,
    constant.DictionaryDictKey.WFReportApproval, constant.DictionaryDictKey.WFDeclarationComplete];

//task不能选择mandatory
constant.DictionaryDictKey.WFNoSelectionTask = [constant.DictionaryDictKey.WFCargoNameMatch];



constant.inValidNum = -1;

constant.ReMapMaxLength = {
    MaxStdCodeLength: 20,
    MaxTextLength: 20,
    MaxRemarkLength: 50
}

constant.ValidationMessag = {
    ValidationExisted: "validation existed",
    ReValidate: "revalidate"
}

constant.WorkflowMessage = {
    Issue: "异常事项:",
    CalDateTime: "计算时间:",
    MessageDetail: "异常详情:",
    ExceptionIssueValue: "数据处理"
}

constant.WholeYearPeriod = -1;

constant.DataProccessStatus = {
    Unstarted: "unstarted", //未生成
    Processing: "processing", //处理中
    Completed: "completed",//已生成
    ToUpdate: "toUpdate",//需更新
    NoData: "noData",//无数据
    Error: "error"//错误

}


/************************************************vat constant end*************************************************/

/********key value*****************/
constant.keyValueType = [
    { value: 1, name: '系统公共' },
    { value: 2, name: '自定义' }
];

constant.geoCoordMap = {
    '海门': [121.15, 31.89],
    '鄂尔多斯': [109.781327, 39.608266],
    '招远': [120.38, 37.35],
    '舟山': [122.207216, 29.985295],
    '齐齐哈尔': [123.97, 47.33],
    '盐城': [120.13, 33.38],
    '赤峰': [118.87, 42.28],
    '青岛': [120.33, 36.07],
    '乳山': [121.52, 36.89],
    '金昌': [102.188043, 38.520089],
    '泉州': [118.58, 24.93],
    '莱西': [120.53, 36.86],
    '日照': [119.46, 35.42],
    '胶南': [119.97, 35.88],
    '南通': [121.05, 32.08],
    '拉萨': [91.11, 29.97],
    '云浮': [112.02, 22.93],
    '梅州': [116.1, 24.55],
    '文登': [122.05, 37.2],
    '上海': [121.48, 31.22],
    '攀枝花': [101.718637, 26.582347],
    '威海': [122.1, 37.5],
    '承德': [117.93, 40.97],
    '厦门': [118.1, 24.46],
    '汕尾': [115.375279, 22.786211],
    '潮州': [116.63, 23.68],
    '丹东': [124.37, 40.13],
    '太仓': [121.1, 31.45],
    '曲靖': [103.79, 25.51],
    '烟台': [121.39, 37.52],
    '福州': [119.3, 26.08],
    '瓦房店': [121.979603, 39.627114],
    '即墨': [120.45, 36.38],
    '抚顺': [123.97, 41.97],
    '玉溪': [102.52, 24.35],
    '张家口': [114.87, 40.82],
    '阳泉': [113.57, 37.85],
    '莱州': [119.942327, 37.177017],
    '湖州': [120.1, 30.86],
    '汕头': [116.69, 23.39],
    '昆山': [120.95, 31.39],
    '宁波': [121.56, 29.86],
    '湛江': [110.359377, 21.270708],
    '揭阳': [116.35, 23.55],
    '荣成': [122.41, 37.16],
    '连云港': [119.16, 34.59],
    '葫芦岛': [120.836932, 40.711052],
    '常熟': [120.74, 31.64],
    '东莞': [113.75, 23.04],
    '河源': [114.68, 23.73],
    '淮安': [119.15, 33.5],
    '泰州': [119.9, 32.49],
    '南宁': [108.33, 22.84],
    '营口': [122.18, 40.65],
    '惠州': [114.4, 23.09],
    '江阴': [120.26, 31.91],
    '蓬莱': [120.75, 37.8],
    '韶关': [113.62, 24.84],
    '嘉峪关': [98.289152, 39.77313],
    '广州': [113.23, 23.16],
    '延安': [109.47, 36.6],
    '太原': [112.53, 37.87],
    '清远': [113.01, 23.7],
    '中山': [113.38, 22.52],
    '昆明': [102.73, 25.04],
    '寿光': [118.73, 36.86],
    '盘锦': [122.070714, 41.119997],
    '长治': [113.08, 36.18],
    '深圳': [114.07, 22.62],
    '珠海': [113.52, 22.3],
    '宿迁': [118.3, 33.96],
    '咸阳': [108.72, 34.36],
    '铜川': [109.11, 35.09],
    '平度': [119.97, 36.77],
    '佛山': [113.11, 23.05],
    '海口': [110.35, 20.02],
    '江门': [113.06, 22.61],
    '章丘': [117.53, 36.72],
    '肇庆': [112.44, 23.05],
    '大连': [121.62, 38.92],
    '临汾': [111.5, 36.08],
    '吴江': [120.63, 31.16],
    '石嘴山': [106.39, 39.04],
    '沈阳': [123.38, 41.8],
    '苏州': [120.62, 31.32],
    '茂名': [110.88, 21.68],
    '嘉兴': [120.76, 30.77],
    '长春': [125.35, 43.88],
    '胶州': [120.03336, 36.264622],
    '银川': [106.27, 38.47],
    '张家港': [120.555821, 31.875428],
    '三门峡': [111.19, 34.76],
    '锦州': [121.15, 41.13],
    '南昌': [115.89, 28.68],
    '柳州': [109.4, 24.33],
    '三亚': [109.511909, 18.252847],
    '自贡': [104.778442, 29.33903],
    '吉林': [126.57, 43.87],
    '阳江': [111.95, 21.85],
    '泸州': [105.39, 28.91],
    '西宁': [101.74, 36.56],
    '宜宾': [104.56, 29.77],
    '呼和浩特': [111.65, 40.82],
    '成都': [104.06, 30.67],
    '大同': [113.3, 40.12],
    '镇江': [119.44, 32.2],
    '桂林': [110.28, 25.29],
    '张家界': [110.479191, 29.117096],
    '宜兴': [119.82, 31.36],
    '北海': [109.12, 21.49],
    '西安': [108.95, 34.27],
    '金坛': [119.56, 31.74],
    '东营': [118.49, 37.46],
    '牡丹江': [129.58, 44.6],
    '遵义': [106.9, 27.7],
    '绍兴': [120.58, 30.01],
    '扬州': [119.42, 32.39],
    '常州': [119.95, 31.79],
    '潍坊': [119.1, 36.62],
    '重庆': [106.54, 29.59],
    '台州': [121.420757, 28.656386],
    '南京': [118.78, 32.04],
    '滨州': [118.03, 37.36],
    '贵阳': [106.71, 26.57],
    '无锡': [120.29, 31.59],
    '本溪': [123.73, 41.3],
    '克拉玛依': [84.77, 45.59],
    '渭南': [109.5, 34.52],
    '马鞍山': [118.48, 31.56],
    '宝鸡': [107.15, 34.38],
    '焦作': [113.21, 35.24],
    '句容': [119.16, 31.95],
    '北京': [116.46, 39.92],
    '徐州': [117.2, 34.26],
    '衡水': [115.72, 37.72],
    '包头': [110, 40.58],
    '绵阳': [104.73, 31.48],
    '乌鲁木齐': [87.68, 43.77],
    '枣庄': [117.57, 34.86],
    '杭州': [120.19, 30.26],
    '淄博': [118.05, 36.78],
    '鞍山': [122.85, 41.12],
    '溧阳': [119.48, 31.43],
    '库尔勒': [86.06, 41.68],
    '安阳': [114.35, 36.1],
    '开封': [114.35, 34.79],
    '济南': [117, 36.65],
    '德阳': [104.37, 31.13],
    '温州': [120.65, 28.01],
    '九江': [115.97, 29.71],
    '邯郸': [114.47, 36.6],
    '临安': [119.72, 30.23],
    '兰州': [103.73, 36.03],
    '沧州': [116.83, 38.33],
    '临沂': [118.35, 35.05],
    '南充': [106.110698, 30.837793],
    '天津': [117.2, 39.13],
    '富阳': [119.95, 30.07],
    '泰安': [117.13, 36.18],
    '诸暨': [120.23, 29.71],
    '郑州': [113.65, 34.76],
    '哈尔滨': [126.63, 45.75],
    '聊城': [115.97, 36.45],
    '芜湖': [118.38, 31.33],
    '唐山': [118.02, 39.63],
    '平顶山': [113.29, 33.75],
    '邢台': [114.48, 37.05],
    '德州': [116.29, 37.45],
    '济宁': [116.59, 35.38],
    '荆州': [112.239741, 30.335165],
    '宜昌': [111.3, 30.7],
    '义乌': [120.06, 29.32],
    '丽水': [119.92, 28.45],
    '洛阳': [112.44, 34.7],
    '秦皇岛': [119.57, 39.95],
    '株洲': [113.16, 27.83],
    '石家庄': [114.48, 38.03],
    '莱芜': [117.67, 36.19],
    '常德': [111.69, 29.05],
    '保定': [115.48, 38.85],
    '湘潭': [112.91, 27.87],
    '金华': [119.64, 29.12],
    '岳阳': [113.09, 29.37],
    '长沙': [113, 28.21],
    '衢州': [118.88, 28.97],
    '廊坊': [116.7, 39.53],
    '菏泽': [115.480656, 35.23375],
    '合肥': [117.27, 31.86],
    '武汉': [114.31, 30.52],
    '大庆': [125.03, 46.58],
    '香港特别行政区': [113.95, 22.26]
};

constant.colorArray = ['#a32020', '#eb8c00', '#db536a', '#dc6900', '#e0301e', '#602320', '#3f3f40', '#968c6d'];


/************************************************cit constant start*************************************************/
constant.yearPeriod = -1;
constant.pageSize = 100;
constant.allDataPageSize = 0;
constant.periodInforConst = {
    NoRecord: -10, //没有记录
};

constant.OutputInvoiceCancalDialog = "cancelGDModal.html";
constant.CaseImportedStatusEnum = {
    Normal: 1,
    Opccupied: 2,
    Duplicated: 3,
    Prohibit: 4,
    Holded: 5
};

constant.TagRule = {

    Unknown: 0,

    // 自动
    Auto: 1,

    // 顺序计算
    Aggregation: 2,

    // 手动
    Manual: 3,
};

constant.purchaserSeller = {
    "N": 0,
    "Y": 1,
    "N/A": 2
};
constant.specialText = {
    "NULL": 0,
    "Other": 1,
    "N/A": 2
};

constant.teslaConfirmClassName = 'tesla-confirm';
constant.splitValidation = "<#@@#>";
//身份证省份
constant.vcity = {
    11: "北京", 12: "天津", 13: "河北", 14: "山西", 15: "内蒙古",
    21: "辽宁", 22: "吉林", 23: "黑龙江", 31: "上海", 32: "江苏",
    33: "浙江", 34: "安徽", 35: "福建", 36: "江西", 37: "山东", 41: "河南",
    42: "湖北", 43: "湖南", 44: "广东", 45: "广西", 46: "海南", 50: "重庆",
    51: "四川", 52: "贵州", 53: "云南", 54: "西藏", 61: "陕西", 62: "甘肃",
    63: "青海", 64: "宁夏", 65: "新疆", 71: "台湾", 81: "香港", 82: "澳门", 91: "国外"
};


constant.taxControlStatus = {
    0: 'InActive',
    1: 'Active',
    null: ''
};

constant.TaxControlDiskType = {
    1: 'BaiWang',
    2: 'HangXing',
    null: ''
};

constant.CarType = ['纯电动轿车', '纯电动乘用车'];

/************************************************cit constant end*************************************************/
// enum for object model
commonModule.factory('enums', ['$translate', function ($translate) {
    'use strict';

    return {
        tabType: {
            main: 0,
            dashboard: 1,
            chartEdit: 2,
            commonUrl: 3
        },

        keyCode: {
            backspace: 8,
            tab: 9,
            enter: 13,
            shift: 16,
            ctrl: 17,
            alt: 18,
            esc: 27,
            space: 32,
            left: 37,
            up: 38,
            right: 39,
            down: 40,
            select: 41,
            delete: 46,
            number0: 48,
            at: 64,
            letterz: 90,
            padmin: 96,
            padmax: 111,
            semicolon: 186,
            graveaccent: 192,
            openbracket: 219,
            singlequote: 222
        },

        domNodeType: {
            element: 1,
            attr: 2,
            text: 3
        },

        userStatus: {
            active: 1,
            inActive: -1,
            disabled: 0,
            locked: -2
        },

        adminEvent: {
            layoutChanged: 'admin:layoutChanged'
        },

        standardAccountDirection: {
            '1': 'StandardAccountDebit',
            '-1': 'StandardAccountCredit'
        },

        standardAccountAcctProp: {
            1: 'Asset',
            2: 'Debt',
            3: 'Joint',
            4: 'Equity',
            5: 'Cost',
            6: 'Loss'
        },

        modelType: {
            1: 'SystemCommonModel',
            2: 'OrgCommonModel',
            3: 'OrgCustomModel'
        },

        modelFeature: {
            1: 'IndexAnalysis',
            2: 'EntriesCheck'
        },

        /*************************************vat enum start************************************/

        vatImportType: {
            erp: 1,             //财务数据导入
            incomeInvoice: 2,   //进项发票导入
            journalEntry: 3,    //序时账导入
            outputInvoice: 4,   //销项发票导入
            tb: 5,              //TB导入
            mapping: 6          //Mapping关系导入
        },


        vatDataImportStatus: {
            UnImported: 0,      //未导入
            TbImported: 1,      //TB数据已导入
            ErpImported: 2      //财务数据已导入
        },

        validationType: {
            TrialBalance: 0,        //试算平衡表
            InputVoice: 1,          //进项发票
            OutputVoice: 2,         //销项发票
            ErpDuplicate: 3,        //重复数据
            ErpBasicCheck: 4,       //基础数据校验
            ErpCorrect: 5,          //数据正确性
            JournalEntry: 6,        //序时账验证错误
            InputInvoiceItem: 7     //进项发票明细
        },

        vatMenuStates: {
            expanded: 0,
            collapsing: 1,
            expanding: 2,
            collapsed: 3
        },

        vatEvent: {
            layoutChanged: 'vat:layoutChanged'
        },

        serviceType:
        {
            VAT: "2",
            FDD: "4",
            CIT: "6",
            TaxAudit: "8",
            RPT: "9",
            DTA: "10",
            CF: "11",
            AssetsManage: "12"
        },

        //发票类型
        invoiceType: {
            VATInvoice: 1,
            FreightTransport: 2,
            MotorVehicle: 3,
            AgriculturalProduct: 4,
            Other: 5
        },

        cellDataType:
        {
            Accounting: 1,
            Percentage: 2,
            Boolean: 3,
            String: 4,
            Integer: 5
        },

        //销项发票类型
        outputInvoiceType: {
            Normal: 0,
            Special: 1,
        },

        cellDataSourceType:
        {
            /// <summary>
            /// 公式(包含KeyValue)
            /// </summary>
            Formula: 1,

            /// <summary>
            /// 凭证
            /// </summary>
            Voucher: 2,

            /// <summary>
            /// 销项发票
            /// </summary>
            OutputInvoice: 3,

            /// <summary>
            /// 进项发票
            /// </summary>
            InputInvoice: 4,

            /// <summary>
            /// 海关发票
            /// </summary>
            CustomInvoice: 5,

            /// <summary>
            /// 手工录入
            /// </summary>
            KeyIn: 6,

            /// <summary>
            /// 关联模型
            /// </summary>
            RelatedModel: 7,

            /// <summary>
            /// SAP日报
            /// </summary>
            SapDaily: 8
        },

        //vat导入按钮类型
        vatImportBtnType: {
            Import: 0,          //导入
            CoverImport: 1,     //覆盖导入
            AddImport: 2        //追加导入
        },

        vatCompareStatus: {
            None: 0,
            UnBilled: 10,
            PartBilled: 20,
            Billed: 30,
            UnAccounted: 40,
            PartAccounted: 50,
            Accounted: 60
        },

        //科目重对应类型
        vatReMapType: {
            ReMapVoucher: 1,
            ReMapCust: 2
        },

        vatModuleEnum:
        {
            //[Display(Name = "试算平衡表导入")]
            Import_TrialBalance: 1,
            //[Display(Name = "序时账导入")]
            Import_JournalEntry: 2,
            //[Display(Name = "财务数据导入")]
            Import_Erpdata: 3,
            //[Display(Name = "销项发票导入")]
            Import_OutputInvoice: 4,
            //[Display(Name = "进项发票导入")]
            Import_InputInvoice: 5,
            //[Display(Name = "海关清单导入")]
            Import_CustomInvoice: 6,
            //[Display(Name = "凭证对应关系导入")]
            Import_VoucherMapping: 7,
            //[Display(Name = "发票对应关系导入")]
            Import_InvoiceMapping: 8,
            //[Display(Name = "审计调整")]
            Import_AuditAdjust: 9,
            //[Display(Name = "科目对应")]
            Import_AccountMapping: 20,
            //[Display(Name = "数据处理")]
            Import_CalculateData: 21,
            //[Display(Name = "货物名称匹配")]
            Import_GoodsMapping: 22,
            // [Display(Name = "未开票销售")]
            Import_UnbilledInvoice: 23,
            //[Description("模型分析")]
            Result_ModelAnalysisResult: 26,

            //[Description("纳税申报表")]
            Report_TaxDeclaration: 60,

            //[Description("增值说纳税申报表")]
            Report_VatTaxReturn: 61,

            //[Description("本期销售情况明细(附表一)")]
            Report_CurrentSalesDetailOne: 62,

            //[Description("本期销售情况明细(附表二)")]
            Report_CurrentSalesDetailTwo: 63,

            //[Description("服务,不动产和无形资产扣除项目明细(附表三)")]
            Report_ServiceAssets: 64,

            //[Description("税额抵减情况表(附表四)")]
            Report_TaxOffset: 65,

            //[Description("不动产分期抵扣表(附表五)")]
            Report_AssetsDeducted: 66,

            //[Description("固定资产")]
            Report_Assets: 67,

            //[Description("抵扣进项税额结构明细表")]
            Report_IncomeTaxDeducted: 68,

            //[Description("增值说减免税申报明细表")]
            Report_VatTaxRelief: 69,

            //[Description("附加税报表")]
            Report_AdditionalTax: 70,

            // [Description("报表生成-财务报表")]
            Report_BSPL: 100
        },

        vatModuleNameDic:
      {
          //[Display(Name = "试算平衡表导入")]
          '1': 'Import_TrialBalance',
          //[Display(Name = "序时账导入")]
          '2': 'Import_JournalEntry',
          //[Display(Name = "财务数据导入")]
          '3': 'Import_Erpdata',
          //[Display(Name = "销项发票导入")]
          '4': 'Import_OutputInvoice',
          //[Display(Name = "进项发票导入")]
          '5': 'Import_InputInvoice',
          //[Display(Name = "海关清单导入")]
          '6': 'Import_CustomInvoice',
          //[Display(Name = "凭证对应关系导入")]
          '7': 'Import_VoucherMapping',
          //[Display(Name = "发票对应关系导入")]
          '8': 'Import_InvoiceMapping',
          //[Display(Name = "审计调整")]
          '9': 'Import_AuditAdjust',
          //[Display(Name = "科目对应")]
          '20': 'Import_AccountMapping',
          //[Display(Name = "数据处理")]
          '21': 'Import_CalculateData',
          //[Display(Name = "货物名称匹配")]
          '22': 'Import_GoodsMapping',
          // [Display(Name = "未开票销售")]
          '23': 'Import_UnbilledInvoice',
          '100': 'FinancialReturn',
          '26': 'Result_ModelAnalysisResult',
          '60': 'TaxReturn'
      },

        vatLogOperationTypeEnum:
        {
            //[Display(Name = "添加")]
            AddData: 1,

            //[Display(Name = "删除")]
            DeleteData: 2,

            //[Display(Name = "导入")]
            Import: 10,

            //[Display(Name = "覆盖导入")]
            CoverImport: 11,

            //[Display(Name = "追加导入")]
            AddImport: 12,

            //[Display(Name = "清空")]
            ClearData: 13,

            //[Display(Name = "删除重复记录")]
            DeleteDuplicate: 14,

            //[Display(Name = "刷新校验")]
            Refresh: 15,

            //[Display(Name = "手工对应")]
            GM_ManualMapping: 20,

            // [Display(Name = "取消对应")]
            GM_CancelMapping: 21,

            //[Display(Name = "自动对应")]
            AM_AutoMapping: 30,

            // [Display(Name = "手工对应")]
            AM_ManualMapping: 31,

            //[Display(Name = "取消对应")]
            AM_CancelMapping: 32,

            //[Display(Name = "新增手工重分类")]
            AM_AddManualClass: 33,

            //[Display(Name = "删除手工重分类")]
            AM_DeleteManualClass: 34,

            //[Display(Name = "编辑手工重分类")]
            AM_EditManualClass: 35,

            //[Display(Name = "新增凭证重分类")]
            AM_AddVoucherClass: 36,

            //[Display(Name = "删除凭证重分类")]
            AM_DeleteVoucherClass: 37,

            //[Display(Name = "编辑凭证重分类")]
            AM_EditVoucherClass: 38,

            //[Display(Name = "数据处理")]
            CalculateData: 40,

            //[Display(Name = "自动数据处理")]
            AutoCalculateData: 41,

            //[Description("财务报表生成")]
            Generate_BSPL: 42,

            //[Description("提交报表")]
            SubmitReport: 43,

            //[Description("撤销报表")]
            WithdrawReport: 44,

            //[Description("审核通过报表")]
            ApproveReport: 45,

            //[Description("拒绝审核")]
            RejectReport: 46,

            //[Description("完成申报")]
            DeclarationComplete: 47,

            //[Description("上传凭证")]
            UploadCertificate: 48,

            //[Description("疑点筛选")]
            DoubtFilter: 53,
        },
        formulaDataSourceType:
        {
            // 其他数据源,如公式中的税率、数字部分
            Other: 0,

            // 进项数据源
            InputInvoice: 1,

            // 进项明细数据源
            InputInvoiceDetail: 2,

            // 销项数据源
            OutputInvoice: 3,

            // 凭证数据源
            Voucher: 4,

            // 报表数据源
            Report: 5,

            // 条件判断数据源
            Judgment: 6,

            //// Sap日报数据源
            //SapDaily: 7,

            //// 土地出让金数据源
            //LandSell: 8,

            ////未开票数据源
            //Unbilled: 9,
            KeyInSource: 10,
            QCYESource: 11,
            QMYESource: 12,
            ModelSource: 13,
            FSESource: 14,
            RuleSource: 15,

            //凭证筛选
            VoucherFilter: 16,
            //发票筛选
            InvoiceFilter: 17,
            //模型数据源
            ModelDatasource: 18,
            // 用于存放特殊逻辑中获取的数据源数值与备注等信息,如未开票视同销售等
            Special: 19,
            BSPL: 20
        },

        VatImportSubStatus: {
            isAdjustImport: 1, //审计调整
            isCustomInvoiceImport: 2, //海关清单
            isEntryImport: 3, //序时账
            isErpImport: 4, //财务数据
            isInputInvoiceImport: 5, //进项发票
            isInvoiceMapImport: 6, //发票对应
            isOutputInvoiceImport: 7,//销项发票
            isTbImport: 8,//试算平衡表
            isVoucherMapImport: 9 //凭证对应
        },


        ReportTemplateCode: {

            TaxDeclarationCategory: "TaxDeclaration", //纳税申报表(不是具体的template,是一个类别)
            VAT000: 'VAT000', //增值税纳税申报表
            VAT001: 'VAT001', //本期销售情况明细(附表一)
            VAT002: 'VAT002', //本期进项税额明细(附表二)
            VAT003: 'VAT003', //服务,不动产和无形资产扣除项目明细(附表三)
            VAT004: 'VAT004', //税额抵减情况表(附表四)
            VAT005: 'VAT005', //不动产分期抵扣表(附表五)
            VAT006: 'VAT006', //固定资产
            VAT007: 'VAT007', //抵扣进项税额结构明细表
            VAT008: 'VAT008', //增值税减免税申报明细表
            VAT009: 'VAT009', //附加税报表
            VAT010: 'VAT010', //增值税预缴税款表
            VAT011: 'VAT011' //营改增税负分析测算明细表
        },

        FinishStatusEnum: {
            NotFinished: 0,
            Finished: 1
        },

        paramDataType: {
            undefined: -1,
            string: 0,
            number: 1
        },

        paramType: {
            input: 0,
            dropdown: 1,
            accountCode: 2,
            dropdownNumber: 3
        },

        sqlBitEnum: {
            asFalse: 0,
            asTrue: 1
        },

        linkShort: {
            PreviewData: 'previewData',
            ReductionData: 'reductionData',
            ImportData: 'importData'
        },

        //Workflow Task的DictionayKey和vat-import-layout.ctrl.js中$scope.menus中name之间的mapping关系
        dictionaryKeyMenusMap: {
            WFImportErpData: 'erpData',
            WFImportBalanceTable: 'balanceSheet',
            WFImportJournalEntry: 'journalEntry',
            WFImportOutputInvoice: 'outputInvoice',
            WFImportIncomeInvoice: 'inputInvoice',
            WFImportCustomInvoice: 'customInvoice',
            WFImportVoucherMap: 'voucherMapping',
            WFImportInvoiceMap: 'invoiceMapping',
            WFImportAuditAdjust: 'auditAdjust',
            WFUnBilledInvoice: 'unbilledInvoice',
            WFDataProcess: 'caculateData',
            WFAccountMap: 'accountMapping',
            WFCargoNameMatch: 'goodsMapping'
        },

        projectImportType: {
            UnImported: 0,
            TbImported: 1,
            ErpImported: 2
        },

        processType: {
            UnDefined: -1,
            Add: 1,
            Edit: 2,
            Delete: 3
        },

        optionType :{
            Add: "Add",
            Edit: "Edit",
            DeleteDuplicate: "DeleteDuplicate",
            Refresh: "Refresh",
            Clear: "Clear",
            Import: "Import"
        },

        /*************************************vat enum end**************************************/

        //发票发生类型
        invoiceAmountType: {
            amount: 1,      //金额
            taxAmount: 2,   //税额
            quntity: 3      //份数
        },

        //项目服务类型
        projectServiceType: {
            VAT: 2,
            CIT: 6,
        },

        /*************************************cit enum start**************************************/

        erpCheckTypeId: {
            Tb_NoAcctCode: 30,//Tb验证 科目不在科目表中
            Tb_PeriodBalance: 31,//本月期初 = 上月期末      
            Tb_BegBalDebitAndCreditBanlace: 32,//期初余额借贷平衡
            Tb_BegBalUpAndDownBanlace: 33,//期初余额上下级平衡
            Tb_CurentDebitAndCreditBanlace: 34,//发生额借贷平衡
            Tb_CurrentUpAndDownBanlace: 35,//发生额上下级平衡
            Tb_EndBalDebitAndCreditBanlace: 36,//期末借贷平衡     
            Tb_EndBalUpAndDownBanlace: 37,//期末上下级平衡 
            Tb_CurrentBalance: 38,//期末:期初+(借-贷)*方向
            Tb_DuplicatedData: 39//重复数据 
        },

        ImageType:
        {
            Success: 1, //成功
            Alert: 2, //提示
            Warning: 3,//警告
            Error: 4 //错误
        },

        //对应PwC.Tax.Tech.Atms.Globals.Utils:ErpCheckType
        ErpCheckTypeEnum:
        {
            Success: 0,
            ComBalanceAcctUnValidate: 1,
            VoucherAcctValidate: 2,
            VSingleDebitCreditUnValidate: 3,
            VEmptyCheckUnValidateItemID: 4,
            VEmptyCheckUnValidateGroup: 5,
            VEmptyCheckUnValidateAcctCode: 6,
            VEmptyCheckUnValidateSummary: 7,
            AcctBegBalAcctLevelUnValidate: 8,
            BegBalUnValidate: 9,
            CompCustEndBalUnValidate: 10,
            CompCustAmountUnValidate: 11,
            CompCustBegBalUnValidate: 12,
            BegEndBalUnValidate: 13,
            DuplicatedVoucher: 14,
            DuplicatedTb: 15
        },

        ValidateCategoryEnum:
        {
            Basic: 1,
            Correctness: 2,
            Duplicate: 3
        },

        TbImportTypeEnum:
        {
            UnImported: 0,
            TbImported: 1,
            ErpImported: 2
        },

        //上传文件有效后缀名
        ValidFileExtension:
        {
            CSV: "csv",
            XLS: "xls",
            XLSX: "xlsx"
        },
        BDStatusEnum: {
            NormalStatus: 1,
            Duplicated: 2,
            Matched: 3,
            Unmatched: 4,
            Cancelled: 5,
            RedLettered: 6
        },

        IssuanceType: {
            SalesForce: 1,
            SmartTax: 2,
            Local: 3
        },
        //针对GD-BD车辆的状态
        GDBDStatusEnum: {
            issued: 1,
            redLettered: 2,
            readyToIssue: 3,
            needRedLetter: 4,
            cancelled: 5,
            pendingForApproval: 6
        },
        //针对GD发票的状态
        GDInvoiceStatusEnum: {
            issued: 1,
            redLettered: 2,
            partialRedLettered: 3,
            //needRedLetter: 4,
            cancelled: 5,
            // pendingForApproval: 6
        },
        // 发车清单比较状态
        ShipmentCheckStatusEnum: {
            Normal: 1,
            Unbalance: 2,
            CantFind: 3
        },
        EditValueTypeEnum: {
            Warranty14: 1,
            FaPiao17: 2,
            FaPiao6: 3
        },
        IsNeedSendEmailEnum: {
            Need: 1,
            NotNeed: 2
        }

        /*************************************cit enum end**************************************/



    }
}]);
commonModule.factory('messagebox', ['$q', '$translate', 'SweetAlert', function ($q, $translate, SweetAlert) {
    'use strict';

    var getMsg = function (resultMsg, hasTranslated) {
        hasTranslated = hasTranslated || false;
        var msg = resultMsg;
        if (!hasTranslated) {
            msg = $translate.instant(resultMsg);
        }
        return msg;
    };

    var success = function (resultMsg, hasTranslated) {
        var msg = this.getMsg(resultMsg, hasTranslated)
        SweetAlert.success(msg);
    };

    var warning = function (resultMsg, hasTranslated) {
        var msg = this.getMsg(resultMsg, hasTranslated)
        SweetAlert.warning(msg);
    };

    //有确认和取消按钮
    var confirm = function (title, text, customClass) {
        var deferred = $q.defer();
        SweetAlert.swal({
            title: title,
            text: text,
            html: true,
            type: "warning",
            customClass: customClass || '',
            showCancelButton: true,
            confirmButtonColor: "#DD6B55",
            allowOutsideClick: false,
            confirmButtonText: $translate.instant('Confirm'),
            cancelButtonText: $translate.instant('Cancel'),
            closeOnConfirm: true,
            closeOnCancel: true
        },
            function (isConfirm) {
                deferred.resolve(isConfirm);
            });

        return deferred.promise;
    };

    //没有取消按钮
    var info = function (title, text, customClass) {
        var deferred = $q.defer();

        SweetAlert.swal({
            title: title,
            text: text,
            html: true,
            type: "warning",
            customClass: customClass || '',
            showCancelButton: false,
            confirmButtonColor: "#DD6B55",
            allowOutsideClick: false,
            confirmButtonText: $translate.instant('Confirm'),
            cancelButtonText: $translate.instant('Cancel'),
            closeOnConfirm: true,
            closeOnCancel: false
        },
            function (isConfirm) {
                deferred.resolve(isConfirm);
            });

        return deferred.promise;
    };

    return {
        getMsg: getMsg,
        success: success,
        warning: warning,
        confirm: confirm,
        info: info
    }
}]);
(function (window, undefined) {
    PWC = window.PWC || {};
    //string extention
    if (!String.prototype.format) {
        String.prototype.format = function () {
            var args = arguments;
            return this.replace(/{(\d+)}/g, function (match, number) {
                return typeof args[number] !== 'undefined' ? args[number] : match;
            });
        };
    }

    if (!String.prototype.formatObj) {
        String.prototype.formatObj = function () {
            var str = this.toString();
            if (!arguments.length) {
                return str;
            }
            var args = typeof arguments[0];
            args = (("string" === args || "number" === args) ? arguments : arguments[0]);
            for (var arg in args) {
                if (args.hasOwnProperty(arg)) {
                    str = str.replace(RegExp("\\{" + arg + "\\}", "gi"), args[arg]);
                }
            }
            return str;
        }
    }

    if (!String.prototype.replaceToEnd) {
        String.prototype.replaceToEnd = function (search, replacement) {
            var target = this;
            return target.replace(new RegExp(search, 'g'), replacement);
        }
    }


    if (!String.prototype.endsWith) {
        String.prototype.endsWith = function (pattern) {
            var d = this.length - pattern.length;
            return d >= 0 && this.lastIndexOf(pattern) === d;
        };
    }

    if (!String.prototype.startWith) {
        String.prototype.startWith = function (pattern) {
            var reg = new RegExp("^" + pattern);
            return reg.test(this);
        };
    }

    if (!Number.prototype.formatAmount) {
        Number.prototype.formatAmount = function (decPlaces) {
            decPlaces = isNaN(decPlaces = Math.abs(decPlaces)) ? 2 : decPlaces;
            var n = this.toFixed(decPlaces);
            if (decPlaces) {
                var i = n.substr(0, n.length - (decPlaces + 1));
                var j = '.' + n.substr(-decPlaces);
            } else {
                i = n;
                j = '';
            }

            function reverse(str) {
                var sr = '';
                for (var l = str.length - 1; l >= 0; l--) {
                    sr += str.charAt(l);
                }
                return sr;
            }

            if (parseInt(i)) {
                i = reverse(reverse(i).replace(/(\d{3})(?=\d)/g, "$1" + ','));
            }
            return i + j;
        };
    }


    PWC.AccountToFloat = function (data) {
        if (data == null || data == undefined) return data;
        var result = {
            value: '',
            isNumber: true
        };
        var formatExp = /^\d+$/;
        //根据.拆分
        var array1 = data.split('.');
        if (array1.length > 0) {
            //根据,拆分
            var array2 = array1[0].split(',');
            for (var i = 0; i < array2.length; i++) {
                var item = array2[i];
                if (formatExp.test(item)) {
                    result.value += item;
                } else {
                    result.isNumber = false;
                    break;
                }
            }
        }
        if (result.isNumber && array1.length === 2) {
            if (formatExp.test(array1[1])) {
                result.value += '.' + array1[1];
            } else {
                result.isNumber = false;
            }
        }
        return result;
    };
    //解决toFixed的小数精度问题 :http://blog.csdn.net/langqiao123/article/details/42173721
    Number.prototype.toFixed = function (d) {
        var s = this + "";
        if (!d) d = 0;
        if (s.indexOf(".") == -1) s += ".";
        s += new Array(d + 1).join("0");
        if (new RegExp("^(-|\\+)?(\\d+(\\.\\d{0," + (d + 1) + "})?)\\d*$").test(s)) {
            var s = "0" + RegExp.$2, pm = RegExp.$1, a = RegExp.$3.length, b = true;
            if (a == d + 2) {
                a = s.match(/\d/g);
                if (parseInt(a[a.length - 1]) > 4) {
                    for (var i = a.length - 2; i >= 0; i--) {
                        a[i] = parseInt(a[i]) + 1;
                        if (a[i] == 10) {
                            a[i] = 0;
                            b = i != 1;
                        } else break;
                    }
                }
                s = a.join("").replace(new RegExp("(\\d+)(\\d{" + d + "})\\d$"), "$1.$2");

            } if (b) s = s.substr(1);
            return (pm + s).replace(/\.$/, "");
        } return this + "";

    };

    if (!Array.prototype.sortBy) {
        Array.prototype.sortBy = function (f) {
            return this.sort(function (a, b) {
                if (a[f] === b[f])
                    return 0;
                if (a[f] && b[f]) {
                    return a[f].toLowerCase() < b[f].toLowerCase() ? -1 : 1;
                }
                return a[f] < b[f] ? -1 : 1;
            });
        };
    }

    //Get duplicate object in array
    if (!Array.prototype.objectDuplicate) {
        Array.prototype.duplicate = function () {
            var tmp = [];
            this.concat().sort().sort(function (a, b) {
                if (isObjectValueEqual(a, b) && tmp.indexOf(a) === -1) {
                    tmp.push(a);
                }
            });
            return tmp;
        };
    }

    //check two object Is congruent
    function isObjectValueEqual(a, b) {
        if (typeof a == 'number' && typeof b == 'number') {
            return a == b
        }


        var aProps = Object.getOwnPropertyNames(a);
        var bProps = Object.getOwnPropertyNames(b);

        if (aProps.length != bProps.length) {
            return false;
        }

        for (var i = 0; i < aProps.length; i++) {
            var propName = aProps[i];
            if (Object.prototype.toString.call(a[propName]) == '[object Object]' || Object.prototype.toString.call(b[propName]) == '[object Object]') {
                var flag = isObjectValueEqual(a[propName], b[propName]);
                if (!flag) {
                    return flag;
                }
            } else if (a[propName] !== b[propName]) {
                return false;
            }
        }
        return true;
    }

    if (!Object.keys) {
        Object.keys = function (obj) {
            if (obj !== Object(obj)) {
                throw new TypeError('Object.keys called on non-object');
            }
            var ret = [],
                p;
            for (p in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, p)) {
                    ret.push(p);
                }
            }
            return ret;
        }
    }

    PWC.newGuid = function () {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
        };
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
    }

    // https://github.com/BlueHuskyStudios/Micro-JS-Enum/wiki
    PWC.enum = function (enumArray) {
        var self = {
            all: [],
            keys: enumArray,
        };
        for (var i = enumArray.length; i--;) {
            self[enumArray[i]] = self.all[i] = i;
        }
        return self;
    };

    // get callee arguments
    // export injected args to global
    // only work in non use strict mode
    // usage PWC.debugger(); // 'use strict';
    PWC.debugger = function () {
        var fn = arguments.callee.caller;
        if (fn) {
            var tmp = fn.toString().match(/\(.*?\)/)[0];
            var argumentNames = tmp.replace(/[()\s]/g, '').split(',');

            var result = {};
            [].splice.call(fn.arguments, 0).forEach(function (arg, i) {
                result[argumentNames[i]] = arg;
            });
            angular.extend(window, result);
        } else {
            console.error('debugger not work, check and disable strict mode');
        }
    }

    // http://anentropic.wordpress.com/2009/06/25/javascript-iso8601-parser-and-pretty-dates/
    // get the milliseconds from 1970/1/1 until now.  
    // input date format: ISO8601 format date string.
    PWC.parseISO8601 = function (str) {
        // we assume str is a UTC date ending in ‘Z’
        var parts = str.split('T');
        var dateParts = parts[0].split('-');
        var timeParts = parts[1].split('Z');
        timeParts = timeParts[0].split('-');
        timeParts = timeParts[0].split('+');
        var timeSubParts = timeParts[0].split(':');
        var timeSecParts = timeSubParts[2].split('.');
        var timeHours = Number(timeSubParts[0]);
        var date = new Date;

        date.setUTCFullYear(Number(dateParts[0]));
        date.setUTCMonth(Number(dateParts[1]) - 1);
        date.setUTCDate(Number(dateParts[2]));
        date.setUTCHours(Number(timeHours));
        date.setUTCMinutes(Number(timeSubParts[1]));
        date.setUTCSeconds(Number(timeSecParts[0]));
        if (timeSecParts[1])
            date.setUTCMilliseconds(Number(timeSecParts[1]));
        return date;
    };

    // Parse date object from a local time string.
    PWC.parseFromLocalTimeString = function (dateString) {

        var parts = dateString.split('T');
        var dateParts = parts[0].split('-');
        var timeParts = parts[1].split('Z');
        timeParts = timeParts[0].split('-');
        timeParts = timeParts[0].split('+');
        var timeSubParts = timeParts[0].split(':');
        var timeSecParts = timeSubParts[2].split('.');
        var timeHours = Number(timeSubParts[0]);
        var date = new Date;

        date.setFullYear(Number(dateParts[0]));
        date.setMonth(Number(dateParts[1]) - 1);
        date.setDate(Number(dateParts[2]));
        date.setHours(Number(timeHours));
        date.setMinutes(Number(timeSubParts[1]));
        date.setSeconds(Number(timeSecParts[0]));
        if (timeSecParts[1])
            date.setMilliseconds(Number(timeSecParts[1]));
        return date;
    };

    PWC.getDateFromTimeSpan = function (dateString, timeSpan, isLocalTime) {
        var datePart = dateString.split('T')[0];
        var timeString = datePart + 'T' + timeSpan;

        if (isLocalTime) {
            return PWC.parseFromLocalTimeString(timeString);
        }
        else {
            return PWC.parseISO8601(timeString);
        }
    }

    // convert the database utc time to local time.
    PWC.toLocalTime = function (dateString) {
        return (new Date(PWC.parseISO8601(dateString)));
    };

    // date extention
    if (!Date.prototype.formatDateTime) {
        Date.prototype.formatDateTime = function (formatStr) {
            var date = this;
            var zeroize = function (value, length) {
                if (!length) {
                    length = 2;
                }

                value = new String(value);
                for (var i = 0, zeros = ''; i < (length - value.length) ; i++) {
                    zeros += '0';
                }
                return zeros + value;
            };

            return formatStr.replace(/"[^"]*"|'[^']*'|\b(?:d{1,4}|M{1,4}|yy(?:yy)?|([hHmstT])\1?|[lLZ])\b/g, function ($0) {
                switch ($0) {
                    case 'yyyyMMdd':
                        return 'AAAAA';
                    case 'd':
                        return date.getDate();
                    case 'dd':
                        return zeroize(date.getDate());
                    case 'ddd':
                        return ['Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat'][date.getDay()];
                    case 'dddd':
                        return ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'][date.getDay()];
                    case 'M':
                        return date.getMonth() + 1;
                    case 'MM':
                        return zeroize(date.getMonth() + 1);
                    case 'MMM':
                        return ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][date.getMonth()];
                    case 'MMMM':
                        return ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'][date.getMonth()];
                    case 'yy':
                        return new String(date.getFullYear()).substr(2);
                    case 'yyyy':
                        return date.getFullYear();
                    case 'h':
                        return date.getHours() % 12 || 12;
                    case 'hh':
                        return zeroize(date.getHours() % 12 || 12);
                    case 'H':
                        return date.getHours();
                    case 'HH':
                        return zeroize(date.getHours());
                    case 'm':
                        return date.getMinutes();
                    case 'mm':
                        return zeroize(date.getMinutes());
                    case 's':
                        return date.getSeconds();
                    case 'ss':
                        return zeroize(date.getSeconds());
                    case 'l':
                        return date.getMilliseconds();
                    case 'll':
                        return zeroize(date.getMilliseconds());
                    case 'tt':
                        return date.getHours() < 12 ? 'am' : 'pm';
                    case 'TT':
                        return date.getHours() < 12 ? 'AM' : 'PM';
                }
            });
        };
    }

    if (!Date.prototype.dateTimeToString) {
        Date.prototype.dateTimeToString = function (formatStr) {
            switch (formatStr) {
                case 'yyyyMMdd':
                    return this.formatDateTime('yyyy') + '-' + this.formatDateTime('MM') + '-' + this.formatDateTime('dd');
                case 'yyyyMMdd hh:mm':
                    return this.formatDateTime('yyyy') + '-' + this.formatDateTime('MM') + '-' + this.formatDateTime('dd') + " " + this.formatDateTime('HH') + ":" + this.formatDateTime('mm');
                case 'yyyyMMddHHmmss':
                    return this.formatDateTime('yyyy') + this.formatDateTime('MM') + this.formatDateTime('dd') + this.formatDateTime('HH') + this.formatDateTime('mm') + this.formatDateTime('ss');
                case 'dd/MM/yyyy':
                    return this.formatDateTime('dd') + '/' + this.formatDateTime('MM') + '/' + this.formatDateTime('yyyy');
            }
        }
    }

    /* 得到日期年月日等加数字后的日期 */
    if (!Date.prototype.dateAdd) {
        Date.prototype.dateAdd = function (interval, number) {
            var d = this;
            var k = { 'y': 'FullYear', 'q': 'Month', 'm': 'Month', 'w': 'Date', 'd': 'Date', 'h': 'Hours', 'n': 'Minutes', 's': 'Seconds', 'ms': 'MilliSeconds' };
            var n = { 'q': 3, 'w': 7 };
            eval('d.set' + k[interval] + '(d.get' + k[interval] + '()+' + ((n[interval] || 1) * number) + ')');
            return d;
        };
    }

    PWC.clearArray = function (array) {
        if (_.isArray(array)) {
            while (array.length > 0) {
                array.pop();
            }
        }
    };

    PWC.today = function () {
        var now = new Date();
        var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
        return today;
    };

    PWC.toDate = function (value) {
        if (_.isString(value)) {
            value = new Date(value);
        }

        if (_.isDate(value)) {
            var date = new Date(value.getFullYear(), value.getMonth(), value.getDate());
            return date;
        }

        return null;
    };

    //考虑传入字符的中文和英文的区别
    PWC.getLength = function strlen(str) {
        var len = 0;
        if (PWC.isNullOrEmpty(str)) {
            return 0;
        }
        for (var i = 0; i < str.length; i++) {
            var c = str.charCodeAt(i);
            //单字节加1 
            if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
                len++;
            } else {
                len += 2;
            }
        }
        return len;
    };

    //不考虑中英文区别,直接获取length
    PWC.getStringLength = function (str) {
        if (PWC.isNullOrEmpty(str)) {
            return 0;
        }
        else {
            return str.length;
        }
    };

    PWC.nIndexOf = function (str, pat, n) {
        var len = str.length, i = -1;
        while (n-- && i++ < len) {
            i = str.indexOf(pat, i);
            if (i < 0) break;
        }
        return i;
    };

    PWC.isNullOrWhiteSpace = function (obj) {
        if (_.isUndefined(obj) || _.isNull(obj) || _.isEmpty(obj)) {
            return true;
        }

        return false;
    };

    PWC.isNullOrEmpty = function (obj) {
        if (_.isUndefined(obj) || _.isNull(obj) || $.trim(obj) === '') {
            return true;
        }
        return false;
    };

    //验证是否为正整数 
    PWC.isPositiveInteger = function (obj) {
        var r = /^\+?[1-9][0-9]*$/;//正整数
        return r.test(obj);
    };

    //验证是否为整数
    PWC.isInteger = function (obj) {
        var r = /^\d+$/;//正整数
        return r.test(obj);
    };

    PWC.limitString = function (str, len) {
        if (str.length <= len) {
            return str;
        }
        else {
            return str.substring(0, len) + "...";
        }
    }

    PWC.round = function (num, decimals) {
        if (PWC.isNullOrEmpty(num) || isNaN(parseFloat(num))) {
            return num;
        }
        return parseFloat(num).formatAmount(decimals);
    };


    PWC.parseFloatRound = function (number, decimals) {
        if (_.isNumber(number)) {

            return parseFloat(parseFloat(number).toFixed(decimals));
        }
        else {
            var numberNoCommas = number.replace(/,/g, '');
            if (PWC.isNullOrEmpty(numberNoCommas) || isNaN(parseFloat(numberNoCommas))) {
                return num;
            }
            return parseFloat(parseFloat(numberNoCommas).toFixed(decimals));
        }
    }

    PWC.checkDate = function (dateval) {
        var arr = new Array();
        //yyyy.mm.dd
        if (dateval.indexOf(".") != -1) {
            dateval = dateval.replace(/\./g, '-');
        }

        if (dateval.indexOf("-") != -1) {
            arr = dateval.toString().split("-");
        } else if (dateval.indexOf("/") != -1) {
            arr = dateval.toString().split("/");
        } else {
            return false;
        }

        //yyyy-mm-dd || yyyy/mm/dd
        if (arr[0].length == 4) {
            var date = new Date(arr[0], arr[1] - 1, arr[2]);
            if (date.getFullYear() == arr[0] && date.getMonth() == arr[1] - 1 && date.getDate() == arr[2]) {
                return true;
            }
        }
        //dd-mm-yyyy || dd/mm/yyyy
        if (arr[2] && arr[2].length == 4) {
            var date = new Date(arr[2], arr[1] - 1, arr[0]);
            if (date.getFullYear() == arr[2] && date.getMonth() == arr[1] - 1 && date.getDate() == arr[0]) {
                return true;
            }
        }
        //mm-dd-yyyy || mm/dd/yyyy
        if (arr[2] && arr[2].length == 4) {
            var date = new Date(arr[2], arr[0] - 1, arr[1]);
            if (date.getFullYear() == arr[2] && date.getMonth() == arr[0] - 1 && date.getDate() == arr[1]) {
                return true;
            }
        }

        return false;
    }

    PWC.checkMonth = function (dateval) {
        var arr = new Array();
        //yyyy.mm
        if (dateval.indexOf(".") != -1) {
            dateval = dateval.replace(/\./g, '-');
        }

        if (dateval.indexOf("-") != -1) {
            arr = dateval.toString().split("-");
        } else if (dateval.indexOf("/") != -1) {
            arr = dateval.toString().split("/");
        } else {
            return false;
        }

        //yyyy-mm || yyyy/mm
        if (arr[0].length == 4) {
            var date = new Date(arr[0], arr[1] - 1, 1);
            if (date.getFullYear() == arr[0] && date.getMonth() == arr[1] - 1 && date.getDate() == 1) {
                return true;
            }
        }
        //dd-mm-yyyy || dd/mm/yyyy
        if (arr[1] && arr[1].length == 4) {
            var date = new Date(arr[1], arr[0] - 1, 1);
            if (date.getFullYear() == arr[2] && date.getMonth() == arr[1] - 1 && date.getDate() == 1) {
                return true;
            }
        }
        //mm-yyyy || mm/yyyy
        if (arr[1] && arr[1].length == 4) {
            var date = new Date(arr[1], arr[0] - 1, 1);
            if (date.getFullYear() == arr[2] && date.getMonth() == arr[0] - 1 && date.getDate() == 1) {
                return true;
            }
        }

        return false;
    }

    //控制在input中输入金额时,必须为数字,且只能保留2位小数
    PWC.inputNumberFormat = function (obj) {
        obj.value = obj.value.replace(/[^\d.]/g, "");  //清除“数字”和“.”以外的字符     
        obj.value = obj.value.replace(/\.{2,}/g, "."); //只保留第一个. 清除多余的     
        obj.value = obj.value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
        obj.value = obj.value.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');//只能输入两个小数     
        if (obj.value.indexOf(".") < 0 && obj.value != "") {//以上已经过滤,此处控制的是如果没有小数点,首位不能为类似于 01、02的金额    
            obj.value = parseFloat(obj.value);
        }
    }

    PWC.stringNumberFormat = function (string) {
        string = string + "";
        string = string.replace(/[^\d.]/g, "");  //清除“数字”和“.”以外的字符     
        string = string.replace(/\.{2,}/g, "."); //只保留第一个. 清除多余的     
        string = string.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
        string = string.replace(/^(\-)*(\d+)\.(\d\d).*$/, '$1$2.$3');//只能输入两个小数     
        if (string.indexOf(".") < 0 && string != "") {//以上已经过滤,此处控制的是如果没有小数点,首位不能为类似于 01、02的金额    
            string = parseFloat(string);
        }
        return string;
    }

    //UI Grid to trigger the click for the tick icon
    PWC.triggerRowSelectOnClick = function (gridID) {
        $(gridID + ' .ui-grid-contents-wrapper > [role=grid] .ui-grid-canvas')
         .on('click', '.ui-grid-row', function (ev) {
             var jqRow = $(this); // '.ui-grid-row'
             var index = jqRow.index();
             var commonAncestor = jqRow.closest(gridID + ' .ui-grid-contents-wrapper');

             var selectButtonQuery = [
               '.ui-grid-pinned-container', // left side class
               '[role=grid] .ui-grid-canvas', // redundant, but doesn't hurt
               '.ui-grid-row .ui-grid-selection-row-header-buttons' // select button class
             ].join(' ');
             var checkboxDiv = commonAncestor.find(selectButtonQuery);
             checkboxDiv.get(index).click();
         });
    };

    PWC.uiTree = {};
    //ui tree 折叠所有
    PWC.uiTree.collapsedAll = function (childNodes) {
        if (!childNodes || childNodes.length == 0)
            return;

        var collapseNode = function (c) {
            if (!c) return;

            c.collapse();

            var childs = c.childNodes();
            for (var i = 0, len = childs.length; i < len; i++) {
                collapseNode(childs[i]);
            }
        }

        for (var i = 0, len = childNodes.length; i < len; i++) {
            collapseNode(childNodes[i]);
        }
    };

    //ui tree 展开所有
    PWC.uiTree.expandAll = function (childNodes) {

        if (!childNodes || childNodes.length == 0)
            return;

        var expandNode = function (c) {
            if (!c) return;

            c.expand();

            var childs = c.childNodes();
            for (var i = 0, len = childs.length; i < len; i++) {
                expandNode(childs[i]);
            }
        }

        for (var i = 0, len = childNodes.length; i < len; i++) {
            expandNode(childNodes[i]);
        }
    };
    PWC.numToLetter = function (num) {
        num++;
        var remainder = 0;
        var colHandler = function (num, result) {
            if (num > 0) {
                if (num >= 1 && num <= 26) {
                    result = String.fromCharCode(64 + parseInt(num));
                } else {
                    while (num > 26) {
                        var count = parseInt(num / 26);
                        var remainder = num % 26;
                        if (remainder == 0) {
                            remainder = 26;
                            count--;
                        }

                        result = String.fromCharCode(64 + parseInt(remainder)) + result;
                        num = count;
                    }
                    result = String.fromCharCode(64 + parseInt(num)) + result;
                }
                return result;
            }
        }

        return colHandler(num, '');
    };
    PWC.numToExcelChar = function (row, col) {
        if (!_.isNumber(col) || isNaN(col) || col < 0
            || !_.isNumber(row) || isNaN(row) || row < 0) {
            return '';
        }

        var rowHandler = function (num, n) {
            num = (++num).toString();
            var len = num.length;
            while (num.length < n) {
                num = "0" + num;
                len++;
            }

            return num;
        }

        return PWC.numToLetter(col) + rowHandler(row, 2);
    };

    var toString = Object.prototype.toString;
    var isObject = function (o) {
        return toString.call(o) == '[object Object]'
    }
    var isArray = function (o) {
        return toString.call(o) == '[object Array]'
    }

    PWC.assignModel = function (source, dest) {
        if (isObject(source) && isObject(dest)) {
            for (var dProp in dest) {
                if (dest.hasOwnProperty(dProp) === true && source.hasOwnProperty(dProp) == true) {
                    dest[dProp] = source[dProp];
                }
            }
        }
    };

    PWC.toDict = function (array, keyProp) {
        var dic = {};
        if (isArray(array)) {
            array.forEach(function (item) {
                dic[item[keyProp]] = item;
            });
        }
        return dic;
    };

    PWC.isHavePermissionForOrg = function (orgID, permission) {
        var isShow = false;
        if (permission) {
            if (permission.isSuperAdmin) {
                isShow = true;
            }
            else {
                // 查找机构
                var findOrg = _.find(permission.organizationPermissionList, function (num) {
                    return num.id === orgID;
                });
                if (findOrg && findOrg.permissionList && findOrg.permissionList.length > 0) {
                    // 查看具体权限
                    isShow = true;
                }
            }
        }
        return isShow;
    }

    PWC.isHavePermission = function (permissionCode, permission) {
        var isShow = false;
        if (permission) {

            if (permission.isSuperAdmin) {
                isShow = true;
            }
            else if (permission.isAdmin && permissionCode.startWith('01')) {
                isShow = true;
            }
            else {
                var find = _.find(permission.permissionList, function (num) {
                    return num.code.startWith(permissionCode);
                });

                if (find) {
                    isShow = true;
                }
            }
        }

        return isShow;
    };

    PWC.isHaveOrganizationPermission = function (orgID, permissionCode, permission) {
        var isShow = false;
        if (permission) {

            if (permission.isSuperAdmin) {
                isShow = true;
            }
            else if (permission.isAdmin && permissionCode.startWith('01')) {
                isShow = true;
            }
            else {

                // 查找机构
                var findOrg = _.find(permission.organizationPermissionList, function (num) {

                    return num.id === orgID;
                });

                if (findOrg) {

                    // 查看具体权限 
                    var find = _.find(findOrg.permissionList, function (num) {
                        return num.code.startWith(permissionCode);
                    });

                    if (find) {
                        isShow = true;
                    }
                }

            }
        }

        return isShow;
    };

    PWC.hasSpecialChar = function (value) {
        var reg = /^[\(\)()\w\u4e00-\u9fa5]+$/;
        if (reg.test(value)) {
            return false;
        } else {
            return true;
        }
    };

    PWC.simulateProgress = function () {

        $('#busy-indicator-container').show();
        setTimeout(function () {

            $('#busy-indicator-container').hide();
        }, 2000);
    };
    PWC.convertDataForMap = function (data) {
        var res = [];
        for (var i = 0; i < data.length; i++) {
            var geoCoord = constant.geoCoordMap[data[i].name];
            if (geoCoord) {
                res.push({
                    name: data[i].name,
                    value: geoCoord.concat(data[i].value)
                });
            }
        }
        return res;
    };
    PWC.sortJSON = function (data) {
        if (_.isString(data)) {
            data = JSON.parse(data);
        }

        // Sort object keys
        data = _.chain(data).pairs().sortBy(function (x) { return x[0]; }).value();

        // Build new object
        data = _.object.apply(_, _.zip.apply(_, data));
        data = JSON.stringify(data, null, 4);

        return data;
    };

    PWC.convertChineseCurrency = function (money) {
        //汉字的数字
        var cnNums = new Array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
        //基本单位
        var cnIntRadice = new Array('', '拾', '佰', '仟');
        //对应整数部分扩展单位
        var cnIntUnits = new Array('', '万', '亿', '兆');
        //对应小数部分单位
        var cnDecUnits = new Array('角', '分', '毫', '厘');
        //整数金额时后面跟的字符
        var cnInteger = '整';
        //整型完以后的单位
        var cnIntLast = '元';
        //最大处理的数字
        var maxNum = 999999999999999.9999;
        //金额整数部分
        var integerNum;
        //金额小数部分
        var decimalNum;
        //输出的中文金额字符串
        var chineseStr = '';
        //分离金额后用的数组,预定义
        var parts;
        if (money == '') { return ''; }
        money = parseFloat(money);
        if (money >= maxNum) {
            //超出最大处理数字
            return '';
        }
        if (money == 0) {
            chineseStr = cnNums[0] + cnIntLast + cnInteger;
            return chineseStr;
        }
        //转换为字符串
        money = money.toString();
        if (money.indexOf('.') == -1) {
            integerNum = money;
            decimalNum = '';
        } else {
            parts = money.split('.');
            integerNum = parts[0];
            decimalNum = parts[1].substr(0, 4);
        }
        //获取整型部分转换
        if (parseInt(integerNum, 10) > 0) {
            var zeroCount = 0;
            var IntLen = integerNum.length;
            for (var i = 0; i < IntLen; i++) {
                var n = integerNum.substr(i, 1);
                var p = IntLen - i - 1;
                var q = p / 4;
                var m = p % 4;
                if (n == '0') {
                    zeroCount++;
                } else {
                    if (zeroCount > 0) {
                        chineseStr += cnNums[0];
                    }
                    //归零
                    zeroCount = 0;
                    chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
                }
                if (m == 0 && zeroCount < 4) {
                    chineseStr += cnIntUnits[q];
                }
            }
            chineseStr += cnIntLast;
        }
        //小数部分
        if (decimalNum != '') {
            var decLen = decimalNum.length;
            for (var i = 0; i < decLen; i++) {
                var n = decimalNum.substr(i, 1);
                if (n != '0') {
                    chineseStr += cnNums[Number(n)] + cnDecUnits[i];
                }
            }
        }
        if (chineseStr == '') {
            chineseStr += cnNums[0] + cnIntLast + cnInteger;
        } else if (decimalNum == '') {
            chineseStr += cnInteger;
        }
        return chineseStr;
    };


    PWC.convertChineseSimple = function (money) {
        //汉字的数字
        var cnNums = new Array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
        //基本单位
        var cnIntRadice = new Array('', '十', '百', '千');
        //对应整数部分扩展单位
        var cnIntUnits = new Array('', '万', '亿', '兆');
        //对应小数部分单位
        var cnDecUnits = new Array('角', '分', '毫', '厘');
        //整数金额时后面跟的字符 '整'
        var cnInteger = '';
        //整型完以后的单位 '元'
        var cnIntLast = '';
        //最大处理的数字
        var maxNum = 999999999999999.9999;
        //金额整数部分
        var integerNum;
        //金额小数部分
        var decimalNum;
        //输出的中文金额字符串
        var chineseStr = '';
        //分离金额后用的数组,预定义
        var parts;
        if (money == '') { return ''; }
        money = parseFloat(money);
        if (money >= maxNum) {
            //超出最大处理数字
            return '';
        }
        if (money == 0) {
            chineseStr = cnNums[0] + cnIntLast + cnInteger;
            return chineseStr;
        }
        //转换为字符串
        money = money.toString();
        if (money.indexOf('.') == -1) {
            integerNum = money;
            decimalNum = '';
        } else {
            parts = money.split('.');
            integerNum = parts[0];
            decimalNum = parts[1].substr(0, 4);
        }
        //获取整型部分转换
        if (parseInt(integerNum, 10) > 0) {
            var zeroCount = 0;
            var IntLen = integerNum.length;
            for (var i = 0; i < IntLen; i++) {
                var n = integerNum.substr(i, 1);
                var p = IntLen - i - 1;
                var q = p / 4;
                var m = p % 4;
                if (n == '0') {
                    zeroCount++;
                } else {
                    if (zeroCount > 0) {
                        chineseStr += cnNums[0];
                    }
                    //归零
                    zeroCount = 0;
                    chineseStr += cnNums[parseInt(n)] + cnIntRadice[m];
                }
                if (m == 0 && zeroCount < 4) {
                    chineseStr += cnIntUnits[q];
                }
            }
            chineseStr += cnIntLast;
        }
        //小数部分
        if (decimalNum != '') {
            var decLen = decimalNum.length;
            for (var i = 0; i < decLen; i++) {
                var n = decimalNum.substr(i, 1);
                if (n != '0') {
                    chineseStr += cnNums[Number(n)] + cnDecUnits[i];
                }
            }
        }
        if (chineseStr == '') {
            chineseStr += cnNums[0] + cnIntLast + cnInteger;
        } else if (decimalNum == '') {
            chineseStr += cnInteger;
        }
        return chineseStr;
    };

    PWC.getEnumKeyByValue = function (enumObj, value) {
        for (var key in enumObj) {
            if (enumObj[key] === value) {
                return key;
            }
        }
        return "";
    };

    PWC.prefixInteger = function (num, length) {
        return (Array(length).join('0') + num).slice(-length);
    };
})(window);
// registration web service proxy
webservices.factory('accountService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getAccountDemoOne: function (accountId) {
            var config = { ignoreLoadingBar: true };
            return $http.get('/NewAccount/' + accountId, apiConfig.create(config));
        },
        getAccountDemoList: function () {
            var config = { ignoreLoadingBar: true };
            return $http.get('/NewAccount', apiConfig.create(config));
        },
        getAccountGroup : function(){
            var config = { ignoreLoadingBar: true };
            return $http.get('/AccountGroup', apiConfig.create(config));
        },
        getProjectList: function (){
            return $http.get('/Account/UserProjects', apiConfig.create());
        },
        getEnterpriseAccounts: function (){
            return $http.get('/EnterpriseAccount', apiConfig.create());
        },
        mapAccount: function (accountMap){
            return $http.post('/EnterpriseAccount/Map', accountMap, apiConfig.create());
        },
        clearAccountMap: function (codes){
            return $http.post('/EnterpriseAccount/ClearMap', codes, apiConfig.create());
        },
        clearAllAccountMap: function (){
            return $http.post('/EnterpriseAccount/ClearAllMap', {},apiConfig.create());
        },
        autoMap: function () {
            return $http.post('/EnterpriseAccount/AutoMap', {}, apiConfig.create());
        }
    };
}]);
// web service proxy for org
webservices.factory('areaService', ['$http', 'apiConfig', 'httpCacheService',
function ($http, apiConfig, httpCacheService) {
    'use strict';
     
    return {
        tree: function (type) {
            return $http.get('/area/tree?type=' + type, apiConfig.create()); 
        },
        add: function (model) {
            return $http.post('/area/add', model, apiConfig.create());
        },
        update: function (model) {
            return $http.post('/area/update', model, apiConfig.create());
        },
        deleteArea: function (model) {
            return $http.post('/area/delete', model, apiConfig.create());
        },
        isactive: function (model) {
            return $http.post('/area/isactive', model, apiConfig.create());
        },
        getAreaList: function (type) {
            return $http.get('/area/getAreaList?type=' + type, apiConfig.create());
        },
        getAreaTreeByID: function (id) {
            return $http.get('/area/getAreaTreeByID?id=' + id, apiConfig.create());
        }
    };
}]);
// web service proxy for org
webservices.factory('areaRegionService', ['$http', 'apiConfig', 'httpCacheService',
function ($http, apiConfig, httpCacheService) {
    'use strict';

    return {
        add: function (model) {
            return $http.post('/areaRegion/add', model, apiConfig.create());
        },
        getProvinces: function () {
            //return $http.get('/areaRegion/getProvinces', apiConfig.create());
            return httpCacheService.get('/areaRegion/getProvinces');
        },
        getCities: function (parentID) {
            //return $http.get('/areaRegion/getCities?parentID=' + parentID, apiConfig.create());
            return httpCacheService.get('/areaRegion/getCities?parentID=' + parentID);
        },

        update: function (model) {
            return $http.post('/areaRegion/update', model, apiConfig.create());
        },
        getRegionOrganizationInfo: function () {
            return $http.get('/areaRegion/getRegionOrganizationInfo', apiConfig.create());
        }
    };
}]);
// web service proxy for role
webservices.factory('businessUnitService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getBusinessUnitList: function () {
            return $http.get('/businessunit/getlist', apiConfig.create());
        },
        updateBusinessUnit: function (organizationStructure) {
            return $http.put('/businessunit', organizationStructure, apiConfig.create());
        },
        addBusinessUnit: function (organizationStructure) {
            return $http.post('/businessunit/add', organizationStructure, apiConfig.create());
        },
        deleteBusinessUnit: function (id) {
            return $http.post('/businessunit/delete', { id: id }, apiConfig.create());
        }
    };
}]);
webservices.factory('cacheService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getAllCache: function () {
            return $http.get('/cache/getallcache', apiConfig.create({ ignoreLoadingBar: true }));
        },  
        getCacheByKey: function (cacheKey) {
            return $http.get('/cache/getcachebykey?cacheKey=' + cacheKey, apiConfig.create());
        },
    }
}]);
// web service proxy for role
webservices.factory('cellCommentService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getCellComments: function (cellDataId) {
            return $http.get('/CellComment/List?cellDataId=' + cellDataId, apiConfig.createVat());
        },
        addCellComment: function (cellComment) {
            return $http.post('/CellComment/Add', cellComment, apiConfig.createVat());
        },
        deleteCellComment: function (commentId) {
            return $http.post('/CellComment/Delete/' + commentId, {}, apiConfig.createVat());
        },
    };
}]);
// common web service proxy
webservices.factory('commonWebService', ['$http', 'apiConfig', 'loginContext', 'vatSessionService', function ($http, apiConfig, loginContext, vatSessionService) {
    'use strict';

    var getCookie = function (cname) {
        var name = cname + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
            var c = ca[i].trim();
            // if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
            if (c.indexOf(name) == 0) return ATMS_EXTRA.decodeCookieValue(c.substring(name.length, c.length));
        }
        return "";
    };

    var apiTokenObj = JSON.parse(getCookie('AtmsApiToken'));
    var apiToken = apiTokenObj.access_token;
    var tokenType = apiTokenObj.token_type;
    var api_host = apiTokenObj.api_host;

    var glyph_opts = {
        map: {
            doc: "glyphicon glyphicon-file",
            docOpen: "glyphicon glyphicon-file",
            checkbox: "glyphicon glyphicon-unchecked",
            checkboxSelected: "glyphicon glyphicon-check",
            checkboxUnknown: "glyphicon glyphicon-share",
            dragHelper: "glyphicon glyphicon-play",
            dropMarker: "glyphicon glyphicon-arrow-right",
            error: "glyphicon glyphicon-warning-sign",
            expanderClosed: "fa fa-plus",
            expanderLazy: "glyphicon glyphicon-menu-right",  // glyphicon-plus-sign
            expanderOpen: "fa fa-minus",  // glyphicon-collapse-down
            folder: "glyphicon glyphicon-folder-close",
            folderOpen: "glyphicon glyphicon-folder-open",
            loading: "glyphicon glyphicon-refresh glyphicon-spin"
        }
    };

    return {

        changePassword: function (passwordList) {
            return $http.put('/Account/userPassword', passwordList, apiConfig.create());
        },
        initFancyTreeAjax: function (treeID, ajaxUrl, dblFn) {

            var prefixUrl = loginContext.apiHost + constant.webapi.prefix;
            var ajaxUrl = prefixUrl + ajaxUrl;

            var ajaxSource = $.ajax({
                url: ajaxUrl,
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('Authorization', tokenType + ' ' + apiToken);
                }
            });

            var treeOptions = {
                extensions: ["edit", "glyph", "table", "filter"],
                quicksearch: true,
                checkbox: false,
                glyph: glyph_opts,
                source: ajaxSource,
                table: {
                    checkboxColumnIdx: 1,
                    nodeColumnIdx: 2
                },
                dblclick: function (event, data) {
                    var node = data.node.data;
                    var code = node.code;
                    var name = node.fullName;
                    var acctProp = node.acctProp;
                    var direction = node.direction;
                    var hasChildren = node.hasChildren;

                    if (code != null && !hasChildren) {
                        dblFn(code, name, acctProp, direction);
                    }
                },
                renderColumns: function (event, data) {
                    var node = data.node,
                    $tdList = $(node.tr).find(">td");
                    $tdList.eq(3).text(!!node.folder);
                },
                filter: {
                    autoApply: true,   // Re-apply last filter if lazy data is loaded
                    autoExpand: true, // Expand all branches that contain matches while filtered
                    counter: true,     // Show a badge with number of matching child nodes near parent icons
                    fuzzy: false,      // Match single characters in order, e.g. 'fb' will match 'FooBar'
                    hideExpandedCounter: false,  // Hide counter badge if parent is expanded
                    hideExpanders: false,       // Hide expanders if all child nodes are hidden by filter
                    highlight: true,   // Highlight matches by wrapping inside <mark> tags
                    leavesOnly: false, // Match end nodes only
                    nodata: true,      // Display a 'no data' status node if result is empty
                    mode: "hide",      // Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
                    regularExpression: false,
                    matchWholeBranch: false
                }
            };

            ///由于fancyTree第一次ajax请求加载的时候,只需要把发送ajax option即可,不需要使用callback去赋值
            ///但是第二次ajax请求重新渲染fancytree的话,需要ajax.done获取返回的数据并做为参数传递给fancytree去重新渲染
            ///所以使用了tick来判断是否是首次请求
            var tree = $.ui.fancytree.getTree("#" + treeID);
            if (tree) {
                ajaxSource.done(function (data) {
                    tree.reload(data).done(function () {
                        console.log('reloaded');
                    });
                }).fail(function (err) { console.log(err); });
            } else {
                $("#" + treeID).fancytree(treeOptions);
            }

            $("input[name=fancytree-search]").keyup(function (e) {
                var n,
                  tree = $.ui.fancytree.getTree("#" + treeID),
                  opts = {},
                  filterFunc = tree.options.filter.matchWholeBranch ? tree.filterBranches : tree.filterNodes,
                  match = $(this).val();

                opts.nodata = tree.options.filter.nodata;
                opts.leavesOnly = tree.options.filter.leavesOnly;
                opts.highlight = tree.options.filter.highlight;
                opts.hideExpanders = tree.options.filter.hideExpanders;
                opts.fuzzy = tree.options.filter.fuzzy;
                opts.autoApply = tree.options.filter.autoApply;
                opts.mode = tree.options.filter.mode;
                opts.autoExpand = tree.options.filter.autoExpand;
                opts.counter = tree.options.filter.counter;

                if (e && e.which === $.ui.keyCode.ESCAPE || $.trim(match) === "") {
                    $("input[name=fancytree-search]").val("");
                    tree.clearFilter();
                    return;
                }
                //opts.
                if (tree.options.filter.regularExpression) {
                    // Pass function to perform match
                    n = filterFunc.call(tree, function (node) {
                        return new RegExp(match, "i").test(node.title);
                    }, opts);
                } else {
                    // Pass a string to perform case insensitive matching
                    n = filterFunc.call(tree, match, opts);
                }
            }).focus();
        },

        initVATFancyTreeAjax: function (treeID, ajaxUrl, dblFn) {

            var prefixUrl = loginContext.vatApiHost + constant.webapi.prefix;
            var ajaxUrl = prefixUrl + ajaxUrl;

            var ajaxSource = $.ajax({
                url: ajaxUrl,
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('Authorization', tokenType + ' ' + apiToken);
                    xhr.setRequestHeader('from', vatSessionService.project.dbName + '@cn.pwc.com');
                }
            });


            ajaxSource.done(function (data) {

                var treeOptions = {
                    extensions: ["edit", "glyph", "table", "filter"],
                    quicksearch: true,
                    checkbox: false,
                    glyph: glyph_opts,
                    source: JSON.parse(data),
                    table: {
                        checkboxColumnIdx: 1,
                        nodeColumnIdx: 2
                    },
                    dblclick: function (event, data) {
                        var node = data.node.data;
                        var code = node.code;
                        var name = node.fullName;
                        var acctProp = node.acctProp;
                        var direction = node.direction;
                        var hasChildren = node.hasChildren;

                        if (code != null && !hasChildren) {
                            dblFn(code, name, acctProp, direction);
                        }
                    },
                    renderColumns: function (event, data) {
                        var node = data.node,
                        $tdList = $(node.tr).find(">td");
                        $tdList.eq(3).text(!!node.folder);
                    },
                    filter: {
                        autoApply: true,   // Re-apply last filter if lazy data is loaded
                        autoExpand: true, // Expand all branches that contain matches while filtered
                        counter: true,     // Show a badge with number of matching child nodes near parent icons
                        fuzzy: false,      // Match single characters in order, e.g. 'fb' will match 'FooBar'
                        hideExpandedCounter: false,  // Hide counter badge if parent is expanded
                        hideExpanders: false,       // Hide expanders if all child nodes are hidden by filter
                        highlight: true,   // Highlight matches by wrapping inside <mark> tags
                        leavesOnly: false, // Match end nodes only
                        nodata: true,      // Display a 'no data' status node if result is empty
                        mode: "hide",      // Grayout unmatched nodes (pass "hide" to remove unmatched node instead)
                        regularExpression: false,
                        matchWholeBranch: false
                    }
                };
                $("#" + treeID).fancytree(treeOptions);

                $("input[name=fancytree-vat-search]").keyup(function (e) {
                    var n,
                      tree = $.ui.fancytree.getTree("#" + treeID),
                      opts = {},
                      filterFunc = tree.options.filter.matchWholeBranch ? tree.filterBranches : tree.filterNodes,
                      match = $(this).val();

                    opts.nodata = tree.options.filter.nodata;
                    opts.leavesOnly = tree.options.filter.leavesOnly;
                    opts.highlight = tree.options.filter.highlight;
                    opts.hideExpanders = tree.options.filter.hideExpanders;
                    opts.fuzzy = tree.options.filter.fuzzy;
                    opts.autoApply = tree.options.filter.autoApply;
                    opts.mode = tree.options.filter.mode;
                    opts.autoExpand = tree.options.filter.autoExpand;
                    opts.counter = tree.options.filter.counter;

                    if (e && e.which === $.ui.keyCode.ESCAPE || $.trim(match) === "") {
                        $("input[name=fancytree-vat-search]").val("");
                        tree.clearFilter();
                        return;
                    }
                    //opts.
                    if (tree.options.filter.regularExpression) {
                        // Pass function to perform match
                        n = filterFunc.call(tree, function (node) {
                            return new RegExp(match, "i").test(node.title);
                        }, opts);
                    } else {
                        // Pass a string to perform case insensitive matching
                        n = filterFunc.call(tree, match, opts);
                    }
                }).focus();
            });
        },
        expandCollapseAll: function (treeID, isCollapsed) {
            if (!isCollapsed) {
                $.ui.fancytree.getTree("#" + treeID).visit(function (node) {
                    node.setExpanded();
                });
            } else {

                $.ui.fancytree.getTree("#" + treeID).visit(function (node) {
                    node.setExpanded(false);
                });
            }
        }
    };
}]);
// configuration web service proxy
webservices.factory('configurationService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        
        getProfiles: function () {
            return $http.get('/configuration/profiles', apiConfig.create());
        },

        getModalityTypes: function () {
            return $http.get('/configuration/modalitytypes', apiConfig.create());
        },

        getModalities: function () {
            return $http.get('/configuration/modalities' , apiConfig.create());
        },
        
        getDictionaries: function () {
            return $http.get('/configuration/dictionaries' , apiConfig.create());
        },
        
        getApplyDepts: function () {
            return $http.get('/configuration/applydepts' , apiConfig.create());
        },

        getApplyDoctors: function () {
            return $http.get('/configuration/applydoctors' , apiConfig.create());
        },

        getUserName: function () {
            return $http.get('/configuration/getusername' , apiConfig.create());

    },
    };
}]);
// web service proxy for customer
webservices.factory('customerService', ['$http', 'apiConfig', 'httpCacheService',
function ($http, apiConfig, httpCacheService) {
    'use strict';
     
    return {
        get: function () {
            return $http.get('/customer/get', apiConfig.create());
        },
        getByID: function (ID) {
            return $http.get('/customer/getByID?ID=' +ID , apiConfig.create());
        },
        addRange: function (customerList) {
            return $http.post('/customer/AddRange', customerList, apiConfig.create());
        },
        updateRange: function (customerList) {
            return $http.post('/customer/UpdateRange', customerList, apiConfig.create());
        },
        deleteRange: function (model) {
            return $http.post('/customer/DeleteRange', model, apiConfig.create());
        }
    };
}]);
// configuration web service proxy
webservices.factory('dashboardService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        
        getChartSetting: function (chartId)
        {
            return $http.get('/Dashboard/ChartSetting/' + chartId, apiConfig.create());
        },

        removeChartSetting: function (chartId)
        {
            return $http.delete('/Dashboard/ChartSetting/' + chartId, apiConfig.create());
        },

        updateChartSortId: function(onechartId,anotherChartId){
            return $http.put('/Dashboard/ChartSort/' + onechartId + '/' + anotherChartId, {_:2}, apiConfig.create());
        },

        getChartData: function (chartType,projectList,yearList,monthList)
        {
            return $http.post('/Dashboard/ChartData/' + chartType, { PorjectIdList: projectList, ProjectYearList: yearList, MonthList: monthList }, apiConfig.create());
        },

        getRangeChartData: function (chartType, projectList, endDate, isMonth)
        {
            return $http.post('/Dashboard/RangeChartData/' + chartType, { PorjectIdList: projectList, EndDate: endDate, IsMonth: isMonth }, apiConfig.create());
        },

        saveSetting: function (chartId,chartName, chartType ,argumentField, valueField, showValue)
        {
            return $http.put('/Dashboard/ChartSetting/' + chartId, {Name: chartName, ChartTypeValue: chartType, ArgumentField: argumentField, valueField: valueField, ShowValue: showValue}, apiConfig.create())
        },

        getChartList: function ()
        {
            return $http.get('/Dashboard/ChartList', apiConfig.create());
        },

        getSystemChartList: function () {
            return $http.get('/Dashboard/systemcharts', apiConfig.create());
        },

        addUserChart: function (systemchartId) {
            return $http.get('/Dashboard/addUserChart/' + systemchartId, apiConfig.create());
        }
    };
}]);
// web service proxy for role
webservices.factory('dashboardConfigSummaryService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        querySummaryData: function (model) {
            return $http.post('/dashboardConfigSummary/querySummaryData', model, apiConfig.create());
        },   
        queryOrganizationData: function (organizationId,year,period) {
            return $http.get('/dashboardConfigSummary/queryOrganizationData/'+ organizationId + '/' + year + '/' + period, apiConfig.create());
        }
    };
}]);
// web service proxy for data file upload
webservices.factory('dataImportService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {

        //getFileContent: function (tempFileName, selectedSheetIndex, topRowNumber) {
        //    return $http.get('/DataImport/FileContent/' + tempFileName + '/' + selectedSheetIndex + '/' + topRowNumber, apiConfig.create());
        //},

        //importBalanceList: function (balanceList, importType) {
        //    return $http.post('/DataImport/ImportBalance', { balanceList: balanceList, importType: importType }, apiConfig.create());
        //},

        //getBalanceList: function (period) {
        //    return $http.get('/DataImport/GetBalanceList/' + period, apiConfig.create());
        //},

        //getValidationList: function (type, period) {
        //    return $http.get('/DataImport/GetValidationList/' + type + '/' + period, apiConfig.create());
        //},

        getDuplicateResults: function () {
            return $http.get('/financeImportData/importData/getDuplicateItems', apiConfig.create());
        },

        getBasicValidationResults: function () {
            return $http.get('/financeImportData/checkData/basicCheck', apiConfig.create());
        },

        getCorrectValidationResults: function (periodId) {
            return $http.get('/financeImportData/checkData/correctCheck/' + periodId, apiConfig.create());
        },

        manageData: function (period) {
            return $http.get('/financeImportData/manageData/' + period, apiConfig.create());
        },

        getVoucherEmptyCheck: function (itemId, period, group, acctCode, summary) {
            return $http.get('/financeImportData/getCheckDetail/voucheEmpty/' + itemId + '/' + period + '/' + group + '/' + acctCode + '/' + summary, apiConfig.create());
        },

        getCompanyBalanceAcctChecks: function () {
            return $http.get('/financeImportData/getCheckDetail/getCompBalanceAcct', apiConfig.create());
        },

        getVoucherAccountChecks: function () {
            return $http.get('/financeImportData/getCheckDetail/getVoucherAcct', apiConfig.create());
        },

        getAccountsNotInVoucherDetails: function(){
            return $http.get('/financeImportData/getCheckDetail/getAccountsNotInVoucherDetails', apiConfig.create());
        },

        getAccountsNotInCompanyBalance: function(){
            return $http.get('/financeImportData/getCheckDetail/getAccountsNotInCompanyBalance', apiConfig.create());
        },

        getSingleVoucherCheck: function () {
            return $http.get('/financeImportData/getCheckDetail/getVSingle', apiConfig.create());
        },

        getAccountBegBalances: function (periodId) {
            return $http.get('/financeImportData/getCheckDetail/getAcctBegBalances/' + periodId, apiConfig.create());
        },

        getBegBalancesByPeriod: function (periodId) {
            return $http.get('/financeImportData/getCheckDetail/getBegBalances/' + periodId, apiConfig.create());
        },
         
        isComBalanceEndBalNotZero: function (periodId) {
            return $http.get('/financeImportData/getCheckDetail/getIsExistsEndBal/' + periodId, apiConfig.create());
        },

        compareCustEndCompBeg: function (compPeriodId, custPeriodId) {
            return $http.get('/financeImportData/getCheckDetail/getCompareCustEndCompBeg/' + compPeriodId + '/' + custPeriodId, apiConfig.create());
        },

        compareCompCustPeriodAmount: function (compPeriodId, custPeriodId) {
            return $http.get('/financeImportData/getCheckDetail/getCompareAmount/' + compPeriodId + '/' + custPeriodId, apiConfig.create());
        },

        getCompCustBalanceDetail: function (compPeriodId, custPeriodId) {
            return $http.get('/financeImportData/getCheckDetail/getCompareEndBal/' + compPeriodId + '/' + custPeriodId, apiConfig.create());
        },

        getDuplicateVouchers: function () {
            return $http.get('/financeImportData/getCheckDetail/getDuplicateVouchers', apiConfig.create());
        },

        deleteVoucherDuplicateItems: function (voucherIds) {
            return $http.post('/financeImportData/getCheckDetail/deleteVouchers',voucherIds,apiConfig.create());
        },

        getCustBalanceDuplicateItems: function (periodId) {
            return $http.get('/financeImportData/getCheckDetail/getDuplicateTbes?periodId=' + periodId, apiConfig.create());
        },

        deleteCustBalanceItems: function (balanceIds) {
            return $http.post('/financeImportData/getCheckDetail/deleteCustBalances',balanceIds,apiConfig.create());
        },

        reManageData: function (periodId) {
            return $http.get('/financeImportData/reManageData/' + periodId, apiConfig.create());
        },

        /***************************************cit services start**************************************************************/

        getCitCorrectValidationResults: function () {
            return $http.get('/financeImportData/checkData/citCorrectCheck', apiConfig.create());
        },


        /***************************************cit services end**************************************************************/
       
    };
}]);
// web service proxy for org
webservices.factory('dataInitService', ['$http', 'apiConfig', 'httpCacheService','FileSaver',
function ($http, apiConfig, httpCacheService, FileSaver) {
    'use strict';
     
    return {
        //tree: function (type) {
        //    return $http.get('/area/tree?type=' + type, apiConfig.create()); 
        //},

        downloadTemplate: function () {

            var thisConfig = apiConfig.create();
            thisConfig.responseType = "arraybuffer";
            return $http.post('/init/downloadTemplate', {}, thisConfig).then(function (response) {
                var data = new Blob([response.data], { type: response.headers('Content-Type') });
                // var filename1 = response.headers('Content-Disposition').split(';')[1].trim().substr('filename='.length);
                var filename = '基础数据模板.xlsx';
                FileSaver.saveAs(data, filename);
            });
        }

    };
}]);
// web service proxy for data file upload
webservices.factory('dataUploadService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {

        getUploadFileList: function (projectId) {
            return $http.get('/FileUpload/uploadfile/' + projectId, apiConfig.create());
        },
        getProjectList: function () {
            return $http.get('/FileUpload/projectlist/', apiConfig.create());
        },
        getUploadFileTypeList: function (){
            return $http.get('/FileUpload/FileTypes', apiConfig.create());
        },
        getFileUploadLimit: function ()
        {
            return $http.get('/FileUpload/FileUploadLimit', apiConfig.create());
        },
        removeUploadFile: function (fileId)
        {
            return $http.delete('/FileUpload/File/' + fileId, apiConfig.create());
        },

    };
}]);
// web service proxy for standard account
webservices.factory('dimensionService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getDimensionStatics: function (espID, orgID) {
            return $http.get('/dimension/getDimensionStatics', apiConfig.create());
        },
        getAllDimensionOrgList: function () {
            return $http.get('/dimension/getAllDimensionOrgList', apiConfig.create());
        },
        getDimensionList: function () {
            return $http.get('/dimension/getDimensionList', apiConfig.create());
        },
        getDimensionById: function (id) {
            return $http.get('/dimension/getDimensionById?id=' + id, apiConfig.create());
        },
        addDimension: function (model) {
            return $http.post('/dimension/addDimension', model, apiConfig.create());
        },
        updateDimension: function (model) {
            return $http.post('/dimension/updateDimension', model, apiConfig.create());
        },
        getDimensionValueList: function (dimensionID) {
            return $http.get('/dimension/getDimensionValueList?dimensionID=' + dimensionID, apiConfig.create());
        },
        getDevDimensionTreeList: function () {
            return $http.get('/dimension/getDevDimensionTreeList', apiConfig.create({ cache: true }));
        },
        updateDimensionValue: function (model) {
            return $http.post('/dimension/updateDimensionValue', model, apiConfig.create());
        },
        addDimensionValue: function (model) {
            return $http.post('/dimension/addDimensionValue', model, apiConfig.create());
        },
        getAllDimensionList: function () {
            return $http.get('/dimension/getAllDimensionList', apiConfig.create());
        }
    };
}]);

// web service proxy for document hierarchy.
webservices.factory('documentHierarchyService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getDocumentHierarchy: function (documentType) {
            return $http.get('/documenthierarchy?documentType=' + documentType, apiConfig.create());
        },
        getDocumentByCode: function (code) {
            return $http.get('/documenthierarchy/document/'+code, apiConfig.create());
        },
        getDocumentList: function (documentType) {
            return $http.get('/documenthierarchy/documentlist/' + documentType, apiConfig.create()); 
        },
        downloadTemplate : function (documentlist) {
            return $http.post('/documenthierarchy/download/template', { documentlist: documentlist }, apiConfig.create({ responseType: 'arraybuffer' }));
        }
    };
}]);



// web service proxy for standard account
webservices.factory('enterpriseAccountService', ['$http', 'apiConfig','FileSaver', function ($http, apiConfig, FileSaver) {
    'use strict';
    return {
        getEnterpriceAccountList: function (espID, orgID, filterType) {
            return $http.get('/enterpriseAccountManage/getEnterpriseAccountList?espID=' + espID + '&orgID=' + orgID + '&filterType=' + filterType, apiConfig.create());
        },
        add: function (model) {
            return $http.post('/enterpriseAccountManage/add', model, apiConfig.create());
        },
        update: function (model) {
            return $http.post('/enterpriseAccountManage/update', model, apiConfig.create());
        },
        isactive: function (model) {
            return $http.post('/enterpriseAccountManage/isactive', model, apiConfig.create());
        },
        get: function (id) {
            return $http.get('/enterpriseAccountManage/getsingle?id=' + id, apiConfig.create());
        },
        mapAccount: function (accountMapDto) {
            return $http.post('/enterpriseAccountManage/mapAccount', {
                'EnterpriseAccountCodes': accountMapDto.enterpriseAccountCodes,
                'orgID': accountMapDto.orgID,
                'StandardAccountCode': accountMapDto.standardAccountCode,
                "AccountSetID": accountMapDto.accountSetID
            }, apiConfig.create());
        },
        autoMap: function (orgID, accountSetID) {
            return $http.get('/enterpriseAccountManage/autoMap?orgID=' + orgID + '&accountSetID=' + accountSetID, apiConfig.create());
        },
        clearMap: function (enterpriseAccountIDs, orgId) {
            return $http.post('/enterpriseAccountManage/clearMap?orgId=' + orgId, enterpriseAccountIDs, apiConfig.create());
        },
        copyMapping: function (mappings) {
            return $http.post('/enterpriseAccountManage/copyMapping', mappings, apiConfig.create());
        },
        checkMapped: function (orgIDs, orgSetID) {
            return $http.post('/enterpriseAccountManage/checkMapped?orgSetID=' + orgSetID, orgIDs, apiConfig.create());
        },
        upload: function (model) {
            $http.post('/enterpriseAccountManage/Upload', model, apiConfig.create());
        },
        getListByEnterpriseAccountSetID: function (enterpriseAccountSetID) {
            return $http.get('/enterpriseAccountManage/getListByEnterpriseAccountSetID?enterpriseAccountSetID=' + enterpriseAccountSetID, apiConfig.create());
        },
        getEnterpriseAccountSetList: function () {
            return $http.get('/enterpriseAccountManage/getEnterpriseAccountSetList', apiConfig.create());
        },

        getEnterpriseAccountSetListByOrgID: function (orgID) {
            return $http.get('/enterpriseAccountManage/getEnterpriseAccountSetListByOrgID?orgID=' + orgID, apiConfig.create());
        },
        getEnterpriseAccountSet: function (id) {
            return $http.get('/enterpriseAccountManage/getEnterpriseAccountSet?id=' + id, apiConfig.create());
        },
        getAccountMappingOrg: function (organizationID) {
            return $http.get('/enterpriseAccountManage/getAccountMappingOrg?organizationID=' + organizationID, apiConfig.create());
        },

        enterpriseAccountSetNameValidate: function (model) {
            return $http.post('/enterpriseAccountManage/enterpriseAccountSetNameValidate', model, apiConfig.create());
        },
        enterpriseAccountSetOrgValidate: function (model) {
            return $http.post('/enterpriseAccountManage/enterpriseAccountSetOrgValidate', model, apiConfig.create());
        },
        updateEnterpriseAccountSet: function (model) {
            return $http.post('/enterpriseAccountManage/updateEnterpriseAccountSet', model, apiConfig.create());
        },
        clearRepeatEnterpriseAccountList: function (enterpriseAccountSetID, repeatCodeList) {

            var model = {
                id: enterpriseAccountSetID,
                repeatCodeList: repeatCodeList
            };

            return $http.post('/enterpriseAccountManage/clearRepeatEnterpriseAccountList', model, apiConfig.create());
        }, addEnterpriseAccountSetOrg: function (model) {
            return $http.post('/enterpriseAccountManage/addEnterpriseAccountSetOrg', model, apiConfig.create());
        },
        updateEnterpriseAccountSetOrg: function (model) {
            return $http.post('/enterpriseAccountManage/updateEnterpriseAccountSetOrg', model, apiConfig.create());
        },
        deleteEnterpriseAccountSetOrg: function (model) {
            return $http.post('/enterpriseAccountManage/deleteEnterpriseAccountSetOrg', model, apiConfig.create());
        },
        downEntepriseAccountTemplate: function () {

            var thisConfig = apiConfig.create();
            thisConfig.responseType = "arraybuffer";
            return $http.post('/enterpriseAccountManage/downEntepriseAccountTemplate', {},thisConfig).then(function (response) {
                var data = new Blob([response.data], { type: response.headers('Content-Type') });
                // var filename1 = response.headers('Content-Disposition').split(';')[1].trim().substr('filename='.length);
                var filename = '企业账套模板.xlsx';
                FileSaver.saveAs(data, filename);
            });
        }
    };
}]);
// web service proxy for formula
webservices.factory('formulaService', ['$http', 'apiConfig', 'httpCacheService', function ($http, apiConfig, httpCacheService) {
    'use strict';
    return {
        getAll: function () {
            return $http.get('/formula/get', apiConfig.create());
        },
        getAllParam: function () {
            return $http.get('/formula/param/get', apiConfig.create());
        },
        getAllParamMapping: function () {
            return $http.get('/formula/parammapping/get', apiConfig.create());
        }
    };
}]);
// web service proxy for menu
webservices.factory('httpCacheService', ['$http', '$q', 'apiConfig', 'CacheFactory', '$log', 'cacheService',
    function ($http, $q, apiConfig, CacheFactory, $log, cacheService) {
        'use strict';

        var deferred, promise;

        //Tell $http to use a cache created by CacheFactory for a specific request
        var getData = function (webApiUrl, isDbRequest) {

            deferred = $q.defer();
            promise = deferred.promise;
            var cacheName = constant.cache.cacheName;
            var start = new Date().getTime();
            var isFromCache = true;
            var cacheKey = constant.webapi.prefix + webApiUrl;
            var slashIndex = PWC.nIndexOf(webApiUrl, '/', 2);
            var questionMarkIndex = PWC.nIndexOf(webApiUrl, '?', 1);
            var routePrefix, dataCache;

            // Check to make sure the cache doesn't already exist
            //get method might be return error,so use the following way

            if (!CacheFactory.get(cacheName)) {
                CacheFactory(cacheName, {
                    storageMode: constant.cache.storageMode, // This cache will use `localStorage`.
                });
            }

            dataCache = CacheFactory.get(cacheName);

            if (slashIndex >= 0) {
                routePrefix = constant.webapi.prefix + webApiUrl.substring(0, slashIndex);
            } else if (questionMarkIndex >= 0) {
                routePrefix = constant.webapi.prefix + webApiUrl.substring(0, questionMarkIndex);
            } else {
                routePrefix = constant.webapi.prefix + webApiUrl;
                console.warn('need to verify the routePrefix in httpCache.svc.js');
            }

            // Now that control of inserting/removing from the cache is in our hands,
            // we can interact with the data in "dataCache" outside of this context,
            // e.g. Modify the data after it has been returned from the server and
            // save those modifications to the cache.
            this.finishedCache = false;
            if (dataCache.get(cacheKey) && !isDbRequest) {
                var data = dataCache.get(cacheKey);
                deferred.resolve(data.cacheResult);
                isFromCache = true;
                logTimeTakenInfo(cacheKey, start, isFromCache);

                promise = deferred.promise;
                this.finishedCache = true;
                return this;
            } else {
                var that = this;
                $http.get(webApiUrl, apiConfig.create()).success(function (data) {
                    cacheService.getCacheByKey(routePrefix).success(function (cache) {

                        var cacheResult = {};

                        isFromCache = false;
                        deferred.resolve(data);
                        logTimeTakenInfo(cacheKey, start, isFromCache);

                        //if could get the last modify time from cache, then align the same cache time
                        if (!cache && typeof (cache) != constant.common.undefined && cache != 0) {
                            cacheResult = { 'cacheResult': data, 'cacheTime': constant.cache.defaultCacheTime };

                        } else {
                            cacheResult = { 'cacheResult': data, 'cacheTime': cache.lastModifyTime };
                        }

                        promise = deferred.promise;
                        dataCache.put(cacheKey, cacheResult);
                        that.finishedCache = true;
                    });
                });
            }

            return this;
        };

        var promiseSuccess = function (fn) {
            promise.then(function (data) {
                fn(data);
            });
            return this;
        };

        var promiseError = function (fn) {
            promise.then(null, function (response) {
                fn(data);
            });
            return this;
        };

        var logTimeTakenInfo = function (cacheKey, start, isFromCache) {
            if (isFromCache) {
                $log.info('time taken from cache - ' + cacheKey + ': ' + (new Date().getTime() - start) + 'ms');
            } else {
                $log.info('time taken from server - ' + cacheKey + ': ' + (new Date().getTime() - start) + 'ms');
            }
        };


        // 加这个方法的原因是,getData 方法,在处理多个请求并发从后端取数据就会出现问题,可能是因为promise已经被替换成最新的了。
        var getCache = function (webApiUrl, isDbRequest, fn) {

            var cacheName = constant.cache.cacheName;
            var start = new Date().getTime();
            var isFromCache = true;
            var cacheKey = constant.webapi.prefix + webApiUrl;
            var slashIndex = PWC.nIndexOf(webApiUrl, '/', 2);
            var questionMarkIndex = PWC.nIndexOf(webApiUrl, '?', 1);
            var routePrefix, dataCache;

            // Check to make sure the cache doesn't already exist
            //get method might be return error,so use the following way

            if (!CacheFactory.get(cacheName)) {
                CacheFactory(cacheName, {
                    storageMode: constant.cache.storageMode, // This cache will use `localStorage`.
                });
            }

            dataCache = CacheFactory.get(cacheName);

            if (slashIndex >= 0) {
                routePrefix = constant.webapi.prefix + webApiUrl.substring(0, slashIndex);
            } else if (questionMarkIndex >= 0) {
                routePrefix = constant.webapi.prefix + webApiUrl.substring(0, questionMarkIndex);
            } else {
                routePrefix = constant.webapi.prefix + webApiUrl;
                console.warn('need to verify the routePrefix in httpCache.svc.js');
            }

            // Now that control of inserting/removing from the cache is in our hands,
            // we can interact with the data in "dataCache" outside of this context,
            // e.g. Modify the data after it has been returned from the server and
            // save those modifications to the cache.
            if (dataCache.get(cacheKey) && !isDbRequest) {
                var data = dataCache.get(cacheKey);

                isFromCache = true;
                logTimeTakenInfo(cacheKey, start, isFromCache);


                if (fn) {
                    fn(data.cacheResult);
                }
            } else {

                $http.get(webApiUrl, apiConfig.create()).success(function (data) {
                    cacheService.getCacheByKey(routePrefix).success(function (cache) {

                        var cacheResult = {};

                        isFromCache = false;


                        logTimeTakenInfo(cacheKey, start, isFromCache);

                        //if could get the last modify time from cache, then align the same cache time
                        if (!cache && typeof (cache) != constant.common.undefined && cache != 0) {
                            cacheResult = { 'cacheResult': data, 'cacheTime': constant.cache.defaultCacheTime };

                        } else {
                            cacheResult = { 'cacheResult': data, 'cacheTime': cache.lastModifyTime };
                        }

                        dataCache.put(cacheKey, cacheResult);
                        //promiseSuccess(thisObj.success);
                        if (fn) {
                            fn(data);
                        }
                    });
                });
            }
        };

        return {
            get: getData,
            success: promiseSuccess,
            error: promiseError,
            getCache: getCache
        };
    }]);
// web service proxy for role
webservices.factory('indexAnalysisDetailService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getIndexAnalysisTreeList: function () {
            return $http.get('/indexAnalysisDetail/getIndexAnalysisTreeList', apiConfig.create());
        },
        getIndexAnalysisDropDownList: function () {
            return $http.get('/indexAnalysisDetail/getIndexAnalysisDropDownList', apiConfig.create());
        }
    };
}]);
// web service proxy for industry
webservices.factory('industryService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getAllAvailableIndustry: function (accountCode) {
            return $http.get('/industry/getAllAvailableIndustry', apiConfig.create());
        },
    };
}]);
// web service proxy for standard account
webservices.factory('KeyValueConfigService', ['$http', 'apiConfig', 'httpCacheService', function ($http, apiConfig, httpCacheService) {
    'use strict';
    return {
        getAll: function () {
            return $http.get('/keyValueConfig', apiConfig.create());
        },
        getFinacialReference: function (id) {
            return $http.get('/keyValueConfig/getFinacialReference/'+id, apiConfig.create());
        },
        getTaxReference: function (id) {
            return $http.get('/keyValueConfig/getTaxReference/'+id, apiConfig.create());
        },
        getModelReference: function (id) {
            return $http.get('/keyValueConfig/getModelReference/'+id, apiConfig.create());
        },
        remove: function (id) {
            return $http.delete('/keyValueConfig?keyValueID=' + id, apiConfig.create());
        },
        addNewKeyValueConifg: function (newKeyValueConfig) {
            return $http.post('/keyValueConfig/add', newKeyValueConfig, apiConfig.create());
        },
        updateNewKeyValueConifg: function (updatedKeyValueConfig) {
            return $http.post('/keyValueConfig/update', updatedKeyValueConfig, apiConfig.create());
        },
        getByOrgID: function (id) {
            return $http.get('/keyValueConfig/getByOrgID/' + id, apiConfig.create());
        },
        mappingDataSource: function (formula) {
            return $http.get('/keyValueConfig/mappingDataSource/' + formula, apiConfig.create());
        },
        getAllDataSource: function () {
            return $http.get('/keyValueConfig/dataSource', apiConfig.create());
        }
    };
}]);
// web service proxy for org
webservices.factory('keywordmapService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        get: function (type) {
            return $http.get('/keywordmap/get?type=' + type, apiConfig.create());
        },
        getsingle: function (type) {
            return $http.get('/keywordmap/getsingle?keywordId=' + type, apiConfig.create());
        },
        add: function (model) {
            return $http.post('/keywordmap/add', model, apiConfig.create());
        },
        update: function (model) {
            return $http.post('/keywordmap/update', model, apiConfig.create());
        },
        isactive: function (model) {
            return $http.post('/keywordmap/isactive', model, apiConfig.create());
        }
    };
}]);
// web service proxy for org
webservices.factory('landManageService', ['$http', 'apiConfig',
function ($http, apiConfig) {
    'use strict';

    return {
        addLand: function (land) {
            return $http.post('/landManage/land', land, apiConfig.create());
        },
        updateLand: function (land) {
            return $http.put('/landManage/land', land, apiConfig.create());
        },
        disableOrEnableLand: function (land) {
            return $http.put('/landManage/disable', land, apiConfig.create());
        },
        loadAll: function () {
            return $http.get('/landManage/land',apiConfig.create());
        },
        loadAllTax: function (landID) {
            return $http.get('/landManage/taxbasic/' + landID, apiConfig.create());            
        },
        addTaxBasic: function (tax) {
            return $http.post('/landManage/taxbasic', tax, apiConfig.create());
        },
        updateTaxBasic: function (tax) {
            return $http.put('/landManage/taxbasic', tax, apiConfig.create());
        },
        deleteTaxBasic: function (taxID) {
            return $http.delete('/landManage/taxbasic/' + taxID, apiConfig.create());
        }
    };
}]);
// web service proxy for menu
webservices.factory('menuService', ['$http', '$q', 'apiConfig', 'httpCacheService',
    function ($http, $q, apiConfig, httpCacheService) {
        'use strict';

        return {
            getMenusForDisplay: function (serviceId) {
                return httpCacheService.get('/menu/display?serviceId=' + serviceId);
                //return $http.get('/menu/display?serviceId=' + serviceId, apiConfig.create());
            },
            getMenus: function (serviceId) {
                //return $http.get('/menu?serviceId=' + serviceId, apiConfig.create());
                return httpCacheService.get('/menu?serviceId=' + serviceId);
            },
            getMenusNew: function (serviceId, fn) {
                return httpCacheService.getCache('/menu?serviceId=' + serviceId, false, fn);
            },
            GetMenusForIvhTree: function (serviceId) {
                return $http.get('/menu/GetMenusForIvhTree?serviceId=' + serviceId, apiConfig.create());
            },
            updateMenu: function (menu) {
                return $http.put('/menu', menu, apiConfig.create());
            },
            addMenu: function (menu) {
                return $http.post('/menu/Add', menu, apiConfig.create());
            },
            deleteMenu: function (menuID) {
                return $http.post('/menu/Delete', menuID, apiConfig.create());
            },
            deleteMenus: function (menuIDs) {
                return $http.post('/menu/DeleteMulti', menuIDs, apiConfig.create());
            }
        };
    }]);
webservices.factory('modelConfigurationService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getModelList: function (OrgID, listQueryCondition) {
            return $http.post('/modelConfiguration/getModelList', {
                OrgID: OrgID,
                ListQueryCondition: listQueryCondition
            }, apiConfig.create());
        },
        getModelListByIndustry: function (serviceTypeID, industryID) {
            return $http.get('/modelConfiguration/model/byIndustry/' + serviceTypeID + '/' + industryID, apiConfig.create());
        },
        getModelSingle: function (orgID, modelId, categoryId) {
            return $http.post('/modelConfiguration/getModelSingle', {
                OrgID: orgID,
                ModelID: modelId,
                CategoryID: categoryId
            }, apiConfig.create());
        },
        addModel: function (modelProfile) {
            return $http.post('/modelConfiguration/addModel', modelProfile, apiConfig.create());
        },
        updateModel: function (modelProfile) {
            return $http.post('/modelConfiguration/updateModel', modelProfile, apiConfig.create());
        },
        getModelResult: function (projectId, serviceTypeId, period) {
            return $http.post('/modelConfiguration/getModelResult', {
                projectId: projectId,
                serviceTypeId: serviceTypeId,
                period: period
            }, apiConfig.create({ ignoreLoadingBar: true }));
        },
        migrateModelResult: function (project) {
            return $http.post('/modelConfiguration/migrateModelResult', project, apiConfig.create({ ignoreLoadingBar: true }));
        },
        resetOrgModelSetting: function (modelId, orgId) {
            return $http.get('/modelConfiguration/resetOrgModelSetting?modelId=' + modelId + '&orgId=' + orgId,
                apiConfig.create());
        },
        getModelDefaultSetting: function (orgID, modelId, categoryId) {
            return $http.post('/modelConfiguration/getModelDefaultSetting', {
                OrgID: orgID,
                ModelID: modelId,
                CategoryID: categoryId
            }, apiConfig.create());
        },
        getIndustry: function (orgId) {
            return $http.get('/modelConfiguration/getIndustry?orgId=' + orgId,
                apiConfig.create());
        },
        updateCategory: function (categoryMto) {
            return $http.post('/modelConfiguration/updateCategory', categoryMto, apiConfig.create());
        },
        updateModelConfig: function (modelID, oldCategoryID, newCategoryID) {
            return $http.post('/modelConfiguration/updateModelConfig', {
                OrgID: newCategoryID,
                ModelID: modelID,
                CategoryID: oldCategoryID
            }, apiConfig.create());
        },
        updateCategoryWhenMove: function (id, oldCategoryID, newCategoryID, sortCurrent) {
            return $http.post('/modelConfiguration/updateCategoryWhenMove', {
                OrgID: newCategoryID,
                ModelID: id,
                CategoryID: oldCategoryID,
                SortCurrent: sortCurrent
            }, apiConfig.create());
        },
        deleteCategory: function (id, orgId) {
            return $http.get('/modelConfiguration/deleteCategory?id=' + id + '&orgId=' + orgId,
                apiConfig.create());
        },
        deleteModel: function (modelId) {
            return $http.get('/modelConfiguration/deleteModel?modelId=' + modelId,
                apiConfig.create());
        },
        deleteModelBackFill: function (id) {
            return $http.get('/modelConfiguration/deleteModelBackFill?id=' + id,
                apiConfig.create());
        },
        uniqueModelName: function (modelName, modelId, orgId, isAdd) {
            return $http.get('/modelConfiguration/uniqueModelName?modelName=' + modelName + '&modelId=' + modelId + '&orgId=' + orgId + '&isAdd=' + isAdd,
                apiConfig.create());
        },
        uniqueCategoryName: function (categoryName, orgId, modelId) {
            return $http.get('/modelConfiguration/uniqueCategoryName?categoryName=' + categoryName + '&orgId=' + orgId + '&modelId=' + modelId,
                apiConfig.create());
        },
        deleteModelResult: function () {
            return $http.get('/modelConfiguration/deleteModelResult', apiConfig.create());
        },
        getProject: function (orgID) {
            return $http.get('/modelConfiguration/getProject?orgID=' + orgID,
                apiConfig.create());
        },
        getServiceList: function (orgId, modelId, isAdd) {
            return $http.get('/modelConfiguration/getServiceList?orgId=' + orgId + '&modelId=' + modelId + '&isAdd=' + isAdd,
                apiConfig.create());
        },
        getModelPreviewResult: function (modelProfile, project) {
            var parmDto = {
                OrgID: project[0].id,
                Project: project,
                ModelProfile: modelProfile
            };
            return $http.post('/modelConfiguration/getModelPreviewResult', parmDto, apiConfig.create({ dbName: project[0].dbName }));
        },
        getModelCategoryString: function (orgId, modelCategoryId) {
            return $http.get('/modelConfiguration/getModelCategoryString?orgId=' + orgId + '&modelCategoryId=' + modelCategoryId,
                apiConfig.create());
        },
        getModelCategory: function (organizationId, industryId, serviceTypeId) {
            return $http.get('/modelConfiguration/getModelCategory?organizationId=' + organizationId + '&industryId=' + industryId + '&serviceTypeId=' + serviceTypeId,
                apiConfig.create());
        },
        getIndexModelResultByCategory: function (categoryId, serviceTypeId, organizationId, industryId) {
            return $http.get('/modelConfiguration/getIndexModelResultByCategory?categoryId=' + categoryId + '&serviceTypeId=' + serviceTypeId + '&organizationId=' + organizationId + '&industryId=' + industryId,
                apiConfig.create());
        },
        getEntriesModelResultByCategory: function (categoryId, serviceTypeId, organizationId, industryId, periodFrom, periodTo) {
            return $http.get('/modelConfiguration/getEntriesModelResultByCategory?categoryId=' + categoryId + '&serviceTypeId=' + serviceTypeId + '&organizationId=' + organizationId + '&industryId=' + industryId + '&periodFrom=' + periodFrom + '&periodTo=' + periodTo,
                apiConfig.create());
        },
        getEntriesModelResultDetail: function (modelId, serviceTypeId, type, periodFrom, periodTo, pagingInfo, isShowFilter, preview) {
            var pageIndex = 0;
            var pageSize = 0
            if (pagingInfo != null) {
                pageIndex = pagingInfo.pageIndex;
                pageSize = pagingInfo.pageSize
            }
            return $http.get('/modelConfiguration/getEntriesModelResultDetail?modelId=' + modelId + '&serviceTypeId=' + serviceTypeId + '&type=' + type + '&periodFrom=' + periodFrom + '&periodTo=' + periodTo + '&pageIndex=' + pageIndex + '&pageSize=' + pageSize + '&isShowFilter=' + isShowFilter + '&preview=' + preview,
                apiConfig.create());
        },
        getEntriesModelResultDetailByVoucher: function (modelId, serviceTypeId, type, periodFrom, periodTo, pagingInfo, isShowFilter) {
            var pageIndex = 0;
            var pageSize = 0
            if (pagingInfo != null) {
                pageIndex = pagingInfo.pageIndex;
                pageSize = pagingInfo.pageSize;
            }
            return $http.get('/modelConfiguration/getEntriesModelResultDetailByVoucher?modelId=' + modelId + '&serviceTypeId=' + serviceTypeId + '&type=' + type + '&periodFrom=' + periodFrom + '&periodTo=' + periodTo + '&pageIndex=' + pageIndex + '&pageSize=' + pageSize + '&isShowFilter=' + isShowFilter,
                apiConfig.create());
        },
        getEntriesByVoucher: function (modelId, serviceTypeId, type, periodFrom, periodTo, period, vid, group, isShowFilter) {
            return $http.get('/modelConfiguration/GetEntriesByVoucher?modelId=' + modelId + '&serviceTypeId=' + serviceTypeId + '&type=' + type + '&periodFrom=' + periodFrom + '&periodTo=' + periodTo + '&period=' + period + '&vid=' + vid + '&group=' + group + '&isShowFilter=' + isShowFilter,
                apiConfig.create());
        },
        updateEntriesFiter: function (entriesDto) {
            return $http.post('/modelConfiguration/updateEntriesFiter', entriesDto, apiConfig.create());
        },
        getGL: function (resultId, fromPeriod, toPeriod) {
            return $http.get('/modelConfiguration/getGL?resultId=' + resultId + '&fromPeriod=' + fromPeriod + '&toPeriod=' + toPeriod,
                apiConfig.create());
        },
        projectHasDirtyData: function (projectID, serviceTypeID) {
            return $http.get('/modelConfiguration/projectHasDirtyData/' + projectID + '/' + serviceTypeID,
                apiConfig.create());
        },
        updateProjectModelDirtyDataSingleCard: function (projectID, serviceTypeID) {
            return $http.get('/modelConfiguration/updateProjectModelDirtyDataSingleCard/' + projectID + '/' + serviceTypeID,
                apiConfig.create());
        },
        organizationsHasDirtyData: function (organizationIDs, year, serviceTypeID) {
            return $http.post('/modelConfiguration/organizationsHasDirtyData', { OrganizationIDs: organizationIDs, Year: year, ServiceTypeID: serviceTypeID },
                apiConfig.create());
        },
        updateOrganizationsModelDirtyData: function (organizationIDs, year, serviceTypeID) {
            return $http.post('/modelConfiguration/updateOrganizationsModelDirtyData', { OrganizationIDs: organizationIDs, Year: year, ServiceTypeID: serviceTypeID },
                apiConfig.create({ ignoreLoadingBar: true }));
        },
        getEntriesModelResultDetailCount: function (modelId, serviceTypeId, type, periodFrom, periodTo, isEntriesShow) {
            return $http.get('/modelConfiguration/getEntriesModelResultDetailCount?modelId=' + modelId + '&serviceTypeId=' + serviceTypeId + '&type=' + type + '&periodFrom=' + periodFrom + '&periodTo=' + periodTo + '&isEntriesShow=' + isEntriesShow,
                apiConfig.create());
        },
        getIndexModelResultByCellInfo: function (model) {
            return $http.post('/modelConfiguration/getIndexModelResultByCellInfo', model,
               apiConfig.create());
        },
        getEntriesModelResultByCellInfo: function (modelIdList) {
            return $http.post('/modelConfiguration/getEntriesModelResultByCellInfo', modelIdList,
               apiConfig.create());
        },
        modelBackFill: function (model) {
            return $http.post('/modelConfiguration/modelBackFill', model,
                apiConfig.create());
        },
        getOutputModelResult: function (modelFeature, project, periodFrom, periodTo, fileName,sheetNames) {
            return $http.post('/modelConfiguration/getOutputModelResult', {
                ModelFeature: modelFeature,
                Project: project,
                PeriodFrom: periodFrom,
                PeriodTo: periodTo,
                FileName: fileName,
                SheetNames: sheetNames
            }, apiConfig.create({ responseType: 'arraybuffer' }));
        }};
}]);
// web service proxy for role
webservices.factory('modifiedReportCellService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        update: function (modifiedReportCell) {
            return $http.post('/ModifiedReportCell/Update', modifiedReportCell, apiConfig.createVat());
        },
        reset: function (id) {
            return $http.post('/ModifiedReportCell/Reset/' + id, {}, apiConfig.createVat());
        },
    };
}]);
// web service proxy for operationlog
webservices.factory('operationLogService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getOrgLogList: function (model) {
            return $http.post('/operationlog/getorgloglist', model
                 , apiConfig.create());
        }
    };
}]);
// web service proxy for org
webservices.factory('orgService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getOrgList: function (type) {
            return $http.get('/org/display?useType=' + type, apiConfig.create());
        },
        getOrgListToJson: function (type) {
            return $http.get('/org/getjson?useType=' + type, apiConfig.create());
        },
        getOrgListForGrid: function () {
            return $http.get('/org/displayForGrid', apiConfig.create());
        },
        getSingleOrg: function (orgId) {
            return $http.get('/org/displaySingle?orgId=' + orgId, apiConfig.create());
        },
        addOrg: function (org) {
            return $http.post('/org/add', org, apiConfig.create());
        },
        updateOrg: function (org) {
            return $http.put('/org/update', org, apiConfig.create());
        },
        updateHierarchy: function (srcOrgID, destOrgID) {
            return $http.put('/org/updateHierarchy?srcOrgID=' + srcOrgID + '&destOrgID=' + destOrgID, org, apiConfig.create());
        },
        disableOrgs: function (orgList) {
            return $http.post('/org/disableOrgs', orgList, apiConfig.create());
        },
        deleteOrg: function (org) {
            return $http.post('/org/delete', org, apiConfig.create());
        },
        deleteOrgs: function (orgList) {
            return $http.post('/org/deleteOrgs', { orgList: orgList }, apiConfig.create());
        },
        getProjectIndustrys: function () {
            return $http.get('/org/getProjectIndustrys', apiConfig.create());
        },
        enableOrgs: function (id) {
            return $http.get('/org/enableOrgs?orgID=' + id, apiConfig.create());
        },
        getOrgIvhTreeList: function (useType, orgSetID) {
            return $http.get('/org/getOrgIvhTreeList?useType=' + useType + '&orgSetID=' + orgSetID, apiConfig.create());
        },
        getOrgDevTreeList: function (useType, orgSetID) {
            return $http.get('/org/getOrgDevTreeList?useType=' + useType + '&orgSetID=' + orgSetID, apiConfig.create());
        },
        codeUniqueValidate: function (id, viewValue) {
            return $http.post('/org/codeUniqueValidate', { Id: id, Value: viewValue }, apiConfig.create({ ignoreLoadingBar: true }));
        },
        taxPayerNumberUniqueValidate: function (id, viewValue) {
            return $http.post('/org/taxPayerNumberUniqueValidate', { Id: id, Value: viewValue }, apiConfig.create({ ignoreLoadingBar: true }));
        },
        getAreaStatistics: function () {
            return $http.get('/org/getAreaStatistics', apiConfig.create());
        },
        getOrgListForDashboard: function (orgID) {
            return $http.get('/org/getOrgListForDashboard?orgID=' + orgID, apiConfig.create({ ignoreLoadingBar: true }));
        },
        getOrgListFirstLevel: function () {
            return $http.get('/org/getOrgListFirstLevel', apiConfig.create());
        },
        getOrgAreaDashboard: function (dimensionValueID, parentDimensionID) {
            return $http.get('/org/getOrgAreaDashboard?dimensionValueID=' + dimensionValueID + '&parentDimensionID=' + parentDimensionID, apiConfig.create());
        },
        //getOrgBuDashboard: function (parentDimensionID) {
        //    return $http.get('/org/getOrgBuDashboard?parentDimensionID=' + parentDimensionID, apiConfig.create());
        //},
        getOrgCustomDashbord: function (dimensionValueID, parentDimensionID, attributeID) {
            return $http.get('/org/getOrgCustomDashbord?dimensionValueID=' + dimensionValueID + '&parentDimensionID=' + parentDimensionID + '&attributeID=' + attributeID, apiConfig.create());
        },
        getAreaOrganizationStaticsTreeList: function () {
            return $http.get('/org/getAreaOrganizationStaticsTreeList', apiConfig.create());
        },
        getOrgUserList: function (orgID) {
            return $http.get('/org/getOrgUserList?orgID=' + orgID, apiConfig.create({ ignoreLoadingBar: true }));
        },
        getOrgCityAreaUserCountList: function (orgID) {
            return $http.get('/org/getOrgCityAreaUserCountList?orgID=' + orgID, apiConfig.create({ ignoreLoadingBar: true }));
        },
        getGeneralInfo: function (orgID) {
            return $http.get('/org/getGeneralInfo?orgID=' + orgID, apiConfig.create({ ignoreLoadingBar: true }));
        },
        getOrgBuAreaIndustryUser: function (userID) {
            return $http.get('/org/getOrgBuAreaIndustryUser?userID=' + userID, apiConfig.create());
        },
        getOrgRoleListView: function (userID) {
            return $http.get('/org/getOrgRoleListView?userID=' + userID, apiConfig.create());
        },
        getOrgListCountDashboard: function (dimensionValueID, parentDimensionID) {
            return $http.get('/org/getOrgListCountDashboard?dimensionValueID=' + dimensionValueID + '&parentDimensionID=' + parentDimensionID, apiConfig.create({ ignoreLoadingBar: true }));
        },
        getOrgDashboard: function (dimensionID, parentOrgID, expandedOrgList) {
            return $http.post('/org/getOrgDashboard?dimensionID=' + dimensionID + '&parentOrgID=' + parentOrgID, expandedOrgList, apiConfig.create());
        },
        getOrgDashboardOnly: function (dimensionID, parentOrgID) {
            return $http.get('/org/getOrgDashboardOnly?dimensionID=' + dimensionID + '&parentOrgID=' + parentOrgID, apiConfig.create());
        },
        getBusinessUnitOrganizationStaticsTreeList: function () {
            return $http.get('/org/getBusinessUnitOrganizationStaticsTreeList', apiConfig.create());
        },
        getOrgListLevel: function () {
            return $http.get('/org/getOrgListLevel', apiConfig.create());
        },
        updateOrgToDimension: function (dimensionValueID, parentDimensionID, orgList) {
            return $http.post('/org/updateOrgToDimension', { dimensionValueID: dimensionValueID, dimensionID: parentDimensionID, orgDtoList: orgList }, apiConfig.create());
        },
        deleteUserDimensionValue: function (dimensionRoleDto, userID) {
            return $http.post('/org/deleteUserDimensionValue?userID=' + userID, dimensionRoleDto, apiConfig.create());
        },
        deleteUserOrg: function (orgRoleDto, userID) {
            return $http.post('/org/deleteUserOrg?userID=' + userID, orgRoleDto, apiConfig.create());
        },
        getOrganizationListByAreaID: function (areaID, attributeID) {
            return $http.get('/org/getOrganizationListByAreaID?areaID=' + areaID + '&attributeID=' + attributeID, apiConfig.create());
        },
        getOrganizationFilterList: function () {
            return $http.get('/org/getOrganizationFilterList', apiConfig.create());
        },
        getActiveOrganizationList: function () {
            return $http.get('/org/getActiveOrganizationList', apiConfig.create());
        },
        getGd: function () {
            return $http.get('/org/gd', apiConfig.create());
        },
        getBdList: function () {
            return $http.get('/org/bdList', apiConfig.create());
        }
    };
}]);
// web service proxy for role
webservices.factory('organizationStructureService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getOrganizationStructureList: function () {
            return $http.get('/organizationstructure/getlist', apiConfig.create());
        },
        updateOrganizationStructure: function (organizationStructure) {
            return $http.put('/organizationstructure', organizationStructure, apiConfig.create());
        },
        addOrganizationStructure: function (organizationStructure) {
            return $http.post('/organizationstructure/add', organizationStructure, apiConfig.create());
        },
        deleteOrganizationStructure: function (id) { 
            return $http.post('/organizationstructure/delete', { id: id }, apiConfig.create());
        }
    };
}]);
// web service proxy for menu
webservices.factory('permissionService', ['$http', '$q', 'apiConfig', 'httpCacheService',
    function ($http, $q, apiConfig, httpCacheService) {
        'use strict';

        return {
            getPermissionTreeList: function (serviceId) {
                return $http.get('/permission/getlist?serviceId=' + serviceId, apiConfig.create());
            },
            getDevTreePermissionsByRoleID: function (roleID, serviceType) {
                var config = { ignoreLoadingBar: false };
                return $http.get('/permission/getIvhTreePermissionsByRoleID?roleID=' + roleID + '&serviceType=' + serviceType, apiConfig.create(config));
            },
            getDevTreePermissionsByRoleIDList: function (roldIDList, serviceType) {
                return $http.post('/permission/getIvhTreePermissionsByRoleIDList?serviceType=' + serviceType, roldIDList, apiConfig.create());
            },
            //返回DevTreeDto list
            getAllPermissions: function (serviceType) {
                return $http.get('/permission/getAllPermissions?serviceType=' + serviceType, apiConfig.create());
                //return httpCacheService.get('/permission/getAllPermissions?serviceType=' + serviceType);
            },
            getPermissionListByRoleID: function (roleID, serviceType) {
                var config = { ignoreLoadingBar: false };
                return $http.get('/permission/getPermissionListByRoleID?roleID=' + roleID + '&serviceType=' + serviceType, apiConfig.create(config));
            }
        };
    }]);
// registration web service proxy
webservices.factory('productService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getFileContent: function (tempFileName, selectedSheetIndex, topRowNumber) {
            return $http.get('/product/FileContent/' + tempFileName + '/' + selectedSheetIndex + '/' + topRowNumber, apiConfig.create());
        },
        getProductList: function () {
            return $http.get('/product/listProduct', apiConfig.create());
        },
        getProductItemList: function (fSetCode, productIDs) {
            return $http.get('/product/listProductItem/'+fSetCode+'/'+productIDs, apiConfig.create());
        },
        getProductItemListByPage: function (paras) {
            return $http.post('/product/listProductItemByPage', paras, apiConfig.create());
        },
        getProductItemValueAmount: function (paras) {
            return $http.post('/product/productItemValueAmount', paras, apiConfig.create());
        },
        importProductItemData: function (productItemList, importType,startYear,startMonth) {
            return $http.post('/product/productItemListImport', { ProductItemList: productItemList, ImportType: importType, StartYear: startYear, StartMonth: startMonth }, apiConfig.create());
        },
        addNewProduct: function (product) {
            return $http.post('/product/addNewProduct', product, apiConfig.create());
        },
        importProductData: function (importProductList) {
            return $http.post('/product/productImport', { ProductList: importProductList }, apiConfig.create());
        }
    };
}]);
// web service proxy for project
webservices.factory('projectService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getServiceList: function () {
            return $http.get('/project/listService', apiConfig.create());
        },
        getProjectList: function (orgID, serviceID, projectYear) {
            return $http.get('/project/display?orgID=' + orgID + '&serviceID=' + serviceID + '&projectYear=' + projectYear, apiConfig.create());
        },
        getOneProjectByDbNameServiceIdAndPeriodId: function (dbName, serviceID, periodId) {
            return $http.get('/project/getOneProjectByDbNameServiceIdAndPeriodId?dbName=' + dbName + '&serviceID=' + serviceID + '&periodId=' + periodId, apiConfig.create());
        },
        

        getAllProjectList: function (orgID, serviceID, projectYear) {
            return $http.get('/project/getAllProjectList?orgID=' + orgID + '&serviceID=' + serviceID + '&projectYear=' + projectYear, apiConfig.create());
        },
        getProjectByID: function (projectID) {
            return $http.get('/project/getProject?projectID=' + projectID, apiConfig.create());
        },
        getProjectExceptSelected: function (userId) {
            return $http.get('/project/displayExceptSelected?userID=' + userId, apiConfig.create());
        },
        getSingleProject: function (projectID) {
            return $http.get('/project/displaySingle?projectID=' + projectID, apiConfig.create());
        },
        addProject: function (projectDto) {
            return $http.post('/project/add', projectDto, apiConfig.create());
        },
        updateProject: function (projectDto) {
            return $http.put('/project/update', projectDto, apiConfig.create());
        },
        getProjectClientList: function (projectID) {
            return $http.get('/project/getProjectClientList', apiConfig.create());
        },
        getProjectStatus: function (dbName, projectId, periodId) {
            return $http.get('/ProjectStatusManage/getProjectStatus/' + dbName + '/' + projectId + '/' + periodId, apiConfig.createVat());
        },
        setProjectStatus: function (dbName, periodId, status) {
            return $http.get('/ProjectStatusManage/setProjectStatus/' + dbName + '/' + periodId + '/' + status, apiConfig.createVat());
        },
        isImportedAnyData: function (periodId,projectId) {
            return $http.get('/ProjectStatusManage/isImportedAnyData/' + periodId + '/' + projectId, apiConfig.createVat());
        },
        isProjectStatusExisted: function (dbName, periodId) {
            return $http.get('/ProjectStatusManage/isProjectStatusExisted/' + dbName + '/' + periodId, apiConfig.createVat());
        },
        getProjectAllStatus: function (dbName) {
            return $http.get('/project/getProjectAllStatus/' + dbName, apiConfig.create());
        }
    };
}]);
// registration web service proxy
webservices.factory('recategoryService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        addAccountRecategory: function (recategory) {
            return $http.post('/AccountRecategory',recategory, apiConfig.create());
        },
        deleteAccountRecategory: function (recategoryIds) {
            return $http.post('/AccountRecategory/Delete', recategoryIds, apiConfig.create());
        },
        updateAccountRecategory: function (recategory) {
            return $http.put('/AccountRecategory', recategory, apiConfig.create());
        },
        getRecategoriesByAccountCode: function (accountCode) {
            return $http.get('/AccountRecategory?accountCode=' + accountCode, apiConfig.create());
        },
    };
}]);
// web service proxy for org
webservices.factory('regionService', ['$http', 'apiConfig', 'httpCacheService',
function ($http, apiConfig, httpCacheService) {
    'use strict';

    return {
        //tree: function (type) {
        //    return $http.get('/region/tree?isactive=' + type, apiConfig.create());
        //},
        //add: function (model) {
        //    return $http.post('/region/add', model, apiConfig.create());
        //},
        //update: function (model) {
        //    return $http.post('/region/update', model, apiConfig.create());
        //},
        //isactive: function (model) {
        //    return $http.post('/region/isactive', model, apiConfig.create());
        //},
        //getRegionList: function (type) {
        //    return $http.get('/region/getRegionList?isactive=' + type, apiConfig.create());
        //},
        //getRegionTreeByID: function (id) {
        //    return $http.get('/region/getRegionTreeByID?id=' + id, apiConfig.create());
        //}, 
        //getProvinceAndCityList: function () {
        //    //return $http.get('/region/getProvinceAndCityList', apiConfig.create());
        //    return httpCacheService.get('/region/getProvinceAndCityList');
        //},
        //getProvinceAndCityListForIvhTree: function () {
        //    //return $http.get('/region/getProvinceAndCityList', apiConfig.create());
        //    return httpCacheService.get('/region/getProvinceAndCityListForIvhTree');
        //},
        getSettingRegionTree: function () {
            return $http.get('/region/getSettingRegionTree', apiConfig.create());
            //return httpCacheService.get('/region/getSettingRegionTree');
        },
        getAreRegionTreeByNodeID: function (areaID) {
            return $http.get('/region/getAreRegionTreeByNodeID?areaID=' + areaID, apiConfig.create());
        },
        getProvinceAndCityTreeList: function () {
            //return $http.get('/region/getProvinceAndCityList', apiConfig.create());
            return httpCacheService.get('/region/getProvinceAndCityTreeList');
        }
    };
}]);
// registration web service proxy
webservices.factory('registrationService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        searchPatient: function (patientName) {
            var config = { params: { patientName: patientName }, isBusyRequest: true };
            return $http.get('/registration/patients/search', apiConfig.create(config));
        },
        saveNewRegistration: function (registration) {
            var config = {isBusyRequest: true };
            return $http.post('/registration/orders/newRegistration', registration, apiConfig.create(config));
        },
        getPatient:function(id){
            var config = { isBusyRequest: true };
            return $http.get("/registration/patients/"+id, apiConfig.create(config));
        },
        updatePatient: function (patient,order) {
            var config = { isBusyRequest: true };
            var data = { patient: patient, order: order };
            return $http.put("/registration/patients/" + patient.uniqueID, data, apiConfig.create(config));
        },
        updateOrder: function (order) {
            var config = {isBusyRequest: true };
            return $http.put("/registration/orders/" + order.uniqueID, order, apiConfig.create(config));
        },
        getPatientNO: function (site) {
            var config = {params:{}, isBusyRequest: true };
            return $http.get('/registration/orders/generate/patientNo/'+site, apiConfig.create(config));
        },
        getAccNo: function () {
            var config = { params: {}, isBusyRequest: true };
            return $http.get('/registration/orders/generate/accNo', apiConfig.create(config));
        },
        getProcedures: function (patientId) {
            return $http.get('/registration/patients/procedures/' + patientId, apiConfig.create());
        },
        getProcedure: function (id) {
            var config = { isBusyRequest: true };
            return $http.get('/registration/procedures/' + id, apiConfig.create());
        },
        updateProcedure: function (id, proceduresRelated) {
            var config = { isBusyRequest: true };       
            return $http.put("/registration/procedures/" + id, proceduresRelated, apiConfig.create(config));
        },
        addProcedure:function(proceduresRelated){
            var config = { isBusyRequest: true };
            return $http.post("/registration/procedures", proceduresRelated, apiConfig.create(config));
        },
        deleteProcedure:function(id){
            return $http.delete('/registration/procedures/' + id, apiConfig.create());
        },
        getEnglishName: function (strChinese, UpperFirstLetter, SeparatePolicy, Separator) {
            var data = { LocalName: strChinese, UpperFirstLetter: UpperFirstLetter, SeparatePolicy: SeparatePolicy, Separator: Separator };
            return $http.post('/registration/orders/simplifiedToEnglish', data, apiConfig.create());
        },
        getRequisitionUrl: function (accNo, modalityType) {
            var config = { params: { accNo: accNo, modalityType: modalityType }, isBusyRequest: true };
            return $http.get('/registration/orders/requisition/url', apiConfig.create(config));
        },
        getBarCodeUrl: function (accNo, modalityType) {
            var config = { params: { accNo: accNo, modalityType: modalityType }, isBusyRequest: true };
            return $http.get('/registration/orders/barcode/url', apiConfig.create(config));
        },
        getOrder: function (orderId) {
            var config = { isBusyRequest: true };
            return $http.get('/registration/orders/' + orderId, apiConfig.create(config));
        },
        getRegistrationInfo: function (orderId) {
            var config = { isBusyRequest: true };
            return $http.get('/registration/' + orderId, apiConfig.create(config));
        },
        getProcedureCodes: function () {
            return $http.get('/registration/procedurecodes', apiConfig.create());
        },
        getBodySystemMaps: function () {
            return $http.get('/registration/bodySystemMaps', apiConfig.create());
        },
        getAccountDemoOne: function (accountId) {
            var config = { isBusyRequest: true };
            return $http.get('/NewAccount/' + accountId, apiConfig.create(config));
        },
        getAccountDemoList: function () {
            var config = { isBusyRequest: true };
            return $http.get('/NewAccount', apiConfig.create(config));
        },
        getAccountGroup : function(){
            var config = { isBusyRequest: true };
            return $http.get('/AccountGroup', apiConfig.create(config));
        },
        finishExam: function (order) {
        var config = { isBusyRequest: true };       
        return $http.put("/registration/finishexam/" + order.uniqueID, order, apiConfig.create(config));
    },
    };
}]);
// worklist web service proxy
webservices.factory('reportService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getReport: function (reportId) {
            var config = { isBusyRequest: true };
            return $http.get('/report/reports/' + reportId, apiConfig.create(config));
        },
        getReportByProcedureID: function (procedureId) {
            var config = { isBusyRequest: true };
            return $http.get('/report/reportbyprocedureid/' + procedureId, apiConfig.create(config));
        },
        createReport: function (newData) {
            var config = { isBusyRequest: true };
            var data =  JSON.stringify(newData);
            return $http.post('/report/reports', data, apiConfig.create(config));
        },
        updateReport: function (newData) {
            var config = { isBusyRequest: true };
            var data =  JSON.stringify(newData);
            return $http.put('/report/reports/' + newData.uniqueID, data, apiConfig.create(config));
        },
        getBaseInfo: function (procedureId) {
            var config = { isBusyRequest: true };
            return $http.get('/report/baseinfo/' + procedureId, apiConfig.create(config));
        },
        getBaseInfoDesc: function (procedureId) {
            var config = { isBusyRequest: true };
            return $http.get('/report/baseinfodesc/' + procedureId, apiConfig.create(config));
        },
        getBaseInfoDescByOrderID: function (orderId) {
            var config = { isBusyRequest: true };
            return $http.get('/report/baseinfodescbyorderid/' + orderId, apiConfig.create(config));
        },
        getBaseInfoByOrderID: function (orderId) {
            var config = { isBusyRequest: true };
            return $http.get('/report/baseinfobyorderid/' + orderId, apiConfig.create(config));
        },
        getProceduresByOrderID: function (orderId) {
            return $http.get('/report/getproceduresbyorderid/' + orderId, apiConfig.create());
        },
        getProceduresByReportID: function (reportId) {
            return $http.get('/report/getproceduresbyreportid/' + reportId, apiConfig.create());
        },
        getLock: function (reportId) {
            return $http.get('/report/getlock/' + reportId, apiConfig.create());
        },
        getLockByOrderID: function (orderId) {
            return $http.get('/report/getlockbyorderid/' + orderId, apiConfig.create());
        },
        getLockByOrderIDByAnyLockType: function (orderId) {
            return $http.get('/report/getlockbyorderidbyanylocktype/' + orderId, apiConfig.create());
        },
        addLock: function (reportId) {
            return $http.get('/report/addlockbyreportid/' + reportId, apiConfig.create());
        },
        deleteLock: function (reportId) {
            return $http.delete('/report/deletelockbyreportid/' + reportId, apiConfig.create());
        },
        addLockByOrderID: function (orderId) {
            return $http.get('/report/addlockbyorderid/' + orderId, apiConfig.create());
        },
        deleteLockByOrderID: function (orderId) {
            return $http.delete('/report/deletelockbyorderid/' + orderId, apiConfig.create());
        },

        addLockByProcedureID: function (procedureId) {
            return $http.get('/report/addlockbyprocedureid/' + procedureId, apiConfig.create());
        },
        addLockByProcedureIDs: function (ids) {
            var config = { isBusyRequest: true };
            var data = JSON.stringify(ids);
            return $http.post('/report/addlockbyprocedureids', data, apiConfig.create(config));
        },
        deleteLockByProcedureID: function (procedureId) {
            return $http.delete('/report/deletelockbyprocedureid/' + procedureId, apiConfig.create());
        },
        deleteLockByProcedureIDs: function (ids) {
            var config = { isBusyRequest: true };
            var data = JSON.stringify(ids);
            return $http.post('/report/deletelockbyprocedureids', data, apiConfig.create(config));
        },
        getAllUserByParentID: function (id) {
            var config = { isBusyRequest: true };
            return $http.get('/report/userforreportbyparentid/' + id, apiConfig.create(config));
        },
        getTemplateByParentID: function (id) {
            return $http.get('/report/gettemplatebyparentid/' + id, apiConfig.create());
        },
        getTemplateID: function (id) {
            return $http.get('/report/getreporttemplate/' + id, apiConfig.create());
        },
        getProcedureByID: function (id) {
            var config = { isBusyRequest: true };
            return $http.get('/report/getprocedurebyid/' + id, apiConfig.create(config));
        },
        getExamedProcedureByOrderID: function (id) {
            var config = { isBusyRequest: true };
            return $http.get('/report/getexamedproceduresbyorderid/' + id, apiConfig.create(config));
        },
        getReportViewerByProcedureID: function (id) {
            var config = { isBusyRequest: true };
            return $http.get('/report/getreportviewerbyprocedureid/' + id, apiConfig.create(config));
        },
        getReportPrintUrlByProcedureID: function (id) {
            var config = {isBusyRequest: true };
            return $http.get('/report/getreportprinturlbyprocedureid/' + id, apiConfig.create(config));
        },
        updateReportPrintStatusByProcedureID: function (id, printer) {
            return $http.get('/report/updatereportprintstatusbyprocedureid/' + id + '/' + printer, apiConfig.create());
        },
        getServerTime: function () {
            return $http.get('/report/getservertime' , apiConfig.create());
        },
        updateComments: function (newData) {
            var data =  JSON.stringify(newData);
            return $http.post('/report/updatecomments', data, apiConfig.create());
        },
        getReportListByID: function (id) {
            var config = { isBusyRequest: true };
            return $http.get('/report/getreportlistbyid/' + id, apiConfig.create(config));
        },
        getOtherReportListByID: function (id) {
            var config = { isBusyRequest: true };
            return $http.get('/report/getotherreportlistbyid/' + id, apiConfig.create(config));
        },
        getOtherReportListByProcedureID: function (id) {
            var config = { isBusyRequest: true };
            return $http.get('/report/getotherreportlistbyprocedureid/' + id, apiConfig.create(config));
        },
    };
}]);
// web service proxy for role
webservices.factory('roleService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getRoleListByServiceGroup: function () {
            return $http.get('/role/displayByServiceGroup', apiConfig.create());
        },
        getUsersByRoleID: function (roleId) {
            return $http.get('/role/getUsersByRoleID?roleId=' + roleId, apiConfig.create());
        },
        getExtraUsersByRoleID: function (roleId) {
            return $http.get('/role/getExtraUsersByRoleID?roleId=' + roleId, apiConfig.create());
        },
        getRoleListByRoleTypeId: function (roleTypeId) {
            return $http.get('/role/displayByRoleType?roleTypeId=' + roleTypeId, apiConfig.create());
        },
        getSingleRole: function (roleId) {
            return $http.get('/role/displaySingle?roleId=' + roleId, apiConfig.create());
        },
        addRole: function (role) {
            return $http.post('/role/add', role, apiConfig.create());
        },
        updateRole: function (updateRole, roleId) {
            return $http.put('/role/update?roleID=' + roleId, updateRole, apiConfig.create());
        },
        deleteRole: function (role) {
            return $http.post('/role/delete', role, apiConfig.create());
        },
        deleteRoles: function (roleList) {
            return $http.post('/role/deleteRoleList', { roleList: roleList }, apiConfig.create());
        },
        checkRoleExist: function (roleId) {
            return $http.get('/role/exist?roleId=' + roleId, apiConfig.create());
        },

        checkReference: function (roleID) {
            return $http.get('/role/checkReferenceforRole?roleID=' + roleID, apiConfig.create());
        },
        getroletree: function (serviceTypeID) {
            return $http.get('/role/getroletree?serviceTypeID=' + serviceTypeID, apiConfig.create());
        },
        getRoleTreeList: function () {
            return $http.get('/role/getRoleTreeList', apiConfig.create());
        },
        getUserRoleList: function (organizationID, dimensionID, dimensionValueID) {
            return $http.get('/role/getUserRoleList?organizationID=' + organizationID + '&dimensionID=' + dimensionID + '&dimensionValueID=' + dimensionValueID, apiConfig.create());
        },
        getAllUserRoleList: function () {
            return $http.get('/role/getAllUserRoleList', apiConfig.create());
        },
        getAllUserRoleListByUserID: function (userID) {
            return $http.get('/role/getAllUserRoleListByUserID?userID=' + userID, apiConfig.create());
        },
        //用户下面多个角色,多少个机构
        getDimensionUserRoleList: function (dimensionID, dimensionValueID) {
            return $http.get('/role/getDimensionUserRoleList?dimensionID=' + dimensionID + '&dimensionValueID=' + dimensionValueID, apiConfig.create());
        },
        getDimensionRoleUserList: function (dimensionID, dimensionValueID) {
            return $http.get('/role/getDimensionRoleUserList?dimensionID=' + dimensionID + '&dimensionValueID=' + dimensionValueID, apiConfig.create());
        },
        getAllOwnUserRoleList: function () {
            return $http.get('/role/getAllOwnUserRoleList', apiConfig.create());
        },
        removeUserRole: function (userID, roleIDList, serviceTypeID) {
            return $http.post('/role/removeUserRole?userID=' + userID + '&serviceTypeID=' + serviceTypeID, roleIDList, apiConfig.create());
        },
        getAllRoleListByUserID: function (userID, serviceTypeID) {
            return $http.get('/role/getAllRoleListByUserID?userID=' + userID + '&serviceTypeID=' + serviceTypeID, apiConfig.create());
        },
        updateUserRole: function (userRoleUpdteModel) {
            return $http.post('/role/updateUserRole', userRoleUpdteModel, apiConfig.create());
        },
        updateDimensionValues: function (dimensionValueModel) {
            return $http.post('/role/updateDimensionValues', dimensionValueModel, apiConfig.create());
        },
        updateUserOrg: function (orgIdList, userID) {
            return $http.post('/role/updateUserOrg?userID=' + userID, orgIdList, apiConfig.create());
        },
        validateRoleNameUnique: function (roleName, oldRoleName) {
            return $http.get('/role/validateRoleNameUnique?roleName=' + roleName + '&oldRoleName=' + oldRoleName, apiConfig.create({ ignoreLoadingBar: true }));
        },
        addRoleCategory: function (name, roleCategoryID) {
            return $http.get('/role/addRoleCategory?name=' + encodeURI(name) + '&roleCategoryID=' + roleCategoryID, apiConfig.create({ ignoreLoadingBar: false }));
        },
        updateRoleCategory: function (updateName, id) {
            return $http.get('/role/updateRoleCategory?updateName=' + encodeURI(updateName) + '&id=' + id, apiConfig.create({ ignoreLoadingBar: false }));
        },
        deleteRoleCategory: function (id) {
            return $http.get('/role/deleteRoleCategory?id=' + id, apiConfig.create({ ignoreLoadingBar: false }));
        },
        getAllRolePermission: function (serviceTypeID) {
            return $http.get('/role/getAllRolePermission?serviceTypeID=' + serviceTypeID, apiConfig.create());
        },
        getActiveUserRoleListByAreaID: function (areaId) {
            return $http.get('/role/getActiveUserRoleListByAreaID?areaID=' + areaId, apiConfig.create());
        }
    };
}]);
// web service proxy for project
webservices.factory('ruleEngineService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getTaxPayerReportMapping: function () {
            return $http.get('/ruleEngineeConfig/taxPayerReportMapping', apiConfig.create());
        },
        getTaxRuleSetting: function (orgID, serviceID, projectYear) {
            return $http.get('/ruleEngineeConfig/taxRuleSetting', apiConfig.create());
        },
        saveTaxRuleSettings: function (taxRuleSettings) {
            return $http.post('/ruleEngineeConfig/taxRuleSetting/Save', taxRuleSettings, apiConfig.create());
        }
    };
}]);
// web service proxy for role
webservices.factory('serviceTypeService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getServiceTypeList: function () {
            return $http.get('/servicetype/getlist', apiConfig.create());
        } 
    };
}]);
// web service proxy for spreadjs display
webservices.factory('spreadJsService', ['$log', '$q', '$http', 'apiConfig', 'documentHierarchyService',
    function ($log, $q, $http, apiConfig, documentHierarchyService) {
        'use strict';

        var formulaValues;
        var editingText;

        var getJsonFromExcel = function (filepath) {
            return $http.post('/spreadjs/getjson', { documentpath: filepath }, apiConfig.create());
        };

        var exportExcel = function (jsonContent) {
            return $http.post('/spreadjs/exportExcel', { jsonContent: jsonContent, fileType: 'application/json' }, apiConfig.create());
        };

        var getFormulaValueByDocumentId = function (documentId) {
            return $http.get('/spreadjs/formulavalue/' + documentId, apiConfig.create());
        };

        //通过公式列表获取公式值
        var getFormulaValueByFormulaList = function (formulaList) {
            var deferred = $q.defer();
            var promise = deferred.promise;
            $http.get('/spreadjs/formulavaluebyformula/' + JSON.stringify(formulaList), apiConfig.create())
                 .success(function (data) {
                     deferred.resolve(data);
                 })
                  .error(function (error) {
                      deferred.reject(error);
                  });
            return promise;
        };

        //通过文件code获取公式值
        var getFormulaValueByDocumentCode = function (code) {
            var deferred = $q.defer();
            var promise = deferred.promise;
            $http.get('/spreadjs/formulavaluebycode/' + code, apiConfig.create())
                 .success(function (data) {
                     deferred.resolve(data);
                 })
                  .error(function (error) {
                      deferred.reject(error);
                  });
            return promise;
        };

        //通过文件名获取公式值
        //ND(-1): 999, BB("CL027",2,5,2,0,0): 888, QR("1471",-1): 100, QR("1471",0): 100, QR("1471",1): 100
        var getFormulaValueByFileName = function (filepath) {
            var deferred = $q.defer();
            var promise = deferred.promise;

            $http.get('/spreadjs/formulavalue/' + filepath, apiConfig.create())
                    .success(function (data) {
                        deferred.resolve(data);
                    })
                    .error(function (error) {
                        deferred.reject(error);
                    });
            return promise;
        };

        var getDocumentCell = function (filepath) {
            return $http.get('/documentcell/byname/' + filepath, apiConfig.create());
        };

        var getDocumentCellByDocumentId = function (documentId) {
            return $http.get('/documentcell/byid/' + documentId, apiConfig.create());
        };

        var getCustomFunctions = function () {
            return $http.get('/spreadjs/customfunction', apiConfig.create());
        };

        var renderFormulaCell = function (sheet, celllist) {
            $.each(celllist, function (n, val) {
                var cIndex = val.columnIndex;
                var rIndex = val.rowIndex;
                var formula = val.formula;

                sheet.setFormula(rIndex, cIndex, "=" + formula);
                sheet.setTag(rIndex, cIndex, "=" + formula);
            })
        };

        var initSpreadCustomFunction = function (sheet, name, minArgs, maxArgs) {

            var customFunction = function (name, minArgs, maxArgs) {
                this.name = name;
                this.maxArgs = maxArgs;
                this.minArgs = minArgs;
            };

            customFunction.prototype = new GcSpread.Sheets.Calc.Functions.Function();
            customFunction.prototype.evaluate = function (args) {

                var formulaName = this.name + "(";

                for (var j = 0; j < args.length; j++) {
                    if (j < args.length - 1) {
                        formulaName += args[j].toString()
                        .replace("\"", "")
                        .replace("\"", "")
                        .replace(" ", "") + ",";
                    }
                    else {
                        formulaName += args[j].toString()
                        .replace("\"", "")
                        .replace("\"", "")
                        .replace(" ", "");
                    }
                }
                formulaName += ")";

                var value = formulaValues['' + formulaName + ''];
                return value;

            };

            var cf = new customFunction(name, minArgs, maxArgs);
            sheet.addCustomFunction(cf);
        };

        var initSpreadExcel = function (id, ssjsondata) {

            var deferred = $q.defer();
            var promise = deferred.promise;

            var spread = new GcSpread.Sheets.Spread(document.getElementById(id));
            var sheet = spread.getActiveSheet();

            spread.showVerticalScrollbar(true);
            spread.showHorizontalScrollbar(true);
            spread.tabNavigationVisible(false);
            spread.tabStripVisible(false);
            spread.newTabVisible(false);

            spread.isPaintSuspended(true);
            spread.fromJSON(JSON.parse(ssjsondata));
            spread.isPaintSuspended(false);

            sheet = spread.getActiveSheet();

            if (sheet != null) {
                sheet.setRowHeaderVisible(true);
                sheet.setColumnHeaderVisible(true);
                sheet.setIsProtected(false);
            }

            spread.bind(GcSpread.Sheets.Events.CellClick, function (sender, args) {
                if (args.sheetArea === GcSpread.Sheets.SheetArea.colHeader) {
                    $log.debug("The column header was clicked.");
                }

                if (args.sheetArea === GcSpread.Sheets.SheetArea.rowHeader) {
                    $log.debug("The row header was clicked.");
                }

                if (args.sheetArea === GcSpread.Sheets.SheetArea.corner) {
                    $log.debug("The corner header was clicked.");
                }

                $log.debug("cIndex: " + args.col);
                $log.debug("rIndex: " + args.row);
                $log.debug(sheet.getTag(args.row, args.col));
            });

            spread.bind(GcSpread.Sheets.Events.EditEnding, function (sender, args) {

                var sheet = spread.getActiveSheet();

                editingText = args.editingText;
                var reg = new RegExp('[a-zA-Z]+[\((]([0-9a-zA-Z,"".]|(-)?)*[\))]');
                var res = reg.test(editingText);

                if (res) {
                    var name = editingText.substring(1, editingText.indexOf("("));
                    $log.debug(name);
                    initSpreadCustomFunctionAsync(sheet, name);
                }
            });

            deferred.resolve(spread);
            return promise;
        };

        var renderSpreadExcelSimple = function (id, filepath) {

            var deferred = $q.defer();
            var promise = deferred.promise;

            getJsonFromExcel(filepath).then(function (ssjson) {
                //4. 加载SpreadExcel
                initSpreadExcel(id, ssjson.data).then(function (spread) {
                    deferred.resolve(spread);
                });
            });
            return promise;
        };

        /**
         * 通过document code获取该code下对应的公式以及公式的值
         * @method renderSpreadExcelFormulaByCode
         * @for 所属类名
         * @param {string} id   spreadjs div的id
         * @param {string} code document code,该code在 CIT_DocumentHierarchy中查到
         * @return {spread} 返回spread的对象
         */
        var renderSpreadExcelFormulaByCode = function (id, code) {

            var customfunctions;

            //1. 获取自定义函数名及对应的计算值 
            getFormulaValueByDocumentCode(code).then(function (formuladata) {
                formulaValues = JSON.parse(formuladata);
                $log.debug(formulaValues);

                //2. 获取自定义函数名
                getCustomFunctions().then(function (functiondata) {
                    customfunctions = functiondata.data;

                    //通过code获取document filepath
                    documentHierarchyService.getDocumentByCode(code).success(function (documentObj) {
                        //3. 获取Excel的ssjon
                        getJsonFromExcel(documentObj.documentPath).then(function (ssjson) {
                            //4. 加载SpreadExcel
                            initSpreadExcel(id, ssjson.data).then(function (spread) {
                                //4. 初始化自定义函数名
                                var sheet = spread.getActiveSheet();
                                for (var i = 0; i < customfunctions.length; i++) {
                                    var func = customfunctions[i];
                                    initSpreadCustomFunction(sheet, func.name, 0, func.parameterCount);
                                }

                                //5. Get Document Cell 
                                getDocumentCellByDocumentId(documentObj.documentID).then(function (celldata) {
                                    renderFormulaCell(sheet, celldata.data);
                                });
                            });
                        });
                    });
                });
            });
        };

        //最开始设计的版本
        var renderSpreadExcelFormula = function (id, documentName) {

            var customfunctions;

            //1. 获取自定义函数名及对应的计算值
            getFormulaValueByFileName(documentName).then(function (formuladata) {
                formulaValues = JSON.parse(formuladata);
                $log.debug(formulaValues);

                //2. 获取自定义函数名
                getCustomFunctions().then(function (functiondata) {
                    customfunctions = functiondata.data;

                    //3. 获取Excel的ssjon
                    getJsonFromExcel(documentName).then(function (ssjson) {
                        //4. 加载SpreadExcel
                        initSpreadExcel(id, ssjson.data).then(function (spread) {
                            //4. 初始化自定义函数名
                            var sheet = spread.getActiveSheet();
                            for (var i = 0; i < customfunctions.length; i++) {
                                var func = customfunctions[i];
                                initSpreadCustomFunction(sheet, func.name, 0, func.parameterCount);
                            }

                            //5. Get Document Cell
                            getDocumentCell(documentName).then(function (celldata) {
                                renderFormulaCell(sheet, celldata.data);
                            });
                        });
                    });
                });
            });
        };


        


        var initSpreadCustomFunctionAsync = function (sheet, name) {

            var asum = function () { }
            //Define a class "ASUM" that extends AsyncFunction
            asum.prototype = new GcSpread.Sheets.Calc.Functions.AsyncFunction(name, 1, 255);
            //Set default value to "Loading..."
            asum.prototype.defaultValue = function () { return "Loading..."; };
            //Override the evaluateAsync function
            asum.prototype.evaluateAsync = function (args, context) {

                var formulaName = this.name + "(";

                for (var j = 0; j < args.length; j++) {
                    if (j < args.length - 1) {
                        formulaName += args[j].toString()
                        .replace("\"", "")
                        .replace("\"", "")
                        .replace(" ", "") + ",";
                    }
                    else {
                        formulaName += args[j].toString()
                        .replace("\"", "")
                        .replace("\"", "")
                        .replace(" ", "");
                    }
                }
                formulaName += ")";
                var value = formulaValues['' + formulaName + ''];
                if (value === undefined) {

                    var formula = editingText.replace('=', '');
                    var formulaList = [formula];
                    //从服务端获取数据
                    getFormulaValueByFormulaList(formulaList).then(function (formuladata) {
                        var data = JSON.parse(formuladata);
                        //添加到全局formulaValues对象中
                        formulaValues[formula] = data[formula];

                        $log.debug(formulaValues);
                        var result = formulaValues['' + formulaName + ''];
                        context.SetAsyncResult(result);
                    });
                }
                return value;
            };

            var cf = new asum();
            sheet.addCustomFunction(cf);
        };






        return {
            getJsonFromExcel: getJsonFromExcel,
            exportExcel: exportExcel,
            getFormulaValueByDocumentId: getFormulaValueByDocumentId,
            getFormulaValueByFileName: getFormulaValueByFileName,
            getDocumentCell: getDocumentCell,
            getCustomFunctions: getCustomFunctions,
            initSpreadCustomFunction: initSpreadCustomFunction,
            initSpreadExcel: initSpreadExcel,
            renderFormulaCell: renderFormulaCell,
            renderSpreadExcelSimple: renderSpreadExcelSimple,
            renderSpreadExcelFormula: renderSpreadExcelFormula,
            renderSpreadExcelFormulaByCode: renderSpreadExcelFormulaByCode
        };
    }]);
// web service proxy for standard account
webservices.factory('statisticAttributeService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        get: function (dictionaryCode) {
            return $http.get('/statisticAttribute/get?dictionaryCode=' + dictionaryCode, apiConfig.create());
        },
        getByParentDimensionID: function (parentDimensionID) {
            return $http.get('/statisticAttribute/getByParentDimensionID?parentDimensionID=' + parentDimensionID, apiConfig.create());
        },
        getOrgSubChildrenStatAttributeList: function (parentDimensionID) {
            return $http.get('/statisticAttribute/getOrgSubChildrenStatAttributeList?parentDimensionID=' + parentDimensionID, apiConfig.create());
        },
        add: function (model) {
            return $http.post('/statisticAttribute/add', model, apiConfig.create());
        },
        updateRange: function (modelList) {
            return $http.post('/statisticAttribute/update', modelList, apiConfig.create());
        }
    };
}]);

// web service proxy for standard account
webservices.factory('stdAccountService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getStdAccountHierarchy: function (orgID) {
            return $http.get('/StdAccount/StdAccountHierarchy?orgID=' + orgID, apiConfig.create());
        },
        GetStdAccountList: function () {
            return $http.get('/StdAccount/GetStdAccountList', apiConfig.create());
        },
        add: function (model) {
            return $http.post('/StdAccount/add', model, apiConfig.create());
        },
        update: function (model) {
            return $http.post('/StdAccount/update', model, apiConfig.create());
        },
        isactive: function (model) {
            return $http.post('/StdAccount/isactive', model, apiConfig.create());
        },
        get: function (id) {
            return $http.get('/StdAccount/getsingle?id=' + id, apiConfig.create());
        },
        getStdAccountLinkEtsAccount: function (orgID, accountSetID) {
            return $http.get('/StdAccount/getStdAccountLinkEtsAccount?orgID=' + orgID + '&accountSetID=' + accountSetID, apiConfig.create());
        },
        getStdAccountByOrgID: function (orgID) {
            return $http.get('/StdAccount/getStdAccountByOrgID?orgID=' + orgID , apiConfig.create());
        },
        getStdAccountByIndustryID: function (industryID) {
            return $http.get('/stdAccount/stdAccount/byIndustry/' + industryID, apiConfig.create());
        }
    };
}]);
// registration web service proxy
webservices.factory('stockService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getStockList: function (param) {
            return $http.post('/stock/getList', param, apiConfig.create());
        },
        updateStock: function (stock) {
            return $http.put('/stock/update', stock, apiConfig.create());
        },
        deleteOrgList: function (stockList, orgID) {
            return $http.post('/stock/delete?orgID=' + orgID, stockList, apiConfig.create());
        },
        addOrgList: function (stockList, orgID) {
            return $http.post('/stock/add?orgID=' + orgID, stockList, apiConfig.create());
        },
        getStockListByOrgID: function (param) {
            return $http.post('/stock/getStockListByOrgID' ,param, apiConfig.create());
        },
        updateOrgList: function (stockList, orgID) {
            return $http.post('/stock/update?orgID=' + orgID, stockList, apiConfig.create());
        },

        //添加变更历史记录
        addHistoryStocks: function (stock) {
            return $http.post('/stock/addHistoryStock', stock, apiConfig.create());
        },
    };
}]);
// web service proxy for standard account
webservices.factory('templateService', ['$log', '$http', '$q', 'apiConfig', 'httpCacheService','$timeout','$rootScope','$interval',
    function ($log, $http, $q, apiConfig, httpCacheService, $timeout, $rootScope, $interval) {
    'use strict';
    var getTemplateJson = function (templateID) {
        //return $http.get('/template/getTemplateJson?templateID=' + templateID, apiConfig.create());
        var result = httpCacheService.get('/template/getTemplateJson?templateID=' + templateID);
        if (result.finishedCache) {
            return result;
        } else {
            return $http.get('/template/getTemplateJson?templateID=' + templateID, apiConfig.create());
        }
    };
       
    var initSpreadExcel = function (id, ssjsondata) {
      
        var deferred = $q.defer();
        var promise = deferred.promise;

        var spread = new GcSpread.Sheets.Spread(document.getElementById(id));
        spread.showVerticalScrollbar(true);
        spread.showHorizontalScrollbar(true);
        spread.scrollbarMaxAlign(true);
        spread.scrollbarShowMax(true);
        spread.tabNavigationVisible(true);
        spread.newTabVisible(false);
        spread.tabEditable(false);
        spread.tabStripVisible(false);
        spread.newTabVisible(false);
        spread.allowUndo(false);
        spread.allowUserResize(false);
        spread.canUserDragDrop(false);
        spread.canUserDragFill(false);
        spread.canUserEditFormula(false);

        spread.isPaintSuspended(true);
        spread.fromJSON(JSON.parse(ssjsondata));
        spread.isPaintSuspended(false);

        var sheet = spread.getActiveSheet();
        if (sheet != null) {
            sheet.setRowHeaderVisible(true);
            sheet.setColumnHeaderVisible(true);
            sheet.setGridlineOptions({ showVerticalGridline: false, showHorizontalGridline: false
        });
        }
                 
        deferred.resolve(spread);
        return promise;
    };

    var renderSpreadExcelSimple = function (id, templateID) {
        var deferred = $q.defer();
        var promise = deferred.promise;
        var spreadSheet;

        getTemplateJson(templateID).success(function (result) { 
            spreadSheet = initSpreadExcel(id, result.data === undefined ? result : result.data);

            deferred.resolve(spreadSheet);
        });
  
        return promise;
    };

    var setRowColName = function (id, rowCellInfo) {
        return $http.post('/template/rowColName/' + id, rowCellInfo, apiConfig.create());
    };

    return {
        getTemplateJson: getTemplateJson,
        renderSpreadExcelSimple: renderSpreadExcelSimple,
        initSpreadExcel: initSpreadExcel,
        setRowColName: setRowColName
    };
}]);
// web service proxy for standard account
webservices.factory('templateFormulaService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getByStandardCode: function (standardCode) {
            return $http.get('/templateFormula/getByStandardCode?standardCode=' + standardCode, apiConfig.create());
        },
        getByTemplateGroupID: function (templateGroupID) {
            return $http.get('/templateFormula/getByTemplateGroupID?templateGroupID=' + templateGroupID, apiConfig.create());
        },
        saveTemplateFormulaList: function (templateFormulaList) {
            return $http.post('/templateFormula/saveTemplateFormulaList', templateFormulaList, apiConfig.create());
        },
        getConfigurationAndFormulaByTemplateID: function (templateID) {
            return $http.get('/templateFormula/getConfigurationAndFormulaByTemplateID?templateID=' + templateID, apiConfig.create());
        },
        validate: function (formula) {
            return $http.post('/templateFormula/validate', angular.toJson(formula), apiConfig.create({ ignoreLoadingBar: true }));
        },
        saveOrUpdateCellTemplateConfig: function (templateConfig) {
            return $http.post('/celltemplate/config', templateConfig, apiConfig.create());
        },
        getCellTemplateConfig: function (cellTemplateID) {
            return $http.get('/celltemplate/config/' + cellTemplateID, apiConfig.create());
        },
        getCellTemplateConfigList: function (templateID) {
            return $http.get('/celltemplate/configList/' + templateID, apiConfig.create());
        }


    };
}]);
// web service proxy for standard account
webservices.factory('templateGroupService', ['$http', 'apiConfig', 'httpCacheService', function ($http, apiConfig, httpCacheService) {
    'use strict';
    return {
        getall: function () {
            return $http.get('/templateGroup/getall', apiConfig.create());
        },
        getByServiceType: function (serviceTypeID,taxPayType) {
            return $http.get('/templateGroup/getByServiceType/' + serviceTypeID + '/' + taxPayType , apiConfig.create());
        },
        addTemplateGroup: function (templateGroup) {
            return $http.post('/templateGroup/addTemplateGroup', templateGroup, apiConfig.create());
        },
        addTemplateGroupWithoutTemplate: function (templateGroup) {
            return $http.post('/templateGroup/templateGroup/withoutTemplate', templateGroup, apiConfig.create());
        },
        getTemplateList: function (templateGroupID, reportType) {
            return $http.get('/template/get?templateGroupID=' + templateGroupID + '&reportType=' + reportType, apiConfig.create());
        },
        getGroupTemplate: function (projectID, serviceType) {
            return $http.get('/template/getGroupTemplate?projectID=' + projectID + '&serviceType=' + serviceType, apiConfig.create());
        },
        getGroupTemplateByGroupID: function (templateGroupID, projectID) {
            return $http.get('/template/getGroupTemplateByGroupID?templateGroupID=' + templateGroupID + '&projectID=' + projectID, apiConfig.create());
        },
        getTemplateByTree:function (projectID, serviceType) {
            return $http.get('/template/getGroupTemplateTree?projectID=' + projectID + '&serviceType=' + serviceType, apiConfig.create());
        },
        getByIndustry: function (serviceTypeID, taxPayType, industryID) {
            return $http.get('/templateGroup/getByIndustry/' + serviceTypeID + '/' + industryID + '?taxPayType=' + (taxPayType || ''), apiConfig.create());
        }
        ,
        getTemplateUniqList:function(serviceTypeID,payTaxType,reportType,industryIDs){
            return $http.get('/template/getTemplateUniqList?serviceTypeID=' + serviceTypeID + '&payTaxType='+payTaxType + '&reportType=' + reportType + '&industryIDs='+industryIDs , apiConfig.create());
        }
        ,addExistTemplate:function(model){
            return $http.post('/template/addExistTemplate', model, apiConfig.create());
        }
        ,deleteTemplate:function(model){
            return $http.post('/template/deleteTemplate', model, apiConfig.create());
        }
        ,updateTemplateName:function(model){
            return $http.post('/template/updateTemplateName', model, apiConfig.create());
        },
        deleteTemplateGroup:function(model){
            return $http.post('/templateGroup/deleteTemplateGroup', model, apiConfig.create());
        },
        updateTemplateGroupName:function(model){
            return $http.post('/templateGroup/updateTemplateGroupName', model, apiConfig.create());
        }
    };
}]);
// web service proxy for user
webservices.factory('userService', ['$http', 'apiConfig', 'httpCacheService', 'loginContext', function ($http, apiConfig, httpCacheService, loginContext) {
    'use strict';

    return {
        getUserList: function () {
            return $http.get('/user/display', apiConfig.create());
            //return httpCacheService.getData('/user/display');
        },
        getUserListByOrgID: function (orgID) {
            return $http.get('/user/displayByOrgID?orgId=' + orgID, apiConfig.create());
            //return httpCacheService.getData('/user/displayByOrgID?orgId=' + orgID);
        },
        getSingleUser: function (userId) {
            return $http.get('/user/displaySingle?userId=' + userId, apiConfig.create());
        },
        getUserByName: function (userName) {
            return $http.post('/user/getUserByName',
                {
                    UserName: userName
                },
                apiConfig.create());
        },
        addUser: function (user) {
            return $http.post('/user/add', user, apiConfig.create());
        },
        updateUser: function (user) {
            return $http.put('/user/update', user, apiConfig.create());
        },
        enableOrDisableUser: function (userId, updateType) {
            return $http.post('/user/enableordisableuser', {
                'UserId': userId,
                'UpdateType': updateType
            }, apiConfig.create());
        },
        getRoleTypeList: function () {
            return $http.get('/user/roleTypeList', apiConfig.create());
        },
        getRoleList: function (roleTypeId) {
            return $http.get('/user/roleList?roleTypeId=' + roleTypeId, apiConfig.create());
        },
        getRoleDisplayList: function () {
            return $http.get('/user/roleDisplayList', apiConfig.create());
        },
        getUserTreeList: function () {
            return $http.get('/user/userTreeList', apiConfig.create());
            //return httpCacheService.getData('/user/userTreeList');
        },
        getProjectListByUserId: function (userId) {
            return $http.get('/user/projectListByUserId?userId=' + userId, apiConfig.create());
        },
        addProjectToUser: function (userProjectInfo) {
            return $http.post('/user/addProjectToUser', { 'UserId': userProjectInfo.UserId, 'ProjectService': userProjectInfo.ProjectIds }, apiConfig.create());
        },
        removeProjectFromUser: function (userProjectInfo) {
            return $http.post('/user/removeProjectFromUser', { 'UserId': userProjectInfo.UserId, 'ProjectService': userProjectInfo.ProjectIds }, apiConfig.create());
        },
        getProjectRoles: function (userProjectInfo) {
            return $http.post('/user/getProjectRoles', { 'UserId': userProjectInfo.UserId, 'ProjectService': userProjectInfo.ProjectIds }, apiConfig.create());
        },
        operateProjectRole: function (userProjectInfo) {
            return $http.post('/user/operateProjectRole', {
                'UserId': userProjectInfo.UserId,
                'ProjectService': userProjectInfo.ProjectIds,
                'IsAdd': userProjectInfo.IsAdd,
                'RoleID': userProjectInfo.RoleID
            }, apiConfig.create())
        },

        setProjectUserRole: function (userRoleList) {
            return $http.post('/user/setProjectUserRole', userRoleList, apiConfig.create())
        },
        getUserRoleSetList: function (userid, serviceTypeid, projectid) {
            return $http.get('/user/getUserRoleSetList?userid=' + userid + '&serviceTypeid=' + serviceTypeid + '&projectid=' + projectid, apiConfig.create());
        },
        getUserListByProject: function (projectID, serviceTypeID) {
            return $http.get('/user/userTreeListByProject?projectID=' + projectID + '&serviceTypeID=' + serviceTypeID, apiConfig.create());
        },
        GetUserById: function (userId) {
            return $http.get('/user/getUser/' + userId, apiConfig.create());
        },
        getUserRoleByDimensionValueID: function (parentDimensionID, dimensionValueID) {
            return $http.get('/user/getUserRoleByDimensionValueID?parentDimensionID=' + parentDimensionID + '&dimensionValueID=' + dimensionValueID, apiConfig.create());
        },
        getSpecialUserRoleByDimensionValueID: function (parentDimensionID, dimensionValueID) {
            return $http.get('/user/getSpecialUserRoleByDimensionValueID?parentDimensionID=' + parentDimensionID + '&dimensionValueID=' + dimensionValueID, apiConfig.create());
        },
        updateUserRoleDimension: function (userRoleList) {
            return $http.post('/user/updateUserRoleDimension', userRoleList, apiConfig.create())
        },
        updateUserToRole: function (userRoleList) {
            return $http.post('/user/addUsersToRole', userRoleList, apiConfig.create())
        },
        getUserRoleListByUserID: function (userId) {
            return $http.get('/user/getUserRoleListByUserID?userId=' + userId, apiConfig.create());
        },
        deleteUserRoleDimension: function (userRoleList) {
            return $http.post('/user/deleteUserRoleDimension', userRoleList, apiConfig.create())
        },
        getAllUserRoleList: function (serviceTypeID) {
            return $http.get('/user/getAllUserRoleList?serviceTypeID=' + serviceTypeID, apiConfig.create());
        },
        deleteUserRoleForOrg: function (userOrgdto) {
            return $http.post('/user/deleteUserRoleForOrg', userOrgdto, apiConfig.create());
        },
        getUserRoleByOrgIDUserID: function (userID, orgID) {
            return $http.get('/user/getUserRoleByOrgIDUserID?userID=' + userID + '&orgID=' + orgID, apiConfig.create());
        },
        getUserRoleByUserID: function (userID) {
            return $http.get('/user/getUserRoleByUserID?userID=' + userID, apiConfig.create());
        },
        updateUserRoleForOrg: function (userRoleList) {
            return $http.post('/user/updateUserRoleForOrg', userRoleList, apiConfig.create())
        },
        updateUserRoleForDimension: function (userRoleList) {
            return $http.post('/user/updateUserRoleForDimension', userRoleList, apiConfig.create())
        },
        deleteUserOrg: function (userRoleList) {
            return $http.post('/user/deleteUserOrg', userRoleList, apiConfig.create())
        },
        updateUserRoleOrganization: function (userRoleList) {
            return $http.post('/user/updateUserRoleOrganization', userRoleList, apiConfig.create())
        },
        getUserPermission: function (userName) {
            return httpCacheService.get('/user/getUserPermission?userName=' + userName);
        },
        getUserPermissionNew: function (userName, fn) {
            return httpCacheService.getCache('/user/getUserPermissionKey?userName=' + userName, false, fn);
        },
        deleteUserRoleOrg: function (userRoleList) {
            return $http.post('/user/deleteUserRoleOrg', userRoleList, apiConfig.create())
        },
        getDimensionUserRoleList: function (parentDimensionID, dimensionValueID) {
            return $http.get('/user/getDimensionUserRoleList?parentDimensionID=' + parentDimensionID + '&dimensionValueID=' + dimensionValueID, apiConfig.create());
        },
        getUserOrgPermission: function (userID, orgID) {
            return $http.get('/user/getUserOrgPermission?userID=' + userID + '&orgID=' + orgID, apiConfig.create());
        },
        getUserListByPermissionCode: function (permissionCode) {
            return $http.get('/user/getUserListByPermissionCode?permissionCode=' + permissionCode, apiConfig.create());
        },
        getUserOwnerOrganization: function () {
            return $http.get('/user/getUserOwnerOrganization', apiConfig.create());
        }
    };
}]);
// web service proxy for voucher
webservices.factory('voucherService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        getVouchersByAccountCode: function (accountCode) {
            return $http.get('/voucher?accountCode=' + accountCode, apiConfig.create());
        },
        getRecategoryVouchers: function (accountRecategoryId) {
            return $http.get('/voucher?accountRecategoryId=' + accountRecategoryId, apiConfig.create());
        },
    };
}]);
// web service proxy for customer
webservices.factory('workflowService', ['$http', 'apiConfig', 'httpCacheService',
function ($http, apiConfig, httpCacheService) {
    'use strict';
     
    return {
        getWorkflowCategoryList: function () {
            return $http.get('/workflow/getWorkflowCategoryList', apiConfig.create());
        },
        getWorkflowCategorymenuList: function () {
            return $http.get('/workflow/getWorkflowCategorymenuList', apiConfig.create());
        },
        getOrgMenuList: function () {
            return $http.get('/workflow/getOrgMenuList', apiConfig.create());
        },
        getWorkflowBasicInfo: function (id) {
            return $http.get('/workflow/getWorkflowBasicInfo?id=' + id, apiConfig.create());
        },
        getWorkFlowDisplayInfo: function (id) {
            return $http.get('/workflow/getWorkFlowDisplayInfo?id=' + id, apiConfig.create());
        },
        getTaskListByNodeID: function (id) {
            return $http.get('/workflow/getTaskListByNodeID?id=' + id, apiConfig.create());
        },
        getExistWorkflowOrgList: function (orgList) {
            return $http.post('/workflow/getExistWorkflowOrgList', orgList, apiConfig.create());
        },
        getWorkflowNodeByOrgList: function (orgIDList) {
            return $http.post('/workflow/getWorkflowNodeByOrgList', orgIDList, apiConfig.create());
        },
        getWorkflowNodeByYearMonth: function (year, month, serviceId) {
            return $http.get('/workflow/getWorkflowNodeByYearMonth?year=' + year + '&month=' + month + '&serviceType=' + serviceId, apiConfig.create());
        },
        getPushNotifications: function (criteria) {

            return $http.post('/workflow/getPushNotifications', {

                IsFirstTimeLoading: criteria.isFirstTimeLoading,
                FilterType: criteria.filterType,
                ServiceType: criteria.serviceType,
                MainFilter: criteria.mainFilter,
                SingleNode: criteria.singleNode,
                SingleTask: criteria.singleTask,
                MultipleNode: criteria.multipleNode,
                MultipleTask: criteria.multipleTask,
                MultipleStatus: criteria.multipleStatus,
                MultipleDueDate: criteria.multipleDueDate,
                MultiplePriority: criteria.multiplePriority,
                MultipleType: criteria.multipleType,
                SearchKeyword: criteria.searchKeyword
            }, apiConfig.create());
          
        },

        setMessageRead: function (id) {
            return $http.get('/workflow/setMessageRead?id=' + id, apiConfig.create());
        },
        getApprovalLogInfo: function (workflowNodeId, dbName, periodId, serviceTypeId) {
            return $http.get('/workflow/getApprovalLogInfo?workflowNodeId=' + workflowNodeId + '&dbName=' + dbName + '&periodId=' + periodId + '&serviceTypeId=' + serviceTypeId, apiConfig.create());
        },

        getErpValidationInfo: function ( dbName, periodId, serviceTypeId) {
            return $http.get('/workflowMessageJob/getErpValidationInfo?dbName=' + dbName + '&periodId=' + periodId + '&serviceTypeId=' + serviceTypeId, apiConfig.create());
        },
        
       
        updateTaskMessage: function (workflowMessageList) {
            return $http.post('/workflow/updateTaskMessage', workflowMessageList, apiConfig.create());
        },
        addWorkFlow: function (workflow) {
            return $http.post('/workflow/addWorkFlow', workflow, apiConfig.create());
        },
        updateWorkFlow: function (workflow) {
            return $http.post('/workflow/updateWorkFlow', workflow, apiConfig.create());
        },
        copyWorkFlow: function (workflow) {
            return $http.post('/workflow/copyWorkFlow', workflow, apiConfig.create());
        },
        getWorkflowNodeAndTask: function () {
            return $http.get('/workflow/getWorkflowNodeAndTask', apiConfig.create());
        },
        getDicTaskListByNodeID: function (nodeID) {
            return $http.get('/workflow/getDicTaskListByNodeID?nodeID=' + nodeID, apiConfig.create());
        },
        getTaskMessageUserRole: function (taskID) {
            return $http.get('/workflow/getTaskMessageUserRole?taskID=' + taskID, apiConfig.create());
        },
        deleteWorkFlow: function (workflow) {
            return $http.post('/workflow/deleteWorkFlow', workflow, apiConfig.create());
        },

        
    };
}]);
// worklist web service proxy
webservices.factory('worklistService', ['$http', 'apiConfig', function ($http, apiConfig) {
    'use strict';
    return {
        simpleSearch: function (criteria) {
            var config = { params: { json: JSON.stringify(criteria) }, isBusyRequest: true };
            return $http.get('/worklist/simple/search/result', apiConfig.create(config));
        },
        advancedSearch: function (criteria) {
            var config = { isBusyRequest: true };
            return $http.post('/worklist/advanced/search/result', criteria, apiConfig.create(config));
        },
        getShortcuts: function () {
            var config = { isBusyRequest: true };
            return $http.get('/worklist/shortcuts', apiConfig.create(config));
        },
        addShortcut: function (data) {
            var config = { isBusyRequest: true };
            return $http.post('/worklist/shortcuts', data, apiConfig.create(config));
        },
        deleteShortcut: function (id) {
            var config = { isBusyRequest: true };
            return $http.delete('/worklist/shortcuts/' + id, apiConfig.create(config));
        },
        setDefaultShortcut: function (id) {
            var config = { isBusyRequest: true };
            return $http.get('/worklist/shortcuts/default/' + id, apiConfig.create(config));
        }
    };
}]);