VaKeR CYBER ARMY
Logo of a company Server : Apache/2.4.41 (Ubuntu)
System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64
User : www-data ( 33)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Directory :  /var/www/html/keeview_app/html/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /var/www/html/keeview_app/html/contact.js
hr.contact.searchDataFunc = function(filter, host){
    return new Promise(function(resolve, reject){
        var func1 = function(){
            var searchValue = filter.searchValue.toLowerCase();
            var nvnText = absol.string.nonAccentVietnamese(searchValue);
            var words = searchValue.split(/[\s,\\.]+/);
            var wordDict = words.reduce(function(ac, cr){
                ac[cr] = true;
                return ac;
            }, {})
            var extraParams = {
                words: words,
                nvnWords: nvnText.split(/[\s,\\.]+/),
                text: searchValue,
                nvnText: nvnText,
                wordDict: wordDict,
                filter: {
                    marked_value: filter.marked_value
                },
                markedDic: filter.markedDic
            };
            data_module.cacheContent_contacts.psearch({
                searchFunc: function (record){
                    if (extraParams.filter.marked_value && !extraParams.markedDic[record.id]) return null;
                    if (extraParams.text === "") return {
                        id: record.id,
                        icld: true,
                        name: record.name
                    };
                    function harmonicMean(a, b) {
                        return 2 / (1 / a + 1 / b);
                    }
                    function wordLike(a, b) {
                        var m = a.length;
                        var n = b.length;

                        function map(i, j) {
                            return i * (n + 1) + j;
                        }

                        var Q = Array((m + 1) * (n + 1)).fill(0);

                        for (var i = 0; i < m; ++i)
                            for (var j = 0; j < n; ++j)
                                if (a.charAt(i) === b.charAt(j)) {
                                    if (Q[map(i + 1, j + 1)]) {
                                        if (Q[map(i + 1, j + 1)] < Q[map(i, j)] + 1)
                                            Q[map(i + 1, j + 1)] = Q[map(i, j)] + 1;
                                    }
                                    else
                                        Q[map(i + 1, j + 1)] = Q[map(i, j)] + 1;
                                }
                                else
                                    Q[map(i + 1, j + 1)] = Math.max(Q[map(i + 1, j)], Q[map(i, j + 1)]);

                        return Q[map(m, n)] / harmonicMean(m, n);
                    }


                    function wordsMatch(sq1, sq2, matchWordPow) {
                        matchWordPow = matchWordPow === undefined ? 1 : matchWordPow;

                        var m = sq1.length;
                        var n = sq2.length;

                        function map(i, j) {
                            return i * (n + 1) + j;
                        }

                        var Q = Array((m + 1) * (n + 1)).fill(0);
                        var e = 0.0;
                        for (var i = 0; i < m; ++i)
                            for (var j = 0; j < n; ++j) {
                                e = Math.pow(wordLike(sq1[i], sq2[j]), matchWordPow);

                                if (Q[map(i + 1, j + 1)]) {
                                    if (Q[map(i + 1, j + 1)] < Q[map(i, j)] + e)
                                        Q[map(i + 1, j + 1)] = Q[map(i, j)] + e;

                                }
                                else
                                    Q[map(i + 1, j + 1)] = Q[map(i, j)] + e;

                                e = Math.max(Q[map(i + 1, j)], Q[map(i, j + 1)]);
                                if (e > Q[map(i + 1, j + 1)]) Q[map(i + 1, j + 1)] = e;

                            }

                        return Q[map(m, n)]/Math.max(harmonicMean(m, n), 1);
                    }

                    function nonAccentVietnamese(s) {
                        return s.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, "a")
                            .replace(/À|Á|Ạ|Ả|Ã|Â|Ầ|Ấ|Ậ|Ẩ|Ẫ|Ă|Ằ|Ắ|Ặ|Ẳ|Ẵ/g, "A")
                            .replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, "e")
                            .replace(/È|É|Ẹ|Ẻ|Ẽ|Ê|Ề|Ế|Ệ|Ể|Ễ/g, "E")
                            .replace(/ì|í|ị|ỉ|ĩ/g, "i")
                            .replace(/Ì|Í|Ị|Ỉ|Ĩ/g, "I")
                            .replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, "o")
                            .replace(/Ò|Ó|Ọ|Ỏ|Õ|Ô|Ồ|Ố|Ộ|Ổ|Ỗ|Ơ|Ờ|Ớ|Ợ|Ở|Ỡ/g, "O")
                            .replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, "u")
                            .replace(/Ù|Ú|Ụ|Ủ|Ũ|Ư|Ừ|Ứ|Ự|Ử|Ữ/g, "U")
                            .replace(/ỳ|ý|ỵ|ỷ|ỹ/g, "y")
                            .replace(/Ỳ|Ý|Ỵ|Ỷ|Ỹ/g, "Y")
                            .replace(/đ/g, "d")
                            .replace(/Đ/g, "D")
                            .replace(/\u0300|\u0301|\u0303|\u0309|\u0323/g, "")
                            .replace(/\u02C6|\u0306|\u031B/g, "");
                    }

                    var text = record.name + ' ' + record.position + ' ' + record.department + ' ' + record.phone_1 + ' ' + record.phone_2;
                    text += ' ' + record.email_1 + ' ' + record.email_2;
                    text = text.toLowerCase();
                    var nvnText = nonAccentVietnamese(text);
                    var words = text.trim().split(/[\s,\\.]+/);
                    var nvnWords = nvnText.trim().split(/[\s,\\.]+/);
                    var wordDict = {};
                    for (var i = 0; i < words.length; i++) {
                        wordDict[words[i]] = true;
                    }

                    var score = 0;
                    var mustIncluded = true;
                    for (var key in extraParams.wordDict) {
                        if (!wordDict[key]) {
                            mustIncluded = false;
                            break;
                        }
                    }
                    if (mustIncluded) score += 1e4;

                    var idx = text.indexOf(extraParams.text);
                    if (idx >= 0) {
                        mustIncluded = true;
                        score += 1e3 / (idx + 1);
                    }
                    else  {
                        idx = nvnText.indexOf(extraParams.nvnText);
                        if (idx >= 0) {
                            mustIncluded = true;
                            score += 1e3 / (idx + 1e3);
                        }
                    }
                    if (mustIncluded) return {
                        id: record.id,
                        icld: true,
                        name: record.name,
                        score: score
                    };
                    score = wordsMatch(nvnWords, extraParams.nvnWords)
                        + wordsMatch(words, extraParams.words);
                    if (score > 0.2)
                        return {
                            id: record.id,
                            score: score
                        };
                    return null;
                },
                extraParams: extraParams,
                callbackfunc: function (values) {
                    var newFilter = {
                        searchValue: host.inputsearchbox.value.trim(),
                        marked_value: host.marked_view_elt? host.marked_view_elt.value : false,
                        markedDic: host.markedDic
                    };
                    if (host && EncodingClass.string.compare(newFilter, filter)){
                        reject("cancel");
                        return;
                    }
                    var forSortingArr = [];
                    var icldArr = [];
                    var maxScore = 0;
                    for (var i = 0; i < values.length; ++i) {
                        if (values[i].icld) {
                            values[i].name = absol.string.nonAccentVietnamese(values[i].name);
                            icldArr.push(values[i]);
                        }
                        else {
                            forSortingArr.push(values[i]);
                        }
                    }

                    if (filter.searchValue === ""){
                        icldArr.sort(function(a, b){
                            if (a.name < b.name) return -1;
                            return 1;
                        });
                    }

                    icldArr.sort(function(a, b) {
                        return b.score - a.score;
                    });
                    var idArr = [];
                    for (var i = 0; i < icldArr.length; i++){
                        idArr.push(icldArr[i].id);
                    }
                    forSortingArr.sort(function(a, b) {
                        return b.score - a.score;
                    });
                    var maxScore;
                    if (forSortingArr.length > 0){
                        maxScore = forSortingArr[0].score;
                        for (var i = 0; i < forSortingArr.length; i++){
                            if (forSortingArr[i].score > (maxScore*0.8)) idArr.push(forSortingArr[i].id);
                        }
                    }
                    if (idArr.length > 500) idArr = idArr.splice(0, 500);
                    for (var i = 0; i < forSortingArr.length; i++){
                        idArr.push(forSortingArr[i].id);
                    }
                    resolve(idArr);
                }
            });
        };
        func1();
    });
};

hr.contact.updateRowById = function(host, id, data){
    var t = host.inputidboxes[id];
    if (t){
        while (t.tagName.toLowerCase() != "tr"){
            t = t.parentNode;
        }
        var oldRows = [t];
        for (var i = 0; i < host.design.rows.length - 1; i++){
            t = t.nextSibling;
            if (t) oldRows.push(t);
        }
        var newRows = hr.contact.getCellContact(host, id, 1, data);
        for (var i = 0; i < oldRows.length; i++){
            var j = 0;
            if (i == 0){
                j = 1;
            }
            for (var m = oldRows[i].childNodes.length - 1; m >= j ; m--){
                oldRows[i].replaceChild(newRows[i].childNodes[m], oldRows[i].childNodes[m]);
            }
        }
    }
};

hr.contact.deleteRowById = function(host, id){
    var index = host.allContactIDList.indexOf(id);
    if (index >= 0) host.allContactIDList.splice(index, 1);
    index = host.idListView.indexOf(id);
    var t;
    if (index >= 0){
        for (var i = index + 1; i < host.countView; i++){
            t = host.inputidboxes[host.idListView[i]];
            if (t){
                while (t.tagName.toLowerCase() != "tr"){
                    t = t.parentNode;
                }
                t.firstChild.innerText = i;
            }
        }
        host.idListView.splice(index, 1);
    }
    t = host.inputidboxes[id];
    if (t){
        while (t.tagName.toLowerCase() != "tr"){
            t = t.parentNode;
        }
        var l = [t];
        for (var i = 0; i < host.design.rows.length; i++){
            t = t.nextSibling;
            if (t) l.push(t);
        }
        for (var i = 0; i < l.length; i++){
            l[i].remove();
        }
        host.countView--;
        delete l;
        delete host.inputidboxes[id];
    }
};

hr.contact.deleteContact = function(host, id){
    return new Promise(function(resolve,reject){
        ModalElement.show_loading();
        FormClass.api_call({
            url: "contact_delete.php",
            params: [{name: "id", value: id}],
            func: function(success, message){
                ModalElement.close(-1);
                if (success){
                    if (message.substr(0, 2) == "ok"){
                        hr.contact.deleteRowById(host, id);
                        resolve();
                    }
                    else if (message == "lock_system"){
                        ModalElement.alert({message: LanguageModule.text("war_txt_system_lock")});
                    }
                    else if (message == "failed_used"){
                        ModalElement.alert({
                            message: LanguageModule.text("war_txt_can_not_delete")
                        });
                    }
                    else {
                        ModalElement.alert({message: message});
                    }
                }
                else {
                    ModalElement.alert({message: message});
                }
            }
        });
    });
};

hr.contact.deleteContactConfirm = function(host, id){
    return new Promise(function(resolve,reject){
        var contactData = data_module.getContent("contacts", id);
        ModalElement.question({
            title: LanguageModule.text("war_title_delete_contact"),
            message: LanguageModule.text2("war_txt_detele", [contactData.name]),
            onclick: function(sel){
                if (sel == 0){
                    hr.contact.deleteContact(host, id).then(function(value){
                        resolve(value);
                    });
                }
            }
        });
    });
};

hr.contact.addContactSubmitFunc = function(host, id, getValueFunction){
    return new Promise(function(resolve,reject){
        var data = getValueFunction();
        if (!data) return;
        var saveFunc = function(){
            var oldData;
            if (id > 0){
                oldData = host.dataContactEdit;
                var ischange = contentModule.isChanged(oldData, data,
                    ["name", "position", "department", "partnerid", "phone_1", "email_1", "phone_2", "email_2", "owner", "available", "extrainfo"]
                );
                if (!ischange){
                    resolve(oldData);
                    return;
                }
            }
            else {
                oldData = {};
            }
            data.id = id;
            data.available = data.available? 1 : 0;
            if (id > 0){
                data.ver = host.dataContactEdit.ver;
            }
            else {
                data.ver = 1;
            }
            data.extrainfo = EncodingClass.string.fromVariable(data.extrainfo);
            ModalElement.show_loading();
            FormClass.api_call({
                url: "contact_save.php",
                params: [
                    {name: "data", value: EncodingClass.string.fromVariable(data)},
                    {name: "old_data", value: EncodingClass.string.fromVariable(oldData)}
                ],
                func: function(success, message){
                    ModalElement.close(-1);
                    if (success){
                        if (message.substr(0, 2) == "ok"){
                            var st = EncodingClass.string.toVariable(message.substr(2));
                            st.extrainfo = EncodingClass.string.toVariable(st.extrainfo);
                            if (host.employeeOfMe.indexOf(st.owner) >= 0 || systemconfig.privSystem >= 2 || (host.privilegesDic[-st.owner] && host.privilegesDic[-st.owner].edit_employees_contacts)) {
                                resolve(st);
                            }
                            else resolve();
                        }
                        else if (message == "lock_system"){
                            ModalElement.alert({message: LanguageModule.text("war_txt_system_lock")});
                        }
                        else if (message == "deleted" || message == "edited"){
                            ModalElement.alert({
                                message: LanguageModule.text("war_txt_failed_ver_reload_data")
                            });
                        }
                        else if (message == "exist_name"){
                            ModalElement.alert({message: LanguageModule.text("war_txt_exist_name")});
                        }
                        else {
                            ModalElement.alert({message: message});
                        }
                    }
                    else {
                        ModalElement.alert({message: message});
                    }
                }
            });
        };
        if (host.employeeOfMe.indexOf(data.owner) < 0 && systemconfig.privSystem < 2 && (!host.privilegesDic[-data.owner] || !host.privilegesDic[-data.owner].edit_employees_contacts)){
            ModalElement.question({
                title: LanguageModule.text("txt_warning"),
                message: "Bạn sẽ mất quyền với liên hệ này.",
                onclick: function(sel){
                    if (sel == 0){
                        saveFunc();
                    }
                }
            });
            return;
        }
        else {
            saveFunc();
        };
    });
};

hr.contact.addContactSubmit = function(host, id, getValueFunction){
    return new Promise(function(resolve, reject) {
        hr.contact.addContactSubmitFunc(host, id, getValueFunction).then(function(st){
            resolve();
            if (!st){
                if (id > 0){
                    window.backLayoutFunc.pop();
                    if (!host.quick_open){
                        host.frameList.removeLast();
                        hr.contact.deleteRowById(host, id);
                    }
                    else {
                        hr.menu.tabPanel.removeTab(host.holder.id);
                    }
                }
            }
            else {
                if (id > 0){
                    host.dataContactEdit = st;
                    host.drawContactViewFunc(host.viewContact);
                    if (!host.quick_open){
                        hr.contact.updateRowById(host, id, st);
                    }
                }
                else {
                    id = st.id;
                    hr.contact.showContactPre(host, id);
                    host.idListView.push(id);
                    host.allContactIDList.push(id);
                    host.countView++;
                    var rows = hr.contact.getCellContact(host, id, host.countView, st);
                    for (var j = 0; j < rows.length; j++){
                        host.tableView.appendChild(rows[j]);
                    }
                }
                if (host.redraw_history_func){
                    host.redraw_history_func();
                }
            }
        });
    });
};

hr.contact.addContactClose = function(host, id, getValueFunction){
    return new Promise(function(resolve, reject){
        var data = getValueFunction("no_alert");
        if (!data) {
            resolve();
            return;
        }
        if (id > 0){
            var oldData = host.dataContactEdit;
            var ischange = contentModule.isChanged(oldData, data,
                ["name", "position", "department", "partnerid", "phone_1", "email_1", "phone_2", "email_2", "owner", "available", "extrainfo"]
            );
        }
        else {
            var ischange = false;
        }
        if (!ischange){
            resolve();
            return;
        }
        contentModule.questionChange({
            onclick: function(sel){
                if (sel == 0){
                    hr.contact.addContactSubmit(host, host.contactid, getValueFunction).then(function(value){
                        resolve();
                    });
                }
                else if (sel == 1){
                    resolve();
                }
            }
        });
    });
};

hr.contact.redrawDetails = function(host, id){
    host.contactid = id;
    function redraw(value){
        var formContainer = DOMElement.div({});
        theme.formContactEdit({
            title: (id == 0)? LanguageModule.text("txt_add") : LanguageModule.text("txt_edit"),
            formContainer: formContainer,
            frameList: host.frameList,
            func: {
                save: function(){
                    return hr.contact.addContactSubmit(host, host.contactid, getValueFunction);
                },
                cancel: function(){
                    return hr.contact.addContactClose(host, host.contactid, getValueFunction);
                }
            }
        });
        var getValueFunction;
        contentModule.makeFormData({
            typeid: data_module.form_config.contact.typeid,
            formid: data_module.form_config.contact.input_form,
            initialValue: value,
            formContainer: formContainer,
            typelists: data_module.typelists.items,
            variableType: "system"
        }).then(function(getValue){
            getValueFunction = getValue;
            absol.form.traversal(formContainer.formFragment.view, function(item){
                if (item.node.tag === "TextInput") {
                    item.node.domElt.focus();
                    item.stop();
                    return;
                }
            });
            formContainer.formFragment.afterEntryCompleted().then(function(){
                if (host.fromPartner){
                    var elt = absol.form.findComponent(formContainer.formFragment.view, {
                        name: 'type_contact_partnerid',
                        depth: false
                    });
                    if (elt){
                        var partnerData = data_module.getContent("partners", host.partnerid);
                        if (partnerData){
                            elt.attributes.items = [{
                                value: host.partnerid,
                                text: partnerData.name
                            }];
                            elt.attributes.value = host.partnerid;
                            var lastPartnerID = host.partnerid;
                            elt.domElt.on("change", function(){
                                if (lastPartnerID == host.partnerid && this.value != host.partnerid){
                                    var message;
                                    if (this.value == 0){
                                        message = LanguageModule.text2("war_txt_warning_change_partner_of_contact_no_select", [partnerData.name]);
                                    }
                                    else {
                                        var newPartnerName = "";
                                        var newPartnerData = data_module.getContent("partners", this.value);
                                        message = LanguageModule.text2("war_txt_warning_change_partner_of_contact", [partnerData.name, newPartnerData.name]);
                                    }
                                    ModalElement.question({
                                        message: message,
                                        onclick: function(sel){
                                            if (sel == 1){
                                                elt.attributes.items = [{
                                                    value: host.partnerid,
                                                    text: partnerData.name
                                                }];
                                                elt.attributes.value = host.partnerid;
                                                lastPartnerID = host.partnerid;
                                            }
                                        }
                                    });
                                }
                                lastPartnerID = this.value;
                            });
                        }
                    }
                }
                if (id == 0 && host.employeeOfMe.length > 0){
                    var elt = absol.form.findComponent(formContainer.formFragment.view, {
                        name: 'type_contact_owner',
                        depth: false
                    });
                    if (elt){
                        elt.attributes.value = host.employeeOfMe[0];
                    }
                }
            });
        });
    };
    if (id == 0){
        redraw();
    }
    else {
        redraw(host.dataContactEdit);
    }
};
hr.contact.loadContactById = function(host, id){
    return new Promise(function(resolve, reject){
        data_module.loadTables(["contacts"], function(){
            if (!data_module.cacheContent_contacts.exists(id)) {
                ModalElement.alert({
                    message: LanguageModule.text("war_txt_failed_data"),
                    func: function(){
                        hr.contact.init(host);
                    }
                });
                return;
            }
            host.dataContactEdit = data_module.getContent("contacts", id);
            delete host.dataContactEdit.uts;
            if (host.dataContactEdit.extrainfo == "") host.dataContactEdit.extrainfo = {};
            else host.dataContactEdit.extrainfo = EncodingClass.string.toVariable(host.dataContactEdit.extrainfo);
            resolve();
        });
    });
};

hr.contact.addContact = function(host, id){
    if (id == 0){
        hr.contact.redrawDetails(host, id);
    }
    else {
        ModalElement.show_loading();
        hr.contact.loadContactById(host, id).then(function(){
            ModalElement.close(-1);
            hr.contact.redrawDetails(host, id);
        });
    }
};

hr.contact.showContact = function(host, id){
    host.contactid = id;
    host.drawContactViewFunc = function(viewContact){
        host.viewContact = viewContact;
        DOMElement.removeAllChildren(host.nameViewCtn);
        host.nameViewCtn.appendChild(DOMElement.span({
            attrs: {style: {fontWeight: "bold"}},
            text: host.dataContactEdit.name
        }));
        contentModule.makeOutputFormData({
            typeid: data_module.form_config.contact.typeid,
            formid: data_module.form_config.contact.output_form,
            initialValue: host.dataContactEdit,
            formContainer: host.viewContact,
            typelists: data_module.typelists.items,
            variableType: "system"
        }).then(function(getValue){});
    };
    var load_history_func = function(){
        return new Promise(function(rs, rj){
            ModalElement.show_loading();
            FormClass.api_call({
                url: "database_load.php",
                params: [
                    {name: "task", value: "contact_load_history_by_id"},
                    {name: "id", value: id}
                ],
                func: function(success, message){
                    if (success){
                        if (message.substr(0, 2) == "ok"){
                            var st = EncodingClass.string.toVariable(message.substr(2));
                            st.sort(function(a, b){
                                return b.createdtime - a.createdtime;
                            });
                            rs(st);
                        }
                        else {
                            ModalElement.alert({message: message});
                        }
                    }
                    else {
                        ModalElement.alert({message: message});
                    }
                }
            });
        });
    };
    var params = {
        func: {
            editContact: function(){
                hr.contact.addContact(host, host.contactid);
            }
        },
        quick_open: host.quick_open,
        load_history_func: function(){
            return load_history_func();
        }
    };
    theme.formContactShow(host, params);
    host.redraw_history_func = params.redraw_history_func;
};

hr.contact.showContactPre = function(host, id){
    ModalElement.show_loading();
    hr.contact.loadContactById(host, id).then(function(){
        ModalElement.close(-1);
        hr.contact.showContact(host, id);
    });
};

hr.contact.getCellContact = function(host, id, stt, res){
    if (!res){
        res = data_module.getContent("contacts", id);
        if (!res) return [];
        if (res.extrainfo != "") res.extrainfo = EncodingClass.string.toVariable(res.extrainfo);
        else res = {};
    }
    if (host.workFlowViewContact){
        var func = host.func;
    }
    else if (host.objectSelectContact){
        if (host.contactNotViewDic[res.id]) return null;
        var func = {
            view: function(){
                checkboxElt.checked = !checkboxElt.checked;
                host.checked_dic[res.id] = checkboxElt.checked;
            }
        };
    }
    else if (host.selectOneContact){
        var func = {
            view: function(){
                radioElt.checked = true;
                host.valueChecked = res.id;
            }
        };
    }
    else {
        var func = {
            view: function(){
                if (!host.merge_ing) hr.contact.showContactPre(host, res.id);
            },
            markedFunc: function(id, marked){
                return contentModule.markedFunc(null, {
                    id: id,
                    marked: marked,
                    task: "contact",
                    tablename: "contact"
                });
            }
        };
        func.delete = function(){
            return new Promise(function(resolve, reject){
                hr.contact.deleteContactConfirm(host, res.id);
            });
        };
    }
    var rows = contentModule.getCellNewTable(host.design, host.configColumnContactDic, res, 3, function(){
        if (func.view) func.view(res.id);
    });
    var starElt;
    if (host.markedDic[res.id]){
        starElt = contentModule.getstarIconView();
        rows[0].children[0].appendChild(starElt);
    }
    if (host.objectSelectContact){
        var checkboxElt = absol.buildDom({
            tag: "checkbox",
            props: {
                checked: host.checked_dic[res.id]
            },
            on: {
                change: function(){
                    host.checked_dic[res.id] = this.checked;
                }
            }
        });
        host.checkboxBoxes[res.id] = checkboxElt;
        rows[0].insertBefore(DOMElement.td({
            attrs: {
                rowSpan: host.design.rows.length, style: {width: "40px", textAlign: "center"}
            },
            children: [checkboxElt]
        }), rows[0].firstChild);
    }
    else if (host.selectOneContact){
        var radioElt = absol.buildDom({
            tag: "radio",
            props: {
                name: "radio_" + host.randomId,
                checked: res.id == host.valueChecked
            },
            on: {
                change: function(){
                    host.valueChecked = res.id;
                }
            }
        });
        rows[0].insertBefore(DOMElement.td({
            attrs: {
                rowSpan: host.design.rows.length, style: {width: "40px", textAlign: "center"}
            },
            children: [radioElt]
        }), rows[0].firstChild);
    }
    if (!host.selectOneContact) rows[0].insertBefore(DOMElement.td({
        attrs: {
            rowSpan: host.design.rows.length, style: {width: "40px", textAlign: "center", cursor: "pointer", color: "burlywood"},
            onclick: function(){
                if (func.view) func.view(res.id);
            }
        },
        text: stt
    }), rows[0].firstChild);
    if (!host.objectSelectContact && !host.selectOneContact) {
        var qmenuButton = DOMElement.div({
            attrs: {
                className: "card-icon-cover"
            },
            children: [DOMElement.i({
                attrs: {
                    className: "material-icons bsc-icon-hover-black",
                    style: {color: "burlywood"}
                },
                text: "more_vert"
            })]
        });
        host.inputidboxes[res.id] = qmenuButton;
        absol.QuickMenu.toggleWhenClick(qmenuButton, {
            getMenuProps: function(){
                var quickMenuItems = [];
                if (func.view) quickMenuItems.push({
                    text: LanguageModule.text("txt_view"),
                    extendClasses: "bsc-quickmenu",
                    icon: DOMElement.i({
                        attrs: {
                            className: "material-icons"
                        },
                        text: "visibility"
                    }),
                    cmd: function(){
                        func.view(res.id);
                    }
                });
                if (func.markedFunc){
                    if (host.markedDic[res.id]){
                        quickMenuItems.push({
                            text: LanguageModule.text("txt_remove_marked"),
                            extendClasses: ["bsc-quickmenu"],
                            icon: DOMElement.i({
                                attrs: {
                                    className: "material-icons",
                                    style: {
                                        color: "#ffa834"
                                    }
                                },
                                text: "star_border"
                            }),
                            cmd: function(){
                                func.markedFunc(res.id, false).then(function(){
                                    host.markedDic[res.id] = false;
                                    starElt.remove();
                                });
                            }
                        });
                    }
                    else {
                        quickMenuItems.push({
                            text: LanguageModule.text("txt_add_to_marked"),
                            extendClasses: ["bsc-quickmenu"],
                            icon: DOMElement.i({
                                attrs: {
                                    className: "material-icons",
                                    style: {
                                        color: "#ffa834"
                                    }
                                },
                                text: "star"
                            }),
                            cmd: function(){
                                func.markedFunc(res.id, true).then(function(){
                                    host.markedDic[res.id] = true;
                                    starElt = contentModule.getstarIconView();
                                    rows[0].children[1].appendChild(starElt);
                                });
                            }
                        });
                    }
                }
                if (func.delete) quickMenuItems.push({
                    text: LanguageModule.text("txt_delete"),
                    extendClasses: ["bsc-quickmenu", "red"],
                    icon: DOMElement.i({
                        attrs: {
                            className: "material-icons"
                        },
                        text: "delete"
                    }),
                    cmd: function(){
                        func.delete(res.id);
                    }
                });
                return {items: quickMenuItems};
            },
            onSelect: function (item){
                item.cmd();
            }
        }, [3, 4]);
        rows[0].appendChild(DOMElement.td({
            attrs: {rowSpan: host.design.rows.length, style: {width: "40px", textAlign: "center"}},
            children: [qmenuButton]
        }));
    }
    return rows;
};

hr.contact.redraw = function(host){
    host.inputidboxes = {};
    var func = function(filter){
        ModalElement.close(-1);
        host.countView = 0;
        var startView = 0;
        host.done = false;
        var getIDList = function(){
            startView = host.countView;
            var idList = [];
            for (var i = host.countView; i < host.countView + 30; i++){
                if (i >= host.idListView.length){
                    host.countView = i;
                    host.done = true;
                    break;
                }
                idList.push(host.idListView[i]);
            }
            if (!host.done) host.countView = host.countView + 30;
            return idList;
        };
        var idList = getIDList();
        var data = [], rows;
        if (host.selectOneContact){
            if (host.allValue || host.selectValue){
                var radioElt = absol.buildDom({
                    tag: "radio",
                    props: {
                        name: "radio_" + host.randomId,
                        checked: host.valueChecked == 0
                    },
                    on: {
                        change: function(){
                            host.valueChecked = 0;
                        }
                    }
                });
                data.push([
                    {
                        attrs: {align: "center"},
                        children: [radioElt]
                    },
                    {
                        attrs: {
                            colSpan: 100,
                            onclick: function(){
                                radioElt.checked = true;
                                host.valueChecked = 0;
                            }
                        },
                        text: host.allValue? LanguageModule.text("txt_all_contact") : LanguageModule.text("txt_select_value")
                    }
                ]);
            }
        }
        for (var i = 0; i < idList.length; i++){
            rows = hr.contact.getCellContact(host, idList[i], i + 1);
            if (rows === null) continue;
            for (var j = 0; j < rows.length; j++){
                data.push(rows[j]);
            }
        }
        host.tableView = DOMElement.table({
            attrs: {style: {backgroundColor: "white"}},
            data: data
        });
        if (host.merge_ing){
            hr.contact.toggleMerge(host, true);
        }
        if (hr.isMobile) host.tableView.style.width = "100%";
        DOMElement.removeAllChildren(host.data_container);
        var table_ctn = DOMElement.table({
            data: [[{
                attrs: {
                    className: "hrnewtableclass"
                },
                children: [host.tableView]
            }]]
        });
        if (hr.isMobile) table_ctn.style.width = "100%";
        host.data_container.appendChild(table_ctn);
        if (!host.done){
            host.see_more_ctn = DOMElement.div({
                attrs: {style: {paddingTop: "20px", textAlign: "center"}},
                children: [DOMElement.span({
                    attrs: {
                        style: {
                            color: "var(--a-color)",
                            cursor: "pointer"
                        },
                        onclick: function(){
                            var idList = getIDList();
                            if (host.done) DOMElement.removeAllChildren(host.see_more_ctn);
                            var rows;
                            for (var i = 0; i < idList.length; i++){
                                rows = hr.contact.getCellContact(host, idList[i], startView + i + 1);
                                if (rows === null) continue;
                                for (var j = 0; j < rows.length; j++){
                                    host.tableView.appendChild(rows[j]);
                                }
                            }
                            if (host.merge_ing){
                                hr.contact.toggleMerge(host, true);
                            }
                        }
                    },
                    text: LanguageModule.text("txt_see_more")
                })]
            });
            table_ctn.appendChild(host.see_more_ctn);
        }
        if (!host.workFlowViewContact && !host.fromPartner) host.data_container.appendChild(DOMElement.div({attrs: {style: {height: "var(--footer-margin)"}}}));
    };
    var isSearch = false;
    if (host.inputsearchbox && host.inputsearchbox.value.trim() !== "") isSearch = true;
    if (!host.workFlowViewContact && !host.fromPartner) ModalElement.show_loading();
    var filter;
    if (isSearch){
        filter = {
            searchValue: host.inputsearchbox? host.inputsearchbox.value.trim() : "",
            marked_value: host.marked_view_elt? host.marked_view_elt.value : false,
            markedDic: host.markedDic
        };
        hr.contact.searchDataFunc(filter, host).then(function(idList){
            host.idListView = idList;
            if (host.idListView.length == 0){
                ModalElement.close(-1);
                DOMElement.removeAllChildren(host.data_container);
                host.data_container.appendChild(DOMElement.div({
                    attrs: {align: "center", style: {paddingTop: "20px", color: "red"}},
                    text: "Không tìm thấy kết quả phù hợp"
                }));
                return;
            }
            func(filter);
        }, function(value){
            if (value == "cancel"){
                // TODO:
            }
        });
    }
    else {
        filter = {};
        if (host.marked_view_elt && host.marked_view_elt.value){
            host.idListView = [];
            for (var x in host.markedDic){
                if (host.markedDic[x]) host.idListView.push(x);
            }
            if (host.idListView.length == 0){
                ModalElement.close(-1);
                DOMElement.removeAllChildren(host.data_container);
                host.data_container.appendChild(DOMElement.div({
                    attrs: {align: "center", style: {paddingTop: "20px", color: "red"}},
                    text: "Không tìm thấy kết quả phù hợp"
                }));
                return;
            }
        }
        else {
            host.idListView = EncodingClass.string.duplicate(host.allContactIDList);
            if (host.workFlowViewContact && host.idListView.length == 0){
                ModalElement.close(-1);
                return;
            }
        }
        window.idListView = host.idListView;
        func(filter);
    }
};

hr.contact.mergeSubmit = function(host, list, data){
    var mainData = contentModule.getContactMainData();
    var value = {};
    for (var x in mainData){
        value[mainData[x]] = data[x];
        delete data[x];
    }
    value.extrainfo = data;
    var idList = [];
    for (var i = 0; i < list.length; i++){
        idList.push(list[i].id);
    }
    value.extrainfo = EncodingClass.string.fromVariable(value.extrainfo);
    ModalElement.show_loading();
    FormClass.api_call({
        url: "contact_merge_save.php",
        params: [
            {name: "data", value: EncodingClass.string.fromVariable(value)},
            {name: "idList", value: EncodingClass.string.fromVariable(idList)}
        ],
        func: function(success, message){
            ModalElement.close(-1);
            if (success){
                if (message.substr(0, 2) == "ok"){
                    var st = EncodingClass.string.toVariable(message.substr(2));
                    st.extrainfo = EncodingClass.string.toVariable(st.extrainfo);
                    var t = data_module.getContent("contacts", idList[0]);
                    st.userid = t.userid;
                    hr.contact.toggleMerge(host, false);
                    hr.contact.updateRowById(host, idList[0], st, true);
                    for (var i = 1; i < idList.length; i++){
                        hr.contact.deleteRowById(host, idList[i]);
                    }
                    host.frameList.removeLast();
                    host.listContactMerge = {};
                    hr.contact.toggleMerge(host, true);
                    window.backLayoutFunc.pop();
                }
                else if (message == "deleted"){
                    ModalElement.alert({
                        message: LanguageModule.text("war_txt_failed_ver_reload_data")
                    });
                }
                else {
                    ModalElement.alert({message: message});
                }
            }
            else {
                ModalElement.alert({message: message});
            }
        }
    });
};

hr.contact.redrawMerge = function(host, list){
    var dict = {};
    data_module.typelists.items.forEach(function (elt, index) {
        dict[elt.id] = elt;
    });
    var mainData = contentModule.getMainData(data_module.form_config.contact.typeid, dict);
    var listData = [], data;
    for (var i = 0; i < list.length; i++){
        data = {};
        for (var x in mainData){
            data[x] = list[i][mainData[x]];
        }
        for (var x in list[i].extrainfo){
            data[x] = list[i].extrainfo[x];
        }
        listData.push(data);
    }
    var mTool;
    host.typelistsDic = contentModule.makeDictionaryIndex(data_module.typelists.items);
    ModalElement.show_loading();
    contentModule.getFieldsMergeByTypeID(host, data_module.form_config.contact.typeid).then(function(descriptor){
        descriptor.displayName = LanguageModule.text("txt_general_information");
        ModalElement.close(-1);
        mTool = absol.buildDom({
            tag: 'objectmergetool',
            props: {
                objects: listData,
                descriptor: descriptor
            }
        });
        data_ctn.appendChild(mTool);
    });
    var data_ctn = DOMElement.div({});
    var singlePage = absol.buildDom({
        tag: "singlepage",
        child: [
            DOMElement.div({
                attrs: {className: 'button-panel-header absol-single-page-header'},
                children: [
                    DOMElement.div({
                        attrs: {className: "single-button-header"},
                        children: [theme.backButton({
                            onclick: function(){
                                host.frameList.removeLast();
                                window.backLayoutFunc.pop();
                            }
                        })]
                    }),
                    DOMElement.div({
                        attrs: {className: "single-button-header"},
                        children: [theme.saveButton({
                            onclick: function(){
                                hr.contact.mergeSubmit(host, list, mTool.data);
                            }
                        })]
                    })
                ]
            }),
            data_ctn
        ]
    });
    host.frameList.addChild(singlePage);
    singlePage.requestActive();
    window.backLayoutFunc.push({
        func: function(){
            host.frameList.removeLast();
            window.backLayoutFunc.pop();
        }
    });
};

hr.contact.merge = function(host, save){
    if (save){
        var idList = [];
        for (var x in host.listContactMerge){
            if (host.listContactMerge[x]){
                idList.push(parseInt(x, 10));
            }
        }
        if (idList.length < 2){
            ModalElement.alert({message: "Bạn phải chọn ít nhất 2 liên hệ để trộn"});
            return;
        }
        var list = [];
        var res;
        for (var i = 0; i < idList.length; i++){
            res = data_module.getContent("contacts", idList[i]);
            if (res.extrainfo == "") res.extrainfo = {};
            else res.extrainfo = EncodingClass.string.toVariable(res.extrainfo);
            list.push(res);
        }
        hr.contact.redrawMerge(host, list);
    }
    else {
        host.merge_ing = true;
        host.listContactMerge = {};
        hr.contact.toggleMerge(host, true);
        host.merge_ing = true;
        host.back_btn_ctn.classList.remove("hidden");
        host.merge_save_btn_ctn.classList.remove("hidden");
        host.close_btn_ctn.classList.add("hidden");
        host.add_btn_ctn.classList.add("hidden");
        host.quickmenu_btn_ctn.classList.add("hidden");
    }
};

hr.contact.getCheckboxElt = function(host, id){
    return absol.buildDom({
        tag: "checkbox",
        props: {
            checked: host.listContactMerge[id]
        },
        on: {
            change: function(){
                host.listContactMerge[id] = this.checked;
            }
        }
    });
};


hr.contact.toggleMerge = function(host, merge_ing){
    var t;
    for (var id in host.inputidboxes){
        t = host.inputidboxes[id];
        if (merge_ing) t.parentNode.style.display = "none";
        else t.parentNode.style.display = "";
        while (t.tagName.toLowerCase() != "tr"){
            t = t.parentNode;
        }
        if (!merge_ing) t.removeChild(t.childNodes[1]);
        else t.insertBefore(DOMElement.td({
            attrs: {
                align: "center",
                colSpan: host.design.rows.length
            },
            children: [hr.contact.getCheckboxElt(host, id)]
        }), t.childNodes[1]);
    }
};
hr.contact.getDisplayDicFromDesign = function(design){
    var res = {};
    if (!design.rows) return res;
    for (var i = 0; i < design.rows.length; i++){
        if (design.rows[i].cells){
            for (var j = 0; j < design.rows[i].cells.length; j++){
                if (design.rows[i].cells[j].variables){
                    for (var k = 0; k < design.rows[i].cells[j].variables.length; k++){
                        res[design.rows[i].cells[j].variables[k].name] = true;
                    }
                }
            }
        }
    }
    return res;
};

hr.contact.init2 = function(host){
    return new Promise(function(resolve, reject){
        if (!host.markedDic) host.markedDic = {};
        host.design = contentModule.getDesign(host, "contact", hr.isMobile);
        var displayDic = hr.contact.getDisplayDicFromDesign(host.design);
        var columnList = contentModule.getColumnListFromDatatype(host, "contact", displayDic);
        host.columnList = columnList;
        contentModule.getColumnListConfig(host, undefined, columnList).then(function(values){
            host.configColumnContactDic = {};
            for (var i = 0; i < values.length; i++){
                host.configColumnContactDic[values[i].value] = values[i];
            }
            hr.contact.redraw(host);
            resolve();
        });
    });
};

hr.contact.init = function(host){
    return new Promise(function(resolveMn, rejectMn){
        hr.menu.changeCurrentUrlTab(host, "contact");
        host.database = {};
        host.merge_ing = false;
        ModalElement.show_loading();
        data_module.loadContactsInit(host).then(function(content){
            var cmdbutton = {
                close: function (event, me) {
                    if (hr.isMobile){
                        host.holder.selfRemove();
                        theme.mobileInitBack();
                    }
                    else {
                        hr.menu.tabPanel.removeTab(host.holder.id);
                    }
                },
                add: function (event, me) {
                    hr.contact.addContact(host, 0);
                },
                merge: function(){
                    hr.contact.merge(host, false);
                },
                merge_save: function(){
                    hr.partner.merge(host, true);
                },
                back: function(){
                    hr.contact.toggleMerge(host, false);
                    host.merge_ing = false;
                    host.merge_save_btn_ctn.classList.add("hidden");
                    host.back_btn_ctn.classList.add("hidden");
                    host.close_btn_ctn.classList.remove("hidden");
                    host.add_btn_ctn.classList.remove("hidden");
                    host.quickmenu_btn_ctn.classList.remove("hidden");
                }
            };
            host.data_container = DOMElement.div({});
            host.holder.addChild(host.frameList);
            var singlePage = theme.formContactInit({
                cmdbutton: cmdbutton,
                data_container: host.data_container,
                func: {
                    filter_change_func: function(){
                        hr.contact.redraw(host);
                    },
                    display_setting: function(){
                        contentModule.display_setting(host, "contact", function(){
                            hr.contact.init2(host);
                        });
                    }
                }
            });
            host.inputsearchbox = singlePage.inputsearchbox;
            host.marked_view_elt = singlePage.marked_view_elt;
            host.close_btn_ctn = singlePage.close_btn_ctn;
            host.back_btn_ctn = singlePage.back_btn_ctn;
            host.add_btn_ctn = singlePage.add_btn_ctn;
            host.merge_save_btn_ctn = singlePage.merge_save_btn_ctn;
            host.quickmenu_btn_ctn = singlePage.quickmenu_btn_ctn;
            host.frameList.addChild(singlePage);
            singlePage.requestActive();
            hr.contact.init2(host);
            resolveMn(host);
        });
    });
};

VaKeR 2022