import { ApiService } from "../../util/apiService.js";
import models from '../modelsIndex.js';
import { HistoryViewModel } from "../period/model.js";
import { Column, Folder } from "./model.js";

export function BaseViewModel(config) {
    var self = this;
    self.entityName = config.entityName;
    self.controllerName = _h.findControllerName(config.entityName);
    self.firstView = true;
    self.groupDirection = ko.observable();
    self.groupProperty = ko.observable();
    self.showType = ko.observable("Table");
    self.iconSize = ko.observable("icon-image");
    self.apiService = new ApiService(config.apiService, config.entityName);
    self.filterType = ko.observable("_");
    if (config.filterProfile) {
        self.activeFilterProfile = ko.observable();
        self.inputFilterProfile = ko.observable();
        self.showInputFilterProfile = ko.observable(false);
        self.toggleInputFilterProfile = function (m, event) {
            event.stopPropagation();
            self.showInputFilterProfile(true);
            if (!_h.isNullOrEmpty(self.activeFilterProfile())) {
                var item = self.getFilterProfile(self.activeFilterProfile());
                self.inputFilterProfile(item.text);
            } else {
                self.inputFilterProfile("");
            }
        };
        self.getFilterProfile = function (id) {
            var target = null;
            if (self.filterProfiles().length > 0) {
                for (var i = 0; i < self.filterProfiles().length; i++) {
                    if (self.filterProfiles()[i].value === id)
                        target = self.filterProfiles()[i];
                }
            }
            return target;
        };
        self.updateFilterProfile = function (controllerName) {
            if (self.inputFilterProfile().length > 0) {
                var model = {
                    controllerName: controllerName,
                    id: self.activeFilterProfile(),
                    title: self.inputFilterProfile(),
                    filters: self.createFilterByModel()
                };
                self.apiService.request({
                    name: "postSearchProfile",
                    data: model,
                    success: function (data) {
                        if (!_h.isNullOrEmpty(data)) {
                            if (_h.isNullOrEmpty(self.activeFilterProfile())) {
                                data.model.value = data.model.id;
                                data.model.text = data.model.title;
                                self.filterProfiles.push(data.model);
                                self.activeFilterProfile(data.model.id);
                            } else {
                                for (var i = 0; i < self.filterProfiles().length; i++) {
                                    if (self.filterProfiles()[i].value === self.activeFilterProfile()) {
                                        self.filterProfiles()[i].text = model.title;
                                        self.filterProfiles()[i].title = model.title;
                                    }
                                }
                            }
                            self.showInputFilterProfile(false);
                        }
                    }
                });
            }
        };
        self.cancelFilterProfile = function (m, event) {
            event.stopPropagation();
            self.showInputFilterProfile(false);
            self.inputFilterProfile(null);
        };
        self.filterProfiles = ko.observableArray();
        self.deleteFilterProfile = function () {
            var item = self.getFilterProfile(self.activeFilterProfile());
            if (!item) return;
            var model = {
                id: item.value
            };
            self.apiService.request({
                name: "DeleteSearchProfile",
                data: model,
                success: function (data) {
                    if (!_h.isNullOrEmpty(data)) {
                        self.activeFilterProfile(null);
                        self.filterProfiles.remove(item);
                    }
                }
            });
        };
    }
    if (_h.any(config.extraParams))
        for (var m in config.extraParams) {
            if (config.extraParams.hasOwnProperty(m)) {
                var param = config.extraParams[m];
                self[param] = ko.observable();
            }
        }
    if (_h.any(config.parentParams))
        for (var k in config.parentParams) {
            if (config.parentParams.hasOwnProperty(k)) {
                var parentParam = config.parentParams[k];
                self[parentParam] = ko.observable();
            }
        }
    self.configTable = config;
    self.dynamicCols = config.dynamicCols;
    self.saveState = config.saveState;
    self.isMultiSelectRows = config.isMultiSelectRows;
    self.selectedRowRecords = ko.observableArray();
    self.filters = config.filters;
    self.extraParams = config.extraParams;
    if (self.dynamicCols) {
        self.tableFields = ko.observable(config.cols);
        self.tableCode = ko.observable(config.tableCode);
        self.tableName = ko.observable(config.tableName);
    }
    self.showCreateForm = ko.observable(false);
    self.createFormModel = ko.observable();
    self.wideRight = ko.observable(true);
    self.showForm = ko.observable(false);
    self.selectedRecord = ko.observable(null);
    self.selectedRowRecord = ko.observable(null);
    self.childModel = ko.observable(null);
    self.records = ko.observableArray();
    self.total = ko.observable(0);
    self.tableProperties = ko.observableArray();
    self.sortDirection = ko.observable(config.sortDirection);
    self.sortProperty = ko.observable(config.sortProperty);
    self.pageSize = ko.observable(24);
    self.pageNumber = ko.observable(1);
    self.searchKey = ko.observable();
    self.showPaggingMenu = ko.observable(false);
    self.pageNumberStr = ko.observable(1);
    self.folderList = ko.observableArray();
    self.tagList = ko.observableArray();
    self.getFolderList = function () {
        var model = {
            controllerName: self.controllerName
        };
        self.apiService.request({
            name: "getTableInfo",
            data: model,
            success: function (data) {
                self.folderList.removeAll();
                self.tagList.removeAll();
                if (_h.any(data.folders))
                    for (var j = 0; j < data.folders.length; j++) {
                        var target = data.folders[j];
                        self.folderList.push(new Folder(target));
                    }
                if (_h.any(data.tags))
                    for (var k = 0; k < data.tags.length; k++) {
                        self.tagList.push({ text: data.tags[k], value: data.tags[k] });
                    }
            },
            messageType: 'getList',
            messageKey: "Folder"
        });
    };
    self.pageNumberStrsub = self.pageNumberStr.supsendableSubscribe(function (newValue) {
        if (newValue !== undefined && newValue !== null) {
            self.pageNumberStrsub.suspend();
            var number = Number(newValue);
            var pageCount = parseInt(self.total() / self.pageSize());
            if (self.total() % self.pageSize() !== 0) {
                pageCount += 1;
            }
            if (number < 1 || number > pageCount) {
                self.pageNumberStr(self.pageNumber());
            }
            self.pageNumberStrsub.unsuspend();
        }
    });
    self.pageNumbers = ko.observableArray([]);
    self.paggingMenu = ko.computed(function () {
        self.pageNumberStr(self.pageNumber());
        var pageCount = parseInt(self.total() / self.pageSize());
        if (self.total() % self.pageSize() !== 0) {
            pageCount += 1;
        }
        self.pageNumbers.removeAll();
        var isActive;
        if (pageCount < 2) {
            self.showPaggingMenu(false);
        } else if (pageCount < 100) {
            for (var i = 0; i < pageCount; i++) {
                isActive = self.pageNumber() === i + 1;
                self.pageNumbers.push({ name: i + 1, active: ko.observable(isActive) });
            }
            self.showPaggingMenu(true);
        } else if (pageCount > 100) {
            self.pageNumbers.push({ name: pageCount - 2, active: ko.observable(self.pageNumber() === pageCount - 2) });
            self.pageNumbers.push({ name: pageCount - 1, active: ko.observable(self.pageNumber() === pageCount - 1) });
            self.pageNumbers.push({ name: pageCount, active: ko.observable(self.pageNumber() === pageCount) });
            self.showPaggingMenu(true);
        }

    });
    self.paggingMenuItemClick = function (item) {
        self.pageNumber(item.name);
        config.context.getRecords();
    };
    self.onClickPageNumberStr = function (d, e) {
        var number = Number(self.pageNumberStr());
        var pageCount = parseInt(self.total() / self.pageSize());
        if (self.total() % self.pageSize() !== 0) {
            pageCount += 1;
        }

        var res = false;
        if (!_h.isNullOrEmpty(number) && number <= pageCount) {
            self.pageNumber(number);
            config.context.getRecords();
            res = true;
        }
        if (res && self.pageNumbers().length) {
            for (var i = 0; i < self.pageNumbers().length; i++) {
                if (self.pageNumbers()[i].name === number)
                    self.pageNumbers()[i].active(true);
                else
                    self.pageNumbers()[i].active(false);
            }
        }
    };
    if (_h.isNullOrEmpty(config.searchKeyType)) {
        self.searchKey.subscribe(function (newValue) {
            self.pageNumber(1);
            config.context.getRecords();
        });
    }
    if (!_h.isNullOrEmpty(config.searchKeyType) && config.searchKeyType === "enter") {
        self.onEnterSearchKey = function (d, e) {
            if (e.keyCode === 13) {
                self.pageNumber(1);
                config.context.getRecords();
                switch (self.entityName) {
                    case "Period":
                        self.wideRight(true);
                        self.childModel(null);
                        break;
                }
            }
            return true;
        };
    }
    self.changePageSize = function (model, e) {
        var target = e.currentTarget;
        var count = target.innerText;
        if (count) {
            self.pageSize(Number(count));
            self.pageNumber(1);
            self.total(0);
            config.context.getRecords();
        }
    }
    self.changeSortProperty = function (item) {
        ko.utils.arrayFilter(self.tableProperties(), function (sortItem) {
            if (item.name === sortItem.name) {
                if (sortItem.sortDir() === "Ascending")
                    sortItem.sortDir("Descending");
                else
                    sortItem.sortDir("Ascending");
            } else {
                sortItem.sortDir("None");
            }
        });
        if (item["alias"] !== null && item["alias"] !== undefined && item["alias"] !== "")
            self.sortProperty(item.alias);
        else
            self.sortProperty(item.name);
        self.sortDirection(item.sortDir());
        config.context.getRecords();
    }
    self.isVisibleColumn = function (name) {
        var record = null;
        for (var i = 0; i < self.tableProperties().length; i++) {
            if (self.tableProperties()[i].name === name) {
                record = self.tableProperties()[i];
            }
        }
        if (record === null)
            return false;

        if (self.showType() === "Table") {
            if (record.name === 'id')
                return true;
            return record.visibleCol();
        } else {
            if (record.name === 'id')
                return false;
            return record.visibleItem();
        }

    };
    self.checkVisibleItem = function (target) {
        var count = 0;
        for (var i = 0; i < self.tableProperties().length; i++) {
            if (self.tableProperties()[i].visibleItem())
                count++;
        }
        if (count > 3)
            target.visibleItem(false);
    }
    self.groupByClick = function (item, e, state) {
        if (state === undefined) {
            if (item.groupBy === true &&
                (_h.isNullOrEmpty(self.groupProperty()) || self.groupProperty() === item.name)) {
                self.records.removeAll();
                if (!item.activeGroupBy()) {
                    item.activeGroupBy(true);
                    self.groupProperty(item.name);
                    self.groupDirection(item.groupDir());
                } else {
                    if (item.groupDir() === "Ascending") {
                        item.groupDir("Descending");
                    } else {
                        item.groupDir("Ascending");
                    }
                    self.groupDirection(item.groupDir());
                }
                item.visibleCol(false);
                self.filterBy();
            }
            if (item.groupBy === true &&
                !_h.isNullOrEmpty(self.groupProperty()) &&
                self.groupProperty() !== item.name) {
                self.records.removeAll();
                ko.utils.arrayFilter(self.tableProperties(),
                    function (sortItem) {
                        sortItem.activeGroupBy(false);
                    });
                if (!item.activeGroupBy()) {
                    item.activeGroupBy(true);
                    self.groupProperty(item.name);
                } else {
                    if (item.groupDir() === "Ascending") {
                        item.groupDir("Descending");
                    } else {
                        item.groupDir("Ascending");
                    }
                    self.groupDirection(item.groupDir());
                }
                item.visibleCol(false);
                self.filterBy();
            }
        } else {
            self.groupProperty(item.name);
            self.groupDirection(item.groupDir());
            item.visibleCol(false);
        }
        _h.kocnx().saveTableState(self);
    }
    self.cancelGroupBy = function (item) {
        self.groupProperty(undefined);
        self.groupDirection(undefined);
        ko.utils.arrayFilter(self.tableProperties(), function (sortItem) {
            sortItem.activeGroupBy(false);
        });
        if (self.entityName !== "TableTemplate")
            item.visibleCol(true);

        self.filterBy();
        if (self.entityName === "TableTemplate")
            _h.kocnx().saveTableState(self);
    }
    self.backward = function () {
        if (self.pageNumber() > 1) {
            self.pageNumber(self.pageNumber() - 1);
            config.context.getRecords();
        }
    }
    self.goTo = function (model, e) {
        var pageNumber = Number($(e.target).attr("data-pageid"));
        if (pageNumber > 0) {
            config.context.pageNumber(pageNumber);
            config.context.getRecords();
        }
    }
    self.forward = function () {
        if (self.records().length !== self.total()) {
            self.pageNumber(self.pageNumber() + 1);
            self.refreshTable();
        }
    }
    self.refreshTable = function () {
        switch (self.entityName) {
            case "BalanceReport":
                if (!config.context.filterBox().validationObject.isValid()) {
                    config.context.filterBox().validationObject.errors.showAllMessages();
                    return false;
                }
                config.context.getRecords();
                break;
            case "Period":
                self.wideRight(true);
                self.childModel(null);
                config.context.getRecords();
                break;
            case "ActionLog":
                self.wideRight(true);
                self.childModel(null);
                config.context.getRecords();
                break;
            default:
                self.childModel(null);
                config.context.getRecords();
                break;
        }

    };
    self.filterBy = function () {
        self.pageNumber(1);
        config.context.getRecords();
    }
    self.extraBufferKey = ko.observable();
    self.changeSelectedRecord = function (target, ctrlSelect, shiftSelect, rightClick) {
        if (self.isMultiSelectRows && self.showType() !== "List") {
            if (shiftSelect) {
                if (self.extraBufferKey() === null || self.extraBufferKey() === undefined) {
                    self.extraBufferKey(target);
                    target.selected(true);
                } else {
                    var first, second, groupRoot, indexFirst, indexSecond, cr = false;
                    ;
                    if (self.groupProperty()) {
                        for (var i = 0; i < self.records().length; i++) {
                            var rec = self.records()[i];
                            for (var j = 0; j < rec.list().length; j++) {
                                var innerRec = rec.list()[j];
                                if (self.extraBufferKey().id() === innerRec.id()) {
                                    groupRoot = rec;
                                    indexFirst = rec.list().indexOf(self.extraBufferKey());
                                    indexSecond = rec.list().indexOf(target);
                                }
                            }
                        }
                        if (indexFirst === indexSecond)
                            return;
                        if (indexFirst > indexSecond) {
                            first = target;
                            second = self.extraBufferKey();
                        }
                        if (indexFirst < indexSecond) {
                            first = self.extraBufferKey();
                            second = target;
                        }

                        ko.utils.arrayFilter(groupRoot.list(),
                            function (rec) {
                                if (rec.id() === first.id())
                                    cr = true;
                                if (cr)
                                    rec.selected(true);
                                if (rec.id() === second.id())
                                    cr = false;
                            });
                    } else {
                        indexFirst = self.records().indexOf(self.extraBufferKey());
                        indexSecond = self.records().indexOf(target);
                        if (indexFirst === indexSecond) {
                            return;
                        }
                        if (indexFirst > indexSecond) {
                            first = target;
                            second = self.extraBufferKey();
                        }
                        if (indexFirst < indexSecond) {
                            first = self.extraBufferKey();
                            second = target;
                        }


                        ko.utils.arrayFilter(self.records(),
                            function (rec) {
                                if (rec.id() === first.id())
                                    cr = true;
                                if (cr)
                                    rec.selected(true);
                                if (rec.id() === second.id())
                                    cr = false;
                            });
                    }

                }
            }
            else {
                if (ctrlSelect) {
                    if (target.selected() === false)
                        self.extraBufferKey(target);
                    target.selected(!target.selected());
                } else {
                    if (rightClick) {
                        if (!target.selected()) {
                            self.extraBufferKey(target);
                            self.multiCommandExecute("toggle", false);
                            target.selected(true);
                        }
                        target.selected(true);
                    } else {
                        self.extraBufferKey(target);
                        self.multiCommandExecute("toggle", false);
                        if (self.configTable.isMultiSelectRows)
                            self.selectedRowRecord(target);
                        target.selected(true);
                    }
                }
            }
        }
        else {
            self.extraBufferKey(target);
            if (self.selectedRowRecord() !== null && self.selectedRowRecord() !== undefined)
                self.selectedRowRecord().selected(false);
            self.selectedRowRecord(target);
            target.selected(true);
        }
    };
    self.onlySelectedRow = function (target) {
        self.multiCommandExecute("toggle", false);
        if (self.selectedRowRecord() !== null && self.selectedRowRecord() !== undefined)
            self.selectedRowRecord().selected(false);
        self.selectedRowRecord(target);
        target.selected(true);
    }
    if (config.selectRow) {
        self.isValidClickSingleRow = function (e) {
            var tag;
            if (e.target === undefined)
                tag = e.tagName.toLowerCase();
            else
                tag = e.target.tagName.toLowerCase();
            switch (tag) {
                case "span":
                case "label":
                    return "label";
                case "button":
                case "i":
                case "a":
                case "li":
                    return false;
                default:
                    return true;
            }
        }
        self.getSelectedRecord = function () {
            return self.selectedRowRecord();
        };
        self.isSelectedRecord = ko.computed(function () {
            return self.selectedRowRecord() !== null && self.selectedRowRecord() !== undefined;
        });
        self.selectedRow = function (target, e, rightClick) {
            var ctrlSelect = e.ctrlKey;
            var shiftSelect = e.shiftKey;
            if (shiftSelect === undefined) shiftSelect = false;
            if (ctrlSelect === undefined) ctrlSelect = false;
            var res = self.isValidClickSingleRow(e);
            if (res !== "label") {
                self.changeSelectedRecord(target, ctrlSelect, shiftSelect, rightClick);
                self.fillChildModel(target);
            } else {
                self.changeSelectedRecord(target, ctrlSelect, shiftSelect, rightClick);
                self.fillChildModel(target);
            }
        };
    }
    self.fillChildModel = function (target) {
        switch (self.entityName) {
            case "Period":
                if (!self.wideRight()) {
                    var model = new HistoryViewModel();
                    model.periodId(target.id());
                    self.childModel(model);
                    self.childModel().init();
                }
                break;
            case "SourceTableData":
            case "Balancesheet":
            case "BalanceReportData":
            case "Tree":
            case "User":
            case "AdjustmentDocument":
                if (self.showBlockType() === "sideBySide" || self.showBlockType() === "fullDetails")
                    config.context.changeChildModel(target);
                break;
            case "ActionLog":
                if (!self.wideRight())
                    config.context.changeChildModel(target);
                break;
            case "CompanyInfo":
                config.context.changeChildModel(target);
                break;

        }
        if (config.context["onSelectRecord"])
            config.context.onSelectRecord(target);
    };
    if (config.isMultiSelectRows) {
        self.checkAll = ko.observable();
        self.checkAllClick = function () {
            self.checkAll(!self.checkAll());
            self.multiCommandExecute("checkAll", self.checkAll());
        };
    }
    self.clearAllSelected = function () {
        if (self.selectedRowRecord() !== null && self.selectedRowRecord() !== undefined) {
            self.selectedRowRecord().selected(false);
            self.selectedRowRecord(null);
        }
        ko.utils.arrayFilter(self.records(), function (record) {
            record.selected(false);
        });
        self.childModel(null);
    }
    self.fillTableProperties = function () {
        var list = null;
        if (self.saveState) {
            var model;
            if (config.dynamicCols)
                model = clientStorage.getSetting(self.tableCode() + "_TableState_" + _h.kocnx().loginCompanyType());
            else
                model = clientStorage.getSetting(self.entityName + "_TableState_" + _h.kocnx().loginCompanyType());
            if (!_h.isNullOrEmpty(model) && model !== "") {
                list = JSON.parse(model);
                switch (self.entityName) {
                    case "AdjustmentDocument":
                    case "AdjustmentDocumentItem":
                        var defList = config.context.createColList();
                        for (var j = 0; j < defList.length; j++) {
                            for (var n = 0; n < list.length; n++) {
                                if (defList[j].colName === list[n].colName) {
                                    defList[j].tablecol = list[n].tablecol;
                                    defList[j].visibleCol = list[n].visibleCol;
                                    defList[j].groupBy = list[n].groupBy;
                                    defList[j].groupDir = list[n].groupDir;
                                    defList[j].groupDir = list[n].groupDir;
                                    defList[j].activeGroupBy = list[n].activeGroupBy;
                                    defList[j].width = list[n].width;
                                    defList[j].enumSourceName = list[n].enumSourceName;
                                }
                            }
                        }
                        list = defList;
                        break;
                }
            } else {
                list = config.cols;
            }
        } else {
            list = config.cols;
        }
        self.tableProperties.removeAll();
        var targetGroupBy = null;
        for (var p in list) {
            if (list.hasOwnProperty(p)) {
                var target = list[p];
                var colRecord = new Column(target, self);
                self.tableProperties.push(colRecord);
                if (target.sortDir !== "None") {
                    self.sortDirection(target.sortDir);
                    self.sortProperty(target.colName);
                }
                if (target.activeGroupBy) {
                    targetGroupBy = colRecord;
                }
            }
        }
        if (targetGroupBy !== null) {
            self.groupByClick(targetGroupBy, null, true);
        }
        var showType = clientStorage.getSetting(self.entityName + "_ShowTableState_" + _h.kocnx().loginCompanyType());
        if (!showType)
            showType = "Table";
        self.showType(showType);
    }
    self.toggleParentItemVisibleCols = function (item, val) {
        for (var k = 0; k < self.tableProperties().length; k++) {
            var target = self.tableProperties()[k];
            if (target.colParent === item.id) {
                target.visibleCol(val);
            }
        }
    }
    self.getInstance = function (target, parent) {
        var model = models[self.entityName];
        if (parent)
            return new model(target, parent);
        return new model(target);
    }
    self.clearSearchBoxes = function () {
        for (var p in self.filters) {
            if (self.filters.hasOwnProperty(p)) {
                var target = self.filters[p];
                if (_h.isNullOrEmpty(target["clear"]) && (!target.type || target.type !== "list"))
                    self[target.name](target.def);
                if (_h.isNullOrEmpty(target["clear"]) && (target.type && target.type === "list"))
                    self[target.name].removeAll();
            }
        }
        self.searchKey("");
        self.pageNumber(1);
        config.context.getRecords();
    }
    self.createFilterByModel = function () {
        var filterModel = {
            searchKey: self.searchKey(),
            pageNumber: self.pageNumber(),
            pageSize: self.pageSize(),
            sortProperty: self.sortProperty(),
            sortDirection: self.sortDirection(),
            groupDirection: self.groupDirection(),
            groupProperty: self.groupProperty(),
            filterType: self.filterType()
        };
        if (self.firstView && self.configTable.filterProfile) {
            filterModel.profileIncluded = true;
            self.firstView = false;
        }
        if (self.filters !== undefined && self.filters.length > 0)
            for (var p in self.filters) {
                if (self.filters.hasOwnProperty(p)) {
                    var target = self.filters[p];
                    if (target.toServer === undefined) {
                        filterModel[target.name] = _h.normalizeAmpersand(self[target.name]());
                    }
                }
            }
        return filterModel;
    }
    self.rightClickSelectRow = function (target, eventTarget, event) {
        if (self.configTable.selectRow && self.configTable.contextMenu)
            self.selectedRow(target, event, true);
    };
    if (_h.any(config.filters)) {
        for (var p in config.filters) {
            if (config.filters.hasOwnProperty(p)) {
                var target = config.filters[p];
                if (target.type && (target.type === "list" || target.type === "multiselect"))
                    self[target.name] = ko.observableArray(target.def);
                else
                    self[target.name] = ko.observable(target.def);
            }
        }
    }
    self.handleOpenFolder = function (type) {
        var target, array = [];
        switch (type) {
            case "set":
                if (self.records().length)
                    for (var i = 0; i < self.records().length; i++) {
                        target = self.records()[i];
                        if (target["vis"] && target.vis()) {
                            array.push(target.title);
                        }
                    }
                if (array.length)
                    localStorage.setItem("Open_Folders_" + self.entityName, JSON.stringify(array));
                else
                    localStorage.removeItem("Open_Folders_" + self.entityName);
                break;
            case "apply":
                var data = localStorage.getItem("Open_Folders_" + self.entityName);
                if (data) {
                    array = JSON.parse(data);
                    for (var j = 0; j < self.records().length; j++) {
                        target = self.records()[j];
                        for (var n = 0; n < array.length; n++) {
                            if (array[n] === target.title)
                                target.vis(true);
                        }
                    }
                }
                break;
        }
    };
    if (config.getList) {
        self.getRecords = function (selectedId) {
            var address = "filterby";
            if (self.configTable.dynamicCols) {
                switch (self.entityName) {
                    case "CompanyInfoData":
                        address = "/api/companyinfodata/filterby";
                        break;
                    default:
                        address = "/api/dynamictabledata/filterby";
                        break;
                }
            }
            var filterModel = self.createFilterByModel();
            self.handleOpenFolder("set");
            self.apiService.request({
                name: address,
                data: filterModel,
                success: function (data) {
                    self.records.removeAll();
                    if (!_h.isNullOrEmpty(data)) {
                        self.total(data.total);
                        self.checkPageNumber(data.total);
                        if (_h.any(self.extraParams)) {
                            self.updateExtraParams(data);
                        }
                        if (_h.any(data.list))
                            for (var m = 0; m < data.list.length; m++) {
                                var target = data.list[m];
                                var record;
                                if (self.dynamicCols)
                                    record = self.getInstance(target, self.tableFields());
                                else
                                    record = self.getInstance(target);
                                self.records.push(record);
                            }
                        if (_h.any(data.groupList)) {
                            for (var j = 0; j < data.groupList.length; j++) {
                                var target2 = data.groupList[j];
                                var object = {
                                    title: target2.title,
                                    vis: ko.observable(false),
                                    list: ko.observableArray()
                                };
                                if (_h.any(target2.list))
                                    for (var i = 0; i < target2.list.length; i++) {
                                        var record2;
                                        if (self.dynamicCols)
                                            record2 = self.getInstance(target2.list[i], self.tableFields());
                                        else
                                            record2 = self.getInstance(target2.list[i]);
                                        record2.gParent = object;
                                        object.list.push(record2);
                                    }
                                self.records.push(object);
                            }
                            self.handleOpenFolder("apply");
                        }
                    }
                    self.childModel(null);
                    if (self["checkAll"])
                        self.checkAll(false);
                    self.extraBufferKey(null);
                    self.unSelectItem();
                    if (config.context["afterFilterBy"])
                        config.context.afterFilterBy(data, selectedId);
                    if (self.configTable.resizable)
                        _h.initResizeTable();
                },
                messageType: 'getList',
                messageKey: self.entityName
            });
        };
    }
    self.checkPageNumber = function (total) {
        if (total > 0) {
            var pageCount = total / self.pageSize();
            var rest = total % self.pageSize();
            if (rest > 0) {
                pageCount++;
            }
            if (self.pageNumber() > pageCount) {
                self.pageNumber(self.pageNumber() - 1);
                self.getRecords();
            }
        }
    };
    self.groupByToggleBtn = function (item) {
        item.vis(!item.vis());
    }
    self.groupByToggleDblBtn = function (item) {
        if (config.isMultiSelectRows && _h.any(item.list())) {
            var first = item.list()[0];
            var res = !first.selected();
            for (var i = 0; i < item.list().length; i++) {
                item.list()[i].selected(res);
            }
        }
        if (!config.isMultiSelectRows) {
            item.vis(!item.vis());
        }

    };
    self.up = function () {
        var index;
        if (self.groupProperty()) {
            var groupTarget = null;
            for (var i = 0; i < self.records().length; i++) {
                var rec = self.records()[i];
                for (var j = 0; j < rec.list().length; j++) {
                    var innerRec = rec.list()[j];
                    if (self.getSelectedRecord().id() === innerRec.id()) {
                        groupTarget = rec;
                    }
                }
            }
            if (groupTarget) {
                index = groupTarget.list().indexOf(self.getSelectedRecord()) - 1;
                if (index < 0) index = 0;
                self.changeSelectedRecord(groupTarget.list()[index]);
                self.fillChildModel(groupTarget.list()[index]);
            }

        } else {
            switch (self.entityName) {
                case "Company":
                    var item = self.getSelectedRecord();
                    if (!_h.isNullOrEmpty(item)) {
                        var id = self.entityName + "-" + item.id();
                        var element = $("#" + id);
                        var preElement = element.prev(":visible");
                        if (preElement.length) {
                            var prvItem = ko.dataFor(preElement[0]);
                            self.changeSelectedRecord(prvItem);
                            self.fillChildModel(self.records()[index]);
                        }
                    } else {
                        index = self.records().indexOf(self.getSelectedRecord()) - 1;
                        if (index === -2) return;
                        if (index === -1) index = 0;
                        self.changeSelectedRecord(self.records()[index]);
                        self.fillChildModel(self.records()[index]);
                    }
                    break;
                default:
                    index = self.records().indexOf(self.getSelectedRecord()) - 1;
                    if (index === -2) return;
                    if (index === -1) index = 0;
                    self.changeSelectedRecord(self.records()[index]);
                    self.fillChildModel(self.records()[index]);
                    break;
            }
        }

    }
    self.down = function () {
        var index;
        if (self.groupProperty()) {
            var groupTarget = null;
            for (var i = 0; i < self.records().length; i++) {
                var rec = self.records()[i];
                for (var j = 0; j < rec.list().length; j++) {
                    var innerRec = rec.list()[j];
                    if (self.getSelectedRecord().id() === innerRec.id()) {
                        groupTarget = rec;
                    }
                }
            }
            if (groupTarget) {
                index = groupTarget.list().indexOf(self.getSelectedRecord()) + 1;
                if (index >= groupTarget.list().length) index = groupTarget.list().length - 1;
                self.changeSelectedRecord(groupTarget.list()[index]);
                self.fillChildModel(groupTarget.list()[index]);
            }
        } else {
            switch (self.entityName) {
                case "Company":
                    var item = self.getSelectedRecord();
                    if (!_h.isNullOrEmpty(item)) {
                        var id = self.entityName + "-" + item.id();
                        var element = $("#" + id);
                        var nextElement = element.next(":visible");
                        if (nextElement.length) {
                            var nextItem = ko.dataFor(nextElement[0]);
                            self.changeSelectedRecord(nextItem);
                            self.fillChildModel(nextItem);
                        }
                    } else {
                        index = self.records().indexOf(self.getSelectedRecord()) + 1;
                        if (index >= self.records().length) index = self.records().length - 1;
                        self.changeSelectedRecord(self.records()[index]);
                        self.fillChildModel(self.records()[index]);
                    }
                    break;
                default:
                    index = self.records().indexOf(self.getSelectedRecord()) + 1;
                    if (index >= self.records().length) index = self.records().length - 1;
                    self.changeSelectedRecord(self.records()[index]);
                    self.fillChildModel(self.records()[index]);
                    break;
            }
        }
    }
    self.right = function () {
        var item = self.getSelectedRecord();
        if (!_h.isNullOrEmpty(item)) {
            if (item["childrenShow"] !== null && item["childrenShow"] !== undefined && item.childrenShow())
                item.childrenShow(false);
            else {
                return true;
            }
        } else {
            return true;
        }
    }
    self.left = function () {
        var item = self.getSelectedRecord();
        if (!_h.isNullOrEmpty(item)) {
            if (item["childrenShow"] !== null && item["childrenShow"] !== undefined && item.childrenShow())
                item.childrenShow(false);
            else {
                return true;
            }
        } else {
            return true;
        }
    }
    if (_h.any(config.buttons)) {
        for (var l in config.buttons) {
            if (config.buttons.hasOwnProperty(l)) {
                var action = config.buttons[l];
                self["vis" + action.name] = ko.observable();
                switch (action.name) {
                    case "refresh":
                        action.icon = "Refresh";
                        action.title = 'refreshTable';
                        action.action = self.refreshTable;
                        break;
                    case "help":
                        action.icon = "Help";
                        action.title = 'helpBtn';
                        action.action = _h.kocnx().openHelp;
                        break;
                }
            }
        }
    }
    self.multiCommandExecute = function (command, val, ids, data) {
        if (self.entityName === "Company")
            return self.parentChildMultiCommandExecute(command, val, ids, data);
        else {
            var record,
                innerRecord,
                selectedItems = [],
                selectedRowRecord = null,
                enableCount = 0,
                disableCount = 0,
                selectedList = 0,
                temporaryCount = 0,
                confirmCount = 0,
                archiveCount = 0,
                unArchiveCount = 0,
                rightDocumentsCount = 0,
                cr = false,
                failCount = 0,
                successCount = 0,
                unconfirmActionCount = 0,
                temp = null;
            if (_h.any(self.records()))
                for (var i = 0; i < self.records().length; i++) {
                    record = self.records()[i];
                    if (record["list"]) {
                        for (var j = 0; j < record.list().length; j++) {
                            innerRecord = record.list()[j];
                            switch (command) {
                                case "checkAll":
                                    innerRecord.selected(val);
                                    break;
                                case "toggle":
                                    innerRecord.selected(val);
                                    break;
                                case "selectedItems":
                                    if (innerRecord.selected())
                                        selectedItems.push(innerRecord);
                                    break;
                                case "selectedItemIds":
                                    if (innerRecord.selected())
                                        selectedItems.push(innerRecord.id());
                                    break;
                                case "selectedRowRecord":
                                    if (innerRecord.selected())
                                        selectedRowRecord = innerRecord;
                                    break;
                                case "btnVisibilityData":
                                    if (innerRecord.selected()) {
                                        if (innerRecord.stateType() === 0)
                                            disableCount++;
                                        if (innerRecord.stateType() === 1)
                                            enableCount++;
                                        rightDocumentsCount++;
                                        selectedList++;
                                        temp = innerRecord;
                                    }
                                    break;
                                case "btnVisibilityData2":
                                    if (innerRecord.selected()) {
                                        if (innerRecord.stateType() === 0)
                                            disableCount++;
                                        if (innerRecord.stateType() === 1)
                                            enableCount++;
                                        if (innerRecord.confirmationState() === 1)
                                            temporaryCount++;
                                        if (innerRecord.confirmationState() === 2)
                                            confirmCount++;
                                        selectedList++;
                                        temp = innerRecord;
                                    }
                                    break;
                                case "btnVisibilityData4":
                                    if (innerRecord.selected()) {
                                        if (innerRecord.archived())
                                            archiveCount++;
                                        if (!innerRecord.archived())
                                            unArchiveCount++;
                                        selectedList++;
                                        temp = innerRecord;
                                    }
                                    break;
                                case "changesLocalStateType":
                                    if (ids.indexOf(innerRecord.id()) !== -1) {
                                        innerRecord.stateType(val);
                                        innerRecord.selected(false);
                                    }
                                    break;
                                case "changesLocalConfirmState":
                                    if (val === 2) {
                                        if (data.failed.indexOf(innerRecord.id()) !== -1) {
                                            innerRecord.selected(false);
                                            innerRecord.messageType(1);
                                            failCount++;
                                        }
                                        if (data.successful.indexOf(innerRecord.id()) !== -1) {
                                            innerRecord.confirmationState(val);
                                            innerRecord.selected(false);
                                            innerRecord.messageType(2);
                                            successCount++;
                                        }
                                    } else {
                                        if (ids.indexOf(innerRecord.id()) !== -1) {
                                            innerRecord.confirmationState(val);
                                            innerRecord.selected(false);
                                            unconfirmActionCount++;
                                        }
                                    }
                                    break;
                                case "resetMessageType":
                                    innerRecord.messageType(0);
                                    break;
                            }
                        }
                    } else {
                        switch (command) {
                            case "checkAll":
                                record.selected(val);
                                break;
                            case "selectedItems":
                                if (record.selected())
                                    selectedItems.push(record);
                                break;
                            case "selectedItemIds":
                                if (record.selected())
                                    selectedItems.push(record.id());
                                break;
                            case "toggle":
                                record.selected(val);
                                break;
                            case "selectedRowRecord":
                                if (record.selected())
                                    selectedRowRecord = record;
                                break;
                            case "btnVisibilityData":
                                if (record.selected()) {
                                    if (record.stateType() === 0)
                                        disableCount++;
                                    if (record.stateType() === 1)
                                        enableCount++;
                                    rightDocumentsCount++;
                                    selectedList++;
                                    temp = record;
                                }
                                break;
                            case "btnVisibilityData2":
                                if (record.selected()) {
                                    if (record.stateType() === 0)
                                        disableCount++;
                                    if (record.stateType() === 1)
                                        enableCount++;
                                    if (record.confirmationState() === 1)
                                        temporaryCount++;
                                    if (record.confirmationState() === 2)
                                        confirmCount++;
                                    selectedList++;
                                    temp = record;
                                }
                                break;
                            case "btnVisibilityData3":
                                if (record.selected()) {
                                    if (!self.adjustmentId()) {
                                        if (record.stateType() === 0 && record.stateTypeEditable())
                                            disableCount++;
                                        if (record.stateType() === 1 && record.stateTypeEditable())
                                            enableCount++;
                                    } else {
                                        if (record.stateType() === 0)
                                            disableCount++;
                                        if (record.stateType() === 1)
                                            enableCount++;
                                    }
                                    selectedList++;
                                    temp = record;
                                }
                                break;
                            case "btnVisibilityData4":
                                if (record.selected()) {
                                    if (record.archived())
                                        archiveCount++;
                                    if (!record.archived())
                                        unArchiveCount++;
                                    selectedList++;
                                    temp = record;
                                }
                                break;
                            case "changesLocalStateType":
                                if (ids.indexOf(record.id()) !== -1) {
                                    record.stateType(val);
                                    record.selected(false);
                                    if (!_h.isNullOrEmpty(self.childModel())
                                        && record.id() === self.childModel().adjustmentId()) {
                                        temp = record;
                                    }
                                }
                                break;
                            case "changesUnlockUser":
                                if (ids.indexOf(record.id()) !== -1) {
                                    record.locked(val);
                                    record.selected(false);
                                }
                                break;
                            case "changesLocalConfirmState":
                                if (val === 2) {
                                    if (data.failed.indexOf(record.id()) !== -1) {
                                        record.selected(false);
                                        record.messageType(1);
                                        failCount++;
                                    }
                                    if (data.successful.indexOf(record.id()) !== -1) {
                                        record.confirmationState(val);
                                        record.selected(false);
                                        record.messageType(2);
                                        successCount++;
                                    }
                                } else {
                                    if (ids.indexOf(record.id()) !== -1) {
                                        record.confirmationState(val);
                                        record.selected(false);
                                        unconfirmActionCount++;
                                    }
                                }
                                break;
                            case "resetMessageType":
                                record.messageType(0);
                                break;
                        }
                    }
                }
            switch (command) {
                case "checkAll":
                    self.selectedRowRecord(null);
                    break;
                case "btnVisibilityData":
                    return [temp, enableCount, disableCount, selectedList, rightDocumentsCount];
                case "btnVisibilityData2":
                    return [temp, enableCount, disableCount, selectedList, temporaryCount, confirmCount];
                case "btnVisibilityData3":
                    return [temp, enableCount, disableCount, selectedList];
                case "btnVisibilityData4":
                    return [temp, archiveCount, unArchiveCount, selectedList];
                case "selectedItems":
                case "selectedItemIds":
                    return selectedItems;
                case "selectedRowRecord":
                    return selectedRowRecord;
                case "changesLocalStateType":
                    if (!_h.isNullOrEmpty(self.childModel()) && temp) {
                        config.context.changeChildModel(temp, true);
                    }
                    break;
                case "changesLocalConfirmState":
                    if (failCount > 0) {
                        toast.custom("error",
                            _h.getApiMessage("PutConfirmTypesError")
                                .replace("__", failCount)
                                .replace("--", toast.getEntitiesValue(self.entityName, 'put', null)));
                    }
                    if (successCount > 0) {
                        var successMessage = toast.createMessage(self.entityName, 'custom', 'ConfirmTypes', 'success');
                        toast.custom("success", successMessage.replace("__", successCount));
                    }
                    if (unconfirmActionCount > 0) {
                        if (ids.length === 1)
                            toast.success(self.entityName, 'custom', 'UnConfirmType');
                        if (ids.length > 1)
                            toast.success(self.entityName, 'custom', 'UnConfirmTypes');
                    }
                    if (self.childModel() !== null && self.childModel() !== undefined) {
                        if (val === 1)
                            self.childModel().isRightEdit(true);
                        else
                            self.childModel().isRightEdit(false);
                    }
                    setTimeout(function () {
                        self.multiCommandExecute("resetMessageType");
                    },
                        10000);
                    break;
            }
        }
    }
    self.parentChildMultiCommandExecute = function (command, val, ids, data) {
        var record,
            targetChild,
            selectedItems = [];
        if (_h.any(self.records()))
            for (var i = 0; i < self.records().length; i++) {
                record = self.records()[i];
                switch (command) {
                    case "selectedItems":
                        if (record.selected())
                            selectedItems.push(record);
                        for (var j = 0; j < record.children().length; j++) {
                            targetChild = record.children()[j];
                            if (targetChild.selected())
                                selectedItems.selected(targetChild);
                        }
                        return selectedItems;
                    case "selectedItemIds":
                        if (record.selected())
                            selectedItems.push(record.id());
                        for (var j = 0; j < record.children().length; j++) {
                            targetChild = record.children()[j];
                            if (targetChild.selected())
                                selectedItems.push(targetChild.id());
                        }
                        return selectedItems;
                    case "toggle":
                        record.selected(val);
                        for (var l = 0; l < record.children().length; l++) {
                            targetChild = record.children()[l];
                            targetChild.selected(val);
                        }
                        break;
                    case "selectedRowRecord":
                        return self.selectedRowRecord();
                    case "changesLocalStateType":
                        if (ids.indexOf(record.id()) !== -1) {
                            record.stateType(val);
                            record.selected(false);
                        }
                        self.changesChildrenLocalStateType(record, ids, val);
                        break;
                }
            }
    };
    self.changesChildrenLocalStateType = function (record, ids, val) {
        if (record.children().length > 0)
            for (var i = 0; i < record.children().length; i++) {
                if (ids.indexOf(record.children()[i].id()) !== -1) {
                    record.children()[i].stateType(val);
                    record.children()[i].selected(false);
                }
                self.changesChildrenLocalStateType(record.children()[i], ids, val);
            }
    };
    self.create = function (m, mo, e) {
        var model;
        var item = m[1];
        switch (self.entityName) {
            case "DynamicDocument":
                if (!item.validateForm()) {
                    return false;
                }
                model = item.toServer();
                break;
            default:
                if (!item.validationObject.isValid()) {
                    item.validationObject.errors.showAllMessages();
                    return false;
                }
                model = item.toServer();
                break;
        }
        self.apiService.request({
            splashId: e,
            name: "post",
            data: model,
            success: function (data) {
                if (!_h.isNullOrEmpty(data)) {
                    switch (self.entityName) {
                        case "Period":
                            self.afterCreate(data.models);
                            break;
                        case "AdjustmentDocumentItem":
                            if (!self.adjustmentId()) {
                                self.refreshTable();
                            } else {
                                self.afterCreate(data.models);
                                _h.kocnx().advm().callBackItemCountData(self.total());
                            }
                            break;
                        case "Company":
                            config.context.collectOpenBranches();
                            self.afterCreate(data.models, true);
                            config.context.configTools();
                            $("#tree_view").treeView("expand", config.context.treeOpenBranches);
                            config.context.getSelectList();
                            _h.kocnx().headerSection.resetActiveSelectMenu(true);
                            break;
                        case "TableTemplate":
                            self.afterCreate(data.models);
                            config.context.getTableTemplateList();
                            break;
                        default:
                            self.afterCreate(data.models);
                            break;
                    }
                    _h.kocnx().closeForm();
                    self.unSelectItem();
                    toast.success(self.entityName, 'post');
                    self.updateExtraParams(data);
                }
            },
            messageType: 'post',
            messageKey: self.entityName
        });
    };
    self.unSelectItem = function () {
        if (!_h.isNullOrEmpty(self.selectedRowRecord())) {
            self.selectedRowRecord().selected(false);
            self.selectedRowRecord(null);
        }
    };
    self.afterCreate = function (models, searchDeep) {
        if (_h.any(models)) {
            for (var i = 0; i < models.length; i++) {
                if (models[i].ad === true) {
                    var item = self.getInstance(models[i]);
                    if (!_h.isNullOrEmpty(self.groupProperty())) {
                        var groupProp = self.getGroupPropertyTitle(models[i]);
                        var addItem = false;
                        for (var j = 0; j < self.records().length; j++) {
                            var record = self.records()[j];
                            if (!_h.isNullOrEmpty(groupProp) && record.title === groupProp) {
                                record.list.push(item);
                                addItem = true;
                            }
                            if (_h.isNullOrEmpty(groupProp) && record.title === "دسته بندی نشده") {
                                record.list.push(item);
                                addItem = true;
                            }
                        }
                        var object;
                        if (addItem === false && _h.isNullOrEmpty(groupProp)) {
                            object = {
                                title: "دسته بندی نشده",
                                vis: ko.observable(false),
                                list: ko.observableArray()
                            };
                            object.list.push(item);
                            self.records.push(object);
                            self.increaseTotal();
                        }
                        if (addItem === false && !_h.isNullOrEmpty(groupProp)) {
                            object = {
                                title: groupProp,
                                vis: ko.observable(false),
                                list: ko.observableArray()
                            };
                            object.list.push(item);
                            self.records.push(object);
                            self.increaseTotal();
                        }
                    } else {
                        if (models[i]["children"]
                            && !_h.isNullOrEmpty(models[i].pi) && searchDeep) {
                            var parent = self.findRecord(models[i].pi, true);
                            models[i].depth = parent.depth + 1;
                            item = self.getInstance(models[i], parent);
                            parent.children.push(item);
                            if (self.entityName === "Company" &&
                                (_h.isNullOrEmpty(self.searchKey()) || self.searchKey() === ""))
                                self.increaseTotal();
                        } else {
                            self.records.push(item);
                            self.increaseTotal();
                        }
                    }
                } else {
                    var oldRecord = self.findRecord(models[i].id);
                    if (!_h.isNullOrEmpty(oldRecord)) {
                        oldRecord.refreshModel(models[i]);
                    }
                }
            }
            self.sortAfterChanges();
        }
    };
    self.sortAfterChanges = function () {
        if (self.entityName === "Company")
            return;

        if (!_h.isNullOrEmpty(self.groupProperty())) {
            var folderList = ko.toJS(self.folderList);
            self.records.sort(function (left, right) {
                var lIndex;
                var rIndex;
                folderList.filter(function (el, index) {
                    if (el.text === left.title) {
                        lIndex = index;
                    }
                    if (el.text === right.title) {
                        rIndex = index;
                    }
                });
                if (self.groupDirection() === "Ascending") {
                    self.sortList(left.list);
                    return lIndex > rIndex ? 1 : lIndex < rIndex ? -1 : 0;
                    // return new Intl.Collator("fa").compare(left.title, right.title);

                } else {
                    self.sortList(left.list);
                    return lIndex < rIndex ? 1 : lIndex > rIndex ? -1 : 0;
                    // return new Intl.Collator("fa").compare(right.title, left.title);
                }
            });
        } else {
            self.sortList(self.records);
        }
    };
    self.sortList = function (list) {
        list.sort(function (left, right) {
            if (self.sortDirection() === "Ascending") {
                if (left[self.sortProperty()] && ko.isObservable(left[self.sortProperty()]) === true) {
                    return left[self.sortProperty()]() === right[self.sortProperty()]() ? 0 :
                        left[self.sortProperty()]() < right[self.sortProperty()]() ? -1 : 1;
                }
                if (left[self.sortProperty()] && ko.isObservable(left[self.sortProperty()]) === false) {
                    return left[self.sortProperty()] === right[self.sortProperty()] ? 0
                        : left[self.sortProperty()] < right[self.sortProperty()] ? -1 : 1;
                }
            } else {
                if (left[self.sortProperty()] && ko.isObservable(left[self.sortProperty()]) === true) {
                    return left[self.sortProperty()]() === right[self.sortProperty()]() ? 0 :
                        left[self.sortProperty()]() > right[self.sortProperty()]() ? -1 : 1;
                }
                if (left[self.sortProperty()] && ko.isObservable(left[self.sortProperty()]) === false) {
                    return left[self.sortProperty()] === right[self.sortProperty()] ? 0 :
                        left[self.sortProperty()] > right[self.sortProperty()] ? -1 : 1;
                }
            }
        });
    }
    self.findRecord = function (itemId, searchDeep) {
        var item;
        if (!_h.isNullOrEmpty(self.groupProperty())) {
            for (var i = 0; i < self.records().length; i++) {
                var target = self.records()[i];
                if (_h.any(target.list())) {
                    for (var j = 0; j < target.list().length; j++) {
                        if (itemId === target.list()[j].id()) {
                            return target.list()[j];
                        }
                        if (searchDeep === true && _h.any(target.list()[j].children())) {
                            item = self.findChildrenRecord(target.list()[j], itemId);
                            if (!_h.isNullOrEmpty(item))
                                return item;
                        }
                    }
                }
            }
        } else {
            for (var l = 0; l < self.records().length; l++) {
                if (itemId === self.records()[l].id()) {
                    return self.records()[l];
                }
                if (searchDeep === true && _h.any(self.records()[l].children())) {
                    item = self.findChildrenRecord(self.records()[l], itemId);
                    if (!_h.isNullOrEmpty(item))
                        return item;
                }
            }
        }
        return undefined;
    };
    self.findChildrenRecord = function (parent, itemId) {
        for (var i = 0; i < parent.children().length; i++) {
            var target = parent.children()[i];
            if (target.id() === itemId) {
                return target;
            }
            if (_h.any(target.children())) {
                var item = self.findChildrenRecord(target, itemId);
                if (!_h.isNullOrEmpty(item))
                    return item;
            }
        }
    };
    self.getGroupPropertyTitle = function (model) {
        var groupProp, val = null;
        for (var i = 0; i < self.tableProperties().length; i++) {
            var col = self.tableProperties()[i];
            if (col.name === self.groupProperty())
                groupProp = col;
        }
        if (groupProp) {
            if (groupProp.type === "enum") {
                var temp = model[self.groupProperty()];
                val = _h.getEnumText(groupProp.name + "s", temp);
            }
            if (groupProp.type === "string") {
                val = model[self.groupProperty()];
            }
        }
        return val;
    };
    self.edit = function (m, mo, e) {
        var item = m[1];
        switch (self.entityName) {
            case "DynamicDocument":
                if (!item.validateForm()) {
                    return false;
                }
                break;
            default:
                if (!item.validationObject.isValid()) {
                    item.validationObject.errors.showAllMessages();
                    return false;
                }
                break;
        }
        var model = item.toServer();
        switch (self.entityName) {
            case "MappingRule":
                model.balanceSheetId = self.balanceSheetId();
                break;
        }
        self.apiService.request({
            splashId: e,
            name: "put",
            data: model,
            success: function (data) {
                if (!_h.isNullOrEmpty(data)) {
                    switch (self.entityName) {
                        case "TableTemplate":
                            //todo   bug remove from editlist
                            self.afterUpdate(data.models);
                            break;
                        case "AdjustmentDocumentItem":
                            if (!self.adjustmentId()) {
                                self.refreshTable();
                            }
                            self.afterUpdate(data.models);
                            break;
                        case "Company":
                            config.context.collectOpenBranches();
                            config.context.afterUpdate(data.models, true);
                            config.context.configTools();
                            $("#tree_view").treeView("expand", config.context.treeOpenBranches);
                            config.context.getSelectList();
                            _h.kocnx().headerSection.resetActiveSelectMenu(true);
                            break;
                        case "CompanyInfoData":
                            self.refreshTable();
                            break;
                        default:
                            self.afterUpdate(data.models);
                            break;
                    }
                    _h.kocnx().closeForm();
                    self.unSelectItem();
                    toast.success(self.entityName, 'put');
                    self.updateExtraParams(data);
                }
            },
            messageType: 'put',
            messageKey: self.entityName
        });
    };
    self.afterUpdate = function (models, searchDeep) {
        if (_h.any(models)) {
            for (var i = 0; i < models.length; i++) {
                var oldRecord = self.findRecord(models[i].id, searchDeep);
                if (_h.isNullOrEmpty(self.groupProperty())) {
                    if (!_h.isNullOrEmpty(oldRecord)) {
                        oldRecord.refreshModel(models[i]);
                    }
                } else {
                    if (!_h.isNullOrEmpty(oldRecord)) {
                        if ((_h.isNullOrEmpty(oldRecord[self.groupProperty()]())
                            && _h.isNullOrEmpty(models[i][self.groupProperty()])) ||
                            oldRecord[self.groupProperty()]() === models[i][self.groupProperty()]) {
                            oldRecord.refreshModel(models[i]);
                        } else {
                            var oldFolder, newFolder, index, uncatFolder, item, object;
                            for (var k = 0; k < self.records().length; k++) {
                                if (oldRecord[self.groupProperty()]() === self.records()[k].title) {
                                    oldFolder = self.records()[k];
                                }
                                if (models[i][self.groupProperty()] === self.records()[k].title) {
                                    newFolder = self.records()[k];
                                }
                                if (_h.isNullOrEmpty(self.records()[k].title) ||
                                    self.records()[k].title === "دسته بندی نشده") {
                                    uncatFolder = self.records()[k];
                                    if (_h.isNullOrEmpty(oldRecord[self.groupProperty()]())) {
                                        oldFolder = self.records()[k];
                                    }
                                }
                            }
                            if (_h.isNullOrEmpty(newFolder)) {
                                newFolder = uncatFolder;
                            }
                            if (!_h.isNullOrEmpty(oldFolder)) {
                                index = oldFolder.list().indexOf(oldRecord);
                                if (index > -1) {
                                    item = oldFolder.list.remove(oldRecord);
                                    item = oldRecord;
                                    if (!_h.isNullOrEmpty(models[i][self.groupProperty()])
                                        && _h.isNullOrEmpty(item[self.groupProperty()]())) {
                                        newFolder.list.push(item);
                                        item.refreshModel(models[i]);
                                    }
                                    if (_h.isNullOrEmpty(models[i][self.groupProperty()])
                                        && !_h.isNullOrEmpty(item[self.groupProperty()]())) {
                                        if (!_h.isNullOrEmpty(uncatFolder)) {
                                            uncatFolder.list.push(item);
                                            item.refreshModel(models[i]);
                                        } else {
                                            object = {
                                                title: "دسته بندی نشده",
                                                vis: ko.observable(false),
                                                list: ko.observableArray()
                                            };
                                            object.list.push(item);
                                            item.refreshModel(models[i]);
                                            self.records.push(object);
                                            self.increaseTotal();
                                        }
                                    }
                                    if (!_h.isNullOrEmpty(models[i][self.groupProperty()]) &&
                                        !_h.isNullOrEmpty(item[self.groupProperty()]()) &&
                                        oldFolder.title !== "دسته بندی نشده") {
                                        if (!_h.isNullOrEmpty(newFolder)) {
                                            newFolder.list.push(item);
                                            item.refreshModel(models[i]);
                                        } else {
                                            object = {
                                                title: models[i][self.groupProperty()],
                                                vis: ko.observable(false),
                                                list: ko.observableArray()
                                            };
                                            object.list.push(item);
                                            self.records.push(object);
                                            self.increaseTotal();
                                        }
                                    }
                                }
                            }
                            if (self.records().length === 1 && self.records()[0].title === "دسته بندی نشده") {
                                item = uncatFolder.list.remove(oldRecord);
                                object = {
                                    title: models[i][self.groupProperty()],
                                    vis: ko.observable(false),
                                    list: ko.observableArray()
                                };

                                oldRecord.refreshModel(models[i]);
                                object.list.push(oldRecord);
                                self.records.push(object);
                                self.increaseTotal();
                            }

                        }
                    }
                }
            }
            self.removeEmptyFolders();
            self.sortAfterChanges();
        }
    };
    self.updateExtraParams = function (extraParams) {
        for (var m in extraParams) {
            if (extraParams.hasOwnProperty(m)) {
                var value = extraParams[m];
                if (self[m] && value && m !== "searchProfiles") {
                    self[m](value);
                }
                if (self[m] && value && m === "searchProfiles") {
                    for (var i = 0; i < value.length; i++) {
                        self.filterProfiles.push({ text: value[i].title, value: value[i].id, filters: value[i].filters });
                    }
                }
            }
        }
    };
    self.deleteBtn = function () {
        var selectedRecord = self.multiCommandExecute("selectedRowRecord");
        var id;
        var confirmText;
        switch (self.entityName) {
            case "AdjustmentDocument":
                id = selectedRecord.id();
                if (selectedRecord.confirmationState() === 2) {
                    toast.custom('error', _h.getApiMessage("DeleteConfirmed" + self.entityName + "Error"));
                    return;
                }
                confirmText = toast.createMessage(self.entityName, 'del', null, 'confirm');
                break;
            case "Consolidate":
                id = selectedRecord.periodId();
                confirmText = toast.createMessage(self.entityName, 'del', null, 'confirm');
                break;
            default:
                id = selectedRecord.id();
                confirmText = toast.createMessage(self.entityName, 'del', null, 'confirm');
                break;
        }
        _h.confirmDeleteAlert(confirmText,
            function (res) {
                if (res) {
                    var model = { id: id };
                    switch (self.entityName) {
                        case "AdjustmentDocumentItem":
                            model.amountType = self.amountType();
                            break;
                        case "CompanyInfoData":
                            model.formId = self.formId();
                            break;
                    }
                    self.apiService.request({
                        name: "delete",
                        data: model,
                        success: function (data) {
                            if (!_h.isNullOrEmpty(data)) {
                                switch (self.entityName) {
                                    case "Company":
                                        config.context.collectOpenBranches();
                                        self.afterDelete(id, data.models, true);
                                        config.context.configTools();
                                        $("#tree_view").treeView("expand", config.context.treeOpenBranches);
                                        config.context.getSelectList();
                                        _h.kocnx().headerSection.resetActiveSelectMenu(true);
                                        break;
                                    case "AdjustmentDocumentItem":
                                        if (!self.adjustmentId()) {
                                            self.refreshTable();
                                        } else {
                                            self.afterDelete(id, data.models);
                                            _h.kocnx().advm().callBackItemCountData(self.total());
                                        }
                                        break;
                                    case "Consolidate":
                                        self.selectedRowRecord(null);
                                        _h.kocnx().advm(null);
                                        self.afterDelete(id, data.models);
                                        break;
                                    case "Tree":
                                        _h.kocnx().treevm().resetTrees();
                                        self.afterDelete(id, data.models);
                                        break;
                                    default:
                                        self.afterDelete(id, data.models);
                                        break;
                                }
                                self.selectedRecord(null);
                                toast.success(self.entityName, 'del');
                                self.updateExtraParams(data);
                            }
                        },
                        messageType: 'del',
                        messageKey: self.entityName
                    });
                }
            });
    };
    self.afterDelete = function (id, models, searchDeep) {
        var group, record;
        if (!_h.isNullOrEmpty(self.groupProperty())) {
            for (var i = 0; i < self.records().length; i++) {
                var target = self.records()[i];
                if (_h.any(target.list())) {
                    for (var j = 0; j < target.list().length; j++) {
                        if (id === target.list()[j].id()) {
                            group = target;
                            record = target.list()[j];
                        }
                    }
                }
            }
            if (group && record) {
                group.list.remove(record);
            }
            self.removeEmptyFolders();
        } else {
            record = self.findRecord(id, searchDeep);
            if (record && record["children"]
                && !_h.isNullOrEmpty(record.pi()) && searchDeep) {
                var parent = record.parent();
                parent.children.remove(record);
                if (self.entityName === "Company" &&
                    (_h.isNullOrEmpty(self.searchKey()) || self.searchKey() === ""))
                    self.decreaseTotal();
            }
            if (record && !record["children"] || !searchDeep) {
                self.records.remove(record);
                self.decreaseTotal();
            }
        }
        if (_h.any(models)) {
            self.afterUpdate(models, searchDeep);
        }
    };
    self.getLastPriority = function (callback, id, e) {
        var model = {
            controllerName: self.controllerName,
            id: id
        };
        self.apiService.request({
            splashId: e,
            name: "getLastPriority",
            data: model,
            success: function (data) {
                callback(data);
            },
            error: function (data) {
                toast.error(self.entityName, 'get', 'LastPriority');
                callback(null);
            },
            messageType: 'get',
            messageKey: "LastPriority"
        });
    };
    self.upBtn = function () {
        var item = self.multiCommandExecute("selectedRowRecord");
        if (item.priority() < 1)
            return;
        self.changePriority(item, 1);
    };
    self.downBtn = function () {
        var item = self.multiCommandExecute("selectedRowRecord");
        self.changePriority(item, 2);
    };
    self.changePriority = function (item, action) {
        var model = {
            controllerName: self.controllerName,
            inputData: {
                direction: action,
                id: item.id()
            }
        };
        switch (self.entityName) {
            case "AdjustmentDocumentItem":
                model.inputData.amountType = self.amountType();
                break;
            case "MappingRule":
                model.inputData.treeId = config.context.treeId();
                model.inputData.balanceSheetId = config.context.balanceSheetId();
                break;
        }
        self.apiService.request({
            name: "putpriority",
            data: model,
            success: function (data) {
                if (!_h.isNullOrEmpty(data)) {
                    self.afterUpdate(data.models);
                    toast.success(self.entityName, 'putUpdate', 'ChangeOrder');
                    self.updateExtraParams(data);
                }
            },
            messageType: 'putUpdate',
            messageKey: "ChangeOrder"
        });
    };
    self.disableBtn = function () {
        var item = self.multiCommandExecute("selectedRowRecord");
        var idList = [];
        idList.push(item.id());
        self.changeStateList(idList, 0, item);
    };
    self.enableBtn = function () {
        var item = self.multiCommandExecute("selectedRowRecord");
        var idList = [];
        idList.push(item.id());
        self.changeStateList(idList, 1, item);
    };
    self.disablesBtn = function () {
        var idList = self.multiCommandExecute("selectedItemIds");
        if (idList.length === 0) {
            var text = _h.getApiMessage("ActionSelectListEmptyError");
            _h.warningToast(text);
        } else {
            self.changeStateList(idList, 0);
        }
    };
    self.enablesBtn = function () {
        var idList = self.multiCommandExecute("selectedItemIds");
        if (idList.length === 0) {
            var text = _h.getApiMessage("ActionSelectListEmptyError");
            _h.warningToast(text);
        } else {
            self.changeStateList(idList, 1);
        }
    };
    self.changeStateList = function (ids, action, itemTarget) {
        var model = {
            controllerName: self.controllerName,
            inputData: {
                idList: ids,
                stateType: action
            }
        };
        switch (self.entityName) {
            case "DynamicTableData":
                model.inputData.tableId = self.configTable.context.tableId();
                break;
            case "AdjustmentDocumentItem":
                model.inputData.amountType = self.amountType();
                break;
        }
        self.apiService.request({
            name: "putStateType",
            data: model,
            success: function (data) {
                if (!_h.isNullOrEmpty(data)) {
                    if (ids.length === 1)
                        toast.success(self.entityName, 'putUpdate', 'StateType');
                    if (ids.length > 1)
                        toast.success(self.entityName, 'putUpdate', 'StateTypes');
                    switch (self.entityName) {
                        case "Period":
                            self.multiCommandExecute("changesLocalStateType", action, ids);
                            break;
                        case "AdjustmentDocument":
                            self.multiCommandExecute("changesLocalStateType", action, ids);
                            if (ids.length === 1) {
                                config.context.changeChildModel(itemTarget, true);
                            }
                            break;
                        case "AdjustmentDocumentItem":
                            if (!self.adjustmentId()) {
                                self.refreshTable();
                            } else {
                                if (_h.any(data.models))
                                    for (var i = 0; i < data.models.length; i++) {
                                        var record = self.findRecord(data.models[i].id);
                                        if (record) {
                                            record.refreshModel(data.models[i]);
                                        }
                                    }

                            }
                            break;
                        case "Company":
                            self.multiCommandExecute("changesLocalStateType", action, ids);
                            config.context.collectOpenBranches();
                            config.context.configTools();
                            $("#tree_view").treeView("expand", config.context.treeOpenBranches);
                            break;
                        default:
                            self.multiCommandExecute("changesLocalStateType", action, ids);
                            break;
                    }
                    self.selectedRecord(null);
                    self.selectedRowRecord(null);
                    self.updateExtraParams(data);
                }
            },
            error: function (data) {
                if (ids.length === 1)
                    toast.error(self.entityName, 'putUpdate', 'StateType');
                if (ids.length > 1)
                    toast.error(self.entityName, 'putUpdate', 'StateTypes');
            }
        });
    };
    self.showBlockType = ko.observable("fullMaster");
    self.changeShowBlock = function (type, model, parent, g) {
        var item = self.multiCommandExecute("selectedRowRecord");
        if (!item)
            return;
        switch (type) {
            case "sideBySide":
                self.showType("List");
                self.showBlockType("sideBySide");
                config.context.changeChildModel(item);
                self.iconSize("icon-image-small");
                if (!_h.isNullOrEmpty(self.childModel()))
                    self.childModel().iconSize("icon-image-small");
                self.renderedHandler();
                setTimeout(function () {
                    $(".User-tbl").css("table-layout", "fixed")
                }, 100);
                break;
            case "fullMaster":
                self.showType("Table");
                self.showBlockType("fullMaster");
                self.iconSize("icon-image");
                if (!_h.isNullOrEmpty(self.childModel()))
                    self.childModel().iconSize("icon-image");
                if (self.entityName === "User") {
                    self.childModel(undefined);
                }
                $(".row-group").css("display", "none");
                self.renderedHandler();
                setTimeout(function () {
                    $(".row-group").css("display", "");
                    $(".User-tbl").css("table-layout", "auto")
                }, 100);
                break;
            case "fullDetails":
                self.showType("Table");
                self.showBlockType("fullDetails");
                self.iconSize("icon-image");
                if (!_h.isNullOrEmpty(self.childModel()))
                    self.childModel().iconSize("icon-image");
                self.renderedHandler();
                break;
        }
    }
    self.visibleColCount = ko.computed(function () {
        var count = 2;
        if (self.showType() === "Table")
            ko.utils.arrayFilter(self.tableProperties(), function (col) {
                if (col.visibleCol() === true) {
                    count++;
                }
            });
        else
            ko.utils.arrayFilter(self.tableProperties(), function (col) {
                if (col.visibleItem() === true) {
                    count++;
                }
            });

        return count;
    });
    self.menuItems = ko.computed(function () {
        if (!_h.any(self.configTable.buttons))
            return [];
        var array = [];
        var textPrefix = self.entityName.indexOf("Item") !== -1 ? "ItemCaption" : "Caption";
        for (var i = 0; i < self.configTable.buttons.length; i++) {
            if (self.configTable.buttons[i].cMenu)
                array.push({
                    visName: 'vis' + self.configTable.buttons[i].name,
                    text: _h.getLocalizedText(self.configTable.buttons[i].name + textPrefix, self.entityName),
                    visible: self['vis' + self.configTable.buttons[i].name](),
                    action: config.context[self.configTable.buttons[i].name + "Btn"],
                    icon: self.configTable.buttons[i].icon
                });
        }
        return array;
    });
    self.increaseTotal = function () {
        self.total(self.total() + 1);
    };
    self.decreaseTotal = function () {
        self.total(self.total() - 1);
    };
    self.removeEmptyFolders = function () {
        if (!_h.isNullOrEmpty(self.groupProperty())) {
            var rArray = [];
            if (_h.any(self.records())) {
                for (var i = 0; i < self.records().length; i++) {
                    var item = self.records()[i];
                    if (item.list().length === 0)
                        rArray.push(i);
                }
                if (_h.any(rArray))
                    for (var j = 0; j < rArray.length; j++) {
                        self.records.splice(rArray[j], 1);
                    }
            }
        }
    };
    self.colSpan = ko.observable();
    self.renderedHandler = function () {
        if (self.groupProperty()) {
            var en = self.entityName;
            var table = $("." + en + "-tbl");
            var colList = table.find("thead th:visible");
            self.colSpan(colList.length - 1);
        }
    };
}

