import { ApiService } from "../../util/apiService.js";
require('knockout.validation');
import { BaseModel, BaseFormModel, FormBuilder } from '../master/baseModels.js';
import { ReportPreview } from '../master/model.js';
import { BaseViewModel } from '../master/baseViewModel.js';
var Big = require("../../vendors/big.js");
export class AdjustmentDocument extends BaseModel {
    messageType = ko.observable(0);

    constructor(model) {
        super(model);
        this.styleRowValue = ko.pureComputed(function () {
            if (this.ineffective() === true && !_h.isNullOrEmpty(_h.kocnx().advm())
                && _h.kocnx().advm().viewMode() === "Edit")
                return 'color: #ccc;';
            if (this.messageType() === 1 && !_h.isNullOrEmpty(_h.kocnx().advm())
                && _h.kocnx().advm().viewMode() === "Edit")
                return 'color: red;';
            if (this.messageType() === 2 && !_h.isNullOrEmpty(_h.kocnx().advm())
                && _h.kocnx().advm().viewMode() === "Edit")
                return 'color: green;';
            return 'color: black;';
        }, this);
        this.isEditable = ko.pureComputed(function () {
            if (this.ineffective() === true || this.confirmationState() === 2 || this.stateType() === 0)
                return false;
            return true;
        }, this);
        this.tagsString = ko.computed(function () {
            var res = "";
            if (_h.any(this.tags()))
                for (let i = 0; i < this.tags().length; i++) {
                    var tag = this.tags()[i];
                    res += this.shortName(tag);
                    if (i + 1 !== this.tags().length)
                        res += "، ";
                }
            return res;
        }.bind(this));
    }

    shortName(name) {
        if (!name)
            return "";
        if (name.length < 20)
            return name;
        return name.substr(0, 17) + "...";
    };
}

export class AdjustmentDocumentForm extends BaseFormModel {
    constructor(viewModel, editMode, res) {
        super(viewModel, editMode, ["tags"]);
        this.lastPriority = ko.observable();
        this.selectTree = ko.observable();
        var context = _h.kocnx();
        this.tags = ko.observableArray();
        this.loginCompanyType = context.loginCompanyType();
        if (editMode) {
            this.lastPriority(res);
            var model = viewModel.multiCommandExecute("selectedRowRecord");
            if (context.loginCompanyType() === 0)
                this.defaultCompanyId(model.defaultCompanyId());
            if (model["balanceSheetId"]())
                this.balanceSheetId(model["balanceSheetId"]());
            var tags = ko.toJS(model.tags());
            this.tags(tags);
            for (let i = 0; i < this.parentVM.trees().length; i++) {
                if (this.treeId() === this.parentVM.trees()[i].value()) {
                    this.selectTree(this.parentVM.trees()[i]);
                }
            }
        } else {
            this.timeCreated(context.periodItem().te);
            this.lastPriority(res + 1);
            this.priority(res + 1);
            this.stateType(1);
            this.itemsCount = ko.observable(0);
        }

        this.disabledByItemsCount = ko.pureComputed(function () {
            return this.itemsCount() > 0;
        }.bind(this));
        this.setValidationObject();
        this.createForm();
    }

    onSelectTree(tree) {
        if (this.disabledByItemsCount())
            return;
        if (this.treeId() === tree.value()) {
            this.treeId(null);
            this.selectTree(null);

        } else {
            this.treeId(tree.value());
            for (let i = 0; i < this.parentVM.trees().length; i++) {
                if (tree.value() === this.parentVM.trees()[i].value()) {
                    this.selectTree(this.parentVM.trees()[i]);
                }
            }
        }
        if (this.loginCompanyType === 0) {
            this.defaultCompanyId(null);

        } else {
            for (let i = 0; i < this.selectTree().items().length; i++) {
                if ("تراز تجمیعی" === this.selectTree().items()[i].text()) {
                    this.selectTree().items()[i].selected(true);
                    this.balanceSheetId(this.selectTree().items()[i].value());
                }
            }
        }
    }

    onSelectItem(item) {
        if (this.disabledByItemsCount())
            return;
        var reset = false;
        if (this.loginCompanyType === 0)
            reset = this.defaultCompanyId() === item.value();

        if (this.loginCompanyType === 1)
            reset = this.balanceSheetId() === item.value();
        if (!reset) {
            item.selected(true);
            if (this.loginCompanyType === 0) {
                this.defaultCompanyId(item.value());
            } else {
                this.balanceSheetId(item.value());
            }
        } else {
            item.selected(false);
            this.defaultCompanyId(null);
            this.balanceSheetId(null);
        }

        for (let i = 0; i < this.selectTree().items().length; i++) {
            if (this.treeId() !== this.selectTree().items()[i].value()) {
                this.selectTree().items()[i].selected(false);
            }
        }
        return true;
    }

    setValidationObject() {
        var self = this;
        self.validationObject = ko.validatedObservable({
            title: self.title.extend({
                required: true,
                minLength: 3,
                maxLength: 100,
                validCharacterName: true,
                remoteIsUniqueRule: { params: [self.id, "AdjustmentDocument", "title"] }
            }),
            code: self.code.extend({
                minLength: {
                    params: 1,
                    message: "لطفاً حداقل 1 رقم وارد نمایید"
                },
                maxLength: {
                    params: 9,
                    message: "لطفاً حداکثر 9 رقم وارد نمایید"
                },
                numberOnly: null,
                remoteIsUniqueRule: { params: [self.id, "AdjustmentDocument", "code"] }
            }),
            timeCreated: self.timeCreated.extend({
                required: true,
                validation: [{
                    validator: function (val, someOtherVal) {
                        var activePeriod = _h.kocnx().periodItem();
                        var start = new Date(activePeriod.ts);
                        var timeEnd = new Date(activePeriod.te);
                        var date = new Date(val);
                        return date >= start && date <= timeEnd;
                    },
                    message: 'تاریخ ثبت سند باید در بازه تاریخ شروع و پایان دوره مالی جاری باشد'
                }]
            }),
            priority: self.priority.extend({
                required: true
            }),
            balanceSheetId: self.balanceSheetId.extend({
                required: {
                    onlyIf: function () {
                        return _h.kocnx().loginCompanyType() === 1 && !_h.isEmpty(self.selectTree()) && self.selectTree().treeType() !== 1;
                    }
                }
            }),
            treeId: self.treeId.extend({
                required: true,
            })
        });
    }

    createForm() {

        const controls = [
            this.createLine({
                t: 'tsp',
                val: this.priority,
                min: 1,
                max: this.editMode() === true ? this.lastPriority() : this.priority()
            },
                { t: 'txb', val: this.code }),
            this.createLine({ t: 'txb', val: this.title },
                null,
                true, 30),

            this.createLine({ t: 'tm', templateName: 'adjustmentdocument-treesection-form-t' }, undefined, true, 0, 0),
            this.createLine({ t: 'dpk', val: this.timeCreated, dateType: 'fa' },
                { t: 'slc', val: this.folderId, options: this.parentVM.folderList }, true, 30),
            this.createLine({
                t: 'slc',
                val: this.tags,
                options: this.parentVM.tagList,
                slcType: "multi",
                tagManager: true,
                renderFunc: _h.tagSelectRowTemplate,
            }, null, true, 30),
            this.createLine({ t: 'txa', val: this.description }, undefined, true, 30)
        ];
        this.formControls(controls);
        this.formButtons({
            name: 'footer-form-t', data: {
                buttons: [
                    { name: 'create', vis: !this.editMode(), click: this.parentVM.create },
                    { name: 'edit', vis: this.editMode, click: this.parentVM.edit },
                    { name: 'cancel', click: _h.kocnx().closeForm }]
            }
        });
    }
}

export class AdjustmentDocumentItem extends BaseModel {
    messageType = ko.observable(0);

    constructor(model) {
        super(model);
        this.styleRowValue = ko.computed(function () {
            if (this.ineffective() === true &&
                !_h.isNullOrEmpty(_h.kocnx().advm()) &&
                _h.kocnx().advm().viewMode() === "Edit")
                return 'color: #ccc;';
            if (this.isForNode() === true && !_h.isNullOrEmpty(_h.kocnx().brvm()))
                return 'color: green;';

            return 'color: #334455;';
        }, this);
    }
}

export function AdjustmentDocumentItemViewModel(mode) {
    var self = this;
    self.parentModel = "";
    self.caption = ko.observable();
    self.viewMode = ko.observable(mode);
    self.treeSelectList = ko.observableArray();
    self.afterFilterBy = function (data) {
        var context = _h.kocnx();
        if (self.amountType()) {
            clientStorage.setSetting(
                [{ key: "AdjustmentDocumentItem_amountType_" + context.loginCompanyType(), value: self.amountType() }]
            );
        } else {
            clientStorage.removeSetting("AdjustmentDocumentItem_amountType_" + context.loginCompanyType());
        }
    }
    self.getTree = function (text) {
        var name = "-";
        ko.utils.arrayFilter(self.treeSelectList(),
            function (item) {
                if (text === item.value)
                    name = item;
            });
        return name;
    }
    self.treeSelectConfig = function (item) {
        var model = self.getTree(item.text);
        return '<div>' +
            '<span class="item-title">' +
            '<span class="item-name">' +
            item.text +
            '</span>' +
            '<span class="item-valueType">' +
            _h.getEnumText(valueTypes, model.valueType) +
            '</span>' +
            '</span>' +
            '<ul class="item-meta">' +
            '<li class="item-type">' +
            model.type +
            '</li></ul></div>';
    };
    self.getFormInfo = function (adjustmentId, itemId, callback) {
        var model = {
            adjustmentId: adjustmentId || self.adjustmentId(),
            itemId: itemId
        };
        self.apiService.request({
            name: "getItemInfo",
            data: model,
            success: function (data) {
                callback(data);
            },
            error: function (message, level) {
                callback(false);
            }
        });
    }
    self.createBtn = function () {
        self.getFormInfo(undefined, undefined, function (data) {
            if (data) {
                _h.kocnx()
                    .openForm(new AdjustmentDocumentItemForm(self, false, data));
            }
        });
    }
    self.editBtn = function () {
        var model = self.multiCommandExecute("selectedRowRecord");
        self.getFormInfo(undefined, model.id(), function (data) {
            if (data) {
                _h.kocnx()
                    .openForm(new AdjustmentDocumentItemForm(self, true, data));
            }
        });
    }
    self.onAdjustmentIdClick = function () {
        self.adjustmentName("");
        self.adjustmentId(null);
        self.treeId(null);
        self.parentModel.changeShowBlock("fullDetails");
    }
    self.createFiltersList = function () {
        var array;
        if (self.viewMode() === "Edit") {
            array = [
                { name: 'adjustmentName', clear: false, toServer: false },
                { name: 'adjustmentId', clear: false },
                { name: 'adjustmentStateType' },
                { name: 'amount', type: "text" },
                { name: 'displayType' },
                { name: 'amountType' },
                { name: 'treeId', clear: false },
                { name: 'nodes', type: 'list' },
                { name: 'nodeIdList', type: 'list' },
                { name: 'codeRange' },
                { name: 'userId' },
                { name: 'repeated' },
                { name: 'justIneffective' },
                { name: 'accountType' },
                { name: 'stateType' },
                { name: 'folders', type: "list" },
                { name: 'tags', type: "list", def: [] }
            ];
            if (_h.kocnx().loginCompanyType() === 0) {
                array.push({
                    name: 'companies',
                    type: 'list'
                });
                array.push({
                    name: 'companyId'
                });
                array.push({
                    name: 'consolidationCompany'
                });
            }
        } else {
            array = [
                { name: 'adjustmentName', clear: false, toServer: false },
                { name: 'adjustmentId', clear: false },
                { name: 'amountType', clear: false },
                { name: 'amount' },
                { name: 'displayType' },
                { name: 'treeId', clear: false },
                { name: 'nodeId', clear: false },
                { name: 'userId' },
                { name: 'repeated' },
                { name: 'codeRange' },
                { name: 'showAll', def: false },
                { name: 'folders', type: "list" },
                { name: 'tags', type: "list", def: [] }
            ];
            if (_h.kocnx().loginCompanyType() === 0)
                array.push({
                    name: 'companyId'
                });
        }
        return array;
    }
    self.createColList = function () {
        var array = [];
        for (var p in adjustmentdocumentitemModelRes) {
            if (adjustmentdocumentitemModelRes.hasOwnProperty(p)) {
                var target = adjustmentdocumentitemModelRes[p];
                if (_h.kocnx().loginCompanyType() === 0) {
                    array.push(target);
                } else {
                    if (target.colName !== "companyName")
                        array.push(target);
                }
            }
        }
        return array;
    }
    self.toggleShowAll = function () {
        self.showAll(!self.showAll());
        self.getRecords();
    }
    self.downloadReportBtn = function () {
        var filters = self.createFilterByModel();
        var model = {
            inputData: filters,
            controllerName: 32
        };
        self.apiService.request({
            name: "/api/filegenerator/postreportpreview",
            data: model,
            success: function (data) {
                if (!_h.isNullOrEmpty(data)) {
                    _h.kocnx()
                        .openForm(new ReportPreview(self, { columns: data.columns, rows: data.rows, controllerName: 32 }));
                }
            },
            error: function (message, level) {
            }
        });
    }
    self.downloadReport = function (parents, btnModel, e) {
        var item = parents[1];
        var model = item.toServer();
        model.inputData = self.createFilterByModel();
        self.apiService.request({
            splashId: e,
            name: "/api/filegenerator/postreport",
            data: model,
            success: function (data) {
                if (!_h.isNullOrEmpty(data)) {
                    _h.kocnx().closeForm();
                    _h.downloadFile(data.model);
                }
            },
            error: function (message, level) {
                var text = _h.getApiMessage("GetFileError");
                _h.failToast(text);
            }
        });
    }
    self.createButtonList = function () {
        var array;
        if (self.viewMode() === "Edit") {
            array = [
                { name: 'edit', access: true, icon: 'Edit', cMenu: true },
                { name: 'delete', access: true, icon: 'Delete', cMenu: true },
                { name: 'disable', access: true, icon: 'DocDisable', cMenu: true },
                { name: 'enable', access: true, icon: 'DocEnable', cMenu: true },
                { name: 'disables', access: true, icon: 'DocsDisable', cMenu: true },
                { name: 'enables', access: true, icon: 'DocsEnable', cMenu: true },
                { name: 'downloadReport', access: true, icon: 'ReportDownload', cMenu: true },
                { name: 'up', access: true, icon: 'Up', cMenu: true },
                { name: 'down', access: true, icon: 'Down', cMenu: true },
                { name: 'help', access: false, cMenu: false },
                { name: 'refresh', access: false, cMenu: false },
                { name: 'tools', access: false, cMenu: false },
                { name: 'create', access: true, cMenu: false }
            ];
        } else {
            array = [
                { name: 'showAllSw', access: false, cMenu: false, templateName: "showAll-item-button-template" },
                { name: 'help', access: false, cMenu: false },
                { name: 'refresh', access: false, cMenu: false },
                { name: 'tools', access: false, cMenu: false }
            ];
        }
        return array;
    }
    ko.utils.extend(self, new BaseViewModel({
        entityName: "AdjustmentDocumentItem",
        filters: self.createFiltersList(),
        buttons: self.createButtonList(),
        apiService: {
            actionList: ["filterby", "post", "put", "delete", "getiteminfo"]
        },
        extraParams: ["lastPriority", "itemsCount", "totalDebtor", "totalCreditor",
            "variance", "searchProfiles"],
        parentParams: ["treeId", "balanceSheetId", "defaultCompanyId",
            "ineffective", "isRightEdit", "parentConfirmationState"],
        sortDirection: "Ascending",
        filterBoxTemplate: "adjustmentitem-filter-box-template",
        sortProperty: "priority",
        context: self,
        saveState: true,
        cols: self.createColList(),
        isMultiSelectRows: self.viewMode() === "Edit",
        selectRow: true,
        contextMenu: true,
        getList: true,
        searchKeyType: "enter",
        styleRow: "styleRowValue",
        tableClass: "table ko-tbl ko-tbl-child",
        tableStyle: "margin-top:10px;font-size:11px;",
        footerTemplate: "adjustmentdocumentitem-footertable-template",
        filterProfile: true,
        resizable: true
    }));
    if (self.viewMode() === "Edit") {
        self.btnVisibility = ko.computed(function () {
            var context = _h.kocnx();
            var adjustmentId = self.adjustmentId();
            var permitPeriodEdit = context.permitPeriodEdit();
            var inListView = self.showType() === "List";
            var isRightEdit = self.isRightEdit();
            var notIneffective = !self.ineffective();
            var data = self.multiCommandExecute("btnVisibilityData3");
            if (_h.isNullOrEmpty(data))
                return;
            var temp = data[0];
            var enableCount = data[1];
            var disableCount = data[2];
            var selectedList = data[3];
            if (selectedList === 0) {
                self.visedit(false);
                self.visdelete(false);
                self.visup(false);
                self.visdown(false);
                self.visdisable(false);
                self.visenable(false);
                self.visdisables(false);
                self.visenables(false);
            }
            if (selectedList === 1) {
                var item = self.getSelectedRecord();
                if (item === null || item === undefined)
                    item = temp;
                var notItemIneffective = !item.ineffective();

                self.visedit(permitPeriodEdit && isRightEdit && notIneffective
                    && notItemIneffective && item.stateType() === 1);
                self.visdelete(permitPeriodEdit && self.parentConfirmationState() !== 2);

                self.visdisable(permitPeriodEdit && disableCount >= 0
                    && enableCount > 0 && !inListView);
                self.visenable(permitPeriodEdit && disableCount >= 0
                    && enableCount === 0 && !inListView);
                if (!adjustmentId) {
                    self.visedit(self.visedit() && item.editable());
                    self.visdelete(self.visdelete() && item.removable());
                    self.visdisable(self.visdisable() && item.stateTypeEditable());
                    self.visenable(self.visenable() && item.stateTypeEditable());
                }

                self.visup(permitPeriodEdit && isRightEdit && notIneffective
                    && item.priority() > 1 && notItemIneffective && !_h.isNullOrEmpty(adjustmentId));
                self.visdown(permitPeriodEdit &&
                    isRightEdit && notIneffective &&
                    self.lastPriority() !== item.priority() && notItemIneffective && !_h.isNullOrEmpty(adjustmentId));
                self.visdisables(false);
                self.visenables(false);
            }
            if (selectedList > 1) {
                self.visedit(false);
                self.visdelete(false);
                self.visup(false);
                self.visdown(false);
                self.visdisable(false);
                self.visenable(false);
                self.visdisables(permitPeriodEdit && disableCount >= 0
                    && enableCount > 0 && !inListView);
                self.visenables(permitPeriodEdit && disableCount >= 0
                    && enableCount === 0 && !inListView);
            }
            self.vishelp(true);
            self.visrefresh(true);
            self.vistools(true);
            self.visdownloadReport(true);
            self.viscreate(permitPeriodEdit && notIneffective && isRightEdit);
        });
        self.loadClientSideFilterData = function () {
            var context = _h.kocnx();
            var amountType = clientStorage.getSetting("AdjustmentDocumentItem_amountType_" + context.loginCompanyType());
            if (amountType) {
                self.amountType(Number(amountType));
            }
        };
    }
    else {
        self.btnVisibility = ko.computed(function () {
            self.vishelp(true);
            self.visrefresh(true);
            self.vistools(true);
        });
    }
    self.init = function () {
        self.fillTableProperties();
        if (self.viewMode() === "Edit") {
            self.loadClientSideFilterData();
        }
        self.getRecords();
    }
    self.onNodeSelect = function (name, list) {
        self.nodes.removeAll();
        self.nodeIdList.removeAll();
        if (_h.any(list)) {
            for (var i = 0; i < list.length; i++) {
                var target = list[i];
                self.nodes.push(target);
                self.nodeIdList.push(target.value);
            }
        }
    }
    self.onSelectNodeSelector = function (name, list) {
        if (_h.any(list)) {
            for (var i = 0; i < list.length; i++) {
                var isExist = false;
                var target = list[i];
                if (_h.any(self.nodes()))
                    for (var j = 0; j < self.nodes().length; j++) {
                        if (self.nodes()[j].value === target.value)
                            isExist = self.nodes()[j];
                    }
                if (!isExist) {
                    self.nodes.push(list[i]);
                    self.nodeIdList.push(list[i].value);
                }
            }
        } else {
            self.nodes.removeAll();
            self.nodeIdList.removeAll();
        }
        setTimeout(function () {
            $(".adjastment-item-filter").parent(".dropdown").addClass("open");
        }, 100);
    }
    self.updateFilterProfileBtn = function (m, event) {
        event.stopPropagation();
        self.updateFilterProfile(32);
    }
    self.refreshNodes = ko.observable(false);
    self.clearSearchBoxes = function () {
        self.activeFilterProfile(null);
        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")) {
                    if (target.name !== "adjustmentId" && target.name !== "adjustmentName")
                        self[target.name](target.def);
                }
                if (_h.isNullOrEmpty(target["clear"]) && (target.type && target.type === "list"))
                    self[target.name].removeAll();
            }
        }
        self.refreshNodes(true);
        self.refreshNodes(false);
        if (self.viewMode() === "Edit")
            self.loadClientSideFilterData();
        self.inputFilterProfile("");
        self.searchKey("");
        self.pageNumber(1);

        self.getRecords();
    }
    self.activeFilterProfile.subscribe(function (newValue) {
        if (!_h.isNullOrEmpty(newValue)) {
            var item = self.getFilterProfile(newValue);
            if (item) {
                for (var p in item.filters) {
                    if (item.filters.hasOwnProperty(p)) {
                        var val = item.filters[p];
                        var filter = self[p];
                        if (filter) {
                            if (p === "nodes") {
                                var dupArray = JSON.parse(JSON.stringify(val));
                                filter(dupArray);
                                self.refreshNodes(true);
                                self.refreshNodes(false);
                            } else if (p === "nodeIdList") {
                                var nodeIdList = JSON.parse(JSON.stringify(val));
                                filter(nodeIdList);
                            } else if (p === "companies") {
                                var companies = JSON.parse(JSON.stringify(val));
                                filter(companies);
                            } else {
                                filter(val);
                            }
                        }
                    }
                }
            }
        }
    });
}

export class AdjustmentDocumentItemForm extends FormBuilder {
    constructor(viewModel, editMode, data) {
        super();
        this.entityName = "AdjustmentDocumentItemForm";
        this.width = "45%";
        this.defaultCompanyId = ko.observable(viewModel.defaultCompanyId());
        this.startDance = ko.observable(false);
        this.editMode = ko.observable(editMode);
        this.caption = ko.observable(!this.editMode() ?
            _h.getLocalizedText('createItemCaption') :
            _h.getLocalizedText('editItemCaption'));
        this.parentVM = viewModel;
        this.createProperties();
        this.allowInputDecimal = ko.pureComputed(function () {
            return this.currencyType() === 2 && this.adjustmentItemType() === 1;
        }.bind(this));
        this.creditor = ko.observable(data.creditor).extend({
            inputNumberFormatter: {
                negative: false,
                decimalNumber: this.allowInputDecimal,
                callback: this.creditorChanged.bind(this)
            }
        });
        this.debtor = ko.observable(data.debtor).extend({
            inputNumberFormatter: {
                negative: false,
                decimalNumber: this.allowInputDecimal,
                callback: this.debtorChanged.bind(this)
            }
        });
        this.fillModel(data);
        this.visAdjustmentId = ko.pureComputed(function () {
            return _h.isNullOrEmpty(this.adjustmentId()) || this.adjustmentId() === 0;
        }.bind(this));
        this.disableRefreshInfo = false;
        this.oldAdjustmentId = this.adjustmentId();
        this.adjustmentId.subscribe(function (newValue) {
            if (!_h.isNullOrEmpty(newValue) && newValue !== this.oldAdjustmentId) {
                this.parentVM.getFormInfo(newValue, undefined, function (dataInfo) {
                    this.disableRefreshInfo = true;
                    this.fillModel(dataInfo);
                    this.startDance(!this.startDance());
                    this.disableRefreshInfo = false;
                }.bind(this));
            }
        }.bind(this));
        this.visAdjustmentItemType = ko.pureComputed(function () {
            return !this.editMode() && !_h.isNullOrEmpty(this.treeType());
        }.bind(this));
        this.visCompanyId = ko.observable(false);
        this.disabledCompanyId = ko.computed(function () {
            var x = this.startDance();
            if (_h.kocnx().loginCompanyType() === 0) {
                this.visCompanyId(true);
                var id;
                if (this.treeType() === 0) {
                    id = this.defaultCompanyId();
                    if (!_h.isNullOrEmpty(id)) {
                        this.companyId(id);
                        return true;
                    } else {
                        return false;
                    }
                }
                if (this.treeType() === 1) {
                    id = _h.kocnx().loginCompanyId();
                    this.companyId(id);
                    return true;
                }
            } else {
                this.visCompanyId(false);
                return true;
            }
        }.bind(this));
        this.disableNodeId = ko.pureComputed(function () {
            return _h.isNullOrEmpty(this.treeId()) || this.treeId() === 0;
        }.bind(this));
        this.visNodeId = ko.computed(function () {
            switch (this.adjustmentItemType()) {
                case 2:
                    return _h.kocnx().loginCompanyType() !== 0
                        || !_h.isNullOrEmpty(this.defaultCompanyId())
                        || !_h.isNullOrEmpty(this.companyId());
                default:
                    return true;
            }
        }.bind(this));
        this.visIsConditional = ko.pureComputed(function () {
            return this.adjustmentItemType() === 2;
        }.bind(this));
        this.visBaseFormula = ko.computed(function () {
            return this.adjustmentItemType() === 2 && this.visNodeId() && this.isConditional() === false;
        }.bind(this));
        this.visOtherFormula = ko.computed(function () {
            return this.adjustmentItemType() === 2 && this.visNodeId() && this.isConditional();
        }.bind(this));
        this.isManualDocument = ko.computed(function () {
            return this.adjustmentItemType() === 1 || this.adjustmentItemType() === 3;
        }.bind(this));
        this.oldRemainedFormated = ko.pureComputed(function () {
            return _h.formatNumber(this.oldRemained());
        }.bind(this));
        this.newRemainedFormated = ko.pureComputed(function () {
            return _h.formatNumber(this.newRemained());
        }.bind(this));
        this.conditionalOperator.subscribe(function (newValue) {
            if (newValue !== undefined && newValue !== null && newValue > 0) {
                if (newValue === 7 || newValue === 8) {
                    this.isDisableRightSide(true);
                } else {
                    this.isDisableRightSide(false);
                }
            }
        }.bind(this));
        this.companyId.subscribe(function (newValue) {
            if (newValue !== undefined && newValue !== null) {
                this.getNodeAmount();
            }
        }.bind(this));
        this.treeType.subscribe(function (newValue) {
            switch (newValue) {
                case 0:
                    this.adjustmentItemTypeList(adjustmentItemTypes);
                    break;
                case 1:
                    this.adjustmentItemTypeList(adjustmentItemTypes2);
                    break;
                case "":
                case undefined:
                case null:
                    this.adjustmentItemTypeList([]);
                    break;
            }
        }.bind(this));
        this.treeType.valueHasMutated();
        this.createForm();
    }

    createProperties() {
        let paramList = [
            { name: "adjustmentList", type: "obar" },
            { name: "adjustmentItemTypeList", type: "obar" },
            { name: "adjustmentId", type: "ob" },
            { name: "adjustmentItemType", type: "ob" },
            { name: "id", type: "ob" },
            { name: "treeId", type: "ob" },
            { name: "treeType", type: "ob" },
            { name: "nodeId", type: "ob" },
            { name: "lastPriority", type: "ob" },
            { name: "priority", type: "ob" },
            { name: "code", type: "ob" },
            { name: "description", type: "ob" },
            { name: "nodeName", type: "" },
            { name: "nodeAccountType", type: "ob" },
            { name: "companyType", type: "ob", val: _h.kocnx().loginCompanyType() },
            { name: "balanceSheetId", type: "ob" },
            { name: "companyId", type: "ob" },
            { name: "accountType", type: "ob" },
            { name: "timeCreated", type: "ob" },
            { name: "firstInputValue", type: "ob" },
            { name: "currencyType", type: "ob" },
            { name: "nodeAmount", type: "ob" },
            { name: "oldRemained", type: "ob" },
            { name: "newRemained", type: "ob" },
            { name: "isDisableCreditor", type: "ob", val: false },
            { name: "isDisableDebtor", type: "ob", val: false },
            { name: "isConditional", type: "ob" },
            { name: "conditionalOperator", type: "ob" },
            { name: "leftSidePhrase", type: "ob" },
            { name: "rightSidePhrase", type: "ob" },
            { name: "baseFormula", type: "ob" },
            { name: "ifTrueFormula", type: "ob" },
            { name: "ifFalseFormula", type: "ob" },
            { name: "isDisableRightSide", type: "ob" }
        ];
        _autoMapper.createPropsFromList(this, paramList);
    }

    fillModel(data) {
        var creditor = _h.clearNumber(data.creditor);
        var debtor = _h.clearNumber(data.debtor);
        for (let property in data) {
            if (this[property]) {
                switch (property) {
                    case "creditor":
                        this[property](creditor);
                        break;
                    case "debtor":
                        this[property](debtor);
                        break;
                    case "lastPriority":
                        this[property](data.lastPriority);
                        break
                    case "priority":
                        this[property](this.editMode() ? data.priority : data.lastPriority + 1);
                        break;
                    default:
                        this[property](data[property]);
                        break;
                }
            }
        }
        this.nodeName = data.nodeName;
        if (Big(debtor).eq(0)) {
            this.isDisableCreditor(false);
            this.isDisableDebtor(true);
            if (this.nodeAccountType() === 1)
                this.firstInputValue(creditor);
            if (this.nodeAccountType() === 2)
                this.firstInputValue("-" + creditor);
        }
        if (Big(creditor).eq(0)) {
            this.isDisableCreditor(true);
            this.isDisableDebtor(false);
            if (this.nodeAccountType() === 1)
                this.firstInputValue("-" + debtor);
            if (this.nodeAccountType() === 2)
                this.firstInputValue(debtor);
        }
        if (Big(creditor).eq(0) && Big(debtor).eq(0)) {
            this.isDisableCreditor(false);
            this.isDisableDebtor(false);
        }

        if (data.adjustmentItemType) {
            this.getNodeAmount();
        }

        if (!this.adjustmentId()) {
            this.getAdjustmentList();
        }
        this.setValidationObject();
    }

    creditorChanged(number) {
        if (!_h.isNullOrEmpty(number) && number !== "" && number !== "0") {
            this.isDisableDebtor(true);
            this.isDisableCreditor(false);
        }
        if (!_h.isNullOrEmpty(number) && (number === "" || number === "0")) {
            this.isDisableDebtor(false);
            this.isDisableCreditor(false);
        }
        this.calculateNewRemained(number, 1);
    }

    debtorChanged(number) {
        if (!_h.isNullOrEmpty(number) && number !== "" && number !== "0") {
            this.isDisableDebtor(false);
            this.isDisableCreditor(true);
        }
        if (!_h.isNullOrEmpty(number) && (number === "" || number === "0")) {
            this.isDisableDebtor(false);
            this.isDisableCreditor(false);
        }
        this.calculateNewRemained(number, 2);
    }

    onNodeSelect(name, value, itemValue) {
        this.nodeId(value);
        switch (this.adjustmentItemType()) {
            case 3:
            case 1:
                if (!_h.isNullOrEmpty(value)) {
                    this.getNodeAmount();
                } else {
                    this.oldRemained(undefined);
                    this.newRemained(undefined);
                    this.creditor(0);
                    this.debtor(0);
                }
                break;
            case 2:
                if (!_h.isNullOrEmpty(value)) {
                    var context = _h.kocnx();
                    var val = null;
                    if (this.companyType() === 0) {
                        val = "[node:" + itemValue.code + "-" + this.companyId() + "-B]";
                    } else
                        val = "[node:" + itemValue.code + "]";

                    this.ifTrueFormula(val);
                    this.ifFalseFormula(val);
                    this.leftSidePhrase(val);
                    this.baseFormula(val);
                    this.rightSidePhrase(val);
                }
                break;
        }
    }

    getNodeAmount() {
        if (_h.isNullOrEmpty(this.nodeId()) || this.nodeId() === "")
            return;
        var model = {
            treeId: this.treeId(),
            nodeId: this.nodeId(),
            companyId: this.companyId(),
            adjustmentId: this.adjustmentId(),
            balanceSheetId: this.balanceSheetId()
        };

        ApiService.request(
            {
                url: "/api/adjustmentdocumentitem/getnodeamount",
                data: model,
                success: function (data) {
                    var number1, number2, resP;
                    var ba = _h.clearNumber(data.balance);
                    if (this.editMode() === false) {
                        this.nodeAmount(data);
                        this.newRemained(ba);
                        this.oldRemained(ba);
                        this.nodeAccountType(data.accountType);

                        if (Big(this.creditor()).gt(0)) {
                            this.calculateNewRemained(this.creditor(), 1);
                        }
                        if (Big(this.debtor()).gt(0)) {
                            this.calculateNewRemained(this.debtor(), 2);
                        }
                        if (Big(this.creditor()).eq(0) && Big(this.debtor()).eq(0)) {
                            this.newRemained(this.oldRemained());
                        }
                    } else {
                        this.nodeAccountType(data.accountType);
                        this.nodeAmount(data);
                        this.newRemained(ba);
                        if (this.firstInputValue() !== 0) {
                            number1 = new Big(ba);
                            number2 = new Big(this.firstInputValue());
                            resP = number1.minus(number2).toString();
                            this.oldRemained(resP);
                            this.firstInputValue(0);
                        } else {
                            this.oldRemained(ba);
                        }
                        if (Big(this.creditor()).gt(0)) {
                            this.calculateNewRemained(this.creditor(), 1);
                        }
                        if (Big(this.debtor()).gt(0)) {
                            this.calculateNewRemained(this.debtor(), 2);
                        }
                        if (Big(this.creditor()).eq(0) && Big(this.debtor()).eq(0)) {
                            this.newRemained(this.oldRemained());
                            this.isDisableCreditor(false);
                            this.isDisableDebtor(false);
                        }
                    }
                }.bind(this),
                error: function (data) {
                    var text = _h.getApiMessage("LoadTreeNodeAmountError");
                    _h.failToast(text);
                }
            });
    }

    calculateNewRemained(value, inputAccountType) {
        if (value === null || value === "" || value === "-" || value === "0" || value === undefined)
            value = 0;
        if (this.oldRemained() === null || this.oldRemained() === undefined)
            this.oldRemained(0);
        var numberInput = new Big(value);
        var old = new Big(this.oldRemained());
        var res;
        if (inputAccountType === this.nodeAccountType())
            res = old.plus(numberInput).toString();
        else
            res = old.minus(numberInput).toString();
        this.newRemained(res);
    }

    setValidationObject() {
        var self = this;
        self.validationObject = ko.validatedObservable({
            adjustmentItemType: self.adjustmentItemType.extend({
                required: true
            }),
            treeId: self.treeId.extend({
                required: true,
            }),
            nodeId: self.nodeId.extend({
                required: true,
            }),
            companyId: self.companyId.extend({
                required: {
                    onlyIf: function () {
                        return self.companyType() === 0;
                    }
                }
            }),
            balanceSheetId: self.balanceSheetId.extend({
                required: {
                    onlyIf: function () {
                        return self.companyType() === 1 && self.treeType() === 0;
                    }
                }
            }),
            creditor: self.creditor.extend({
                number: true,
                onlyTenDigitDecimal: true,
                max29Digit: true,
                required: {
                    onlyIf: function () {
                        return (self.adjustmentItemType() === 1 || self.adjustmentItemType() === 3) && (self.debtor() === null || self.debtor() === undefined || self.debtor() < 1);
                    }
                }
            }),
            debtor: self.debtor.extend({
                number: true,
                onlyTenDigitDecimal: true,
                max29Digit: true,
                required: {
                    onlyIf: function () {
                        return (self.adjustmentItemType() === 1 || self.adjustmentItemType() === 3) && (self.creditor() === null || self.creditor() === undefined || self.creditor() < 1);
                    }
                }
            }),
            code: self.code.extend({
                minLength: {
                    params: 1,
                    message: "لطفاً حداقل 1 رقم وارد نمایید"
                },
                maxLength: {
                    params: 9,
                    message: "لطفاً حداکثر 9 رقم وارد نمایید"
                },
                numberOnly: null,
                remoteIsUniqueRule: { params: [self.id, "AdjustmentDocumentItem", "code", self.adjustmentId ] }
            }),
            priority: self.priority.extend({
                required: true
            }),
            baseFormula: self.baseFormula.extend({
                required: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === false;
                    }
                },
                remoteIsValidateFormula: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === false;
                    },
                    params: 32
                }
            }),
            rightSidePhrase: self.rightSidePhrase.extend({
                required: {
                    onlyIf: function () {
                        if (self.adjustmentItemType() !== 2 || self.isConditional() !== true)
                            return false;
                        return self.conditionalOperator() !== 7 && self.conditionalOperator() !== 8 && self.conditionalOperator() !== 0;
                    }
                },
                remoteIsValidateFormula: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === true;
                    },
                    params: 32
                }
            }),
            leftSidePhrase: self.leftSidePhrase.extend({
                required: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === true;
                    }
                },
                remoteIsValidateFormula: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === true;
                    },
                    params: 32
                }
            }),
            conditionalOperator: self.conditionalOperator.extend({
                required: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === true;
                    }
                }
            }),
            ifTrueFormula: self.ifTrueFormula.extend({
                required: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === true;
                    }
                },
                remoteIsValidateFormula: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === true;
                    },
                    params: 32
                }
            }),
            ifFalseFormula: self.ifFalseFormula.extend({
                required: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === true;
                    }
                },
                remoteIsValidateFormula: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2 && self.isConditional() === true;
                    },
                    params: 32
                }
            }),
            accountType: self.accountType.extend({
                required: {
                    onlyIf: function () {
                        return self.adjustmentItemType() === 2;
                    }
                },
            }),

        });
    }

    toggleIsConditional() {
        this.isConditional(!this.isConditional());
    }

    getAdjustmentList() {
        ApiService.request(
            {
                url: "/api/adjustmentdocument/getadjustmentselectlist",
                success: function (list) {
                    if (_h.any(list)) {
                        for (let i = 0; i < list.length; i++) {
                            this.adjustmentList.push(new SelectItem(list[i]));
                        }
                    }
                }.bind(this),
                error: function (data) {
                }
            });
    }

    onChangeFormula(value, name) {
        this[name](value);
    }

    createForm() {
        const controls = [
            this.createLine({
                t: 'slc',
                val: this.adjustmentId,
                options: this.adjustmentList
            }, null, this.visAdjustmentId, 30),
            this.createLine({
                t: 'slc',
                val: this.adjustmentItemType,
                options: this.adjustmentItemTypeList
            }, null, this.visAdjustmentItemType, 30),
            this.createLine({
                t: 'slc',
                val: this.companyId,
                options: _h.kocnx().advm().companies,
                dis: this.disabledCompanyId
            }, null, this.visCompanyId, 30),
            this.createLine({
                t: 'tsp', val: this.priority, min: 1,
                max: this.editMode() === true ? this.lastPriority() : this.priority()
            }, { t: 'txb', val: this.code }, true, 30),
            this.createLine({
                t: 'slcn', treeId: this.treeId, slcType: "single", branchSelectable: false, val: this.nodeId,
                valName: this.nodeName, dis: this.disableNodeId, location: "AutomaticAdjustmentDocumentItem"
            }, undefined, this.visNodeId, 30),
            this.createLine({
                t: 'chk',
                val: this.isConditional,
                click: this.toggleIsConditional
            }, undefined, this.visIsConditional, 30),
            this.createLine({ t: 'slcfm', val: this.baseFormula }, null, this.visBaseFormula, 30),
            this.createLine({ t: 'slcfm', val: this.rightSidePhrase }, null, this.visOtherFormula, 30),
            this.createLine({
                t: 'slc',
                val: this.conditionalOperator,
                options: conditionalOperators
            }, null, this.visOtherFormula, 30),
            this.createLine({ t: 'slcfm', val: this.leftSidePhrase }, null, this.visOtherFormula, 30),
            this.createLine({ t: 'slcfm', val: this.ifTrueFormula }, null, this.visOtherFormula, 30),
            this.createLine({ t: 'slcfm', val: this.ifFalseFormula }, null, this.visOtherFormula, 30),
            this.createLine({ t: 'slc', val: this.accountType, options: accountTypes }, null, this.visIsConditional, 30),
            this.createLine({ t: 'txf', val: this.debtor, dis: this.isDisableDebtor },
                { t: 'txf', val: this.creditor, dis: this.isDisableCreditor }, this.isManualDocument, 30),
            this.createLine({
                t: 'tm',
                templateName: 'adjustmentdocumentitem-remainedformated-form-t'
            }, undefined, true, 0, 0),
            this.createLine({ t: 'txa', val: this.description }, undefined, true, 30)
        ];
        this.formControls(controls);
        this.formButtons({
            name: 'footer-form-t', data: {
                buttons: [
                    { name: 'create', vis: !this.editMode(), click: this.parentVM.create },
                    { name: 'edit', vis: this.editMode, click: this.parentVM.edit },
                    { name: 'cancel', click: _h.kocnx().closeForm }]
            }
        });
    }

    toServer() {
        let amendmentItem = ko.toJS(this);
        amendmentItem.nodeSelectModeForm = null;
        amendmentItem.nodeAmount = null;
        amendmentItem.amountType = this.parentVM.amountType();
        delete amendmentItem["validationObject"];
        delete amendmentItem["formButtons"];
        delete amendmentItem["formControls"];
        delete amendmentItem["parentVM"];
        delete amendmentItem["editMode"];
        delete amendmentItem["ad"];
        delete amendmentItem["selected"];
        delete amendmentItem["ruleModel"];

        return amendmentItem;
    }
}